]> granicus.if.org Git - python/commitdiff
Issue 1704621. Fix segfaults in list_repeat() and list_inplace_repeat().
authorGuido van Rossum <guido@python.org>
Mon, 12 Nov 2007 20:04:41 +0000 (20:04 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 12 Nov 2007 20:04:41 +0000 (20:04 +0000)
The C changes aren't quite the same as the patch given there; the test is.

Lib/test/seq_tests.py
Objects/listobject.c

index 18fb3b786de00c2d0973e0ac0cfec94585be3766..df29a33665dfb0933d3b4d85a3048a67965124e1 100644 (file)
@@ -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)
index 739a571b9b5b6129ce398c66f664fbe90aaafbbe..75ba6d071a3408a17dffe03c7333562480f7d49e 100644 (file)
@@ -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;
 }
-