diff options
-rw-r--r-- | Lib/test/test_builtin.py | 5 | ||||
-rw-r--r-- | Objects/listobject.c | 30 |
2 files changed, 25 insertions, 10 deletions
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 8e3a925..9f90925 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -712,6 +712,11 @@ class BuiltinTest(unittest.TestCase): # http://sources.redhat.com/ml/newlib/2002/msg00369.html self.assertRaises(MemoryError, list, xrange(sys.maxint // 2)) + # This code used to segfault in Py2.4a3 + x = [] + x.extend(-y for y in x) + self.assertEqual(x, []) + def test_long(self): self.assertEqual(long(314), 314L) self.assertEqual(long(3.14), 3L) diff --git a/Objects/listobject.c b/Objects/listobject.c index 1fb77b9..44616e5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -769,12 +769,20 @@ listextend(PyListObject *self, PyObject *b) } m = self->ob_size; mn = m + n; - if (list_resize(self, mn) == -1) - goto error; - memset(&(self->ob_item[m]), 0, sizeof(*self->ob_item) * n); + if (mn >= m) { + /* Make room. */ + if (list_resize(self, mn) == -1) + goto error; + /* Make the list sane again. */ + self->ob_size = m; + } + /* Else m + n overflowed; on the chance that n lied, and there really + * is enough room, ignore it. If n was telling the truth, we'll + * eventually run out of memory during the loop. + */ /* Run iterator to exhaustion. */ - for (i = m; ; i++) { + for (;;) { PyObject *item = iternext(it); if (item == NULL) { if (PyErr_Occurred()) { @@ -785,8 +793,11 @@ listextend(PyListObject *self, PyObject *b) } break; } - if (i < mn) - PyList_SET_ITEM(self, i, item); /* steals ref */ + if (self->ob_size < self->allocated) { + /* steals ref */ + PyList_SET_ITEM(self, self->ob_size, item); + ++self->ob_size; + } else { int status = app1(self, item); Py_DECREF(item); /* append creates a new ref */ @@ -796,10 +807,9 @@ listextend(PyListObject *self, PyObject *b) } /* Cut back result list if initial guess was too large. */ - if (i < mn && self != NULL) { - if (list_ass_slice(self, i, mn, (PyObject *)NULL) != 0) - goto error; - } + if (self->ob_size < self->allocated) + list_resize(self, self->ob_size); /* shrinking can't fail */ + Py_DECREF(it); Py_RETURN_NONE; |