def unpickle(file_path=None): """Load pickled Python objects from a file. Almost like ``cPickle.load(open(file_path))``, but also loads object saved with older versions of Eelbrain, and allows using a system file dialog to select a file. Parameters ---------- file_path : None | str Path to a pickled file. If None (default), a system file dialog will be shown. If the user cancels the file dialog, a RuntimeError is raised. """ if file_path is None: filetypes = [("Pickles (*.pickled)", '*.pickled'), ("All files", '*')] file_path = ui.ask_file("Select File to Unpickle", "Select a pickled " "file to unpickle", filetypes) if file_path is False: raise RuntimeError("User canceled") else: print(repr(file_path)) else: file_path = os.path.expanduser(file_path) if not os.path.exists(file_path): new_path = os.extsep.join((file_path, 'pickled')) if os.path.exists(new_path): file_path = new_path with open(file_path, 'rb') as fid: unpickler = Unpickler(fid) unpickler.find_global = map_paths obj = unpickler.load() return obj
def _unpickle(pickled): """ Unpickles a string and catch all types of errors it can throw, to raise only NotReadableJobError in case of error. odoo stores the text fields as 'utf-8', so we specify the encoding. `loads()` may raises many types of exceptions (AttributeError, IndexError, TypeError, KeyError, ...). They are all catched and raised as `NotReadableJobError`). Pickle could be exploited by an attacker who would write a value in a job that would run arbitrary code when unpickled. This is why we set a custom ``find_global`` method on the ``Unpickler``, only jobs and a whitelist of classes/functions are allowed to be unpickled (plus the builtins types). """ def restricted_find_global(mod_name, fn_name): __import__(mod_name) mod = sys.modules[mod_name] fn = getattr(mod, fn_name) if not (fn in JOB_REGISTRY or fn in _UNPICKLE_WHITELIST): raise UnpicklingError('{}.{} is not allowed in jobs'.format( mod_name, fn_name)) return fn unpickler = Unpickler(StringIO(pickled)) unpickler.find_global = restricted_find_global try: unpickled = unpickler.load() except (Exception, UnpicklingError): raise NotReadableJobError('Could not unpickle.', pickled) return unpickled
def load(self, file): """Unpickle a file.""" safeUnpickler = Unpickler(file) safeUnpickler.find_global = self.findGlobal return safeUnpickler.load()