diff options
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 4 | ||||
-rw-r--r-- | numpy/core/tests/test_umath.py | 19 |
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 |