summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2018-06-10 00:01:28 -0700
committerEric Wieser <wieser.eric@gmail.com>2018-06-10 00:04:38 -0700
commit1d4107ace54a4cce5e8aa5d115a6deee97f7474f (patch)
tree88129976503e9c583c19ddcfc44018d1edc997da
parentda5eaf97281453083252c22b2b94aded846a936b (diff)
downloadnumpy-1d4107ace54a4cce5e8aa5d115a6deee97f7474f.tar.gz
BUG: Fix segfault on failing __array_wrap__
-rw-r--r--numpy/core/src/umath/ufunc_object.c4
-rw-r--r--numpy/core/tests/test_umath.py19
2 files changed, 21 insertions, 2 deletions
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index 9b03a7916..8d96a1521 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -4593,11 +4593,11 @@ ufunc_generic_call(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
res = PyObject_CallFunctionObjArgs(wrap, mps[j], NULL);
}
Py_DECREF(wrap);
+ Py_DECREF(mps[j]);
+ mps[j] = NULL; /* Prevent fail double-freeing this */
if (res == NULL) {
goto fail;
}
-
- Py_DECREF(mps[j]);
retobj[i] = res;
}
}
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index 3c0d1759a..4772913be 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -1576,6 +1576,25 @@ class TestSpecialMethods(object):
a = A()
assert_raises(RuntimeError, ncu.maximum, a, a)
+ def test_failing_out_wrap(self):
+
+ singleton = np.array([1.0])
+
+ class Ok(np.ndarray):
+ def __array_wrap__(self, obj):
+ return singleton
+
+ class Bad(np.ndarray):
+ def __array_wrap__(self, obj):
+ raise RuntimeError
+
+ ok = np.empty(1).view(Ok)
+ bad = np.empty(1).view(Bad)
+
+ # double-free (segfault) of "ok" if "bad" raises an exception
+ for i in range(10):
+ assert_raises(RuntimeError, ncu.frexp, 1, ok, bad)
+
def test_none_wrap(self):
# Tests that issue #8507 is resolved. Previously, this would segfault