From 9b2ca4c16b25d8c11e7ae2ec526e8c42fedda68e Mon Sep 17 00:00:00 2001 From: Jeff VanOss Date: Wed, 5 Sep 2018 12:29:50 -0400 Subject: BUG: fix memory leak of tmp object in PY3K --- numpy/core/src/multiarray/buffer.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index 0b15db5f4..1e4493b0d 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -299,13 +299,18 @@ _buffer_format_string(PyArray_Descr *descr, _tmp_string_t *str, tmp = PyUnicode_AsUTF8String(name); #else tmp = name; + Py_INCREF(tmp); #endif if (tmp == NULL || PyBytes_AsStringAndSize(tmp, &p, &len) < 0) { PyErr_Clear(); PyErr_SetString(PyExc_ValueError, "invalid field name"); + Py_XDECREF(tmp); + return -1; + } + if (_append_char(str, ':') < 0) { + Py_DECREF(tmp); return -1; } - if (_append_char(str, ':') < 0) return -1; while (len > 0) { if (*p == ':') { Py_DECREF(tmp); @@ -314,14 +319,18 @@ _buffer_format_string(PyArray_Descr *descr, _tmp_string_t *str, "field names"); return -1; } - if (_append_char(str, *p) < 0) return -1; + if (_append_char(str, *p) < 0) { + Py_DECREF(tmp); + return -1; + } ++p; --len; } - if (_append_char(str, ':') < 0) return -1; -#if defined(NPY_PY3K) + if (_append_char(str, ':') < 0) { + Py_DECREF(tmp); + return -1; + } Py_DECREF(tmp); -#endif } if (_append_char(str, '}') < 0) return -1; } -- cgit v1.2.1 From 7f72233e2cbca3d5002566f186e02c324a063f0b Mon Sep 17 00:00:00 2001 From: Jeff VanOss Date: Wed, 26 Sep 2018 12:56:43 -0400 Subject: MAINT: refactor pep3118 field name construction --- numpy/core/src/multiarray/buffer.c | 90 +++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index 1e4493b0d..57ce0398f 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -141,6 +141,53 @@ _append_str(_tmp_string_t *s, char const *p) return 0; } +/* + * Append a PEP3118-formatted field name, ":name:", to str + */ +static int +_append_field_name(_tmp_string_t *str, PyObject *name) +{ + int ret = -1; + char *p; + Py_ssize_t len; + PyObject *tmp; +#if defined(NPY_PY3K) + /* FIXME: XXX -- should it use UTF-8 here? */ + tmp = PyUnicode_AsUTF8String(name); +#else + tmp = name; + Py_INCREF(tmp); +#endif + if (tmp == NULL || PyBytes_AsStringAndSize(tmp, &p, &len) < 0) { + PyErr_Clear(); + PyErr_SetString(PyExc_ValueError, "invalid field name"); + goto fail; + } + if (_append_char(str, ':') < 0) { + goto fail; + } + while (len > 0) { + if (*p == ':') { + PyErr_SetString(PyExc_ValueError, + "':' is not an allowed character in buffer " + "field names"); + goto fail; + } + if (_append_char(str, *p) < 0) { + goto fail; + } + ++p; + --len; + } + if (_append_char(str, ':') < 0) { + goto fail; + } + ret = 0; +fail: + Py_XDECREF(tmp); + return ret; +} + /* * Return non-zero if a type is aligned in each item in the given array, * AND, the descr element size is a multiple of the alignment, @@ -255,10 +302,9 @@ _buffer_format_string(PyArray_Descr *descr, _tmp_string_t *str, if (_append_str(str, "T{") < 0) return -1; for (k = 0; k < PyTuple_GET_SIZE(descr->names); ++k) { - PyObject *name, *item, *offset_obj, *tmp; + PyObject *name, *item, *offset_obj; PyArray_Descr *child; - char *p; - Py_ssize_t len, new_offset; + Py_ssize_t new_offset; int ret; name = PyTuple_GET_ITEM(descr->names, k); @@ -294,43 +340,7 @@ _buffer_format_string(PyArray_Descr *descr, _tmp_string_t *str, } /* Insert field name */ -#if defined(NPY_PY3K) - /* FIXME: XXX -- should it use UTF-8 here? */ - tmp = PyUnicode_AsUTF8String(name); -#else - tmp = name; - Py_INCREF(tmp); -#endif - if (tmp == NULL || PyBytes_AsStringAndSize(tmp, &p, &len) < 0) { - PyErr_Clear(); - PyErr_SetString(PyExc_ValueError, "invalid field name"); - Py_XDECREF(tmp); - return -1; - } - if (_append_char(str, ':') < 0) { - Py_DECREF(tmp); - return -1; - } - while (len > 0) { - if (*p == ':') { - Py_DECREF(tmp); - PyErr_SetString(PyExc_ValueError, - "':' is not an allowed character in buffer " - "field names"); - return -1; - } - if (_append_char(str, *p) < 0) { - Py_DECREF(tmp); - return -1; - } - ++p; - --len; - } - if (_append_char(str, ':') < 0) { - Py_DECREF(tmp); - return -1; - } - Py_DECREF(tmp); + if (_append_field_name(str, name) < 0) return -1; } if (_append_char(str, '}') < 0) return -1; } -- cgit v1.2.1