summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Taylor <juliantaylor108@gmail.com>2017-05-06 21:47:01 +0200
committerGitHub <noreply@github.com>2017-05-06 21:47:01 +0200
commit25a6dfbbebb1d92e0e402aed7c8f11e4f5d3bc5b (patch)
tree19b6cb8d6321ada49010b759360097acf6ee1d0c
parentbde121f9aefd4ad15aab7a7652efc5a9ee0897d9 (diff)
parenta16f16b94b61fc35b887d9e9f2e12c817c2819b6 (diff)
downloadpython-numpy-25a6dfbbebb1d92e0e402aed7c8f11e4f5d3bc5b.tar.gz
python-numpy-25a6dfbbebb1d92e0e402aed7c8f11e4f5d3bc5b.tar.bz2
python-numpy-25a6dfbbebb1d92e0e402aed7c8f11e4f5d3bc5b.zip
Merge pull request #8964 from juliantaylor/empty-read
BUG: don't create array with invalid memory in where
-rw-r--r--numpy/core/src/multiarray/item_selection.c12
-rw-r--r--numpy/core/src/multiarray/lowlevel_strided_loops.c.src3
-rw-r--r--numpy/core/tests/test_multiarray.py8
3 files changed, 22 insertions, 1 deletions
diff --git a/numpy/core/src/multiarray/item_selection.c b/numpy/core/src/multiarray/item_selection.c
index 3c0f0782e..c88cdfdcb 100644
--- a/numpy/core/src/multiarray/item_selection.c
+++ b/numpy/core/src/multiarray/item_selection.c
@@ -2176,6 +2176,7 @@ PyArray_Nonzero(PyArrayObject *self)
NpyIter_IterNextFunc *iternext;
NpyIter_GetMultiIndexFunc *get_multi_index;
char **dataptr;
+ int is_empty = 0;
/*
* First count the number of non-zeros in 'self'.
@@ -2329,13 +2330,22 @@ finish:
return NULL;
}
+ for (i = 0; i < ndim; ++i) {
+ if (PyArray_DIMS(ret)[i] == 0) {
+ is_empty = 1;
+ break;
+ }
+ }
+
/* Create views into ret, one for each dimension */
for (i = 0; i < ndim; ++i) {
npy_intp stride = ndim * NPY_SIZEOF_INTP;
+ /* the result is an empty array, the view must point to valid memory */
+ npy_intp data_offset = is_empty ? 0 : i * NPY_SIZEOF_INTP;
PyArrayObject *view = (PyArrayObject *)PyArray_New(Py_TYPE(ret), 1,
&nonzero_count, NPY_INTP, &stride,
- PyArray_BYTES(ret) + i*NPY_SIZEOF_INTP,
+ PyArray_BYTES(ret) + data_offset,
0, PyArray_FLAGS(ret), (PyObject *)ret);
if (view == NULL) {
Py_DECREF(ret);
diff --git a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
index 9a5c3004d..397aaf209 100644
--- a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
+++ b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
@@ -206,6 +206,9 @@ static NPY_GCC_OPT_3 void
#else
npy_uint64 temp0, temp1;
#endif
+ if (N == 0) {
+ return;
+ }
#if @is_aligned@ && @elsize@ != 16
/* sanity check */
assert(npy_is_aligned(dst, _ALIGN(@type@)));
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 3f4b183aa..4dc82eb1d 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -6547,6 +6547,14 @@ class TestWhere(TestCase):
assert_equal(np.where(True, a, b), "abcd")
assert_equal(np.where(False, b, a), "abcd")
+ def test_empty_result(self):
+ # pass empty where result through an assignment which reads the data of
+ # empty arrays, error detectable with valgrind, see gh-8922
+ x = np.zeros((1, 1))
+ ibad = np.vstack(np.where(x == 99.))
+ assert_array_equal(ibad,
+ np.atleast_2d(np.array([[],[]], dtype=np.intp)))
+
if not IS_PYPY:
# sys.getsizeof() is not valid on PyPy