diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2017-04-22 15:15:50 +0100 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2017-10-01 16:46:21 -0700 |
commit | 0ad1ab9dc7da9c1d187b6f2a823adb1806e5b096 (patch) | |
tree | e9860497a618d7b2631320571bdcf502249ff99d | |
parent | ba829d0b8e921afbe9197e056c41be9283a9daf6 (diff) | |
download | numpy-0ad1ab9dc7da9c1d187b6f2a823adb1806e5b096.tar.gz |
MAINT: Pre-emptively handle the case when elsize == 0
Fixes np.fromiter and np.dtype. Neither of these code paths can currently be hit.
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 5 | ||||
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 15 |
2 files changed, 15 insertions, 5 deletions
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index fb913d288..7958c619f 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -3708,14 +3708,15 @@ PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count) for (i = 0; (i < count || count == -1) && (value = PyIter_Next(iter)); i++) { if (i >= elcount) { + npy_intp nbytes; /* Grow PyArray_DATA(ret): this is similar for the strategy for PyListObject, but we use 50% overallocation => 0, 4, 8, 14, 23, 36, 56, 86 ... */ elcount = (i >> 1) + (i < 4 ? 4 : 2) + i; - if (elcount <= NPY_MAX_INTP/elsize) { - new_data = PyDataMem_RENEW(PyArray_DATA(ret), elcount * elsize); + if (!npy_mul_with_overflow_intp(&nbytes, elcount, elsize)) { + new_data = PyDataMem_RENEW(PyArray_DATA(ret), nbytes); } else { new_data = NULL; diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 1ae6e34a6..608b5aa84 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -15,6 +15,7 @@ #include "_datetime.h" #include "common.h" +#include "templ_common.h" /* for npy_mul_with_overflow_intp */ #include "descriptor.h" #include "alloc.h" @@ -304,7 +305,8 @@ _convert_from_tuple(PyObject *obj) PyArray_Dims shape = {NULL, -1}; PyArray_Descr *newdescr; npy_intp items; - int i; + int i, overflowed; + int nbytes; if (!(PyArray_IntpConverter(val, &shape)) || (shape.len > NPY_MAXDIMS)) { npy_free_cache_dim_obj(shape); @@ -348,14 +350,21 @@ _convert_from_tuple(PyObject *obj) } } items = PyArray_OverflowMultiplyList(shape.ptr, shape.len); - if ((items < 0) || (items > (NPY_MAX_INT / type->elsize))) { + if (items < 0 || items > NPY_MAX_INT) { + overflowed = 1; + } + else { + overflowed = npy_mul_with_overflow_int( + &nbytes, type->elsize, (int) items); + } + if (overflowed) { PyErr_SetString(PyExc_ValueError, "invalid shape in fixed-type tuple: dtype size in " "bytes must fit into a C int."); npy_free_cache_dim_obj(shape); goto fail; } - newdescr->elsize = type->elsize * items; + newdescr->elsize = nbytes; if (newdescr->elsize == -1) { npy_free_cache_dim_obj(shape); goto fail; |