From 9da18b313342ec6d81bd5ea5d19c1d05f6a41a08 Mon Sep 17 00:00:00 2001 From: Facundo Batista Date: Sun, 22 Jun 2008 23:19:14 +0000 Subject: Fixing the problem stated in issue 2702 with the patch submitted in the issue 3165. Now cPickle does not fails with uncontrolled behaviour when pickling into a very deep nested structure. --- Lib/test/test_cpickle.py | 20 ++++++++++++++++++-- Modules/cPickle.c | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_cpickle.py b/Lib/test/test_cpickle.py index d6e703a..7f6c35a 100644 --- a/Lib/test/test_cpickle.py +++ b/Lib/test/test_cpickle.py @@ -1,4 +1,4 @@ -import cPickle +import cPickle, unittest from cStringIO import StringIO from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests from test import test_support @@ -90,12 +90,28 @@ class cPickleFastPicklerTests(AbstractPickleTests): b = self.loads(self.dumps(a)) self.assertEqual(a, b) +class Node(object): + pass + +class cPickleDeepRecursive(unittest.TestCase): + '''Issue 2702. This should raise a RecursionLimit but in some + platforms (FreeBSD, win32) sometimes raises KeyError instead, + or just silently terminates the interpreter (=crashes). + ''' + def test_deep_recursive(self): + nodes = [Node() for i in range(500)] + for n in nodes: + n.connections = list(nodes) + n.connections.remove(n) + self.assertRaises(RuntimeError, cPickle.dumps, n) + def test_main(): test_support.run_unittest( cPickleTests, cPicklePicklerTests, cPickleListPicklerTests, - cPickleFastPicklerTests + cPickleFastPicklerTests, + cPickleDeepRecursive, ) if __name__ == "__main__": diff --git a/Modules/cPickle.c b/Modules/cPickle.c index afa75fd..e4bb7a1 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -1519,6 +1519,7 @@ batch_list(Picklerobject *self, PyObject *iter) PyObject *obj; PyObject *slice[BATCHSIZE]; int i, n; + self->nesting++; static char append = APPEND; static char appends = APPENDS; @@ -1658,6 +1659,7 @@ batch_dict(Picklerobject *self, PyObject *iter) PyObject *p; PyObject *slice[BATCHSIZE]; int i, n; + self->nesting++; static char setitem = SETITEM; static char setitems = SETITEMS; -- cgit v0.12