8000 BUG: sanity check ``__array_interface__`` number of dimensions (#28407) · numpy/numpy@72efa8e · GitHub
[go: up one dir, main page]

Skip to content

Commit 72efa8e

Browse files
lvllvlcharris
authored andcommitted
BUG: sanity check __array_interface__ number of dimensions (#28407)
``__array_interface__`` should typically not have more dimensions than NumPy supports, but unlike other malformed interfaces, this should fail gracefully if someone were to pass more.
1 parent 17678bf commit 72efa8e

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

numpy/_core/src/multiarray/ctors.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2153,7 +2153,7 @@ PyArray_FromInterface(PyObject *origin)
21532153
PyArray_Descr *dtype = NULL;
21542154
char *data = NULL;
21552155
Py_buffer view;
2156-
int i, n;
2156+
Py_ssize_t i, n;
21572157
npy_intp dims[NPY_MAXDIMS], strides[NPY_MAXDIMS];
21582158
int dataflags = NPY_ARRAY_BEHAVED;
21592159

@@ -2269,6 +2269,12 @@ PyArray_FromInterface(PyObject *origin)
22692269
/* Get dimensions from shape tuple */
22702270
else {
22712271
n = PyTuple_GET_SIZE(attr);
2272+
if (n > NPY_MAXDIMS) {
2273+
PyErr_Format(PyExc_ValueError,
2274+
"number of dimensions must be within [0, %d], got %d",
2275+
NPY_MAXDIMS, n);
2276+
goto fail;
2277+
}
22722278
for (i = 0; i < n; i++) {
22732279
PyObject *tmp = PyTuple_GET_ITEM(attr, i);
22742280
dims[i] = PyArray_PyIntAsIntp(tmp);

numpy/_core/tests/test_multiarray.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10358,3 +10358,24 @@ def test_to_device(self):
1035810358
r"The stream argument in to_device\(\) is not supported"
1035910359
):
1036010360
arr.to_device("cpu", stream=1)
10361+
10362+
def test_array_interface_excess_dimensions_raises():
10363+
"""Regression test for gh-27949: ensure too many dims raises ValueError instead of segfault."""
10364+
10365+
# Dummy object to hold a custom __array_interface__
10366+
class DummyArray:
10367+
def __init__(self, interface):
10368+
# Attach the array interface dict to mimic an array
10369+
self.__array_interface__ = interface
10370+
10371+
# Create a base array (scalar) and copy its interface
10372+
base = np.array(42) # base can be any scalar or array
10373+
interface = dict(base.__array_interface__)
10374+
10375+
# Modify the shape to exceed NumPy's dimension limit (NPY_MAXDIMS, typically 64)
10376+
interface['shape'] = tuple([1] * 136) # match the original bug report
10377+
10378+
dummy = DummyArray(interface)
10379+
# Now, using np.asanyarray on this dummy should trigger a ValueError (not segfault)
10380+
with pytest.raises(ValueError, match="dimensions must be within"):
10381+
np.asanyarray(dummy)

0 commit comments

Comments
 (0)
0