diff options
author | Sebastian Berg <sebastian@sipsolutions.net> | 2021-07-22 17:50:19 -0500 |
---|---|---|
committer | Sebastian Berg <sebastian@sipsolutions.net> | 2021-07-22 19:52:52 -0500 |
commit | df8b85d63a173117fd9a64e818ffe9ed15f2ef0d (patch) | |
tree | f185aa787d6e201c37c8b583389bb731c9860df9 /numpy/core | |
parent | 971185ebf980d12e0c4a85622a4482783b83fa40 (diff) | |
download | numpy-df8b85d63a173117fd9a64e818ffe9ed15f2ef0d.tar.gz |
MAINT: Add complete input validation for info
This is currently unnecessary, but does not hurt. Eventually,
it should potentially move elsewhere.
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/src/umath/dispatching.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/numpy/core/src/umath/dispatching.c b/numpy/core/src/umath/dispatching.c index 8638c4e2e..966f8f1ab 100644 --- a/numpy/core/src/umath/dispatching.c +++ b/numpy/core/src/umath/dispatching.c @@ -70,7 +70,37 @@ promote_and_get_info_and_ufuncimpl(PyUFuncObject *ufunc, static int add_ufunc_loop(PyUFuncObject *ufunc, PyObject *info, int ignore_duplicate) { - assert(PyTuple_CheckExact(info) && PyTuple_GET_SIZE(info) == 2); + /* + * Validate the info object, this should likely move to to a different + * entry-point in the future (and is mostly unnecessary currently). + */ + if (!PyTuple_CheckExact(info) || PyTuple_GET_SIZE(info) != 2) { + PyErr_SetString(PyExc_TypeError, + "Info must be a tuple: " + "(tuple of DTypes or None, ArrayMethod or promoter)"); + return -1; + } + PyObject *DType_tuple = PyTuple_GetItem(info, 0); + if (PyTuple_GET_SIZE(DType_tuple) != ufunc->nargs) { + PyErr_SetString(PyExc_TypeError, + "DType tuple length does not match ufunc number of operands"); + return -1; + } + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(DType_tuple); i++) { + PyObject *item = PyTuple_GET_ITEM(DType_tuple, i); + if (item != Py_None + && !PyObject_TypeCheck(item, &PyArrayDTypeMeta_Type)) { + PyErr_SetString(PyExc_TypeError, + "DType tuple may only contain None and DType classes"); + return -1; + } + } + if (!PyObject_TypeCheck(PyTuple_GET_ITEM(info, 1), &PyArrayMethod_Type)) { + /* Must also accept promoters in the future. */ + PyErr_SetString(PyExc_TypeError, + "Second argument to info must be an ArrayMethod or promoter"); + return -1; + } if (ufunc->_loops == NULL) { ufunc->_loops = PyList_New(0); @@ -79,8 +109,6 @@ add_ufunc_loop(PyUFuncObject *ufunc, PyObject *info, int ignore_duplicate) } } - PyObject *DType_tuple = PyTuple_GetItem(info, 0); - PyObject *loops = ufunc->_loops; Py_ssize_t length = PyList_Size(loops); for (Py_ssize_t i = 0; i < length; i++) { |