From 809123c61f6d8c09e87d2a5e7bd0bfc9c36791d3 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 12 Nov 2007 20:04:41 +0000 Subject: [PATCH] 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. --- Lib/test/seq_tests.py | 7 +++++++ Objects/listobject.c | 12 +++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Lib/test/seq_tests.py b/Lib/test/seq_tests.py index 18fb3b786de..df29a33665d 100644 --- a/Lib/test/seq_tests.py +++ b/Lib/test/seq_tests.py @@ -306,6 +306,13 @@ class CommonTest(unittest.TestCase): self.assertEqual(self.type2test(s)*(-4), self.type2test([])) 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): a = self.type2test([10, 11]) self.assertEqual(a.__getitem__(0L), 10) diff --git a/Objects/listobject.c b/Objects/listobject.c index 739a571b9b5..75ba6d071a3 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -487,10 +487,10 @@ list_repeat(PyListObject *a, Py_ssize_t n) if (n < 0) n = 0; size = a->ob_size * n; - if (size == 0) - return PyList_New(0); if (n && size/n != a->ob_size) return PyErr_NoMemory(); + if (size == 0) + return PyList_New(0); np = (PyListObject *) PyList_New(size); if (np == NULL) return NULL; @@ -661,7 +661,7 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n) size = PyList_GET_SIZE(self); - if (size == 0) { + if (size == 0 || n == 1) { Py_INCREF(self); return (PyObject *)self; } @@ -672,7 +672,10 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n) 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; p = size; @@ -2927,4 +2930,3 @@ listreviter_len(listreviterobject *it) return 0; return len; } -