diff options
author | Lars Buitinck <larsmans@gmail.com> | 2014-12-10 21:49:45 +0100 |
---|---|---|
committer | Lars Buitinck <larsmans@gmail.com> | 2014-12-10 21:49:45 +0100 |
commit | bf447860aa4d079cc472c3df34d4d8ab4dfbcd36 (patch) | |
tree | 8348227b8ef1b519a81833c519cb5b146850513b | |
parent | 2473f8f6565b98e8fa8d71a6a0ed23bedcac15c1 (diff) | |
download | cython-bf447860aa4d079cc472c3df34d4d8ab4dfbcd36.tar.gz |
fix shrinking and overflow in cpython.array
--HG--
extra : transplant_source : %AA%EEbVu%DE%10%27%F1%E6%12%BE%077%3B%40%15%3F%A9O
-rw-r--r-- | Cython/Utility/arrayarray.h | 14 | ||||
-rw-r--r-- | tests/run/pyarray.pyx | 10 |
2 files changed, 18 insertions, 6 deletions
diff --git a/Cython/Utility/arrayarray.h b/Cython/Utility/arrayarray.h index 46c1a2086..bbd0da1a0 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 970e35e3b..b6b403a6e 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() |