8000 BUG: non-integers can end up in dtype offsets · numpy/numpy@7efef9d · GitHub
[go: up one dir, main page]

Skip to content

Commit 7efef9d

Browse files
committed
BUG: non-integers can end up in dtype offsets
Fix is to convert offsets to python ints at dtype creation. Fixes #8059
1 parent e1ad72d commit 7efef9d

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

numpy/core/src/multiarray/common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,7 @@ _unpack_field(PyObject *value, PyArray_Descr **descr, npy_intp *offset)
867867
*offset = PyLong_AsSsize_t(off);
868868
}
869869
else {
870+
PyErr_SetString(PyExc_IndexError, "can't convert offset");
870871
return -1;
871872
}
872873

numpy/core/src/multiarray/descriptor.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,8 +1071,19 @@ _convert_from_dict(PyObject *obj, int align)
10711071
if (!off) {
10721072
goto fail;
10731073
}
1074-
offset = PyInt_AsLong(off);
1075-
PyTuple_SET_ITEM(tup, 1, off);
1074+
offset = PyArray_PyIntAsInt(off);
1075+
if (offset == -1 && PyErr_Occurred()) {
1076+
Py_DECREF(off);
1077+
goto fail;
1078+
}
1079+
Py_DECREF(off);
1080+
if (offset < 0) {
1081+
PyErr_Format(PyExc_ValueError, "offset %d cannot be negative",
1082+
(int)offset);
1083+
goto fail;
1084+
}
1085+
1086+
PyTuple_SET_ITEM(tup, 1, PyInt_FromLong(offset));
10761087
/* Flag whether the fields are specified out of order */
10771088
if (offset < totalsize) {
10781089
has_out_of_order_fields = 1;
@@ -1186,7 +1197,7 @@ _convert_from_dict(PyObject *obj, int align)
11861197
if (tmp == NULL) {
11871198
PyErr_Clear();
11881199
} else {
1189-
itemsize = (int)PyInt_AsLong(tmp);
1200+
itemsize = (int)PyArray_PyIntAsInt(tmp);
11901201
if (itemsize == -1 && PyErr_Occurred()) {
11911202
Py_DECREF(new);
11921203
return NULL;

numpy/core/tests/test_dtype.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,21 @@ def test_bool_commastring(self):
272272
for n in d.names:
273273
assert_equal(d.fields[n][0], np.dtype('?'))
274274

275+
def test_nonint_offsets(self):
276+
# gh-8059
277+
def make_dtype(off):
278+
return np.dtype({'names': ['A'], 'formats': ['i4'],
279+
'offsets': [off]})
280+
281+
assert_raises(TypeError, make_dtype, 'ASD')
282+
assert_raises(OverflowError, make_dtype, 2**70)
283+
assert_raises(TypeError, make_dtype, 2.3)
284+
assert_raises(ValueError, make_dtype, -10)
285+
286+
# no errors here:
287+
dt = make_dtype(np.uint32(0))
288+
np.zeros(1, dtype=dt)[0].item()
289+
275290

276291
class TestSubarray(TestCase):
277292
def test_single_subarray(self):

0 commit comments

Comments
 (0)
0