From a92d16aaec1dc3c0d2e54c27516853b3e1bbd96a Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 18 Aug 2001 21:22:07 +0000 Subject: [PATCH] SF patch #452239 by Gordon McMillan, to fix SF bug #451547. This patch attempts to do to cPickle what Guido did for pickle.py v 1.50. That is: save_global tries importing the module, and fetching the name from the module. If that fails, or the returned object is not the same one we started with, it raises a PicklingError. (All this so pickling a lambda will fail at save time, rather than load time). --- Modules/cPickle.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Modules/cPickle.c b/Modules/cPickle.c index bb0d281f0fe..2b058ef4463 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -1623,7 +1623,7 @@ finally: static int save_global(Picklerobject *self, PyObject *args, PyObject *name) { - PyObject *global_name = 0, *module = 0; + PyObject *global_name = 0, *module = 0, *mod = 0, *moddict = 0, *klass = 0; char *name_str, *module_str; int module_size, name_size, res = -1; @@ -1648,6 +1648,29 @@ save_global(Picklerobject *self, PyObject *args, PyObject *name) { module_str = PyString_AS_STRING((PyStringObject *)module); name_str = PyString_AS_STRING((PyStringObject *)global_name); + mod = PyImport_ImportModule(module_str); + if (mod == NULL) { + /* Py_ErrClear(); ?? */ + cPickle_ErrFormat(PicklingError, + "Can't pickle %s: it's not found as %s.%s", + "OSS", args, module, global_name); + goto finally; + } + moddict = PyModule_GetDict(mod); /* borrowed ref */ + klass = PyDict_GetItemString(moddict, name_str); /* borrowed ref */ + if (klass == NULL) { + cPickle_ErrFormat(PicklingError, + "Can't pickle %s: it's not found as %s.%s", + "OSS", args, module, global_name); + goto finally; + } + if (klass != args) { + cPickle_ErrFormat(PicklingError, + "Can't pickle %s: it's not the same object as %s.%s", + "OSS", args, module, global_name); + goto finally; + } + if ((*self->write_func)(self, &global, 1) < 0) goto finally; @@ -1671,6 +1694,7 @@ save_global(Picklerobject *self, PyObject *args, PyObject *name) { finally: Py_XDECREF(module); Py_XDECREF(global_name); + Py_XDECREF(mod); return res; }