diff options
author | Julian Taylor <juliantaylor108@gmail.com> | 2017-05-06 21:47:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-06 21:47:01 +0200 |
commit | 25a6dfbbebb1d92e0e402aed7c8f11e4f5d3bc5b (patch) | |
tree | 19b6cb8d6321ada49010b759360097acf6ee1d0c | |
parent | bde121f9aefd4ad15aab7a7652efc5a9ee0897d9 (diff) | |
parent | a16f16b94b61fc35b887d9e9f2e12c817c2819b6 (diff) | |
download | python-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.c | 12 | ||||
-rw-r--r-- | numpy/core/src/multiarray/lowlevel_strided_loops.c.src | 3 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 8 |
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 |