summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorMark Wiebe <mwwiebe@gmail.com>2012-08-31 00:44:19 -0700
committerOndřej Čertík <ondrej.certik@gmail.com>2012-08-31 15:17:39 -0700
commit8b2e6bed904415006d59344b27a0b23b35fab9ca (patch)
tree9b3ecb413bb3c94482e0e601c0e2b9f401c8cbf9 /numpy
parent8c75aa01e2f4ec02eb1d852a14da3e9e03107da8 (diff)
downloadnumpy-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.c26
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);