]> granicus.if.org Git - python/commitdiff
Fix the overflow checking of list_repeat.
authorArmin Rigo <arigo@tunes.org>
Wed, 17 Oct 2007 18:46:37 +0000 (18:46 +0000)
committerArmin Rigo <arigo@tunes.org>
Wed, 17 Oct 2007 18:46:37 +0000 (18:46 +0000)
Introduce overflow checking into list_inplace_repeat.

Backport candidate, possibly.

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

index 711ac4b75c91968b5391d9dcfee1acb8fb63159d..34895290a64f6b89b60572c3fe7b7ace695870bb 100644 (file)
@@ -1,4 +1,5 @@
 import unittest
+import sys
 from test import test_support, list_tests
 
 class ListTest(list_tests.CommonTest):
@@ -18,6 +19,14 @@ class ListTest(list_tests.CommonTest):
         self.assertEqual(len([0]), 1)
         self.assertEqual(len([0, 1, 2]), 3)
 
+    def test_overflow(self):
+        lst = [4, 5, 6, 7]
+        n = int((sys.maxint*2+2) // len(lst))
+        def mul(a, b): return a * b
+        def imul(a, b): a *= b
+        self.assertRaises((MemoryError, OverflowError), mul, lst, n)
+        self.assertRaises((MemoryError, OverflowError), imul, lst, n)
+
 def test_main(verbose=None):
     test_support.run_unittest(ListTest)
 
index a3fa983c59b2f7d08cda55f774422f8640842f80..fb5ce82cb0e25354c06890ba9b44bb6be7fc20b6 100644 (file)
@@ -499,10 +499,10 @@ list_repeat(PyListObject *a, Py_ssize_t n)
        if (n < 0)
                n = 0;
        size = Py_Size(a) * n;
-       if (size == 0)
-              return PyList_New(0);
        if (n && size/n != Py_Size(a))
                return PyErr_NoMemory();
+       if (size == 0)
+              return PyList_New(0);
        np = (PyListObject *) PyList_New(size);
        if (np == NULL)
                return NULL;
@@ -669,7 +669,7 @@ static PyObject *
 list_inplace_repeat(PyListObject *self, Py_ssize_t n)
 {
        PyObject **items;
-       Py_ssize_t size, i, j, p;
+       Py_ssize_t size, i, j, p, newsize;
 
 
        size = PyList_GET_SIZE(self);
@@ -684,7 +684,10 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n)
                return (PyObject *)self;
        }
 
-       if (list_resize(self, size*n) == -1)
+       newsize = size * n;
+       if (newsize/n != size)
+               return PyErr_NoMemory();
+       if (list_resize(self, newsize) == -1)
                return NULL;
 
        p = size;