summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2017-04-22 15:15:50 +0100
committerEric Wieser <wieser.eric@gmail.com>2017-10-01 16:46:21 -0700
commit0ad1ab9dc7da9c1d187b6f2a823adb1806e5b096 (patch)
treee9860497a618d7b2631320571bdcf502249ff99d
parentba829d0b8e921afbe9197e056c41be9283a9daf6 (diff)
downloadnumpy-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.c5
-rw-r--r--numpy/core/src/multiarray/descriptor.c15
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;