Somewhat safer unpickler
This class inherits all the implementation from the builtin pickle.Unpickler
but modifies the self.dispatch
dictionary used to unpack the serialized structures.
This is not checked to be safe, but in case you are using pickled files in production and you are searching for some safer way to load them to convert the data to a different format, this class can be handy.
The same idea works for Python 3, subclassing pickle._Unpickler
.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ####################################################################### | |
# Somewhat safer unpickler, only builtins (/usr/lib/python2.7/pickle.py) | |
# ####################################################################### | |
class LimitedUnpickler(pickle.Unpickler): | |
""" | |
This class inherits all the implementation from the builtin | |
`pickle.Unpickler` but modifies the `self.dispatch` dictionary | |
used to unpack the serialized structures. | |
This is not checked to be safe, but in case you are using pickled | |
files in production and you are searching for some safer way to load | |
them to convert the data to a different format, this class can be handy. | |
""" | |
def __init__(self, file): | |
pickle.Unpickler.__init__(self, file) | |
safe =\ | |
{ pickle.MARK | |
, pickle.STOP | |
, pickle.POP | |
, pickle.POP_MARK | |
, pickle.DUP | |
, pickle.FLOAT | |
, pickle.INT | |
, pickle.BININT | |
, pickle.BININT1 | |
, pickle.LONG | |
, pickle.BININT2 | |
, pickle.NONE | |
, pickle.PERSID | |
, pickle.BINPERSID | |
#, pickle.REDUCE | |
, pickle.STRING | |
, pickle.BINSTRING | |
, pickle.SHORT_BINSTRING | |
, pickle.UNICODE | |
, pickle.BINUNICODE | |
, pickle.APPEND | |
#, pickle.BUILD | |
#, pickle.GLOBAL | |
, pickle.DICT | |
, pickle.EMPTY_DICT | |
, pickle.APPENDS | |
, pickle.GET | |
, pickle.BINGET | |
, pickle.INST | |
, pickle.LONG_BINGET | |
, pickle.LIST | |
, pickle.EMPTY_LIST | |
#, pickle.OBJ | |
, pickle.PUT | |
, pickle.BINPUT | |
, pickle.LONG_BINPUT | |
, pickle.SETITEM | |
, pickle.TUPLE | |
, pickle.EMPTY_TUPLE | |
, pickle.SETITEMS | |
, pickle.BINFLOAT | |
, pickle.TRUE | |
, pickle.FALSE | |
, pickle.PROTO | |
#, pickle.NEWOBJ | |
#, pickle.EXT1 | |
#, pickle.EXT2 | |
#, pickle.EXT4 | |
, pickle.TUPLE1 | |
, pickle.TUPLE2 | |
, pickle.TUPLE3 | |
, pickle.NEWTRUE | |
, pickle.NEWFALSE | |
, pickle.LONG1 | |
, pickle.LONG4 | |
, '' # EOF hardcoded as `dispatch[''] = load_eof` in pickle.py | |
} | |
self.dispatch = {k: v for k, v in self.dispatch.items() if k in safe} | |
def pickle_limited_load(file): | |
return LimitedUnpickler(file).load() |