Merged revisions 72930 via svnmerge from

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.
........
This commit is contained in:
Collin Winter 2009-05-26 05:37:22 +00:00
parent bcc2f1aaa6
commit e9a6514767
3 changed files with 24 additions and 10 deletions

View file

@ -428,6 +428,16 @@ class AbstractPickleTests(unittest.TestCase):
self.assertEqual(len(x), 1) self.assertEqual(len(x), 1)
self.assert_(x is x[0]) 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): def test_recursive_dict(self):
d = {} d = {}
d[1] = d d[1] = d

View file

@ -64,6 +64,11 @@ class cPickleFastPicklerTests(AbstractPickleTests):
AbstractPickleTests.test_recursive_list, AbstractPickleTests.test_recursive_list,
self) self)
def test_recursive_tuple(self):
self.assertRaises(ValueError,
AbstractPickleTests.test_recursive_tuple,
self)
def test_recursive_inst(self): def test_recursive_inst(self):
self.assertRaises(ValueError, self.assertRaises(ValueError,
AbstractPickleTests.test_recursive_inst, AbstractPickleTests.test_recursive_inst,

View file

@ -4016,25 +4016,24 @@ load_binpersid(Unpicklerobject *self)
static int static int
load_pop(Unpicklerobject *self) load_pop(Unpicklerobject *self)
{ {
int len; int len = self->stack->length;
if (!( (len=self->stack->length) > 0 )) return stackUnderflow();
/* Note that we split the (pickle.py) stack into two stacks, /* Note that we split the (pickle.py) stack into two stacks,
an object stack and a mark stack. We have to be clever and 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 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--; self->num_marks--;
else { } else if (len >= 0) {
len--; len--;
Py_DECREF(self->stack->data[len]); Py_DECREF(self->stack->data[len]);
self->stack->length=len; self->stack->length = len;
} else {
return stackUnderflow();
} }
return 0; return 0;
} }