diff options
author | Barry Warsaw <barry@python.org> | 1998-01-26 22:47:35 (GMT) |
---|---|---|
committer | Barry Warsaw <barry@python.org> | 1998-01-26 22:47:35 (GMT) |
commit | abe2a457de09d728ddd0704fc1de855adf263944 (patch) | |
tree | a6319828e132f7bf3598915f526cabffcc930c26 /Lib | |
parent | 5da0f504baa10c6125b5c7cc6dccc801f26f5ff0 (diff) | |
download | cpython-abe2a457de09d728ddd0704fc1de855adf263944.zip cpython-abe2a457de09d728ddd0704fc1de855adf263944.tar.gz cpython-abe2a457de09d728ddd0704fc1de855adf263944.tar.bz2 |
Unpickler.load_inst(), Unpickler.load_obj(), Unpickler.load_build():
Fixed problems when unpickling in restricted execution environments.
These methods try to assign to an instance's __class__ attribute, or
access the instances __dict__, which are prohibited in REE. For the
first two methods, I re-implemented the old behavior when assignment
to value.__class__ fails.
For the load_build() I also re-implemented the old behavior when
inst.__dict__.update() fails but this means that unpickling in REE is
semantically different than unpickling in unrestricted mode.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/pickle.py | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py index 4644ee9..5c69f7a 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -601,11 +601,17 @@ class Unpickler: module = self.readline()[:-1] name = self.readline()[:-1] klass = self.find_class(module, name) + instantiated = 0 if (not args and type(klass) is ClassType and not hasattr(klass, "__getinitargs__")): - value = _EmptyClass() - value.__class__ = klass - else: + try: + value = _EmptyClass() + value.__class__ = klass + except RuntimeError: + # In restricted execution, assignment to inst.__class__ is + # prohibited + pass + if not instantiated: value = apply(klass, args) self.append(value) dispatch[INST] = load_inst @@ -617,11 +623,18 @@ class Unpickler: del stack[k + 1] args = tuple(stack[k + 1:]) del stack[k:] + instantiated = 0 if (not args and type(klass) is ClassType and not hasattr(klass, "__getinitargs__")): - value = _EmptyClass() - value.__class__ = klass - else: + try: + value = _EmptyClass() + value.__class__ = klass + instantiated = 1 + except RuntimeError: + # In restricted execution, assignment to inst.__class__ is + # prohibited + pass + if not instantiated: value = apply(klass, args) self.append(value) dispatch[OBJ] = load_obj @@ -756,7 +769,15 @@ class Unpickler: try: setstate = inst.__setstate__ except AttributeError: - inst.__dict__.update(value) + try: + inst.__dict__.update(value) + except RuntimeError: + # XXX In restricted execution, the instance's __dict__ is not + # accessible. Use the old way of unpickling the instance + # variables. This is a semantic different when unpickling in + # restricted vs. unrestricted modes. + for k, v in value.items(): + setattr(inst, k, v) else: setstate(value) dispatch[BUILD] = load_build |