diff --git a/Cython/Utility/arrayarray.h b/Cython/Utility/arrayarray.h index 46c1a208618ee7efec507b530ed9b3c6846225d6..bbd0da1a0ed0c9f574f4ffb8d57021695a4dd45c 100644 --- a/Cython/Utility/arrayarray.h +++ b/Cython/Utility/arrayarray.h @@ -121,13 +121,15 @@ static CYTHON_INLINE int resize(arrayobject *self, Py_ssize_t n) { static CYTHON_INLINE int resize_smart(arrayobject *self, Py_ssize_t n) { void *items = (void*) self->data.ob_item; Py_ssize_t newsize; - if (n < self->allocated) { - if (n*4 > self->allocated) { - self->ob_size = n; - return 0; - } + if (n < self->ob_size) { + self->ob_size = n; + return 0; + } + newsize = n + (n / 2) + 1; + if (newsize <= self->allocated) { /* overflow */ + PyErr_NoMemory(); + return -1; } - newsize = n * 3 / 2 + 1; PyMem_Resize(items, char, (size_t)(newsize * self->ob_descr->itemsize)); if (items == NULL) { PyErr_NoMemory(); diff --git a/tests/run/pyarray.pyx b/tests/run/pyarray.pyx index 970e35e3b8c9627976884646b4efe44d6e4fcb37..b6b403a6eb6264602cf62a2594e1c5e0fe47cba3 100644 --- a/tests/run/pyarray.pyx +++ b/tests/run/pyarray.pyx @@ -105,6 +105,16 @@ def test_resize(a): assert len(cb) == 10 assert cb[9] == cb[-1] == cb.data.as_floats[9] == 9 +def test_resize_smart(a): + """ + >>> a = array.array('d', [1, 2, 3]) + >>> test_resize_smart(a) + 2 + """ + cdef array.array cb = array.copy(a) + array.resize_smart(cb, 2) + return len(cb) + def test_buffer(): """ >>> test_buffer()