summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2019-06-05 00:18:09 -0700
committerEric Wieser <wieser.eric@gmail.com>2019-06-05 19:49:39 -0700
commit2a1b2e5ed87a9dcf39342c394f815ccfbc93b7bd (patch)
tree031aed8e02f035e37d01ee2fa7c185149fdaddc1 /numpy
parent5971d6099fbb410d9cb0003361c755bee598a1dc (diff)
downloadnumpy-2a1b2e5ed87a9dcf39342c394f815ccfbc93b7bd.tar.gz
BUG: Prevent unsafe string concatenation
This did not handle exceptions correctly. Changed to use python to format the exception like all the others in this file. This also adds quotes around the ufunc name.
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/_exceptions.py16
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.c34
-rw-r--r--numpy/core/tests/test_datetime.py2
3 files changed, 39 insertions, 13 deletions
diff --git a/numpy/core/_exceptions.py b/numpy/core/_exceptions.py
index 1dcea6255..a1af7a78d 100644
--- a/numpy/core/_exceptions.py
+++ b/numpy/core/_exceptions.py
@@ -37,6 +37,22 @@ class UFuncTypeError(TypeError):
@_display_as_base
+class _UFuncBinaryResolutionError(UFuncTypeError):
+ """ Thrown when a binary resolution fails """
+ def __init__(self, ufunc, dtypes):
+ super().__init__(ufunc)
+ self.dtypes = tuple(dtypes)
+ assert len(self.dtypes) == 2
+
+ def __str__(self):
+ return (
+ "ufunc {!r} cannot use operands with types {!r} and {!r}"
+ ).format(
+ self.ufunc.__name__, *self.dtypes
+ )
+
+
+@_display_as_base
class _UFuncNoLoopError(UFuncTypeError):
""" Thrown when a ufunc loop cannot be found """
def __init__(self, ufunc, dtypes):
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c
index 8207be666..58f915c6e 100644
--- a/numpy/core/src/umath/ufunc_type_resolution.c
+++ b/numpy/core/src/umath/ufunc_type_resolution.c
@@ -74,18 +74,28 @@ npy_casting_to_string(NPY_CASTING casting)
*/
static int
raise_binary_type_reso_error(PyUFuncObject *ufunc, PyArrayObject **operands) {
- PyObject *errmsg;
- const char *ufunc_name = ufunc_get_name_cstr(ufunc);
- errmsg = PyUString_FromFormat("ufunc %s cannot use operands "
- "with types ", ufunc_name);
- PyUString_ConcatAndDel(&errmsg,
- PyObject_Repr((PyObject *)PyArray_DESCR(operands[0])));
- PyUString_ConcatAndDel(&errmsg,
- PyUString_FromString(" and "));
- PyUString_ConcatAndDel(&errmsg,
- PyObject_Repr((PyObject *)PyArray_DESCR(operands[1])));
- PyErr_SetObject(PyExc_TypeError, errmsg);
- Py_DECREF(errmsg);
+ static PyObject *exc_type = NULL;
+ PyObject *exc_value;
+
+ npy_cache_import(
+ "numpy.core._exceptions", "_UFuncBinaryResolutionError",
+ &exc_type);
+ if (exc_type == NULL) {
+ return -1;
+ }
+
+ /* produce an error object */
+ exc_value = Py_BuildValue(
+ "O(OO)", ufunc,
+ (PyObject *)PyArray_DESCR(operands[0]),
+ (PyObject *)PyArray_DESCR(operands[1])
+ );
+ if (exc_value == NULL){
+ return -1;
+ }
+ PyErr_SetObject(exc_type, exc_value);
+ Py_DECREF(exc_value);
+
return -1;
}
diff --git a/numpy/core/tests/test_datetime.py b/numpy/core/tests/test_datetime.py
index f48bfdf9b..f99c0f72b 100644
--- a/numpy/core/tests/test_datetime.py
+++ b/numpy/core/tests/test_datetime.py
@@ -1825,7 +1825,7 @@ class TestDateTime(object):
# NOTE: some of the operations may be supported
# in the future
with assert_raises_regex(TypeError,
- "remainder cannot use operands with types"):
+ "'remainder' cannot use operands with types"):
val1 % val2
def test_timedelta_arange_no_dtype(self):