]> granicus.if.org Git - python/commitdiff
Issue 4509: Do not modify an array if we know the change would result
authorAlexandre Vassalotti <alexandre@peadrop.com>
Sun, 5 Jul 2009 05:38:18 +0000 (05:38 +0000)
committerAlexandre Vassalotti <alexandre@peadrop.com>
Sun, 5 Jul 2009 05:38:18 +0000 (05:38 +0000)
in a failure due to exported buffers.

Lib/test/test_array.py
Modules/arraymodule.c

index 7ae34a99a9e5b11507967e099e29cad994a10436..eb1fffb7dd9b7b376aa5a2c2e932c9540082aab5 100755 (executable)
@@ -749,9 +749,25 @@ class BaseTest(unittest.TestCase):
         ArraySubclassWithKwargs('b', newarg=1)
 
     def test_create_from_bytes(self):
+        # XXX This test probably needs to be moved in a subclass or
+        # generalized to use self.typecode.
         a = array.array('H', b"1234")
         self.assertEqual(len(a) * a.itemsize, 4)
 
+    def test_memoryview_no_resize(self):
+        # Test for issue 4509.
+        a = array.array(self.typecode, self.example)
+        m = memoryview(a)
+        expected = m.tobytes()
+        self.assertRaises(BufferError, a.pop, 0)
+        self.assertEqual(m.tobytes(), expected)
+        self.assertRaises(BufferError, a.remove, a[0])
+        self.assertEqual(m.tobytes(), expected)
+        self.assertRaises(BufferError, a.__setitem__, slice(0, 0), a)
+        self.assertEqual(m.tobytes(), expected)
+        self.assertRaises(BufferError, a.__delitem__, slice(0, len(a)))
+        self.assertEqual(m.tobytes(), expected)
+
 
 class StringTest(BaseTest):
 
index 6dc46ad0b4d170c3ebe51160b30835bffdb9487a..256bcd8edc96b96d468f232229fc642c7eec380e 100644 (file)
@@ -735,6 +735,14 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
                ihigh = Py_SIZE(a);
        item = a->ob_item;
        d = n - (ihigh-ilow);
+       /* Issue #4509: If the array has exported buffers and the slice
+          assignment would change the size of the array, fail early to make
+          sure we don't modify it. */
+       if (d != 0 && a->ob_exports > 0) {
+               PyErr_SetString(PyExc_BufferError, 
+                       "cannot resize an array that is exporting buffers");
+               return -1;
+       }
        if (d < 0) { /* Delete -d items */
                memmove(item + (ihigh+d)*a->ob_descr->itemsize,
                        item + ihigh*a->ob_descr->itemsize,