]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Unpickler.load_inst(), Unpickler.load_obj(), Unpickler.load_build():
authorBarry Warsaw <barry@python.org>
Mon, 26 Jan 1998 22:47:35 +0000 (22:47 +0000)
committerBarry Warsaw <barry@python.org>
Mon, 26 Jan 1998 22:47:35 +0000 (22:47 +0000)
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.

Lib/pickle.py

index 4644ee9b53034e8901f72465354d45796601071b..5c69f7a71e5b143ffcf5859ae146a1737a9ae319 100644 (file)
@@ -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