bug in PyArray_GetCastFunc
When attempting to cast to a user defined type, PyArray_GetCast looks up the cast function in the dictionary but doesn't check if the entry exists. This causes segfaults. Here's a patch. Geoffrey diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index 818d558..4b8f38b 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -81,7 +81,7 @@ PyArray_GetCastFunc(PyArray_Descr *descr, int type_num) key = PyInt_FromLong(type_num); cobj = PyDict_GetItem(obj, key); Py_DECREF(key); - if (NpyCapsule_Check(cobj)) { + if (cobj && NpyCapsule_Check(cobj)) { castfunc = NpyCapsule_AsVoidPtr(cobj); } }
On Sat, Dec 3, 2011 at 5:28 PM, Geoffrey Irving <irving@naml.us> wrote:
When attempting to cast to a user defined type, PyArray_GetCast looks up the cast function in the dictionary but doesn't check if the entry exists. This causes segfaults. Here's a patch.
Geoffrey
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index 818d558..4b8f38b 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -81,7 +81,7 @@ PyArray_GetCastFunc(PyArray_Descr *descr, int type_num) key = PyInt_FromLong(type_num); cobj = PyDict_GetItem(obj, key); Py_DECREF(key); - if (NpyCapsule_Check(cobj)) { + if (cobj && NpyCapsule_Check(cobj)) { castfunc = NpyCapsule_AsVoidPtr(cobj); } } __
I'm thinking NpyCapsule_Check should catch this. From the documentation it probably should: int PyCObject_Check(PyObject<http://docs.python.org/release/2.7/c-api/structures.html#PyObject> * *p*) Return true if its argument is a PyCObject<http://docs.python.org/release/2.7/c-api/cobject.html#PyCObject> I don't think NULL is a valid PyCObject ;) However, it should be easy to add the NULL check to the numpy version of the function. I'll do that. Chuck
On Sun, Dec 4, 2011 at 10:02 AM, Charles R Harris <charlesr.harris@gmail.com> wrote:
On Sat, Dec 3, 2011 at 5:28 PM, Geoffrey Irving <irving@naml.us> wrote:
When attempting to cast to a user defined type, PyArray_GetCast looks up the cast function in the dictionary but doesn't check if the entry exists. This causes segfaults. Here's a patch.
Geoffrey
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index 818d558..4b8f38b 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -81,7 +81,7 @@ PyArray_GetCastFunc(PyArray_Descr *descr, int type_num) key = PyInt_FromLong(type_num); cobj = PyDict_GetItem(obj, key); Py_DECREF(key); - if (NpyCapsule_Check(cobj)) { + if (cobj && NpyCapsule_Check(cobj)) { castfunc = NpyCapsule_AsVoidPtr(cobj); } } __
I'm thinking NpyCapsule_Check should catch this. From the documentation it probably should:
int PyCObject_Check(PyObject *p) Return true if its argument is a PyCObject
I don't think NULL is a valid PyCObject ;) However, it should be easy to add the NULL check to the numpy version of the function. I'll do that.
That would work, but I think would match the rest of the Python API better if NpyCapsule_Check required a nonnull argument. PyCapsule_Check and essentially every other Python API function have documented undefined behavior if you pass in null, so it might be surprising one numpy macro violates this. Incidentally, every other use of NpyCapsule_Check correctly tests for null. Geoffrey
On Sun, Dec 4, 2011 at 6:30 PM, Geoffrey Irving <irving@naml.us> wrote:
On Sun, Dec 4, 2011 at 10:02 AM, Charles R Harris <charlesr.harris@gmail.com> wrote:
On Sat, Dec 3, 2011 at 5:28 PM, Geoffrey Irving <irving@naml.us> wrote:
When attempting to cast to a user defined type, PyArray_GetCast looks up the cast function in the dictionary but doesn't check if the entry exists. This causes segfaults. Here's a patch.
Geoffrey
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index 818d558..4b8f38b 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -81,7 +81,7 @@ PyArray_GetCastFunc(PyArray_Descr *descr, int
type_num)
key = PyInt_FromLong(type_num); cobj = PyDict_GetItem(obj, key); Py_DECREF(key); - if (NpyCapsule_Check(cobj)) { + if (cobj && NpyCapsule_Check(cobj)) { castfunc = NpyCapsule_AsVoidPtr(cobj); } } __
I'm thinking NpyCapsule_Check should catch this. From the documentation it probably should:
int PyCObject_Check(PyObject *p) Return true if its argument is a PyCObject
I don't think NULL is a valid PyCObject ;) However, it should be easy to add the NULL check to the numpy version of the function. I'll do that.
That would work, but I think would match the rest of the Python API better if NpyCapsule_Check required a nonnull argument. PyCapsule_Check and essentially every other Python API function have documented undefined behavior if you pass in null, so it might be surprising one numpy macro violates this. Incidentally, every other use of NpyCapsule_Check correctly tests for null.
Good points. I may change it back ;) Chuck
participants (2)
-
Charles R Harris -
Geoffrey Irving