diff options
author | Mark Wiebe <mwwiebe@gmail.com> | 2011-08-22 14:20:08 -0700 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2011-08-27 07:26:59 -0600 |
commit | 4b79354bd51f7702794fd8c0793adc82440f4c6f (patch) | |
tree | 3b401b4849c023029bf34945065fe4361fc58c59 | |
parent | d7076dcb8920e24d01507677efe4f206bd0fa1eb (diff) | |
download | numpy-4b79354bd51f7702794fd8c0793adc82440f4c6f.tar.gz |
BUG: dtype: Mitigate crash bug for some kinds of dtype inputs
This doesn't fix it in general, but does for the specific case.
The particular code in question is calling from C into Python
to do parsing. I think this is a bad idea, and should be converted
to straightforward C code instead.
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 21 | ||||
-rw-r--r-- | numpy/core/src/multiarray/methods.c | 2 | ||||
-rw-r--r-- | numpy/core/tests/test_dtype.py | 3 |
3 files changed, 21 insertions, 5 deletions
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 9a501976c..7e7daa724 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -120,6 +120,7 @@ static int _check_for_commastring(char *type, Py_ssize_t len) { Py_ssize_t i; + int sqbracket; /* Check for ints at start of string */ if ((type[0] >= '0' @@ -140,10 +141,21 @@ _check_for_commastring(char *type, Py_ssize_t len) && type[2] == ')'))) { return 1; } - /* Check for presence of commas */ + /* Check for presence of commas outside square [] brackets */ + sqbracket = 0; for (i = 1; i < len; i++) { - if (type[i] == ',') { - return 1; + switch (type[i]) { + case ',': + if (sqbracket == 0) { + return 1; + } + break; + case '[': + ++sqbracket; + break; + case ']': + --sqbracket; + break; } } return 0; @@ -582,6 +594,9 @@ _convert_from_list(PyObject *obj, int align) * found in the _internal.py file patterned after that one -- the approach is * to try to convert to a list (with tuples if any repeat information is * present) and then call the _convert_from_list) + * + * TODO: Calling Python from C like this in critical-path code is not + * a good idea. This should all be converted to C code. */ static PyArray_Descr * _convert_from_commastring(PyObject *obj, int align) diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index b26350fbd..5cff8f767 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -247,7 +247,7 @@ array_view(PyArrayObject *self, PyObject *args, PyObject *kwds) } return ret; } - else if (maskna == 0 && PyArray_HASMASKNA(ret)) { + else if (maskna == 0 && PyArray_HASMASKNA((PyArrayObject *)ret)) { PyErr_SetString(PyExc_ValueError, "Cannot take a view of an NA-masked array " "with maskna=False"); diff --git a/numpy/core/tests/test_dtype.py b/numpy/core/tests/test_dtype.py index 6dc3e7554..3625d58b4 100644 --- a/numpy/core/tests/test_dtype.py +++ b/numpy/core/tests/test_dtype.py @@ -37,7 +37,8 @@ class TestBuiltin(TestCase): # Make sure invalid type strings raise exceptions for typestr in ['O3', 'O5', 'O7', 'b3', 'h4', 'I5', 'l4', 'l8', 'L4', 'L8', 'q8', 'q16', 'Q8', 'Q16', 'e3', - 'f5', 'd8', 't8', 'g12', 'g16']: + 'f5', 'd8', 't8', 'g12', 'g16', + 'NA[u4,0xffffffff]']: #print typestr assert_raises(TypeError, np.dtype, typestr) |