diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2018-06-10 00:01:28 -0700 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2018-06-10 00:04:38 -0700 |
commit | 1d4107ace54a4cce5e8aa5d115a6deee97f7474f (patch) | |
tree | 88129976503e9c583c19ddcfc44018d1edc997da | |
parent | da5eaf97281453083252c22b2b94aded846a936b (diff) | |
download | numpy-1d4107ace54a4cce5e8aa5d115a6deee97f7474f.tar.gz |
BUG: Fix segfault on failing __array_wrap__
-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 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 |