Commit 809123c6 authored by Guido van Rossum's avatar Guido van Rossum

Issue 1704621. Fix segfaults in list_repeat() and list_inplace_repeat().

The C changes aren't quite the same as the patch given there; the test is.
parent 50bbcc27
...@@ -306,6 +306,13 @@ class CommonTest(unittest.TestCase): ...@@ -306,6 +306,13 @@ class CommonTest(unittest.TestCase):
self.assertEqual(self.type2test(s)*(-4), self.type2test([])) self.assertEqual(self.type2test(s)*(-4), self.type2test([]))
self.assertEqual(id(s), id(s*1)) self.assertEqual(id(s), id(s*1))
def test_bigrepeat(self):
x = self.type2test([0])
x *= 2**16
self.assertRaises(MemoryError, x.__mul__, 2**16)
if hasattr(x, '__imul__'):
self.assertRaises(MemoryError, x.__imul__, 2**16)
def test_subscript(self): def test_subscript(self):
a = self.type2test([10, 11]) a = self.type2test([10, 11])
self.assertEqual(a.__getitem__(0L), 10) self.assertEqual(a.__getitem__(0L), 10)
......
...@@ -487,10 +487,10 @@ list_repeat(PyListObject *a, Py_ssize_t n) ...@@ -487,10 +487,10 @@ list_repeat(PyListObject *a, Py_ssize_t n)
if (n < 0) if (n < 0)
n = 0; n = 0;
size = a->ob_size * n; size = a->ob_size * n;
if (size == 0)
return PyList_New(0);
if (n && size/n != a->ob_size) if (n && size/n != a->ob_size)
return PyErr_NoMemory(); return PyErr_NoMemory();
if (size == 0)
return PyList_New(0);
np = (PyListObject *) PyList_New(size); np = (PyListObject *) PyList_New(size);
if (np == NULL) if (np == NULL)
return NULL; return NULL;
...@@ -661,7 +661,7 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n) ...@@ -661,7 +661,7 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n)
size = PyList_GET_SIZE(self); size = PyList_GET_SIZE(self);
if (size == 0) { if (size == 0 || n == 1) {
Py_INCREF(self); Py_INCREF(self);
return (PyObject *)self; return (PyObject *)self;
} }
...@@ -672,7 +672,10 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n) ...@@ -672,7 +672,10 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n)
return (PyObject *)self; return (PyObject *)self;
} }
if (list_resize(self, size*n) == -1) p = size*n;
if (p/n != size)
return PyErr_NoMemory();
if (list_resize(self, p) == -1)
return NULL; return NULL;
p = size; p = size;
...@@ -2927,4 +2930,3 @@ listreviter_len(listreviterobject *it) ...@@ -2927,4 +2930,3 @@ listreviter_len(listreviterobject *it)
return 0; return 0;
return len; return len;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment