summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Buitinck <larsmans@gmail.com>2014-12-10 21:49:45 +0100
committerLars Buitinck <larsmans@gmail.com>2014-12-10 21:49:45 +0100
commitbf447860aa4d079cc472c3df34d4d8ab4dfbcd36 (patch)
tree8348227b8ef1b519a81833c519cb5b146850513b
parent2473f8f6565b98e8fa8d71a6a0ed23bedcac15c1 (diff)
downloadcython-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.h14
-rw-r--r--tests/run/pyarray.pyx10
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()