]> granicus.if.org Git - python/commitdiff
Merged revisions 72930 via svnmerge from
authorCollin Winter <collinw@gmail.com>
Tue, 26 May 2009 05:37:22 +0000 (05:37 +0000)
committerCollin Winter <collinw@gmail.com>
Tue, 26 May 2009 05:37:22 +0000 (05:37 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r72930 | collin.winter | 2009-05-25 21:12:39 -0700 (Mon, 25 May 2009) | 1 line

  Issue 5794: fix cPickle's unpickling of recursive tuples.
........

Lib/test/pickletester.py
Lib/test/test_cpickle.py
Modules/cPickle.c

index e34d55b85d11272cfdc7b12c2dafea4fab982be8..f7099a1b3009ab3832043d489b913a7b719cbf1a 100644 (file)
@@ -428,6 +428,16 @@ class AbstractPickleTests(unittest.TestCase):
             self.assertEqual(len(x), 1)
             self.assert_(x is x[0])
 
+    def test_recursive_tuple(self):
+        t = ([],)
+        t[0].append(t)
+        for proto in protocols:
+            s = self.dumps(t, proto)
+            x = self.loads(s)
+            self.assertEqual(len(x), 1)
+            self.assertEqual(len(x[0]), 1)
+            self.assert_(x is x[0][0])
+
     def test_recursive_dict(self):
         d = {}
         d[1] = d
index 0b02b624734002cf7fc7b5c838604fe2ac42302f..c874481cdd6ca5794010d3970c8226b82409d3c4 100644 (file)
@@ -64,6 +64,11 @@ class cPickleFastPicklerTests(AbstractPickleTests):
                           AbstractPickleTests.test_recursive_list,
                           self)
 
+    def test_recursive_tuple(self):
+        self.assertRaises(ValueError,
+                          AbstractPickleTests.test_recursive_tuple,
+                          self)
+
     def test_recursive_inst(self):
         self.assertRaises(ValueError,
                           AbstractPickleTests.test_recursive_inst,
index fb13ba18bc459ecc56a9df125a9d42624015ae47..1cef5c1f704673370f43057658440da71b6b5e42 100644 (file)
@@ -4016,25 +4016,24 @@ load_binpersid(Unpicklerobject *self)
 static int
 load_pop(Unpicklerobject *self)
 {
-       int len;
-
-       if (!( (len=self->stack->length) > 0 ))  return stackUnderflow();
+       int len = self->stack->length;
 
        /* Note that we split the (pickle.py) stack into two stacks,
           an object stack and a mark stack. We have to be clever and
           pop the right one. We do this by looking at the top of the
-          mark stack.
+          mark stack first, and only signalling a stack underflow if
+          the object stack is empty and the mark stack doesn't match
+          our expectations.
        */
-
-       if ((self->num_marks > 0) &&
-           (self->marks[self->num_marks - 1] == len))
+       if (self->num_marks > 0 && self->marks[self->num_marks - 1] == len) {
                self->num_marks--;
-       else {
+       } else if (len >= 0) {
                len--;
                Py_DECREF(self->stack->data[len]);
-               self->stack->length=len;
+               self->stack->length = len;
+       } else {
+               return stackUnderflow();
        }
-
        return 0;
 }