summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndřej Čertík <ondrej.certik@gmail.com>2012-08-31 15:46:41 -0700
committerOndřej Čertík <ondrej.certik@gmail.com>2012-08-31 15:46:41 -0700
commite60c70d7ca5dbe45860c44673ddab02d47770155 (patch)
treeaac7166a9a711c5da173c1f8b0a695af8fdd958c
parent8c75aa01e2f4ec02eb1d852a14da3e9e03107da8 (diff)
parent103988055053f7a30083fd28c0887a5f2922a67c (diff)
downloadnumpy-e60c70d7ca5dbe45860c44673ddab02d47770155.tar.gz
Merge pull request #405 from certik/pr400_fix
BUG: Fix ticket #1588/gh issue #398, refcount error in clip
-rw-r--r--numpy/core/src/multiarray/calculation.c26
-rw-r--r--numpy/core/tests/test_regression.py9
2 files changed, 26 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);
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 31a99909b..08431c6f0 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -1728,5 +1728,14 @@ class TestRegression(TestCase):
a = np.array(['abc'], dtype=np.unicode)[0]
del a
+ def test_refcount_error_in_clip(self):
+ # Ticket #1588
+ a = np.zeros((2,), dtype='>i2').clip(min=0)
+ x = a + a
+ # This used to segfault:
+ y = str(x)
+ # Check the final string:
+ assert_(y == "[0 0]")
+
if __name__ == "__main__":
run_module_suite()