From abe2a457de09d728ddd0704fc1de855adf263944 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Mon, 26 Jan 1998 22:47:35 +0000 Subject: [PATCH] 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. --- Lib/pickle.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/Lib/pickle.py b/Lib/pickle.py index 4644ee9b530..5c69f7a71e5 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