8000 BUG: don't create array with invalid memory in where · mherkazandjian/numpy@e0b7331 · GitHub
[go: up one dir, main page]

Skip to content

Commit e0b7331

Browse files
juliantaylormherkazandjian
authored andcommitted
BUG: don't create array with invalid memory in where
When creating the tuple view of np.where, make sure the arrays point to valid memory when they are empty. Numpy assumes that even empty arrays have valid memory, e.g. in the source stride == 0 assignments. Closes numpygh-8922.
1 parent 03df04a commit e0b7331

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

numpy/core/src/multiarray/item_selection.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2176,6 +2176,7 @@ PyArray_Nonzero(PyArrayObject *self)
21762176
NpyIter_IterNextFunc *iternext;
21772177
NpyIter_GetMultiIndexFunc *get_multi_index;
21782178
char **dataptr;
2179+
int is_empty = 0;
21792180

21802181
/*
21812182
* First count the number of non-zeros in 'self'.
@@ -2329,13 +2330,22 @@ PyArray_Nonzero(PyArrayObject *self)
23292330
return NULL;
23302331
}
23312332

2333+
for (i = 0; i < ndim; ++i) {
2334+
if (PyArray_DIMS(ret)[i] == 0) {
2335+
is_empty = 1;
2336+
break;
2337+
}
2338+
}
2339+
23322340
/* Create views into ret, one for each dimension */
23332341
for (i = 0; i < ndim; ++i) {
23342342
npy_intp stride = ndim * NPY_SIZEOF_INTP;
2343+
/* the result is an empty array, the view must point to valid memory */
2344+
npy_intp data_offset = is_empty ? 0 : i * NPY_SIZEOF_INTP;
23352345

23362346
PyArrayObject *view = (PyArrayObject *)PyArray_New(Py_TYPE(ret), 1,
23372347
&nonzero_count, NPY_INTP, &stride,
2338-
PyArray_BYTES(ret) + i*NPY_SIZEOF_INTP,
2348+
PyArray_BYTES(ret) + data_offset,
23392349
0, PyArray_FLAGS(ret), (PyObject *)ret);
23402350
if (view == NULL) {
23412351
Py_DECREF(ret);

numpy/core/tests/test_multiarray.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6633,6 +6633,14 @@ def test_string(self):
66336633
assert_equal(np.where(True, a, b), "abcd")
66346634
assert_equal(np.where(False, b, a), "abcd")
66356635

6636+
def test_empty_result(self):
6637+
# pass empty where result through an assignment which reads the data of
6638+
# empty arrays, error detectable with valgrind, see gh-8922
6639+
x = np.zeros((1, 1))
6640+
ibad = np.vstack(np.where(x == 99.))
6641+
assert_array_equal(ibad,
6642+
np.atleast_2d(np.array([[],[]], dtype=np.intp)))
6643+
66366644

66376645
if not IS_PYPY:
66386646
# sys.getsizeof() is not valid on PyPy

0 commit comments

Comments
 (0)
0