summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 41765e7f2..5e92bc991 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -4584,11 +4584,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