summaryrefslogtreecommitdiffstats
path: root/Lib/pickle.py
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>1998-01-26 22:47:35 (GMT)
committerBarry Warsaw <barry@python.org>1998-01-26 22:47:35 (GMT)
commitabe2a457de09d728ddd0704fc1de855adf263944 (patch)
treea6319828e132f7bf3598915f526cabffcc930c26 /Lib/pickle.py
parent5da0f504baa10c6125b5c7cc6dccc801f26f5ff0 (diff)
downloadcpython-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/pickle.py')
-rw-r--r--Lib/pickle.py35
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