[kupfer] puid: Only reconstruct SerializedObjects using loaded modules
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [kupfer] puid: Only reconstruct SerializedObjects using loaded modules
- Date: Sat, 23 Jan 2010 12:18:16 +0000 (UTC)
commit d751d6c647b84df6b735fb1391ee28565db49184
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Sat Jan 23 02:26:19 2010 +0100
puid: Only reconstruct SerializedObjects using loaded modules
We customize the Unpickler so that it refuses load any new modules at
all.
What we want to do is limit restoration of objects to only those from
plugins already loaded. However this will not have effect until the
modified plugin scheme is merged.
kupfer/puid.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 47 insertions(+), 4 deletions(-)
---
diff --git a/kupfer/puid.py b/kupfer/puid.py
index ffbefb3..fda399d 100644
--- a/kupfer/puid.py
+++ b/kupfer/puid.py
@@ -5,20 +5,63 @@ Persistent Globally Unique Indentifiers for KupferObjects.
from __future__ import with_statement
import contextlib
+import cPickle as pickle
+import sys
try:
- import cPickle as pickle
+ from cStringIO import StringIO
except ImportError:
- import pickle
+ from StringIO import StringIO
from kupfer import pretty
-
from kupfer.core import actioncompat
from kupfer.core import qfurl
from kupfer.core.sources import GetSourceController
+__all__ = [
+ "SerializedObject", "SERIALIZABLE_ATTRIBUTE",
+ "resolve_unique_id", "resolve_action_id", "get_unique_id", "is_reference",
+]
+
+
SERIALIZABLE_ATTRIBUTE = "serilizable"
+"""
+SerializedObject is a saved representation of a KupferObject, i.e. a
+data model user-level object.
+
+We unpickle SerializedObjects in an especially conservative way: new
+module loading is always refused; this way, we avoid loading parts of
+the program that we didn't wish to activate.
+
+The implementation with Pure-Python pickle would look like::
+
+ class ConservativeUnpickler (pickle.Unpickler):
+ "An Unpickler that refuses to import new modules"
+ def find_class(self, module, name):
+ if module not in sys.modules:
+ raise ValueError("Plugin %s is not loaded" % module)
+ return pickle.Unpickler.find_class(self, module, name)
+
+ @classmethod
+ def loads(cls, pickledata):
+ unpickler = cls(StringIO(pickledata))
+ return unpickler.load()
+
+"""
+
+def _conservative_find_global(module, name):
+ if module not in sys.modules:
+ raise pickle.UnpicklingError("Refusing to load module %s" % module)
+ return getattr(sys.modules[module], name)
+
+def conservative_loads(pickledata):
+ "Unpickle, but refuse to import new modules"
+ unpickler = pickle.Unpickler(StringIO(pickledata))
+ unpickler.find_global = _conservative_find_global
+ return unpickler.load()
+
+
class SerializedObject (object):
# treat the serilizable attribute as a version number, defined on the class
def __init__(self, obj):
@@ -28,7 +71,7 @@ class SerializedObject (object):
return (isinstance(other, type(self)) and self.data == other.data and
self.version == other.version)
def reconstruct(self):
- obj = pickle.loads(self.data)
+ obj = conservative_loads(self.data)
if self.version != getattr(obj, SERIALIZABLE_ATTRIBUTE):
raise ValueError("Version mismatch for reconstructed %s" % obj)
return obj
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]