diff options
author | Mark Wiebe <mwwiebe@gmail.com> | 2012-08-31 00:44:19 -0700 |
---|---|---|
committer | Ondřej Čertík <ondrej.certik@gmail.com> | 2012-08-31 15:17:39 -0700 |
commit | 8b2e6bed904415006d59344b27a0b23b35fab9ca (patch) | |
tree | 9b3ecb413bb3c94482e0e601c0e2b9f401c8cbf9 /numpy | |
parent | 8c75aa01e2f4ec02eb1d852a14da3e9e03107da8 (diff) | |
download | numpy-8b2e6bed904415006d59344b27a0b23b35fab9ca.tar.gz |
BUG: Fix ticket #1588/gh issue #398, refcount error in clip
This patch enforces a strict dichotomy for the variables 'indescr'
and 'newdescr', so they are either NULL, or they own a reference.
Following the consequences of this allowed the reference error
to be tracked down.
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/calculation.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/numpy/core/src/multiarray/calculation.c b/numpy/core/src/multiarray/calculation.c index 618a8714c..c083a00f0 100644 --- a/numpy/core/src/multiarray/calculation.c +++ b/numpy/core/src/multiarray/calculation.c @@ -895,7 +895,7 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o PyArrayObject *maxa = NULL; PyArrayObject *mina = NULL; PyArrayObject *newout = NULL, *newin = NULL; - PyArray_Descr *indescr, *newdescr; + PyArray_Descr *indescr = NULL, *newdescr = NULL; char *max_data, *min_data; PyObject *zero; @@ -922,23 +922,24 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o /* Use the fast scalar clip function */ /* First we need to figure out the correct type */ - indescr = NULL; if (min != NULL) { indescr = PyArray_DescrFromObject(min, NULL); if (indescr == NULL) { - return NULL; + goto fail; } } if (max != NULL) { newdescr = PyArray_DescrFromObject(max, indescr); Py_XDECREF(indescr); + indescr = NULL; if (newdescr == NULL) { - return NULL; + goto fail; } } else { /* Steal the reference */ newdescr = indescr; + indescr = NULL; } @@ -950,8 +951,12 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o if (PyArray_ScalarKind(newdescr->type_num, NULL) > PyArray_ScalarKind(PyArray_DESCR(self)->type_num, NULL)) { indescr = PyArray_PromoteTypes(newdescr, PyArray_DESCR(self)); + if (indescr == NULL) { + goto fail; + } func = indescr->f->fastclip; if (func == NULL) { + Py_DECREF(indescr); return _slow_array_clip(self, min, max, out); } } @@ -960,11 +965,13 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o Py_INCREF(indescr); } Py_DECREF(newdescr); + newdescr = NULL; if (!PyDataType_ISNOTSWAPPED(indescr)) { PyArray_Descr *descr2; descr2 = PyArray_DescrNewByteorder(indescr, '='); Py_DECREF(indescr); + indescr = NULL; if (descr2 == NULL) { goto fail; } @@ -973,16 +980,13 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o /* Convert max to an array */ if (max != NULL) { + Py_INCREF(indescr); maxa = (PyArrayObject *)PyArray_FromAny(max, indescr, 0, 0, NPY_ARRAY_DEFAULT, NULL); if (maxa == NULL) { - return NULL; + goto fail; } } - else { - /* Side-effect of PyArray_FromAny */ - Py_DECREF(indescr); - } /* * If we are unsigned, then make sure min is not < 0 @@ -1147,6 +1151,8 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o func(PyArray_DATA(newin), PyArray_SIZE(newin), min_data, max_data, PyArray_DATA(newout)); /* Clean up temporary variables */ + Py_XDECREF(indescr); + Py_XDECREF(newdescr); Py_XDECREF(mina); Py_XDECREF(maxa); Py_DECREF(newin); @@ -1155,6 +1161,8 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o return (PyObject *)out; fail: + Py_XDECREF(indescr); + Py_XDECREF(newdescr); Py_XDECREF(maxa); Py_XDECREF(mina); Py_XDECREF(newin); |