8000 BUG: Fix ticket #1588/gh issue #398, refcount error in clip · seberg/numpy@7b5dba0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7b5dba0

Browse files
mwiebecertik
authored andcommitted
BUG: Fix ticket numpy#1588/gh issue numpy#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.
1 parent f65ff87 commit 7b5dba0

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

numpy/core/src/multiarray/calculation.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
895895
PyArrayObject *maxa = NULL;
896896
PyArrayObject *mina = NULL;
897897
PyArrayObject *newout = NULL, *newin = NULL;
898-
PyArray_Descr *indescr, *newdescr;
898+
PyArray_Descr *indescr = NULL, *newdescr = NULL;
899899
char *max_data, *min_data;
900900
PyObject *zero;
901901

@@ -922,23 +922,24 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
922922
/* Use the fast scalar clip function */
923923

924924
/* First we need to figure out the correct type */
925-
indescr = NULL;
926925
if (min != NULL) {
927926
indescr = PyArray_DescrFromObject(min, NULL);
928927
if (indescr == NULL) {
929-
return NULL;
928+
goto fail;
930929
}
931930
}
932931
if (max != NULL) {
933932
newdescr = PyArray_DescrFromObject(max, indescr);
934933
Py_XDECREF(indescr);
934+
indescr = NULL;
935935
if (newdescr == NULL) {
936-
return NULL;
936+
goto fail;
937937
}
938938
}
939939
else {
940940
/* Steal the reference */
941941
newdescr = indescr;
942+
indescr = NULL;
942943
}
943944

944945

@@ -950,8 +951,12 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
950951
if (PyArray_ScalarKind(newdescr->type_num, NULL) >
951952
PyArray_ScalarKind(PyArray_DESCR(self)->type_num, NULL)) {
952953
indescr = PyArray_PromoteTypes(newdescr, PyArray_DESCR(self));
954+
if (indescr == NULL) {
955+
goto fail;
956+
}
953957
func = indescr->f->fastclip;
954958
if (func == NULL) {
959+
Py_DECREF(indescr);
955960
return _slow_array_clip(self, min, max, out);
956961
}
957962
}
@@ -960,11 +965,13 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
960965
Py_INCREF(indescr);
961966
}
962967
Py_DECREF(newdescr);
968+
newdescr = NULL;
963969

964970
if (!PyDataType_ISNOTSWAPPED(indescr)) {
965971
PyArray_Descr *descr2;
966972
descr2 = PyArray_DescrNewByteorder(indescr, '=');
967973
Py_DECREF(indescr);
974+
indescr = NULL;
968975
if (descr2 == NULL) {
969976
goto fail;
970977
}
@@ -973,16 +980,13 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
973980

974981
/* Convert max to an array */
975982
if (max != NULL) {
983+
Py_INCREF(indescr);
976984
maxa = (PyArrayObject *)PyArray_FromAny(max, indescr, 0, 0,
977985
NPY_ARRAY_DEFAULT, NULL);
978986
if (maxa == NULL) {
979-
return NULL;
987+
goto fail;
980988
}
981989
}
982-
else {
983-
/* Side-effect of PyArray_FromAny */
984-
Py_DECREF(indescr);
985-
}
986990

987991
/*
988992
* 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
11471151
func(PyArray_DATA(newin), PyArray_SIZE(newin), min_data, max_data, PyArray_DATA(newout));
11481152

11491153
/* Clean up temporary variables */
1154+
Py_XDECREF(indescr);
1155+
Py_XDECREF(newdescr);
11501156
Py_XDECREF(mina);
11511157
Py_XDECREF(maxa);
11521158
Py_DECREF(newin);
@@ -1155,6 +1161,8 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
11551161
return (PyObject *)out;
11561162

11571163
fail:
1164+
Py_XDECREF(indescr);
1165+
Py_XDECREF(newdescr);
11581166
Py_XDECREF(maxa);
11591167
Py_XDECREF(mina);
11601168
Py_XDECREF(newin);

0 commit comments

Comments
 (0)
0