diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2013-08-30 06:26:51 -0700 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2013-08-30 06:26:51 -0700 |
commit | 78785a496440e0861561c13aafa104082d69fbe7 (patch) | |
tree | 0f2b554ce3dc0db7c2f980339ed6e95f19f50033 | |
parent | b350089f440fdfd28d7be1cfa23cb6b1b66fc1e4 (diff) | |
parent | 0167ac1daa6adb058d646efd0790ce129059116a (diff) | |
download | numpy-78785a496440e0861561c13aafa104082d69fbe7.tar.gz |
Merge pull request #3655 from larsmans/c-fixes
FIX: unchecked mallocs and various other things
-rw-r--r-- | numpy/core/src/multiarray/array_assign_array.c | 1 | ||||
-rw-r--r-- | numpy/core/src/multiarray/arrayobject.c | 14 | ||||
-rw-r--r-- | numpy/core/src/multiarray/buffer.c | 74 | ||||
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 12 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 6 | ||||
-rw-r--r-- | numpy/core/src/npysort/heapsort.c.src | 2 | ||||
-rw-r--r-- | numpy/core/src/npysort/mergesort.c.src | 16 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 39 |
8 files changed, 101 insertions, 63 deletions
diff --git a/numpy/core/src/multiarray/array_assign_array.c b/numpy/core/src/multiarray/array_assign_array.c index 7e7cc0c29..1cf4b3a3b 100644 --- a/numpy/core/src/multiarray/array_assign_array.c +++ b/numpy/core/src/multiarray/array_assign_array.c @@ -381,7 +381,6 @@ PyArray_AssignArray(PyArrayObject *dst, PyArrayObject *src, } } -finish: if (copied_src) { Py_DECREF(src); } diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c index 86a6b0137..fab9a056a 100644 --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -221,8 +221,13 @@ PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object) n_new = PyArray_DIMS(dest)[PyArray_NDIM(dest)-1]; n_old = PyString_Size(src_object); if (n_new > n_old) { - new_string = (char *)malloc(n_new); - memmove(new_string, PyString_AS_STRING(src_object), n_old); + new_string = malloc(n_new); + if (new_string == NULL) { + Py_DECREF(src_object); + PyErr_NoMemory(); + return -1; + } + memcpy(new_string, PyString_AS_STRING(src_object), n_old); memset(new_string + n_old, ' ', n_new - n_old); tmp = PyString_FromStringAndSize(new_string, n_new); free(new_string); @@ -552,7 +557,7 @@ array_repr_builtin(PyArrayObject *self, int repr) max_n = PyArray_NBYTES(self)*4*sizeof(char) + 7; - if ((string = (char *)PyArray_malloc(max_n)) == NULL) { + if ((string = PyArray_malloc(max_n)) == NULL) { return PyErr_NoMemory(); } @@ -1653,9 +1658,8 @@ array_iter(PyArrayObject *arr) static PyObject * array_alloc(PyTypeObject *type, Py_ssize_t NPY_UNUSED(nitems)) { - PyObject *obj; /* nitems will always be 0 */ - obj = (PyObject *)PyArray_malloc(type->tp_basicsize); + PyObject *obj = PyArray_malloc(type->tp_basicsize); PyObject_Init(obj, type); return obj; } diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index d69cd36c5..3ae3c7d0d 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -102,27 +102,26 @@ array_getcharbuf(PyArrayObject *self, Py_ssize_t segment, constchar **ptrptr) /* Fast string 'class' */ typedef struct { char *s; - int allocated; - int pos; + size_t allocated; + size_t pos; } _tmp_string_t; +#define INIT_SIZE 16 + static int _append_char(_tmp_string_t *s, char c) { - char *p; - if (s->s == NULL) { - s->s = (char*)malloc(16); - s->pos = 0; - s->allocated = 16; - } if (s->pos >= s->allocated) { - p = (char*)realloc(s->s, 2*s->allocated); + char *p; + size_t to_alloc = (s->allocated == 0) ? INIT_SIZE : (2 * s->allocated); + + p = realloc(s->s, to_alloc); if (p == NULL) { PyErr_SetString(PyExc_MemoryError, "memory allocation failed"); return -1; } s->s = p; - s->allocated *= 2; + s->allocated = to_alloc; } s->s[s->pos] = c; ++s->pos; @@ -130,11 +129,12 @@ _append_char(_tmp_string_t *s, char c) } static int -_append_str(_tmp_string_t *s, char *c) +_append_str(_tmp_string_t *s, char const *p) { - while (*c != '\0') { - if (_append_char(s, *c)) return -1; - ++c; + for (; *p != '\0'; p++) { + if (_append_char(s, *p) != 0) { + return -1; + } } return 0; } @@ -446,12 +446,14 @@ _buffer_info_new(PyArrayObject *arr) _tmp_string_t fmt = {0,0,0}; int k; - info = (_buffer_info_t*)malloc(sizeof(_buffer_info_t)); + info = malloc(sizeof(_buffer_info_t)); + if (info == NULL) { + goto fail; + } /* Fill in format */ if (_buffer_format_string(PyArray_DESCR(arr), &fmt, arr, NULL, NULL) != 0) { - free(info); - return NULL; + goto fail; } _append_char(&fmt, '\0'); info->format = fmt.s; @@ -464,8 +466,10 @@ _buffer_info_new(PyArrayObject *arr) info->strides = NULL; } else { - info->shape = (Py_ssize_t*)malloc(sizeof(Py_ssize_t) - * PyArray_NDIM(arr) * 2 + 1); + info->shape = malloc(sizeof(Py_ssize_t) * PyArray_NDIM(arr) * 2 + 1); + if (info->shape == NULL) { + goto fail; + } info->strides = info->shape + PyArray_NDIM(arr); for (k = 0; k < PyArray_NDIM(arr); ++k) { info->shape[k] = PyArray_DIMS(arr)[k]; @@ -474,6 +478,10 @@ _buffer_info_new(PyArrayObject *arr) } return info; + +fail: + free(info); + return NULL; } /* Compare two info structures */ @@ -515,7 +523,7 @@ _buffer_info_free(_buffer_info_t *info) static _buffer_info_t* _buffer_get_info(PyObject *arr) { - PyObject *key, *item_list, *item; + PyObject *key = NULL, *item_list = NULL, *item = NULL; _buffer_info_t *info = NULL, *old_info = NULL; if (_buffer_info_cache == NULL) { @@ -533,6 +541,9 @@ _buffer_get_info(PyObject *arr) /* Check if it is identical with an old one; reuse old one, if yes */ key = PyLong_FromVoidPtr((void*)arr); + if (key == NULL) { + goto fail; + } item_list = PyDict_GetItem(_buffer_info_cache, key); if (item_list != NULL) { @@ -549,12 +560,20 @@ _buffer_get_info(PyObject *arr) } else { item_list = PyList_New(0); - PyDict_SetItem(_buffer_info_cache, key, item_list); + if (item_list == NULL) { + goto fail; + } + if (PyDict_SetItem(_buffer_info_cache, key, item_list) != 0) { + goto fail; + } } if (info != old_info) { /* Needs insertion */ item = PyLong_FromVoidPtr((void*)info); + if (item == NULL) { + goto fail; + } PyList_Append(item_list, item); Py_DECREF(item); } @@ -562,6 +581,14 @@ _buffer_get_info(PyObject *arr) Py_DECREF(item_list); Py_DECREF(key); return info; + +fail: + if (info != NULL && info != old_info) { + _buffer_info_free(info); + } + Py_XDECREF(item_list); + Py_XDECREF(key); + return NULL; } /* Clear buffer info from the global dictionary */ @@ -754,7 +781,10 @@ _descriptor_from_pep3118_format(char *s) } /* Strip whitespace, except from field names */ - buf = (char*)malloc(strlen(s) + 1); + buf = malloc(strlen(s) + 1); + if (buf == NULL) { + return NULL; + } p = buf; while (*s != '\0') { if (*s == ':') { diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 07de463f7..70f63269e 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -60,12 +60,15 @@ fromfile_next_element(FILE **fp, void *dptr, PyArray_Descr *dtype, * beginning and end. This simplifies the separator-skipping code below. */ static char * -swab_separator(char *sep) +swab_separator(const char *sep) { int skip_space = 0; char *s, *start; s = start = malloc(strlen(sep)+3); + if (s == NULL) { + return NULL; + } /* add space to front if there isn't one */ if (*sep != '\0' && !isspace(*sep)) { *s = ' '; s++; @@ -3146,6 +3149,11 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread, return NULL; } clean_sep = swab_separator(sep); + if (clean_sep == NULL) { + err = 1; + goto fail; + } + NPY_BEGIN_ALLOW_THREADS; totalbytes = bytes = size * dtype->elsize; dptr = PyArray_DATA(r); @@ -3183,6 +3191,8 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread, } NPY_END_ALLOW_THREADS; free(clean_sep); + +fail: if (err == 1) { PyErr_NoMemory(); } diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index 9fe406c72..85dd8ab01 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -3496,7 +3496,7 @@ PyDataMem_NEW(size_t size) } PyGILState_Release(gilstate); } - return (char *)result; + return result; } /*NUMPY_API @@ -3516,7 +3516,7 @@ PyDataMem_NEW_ZEROED(size_t size, size_t elsize) } PyGILState_Release(gilstate); } - return (char *)result; + return result; } /*NUMPY_API @@ -3553,7 +3553,7 @@ PyDataMem_RENEW(void *ptr, size_t size) } PyGILState_Release(gilstate); } - return (char *)result; + return result; } static PyObject * diff --git a/numpy/core/src/npysort/heapsort.c.src b/numpy/core/src/npysort/heapsort.c.src index 6a8c79f7a..45d9deb92 100644 --- a/numpy/core/src/npysort/heapsort.c.src +++ b/numpy/core/src/npysort/heapsort.c.src @@ -292,7 +292,7 @@ aheapsort_@suff@(@type@ *v, npy_intp *tosort, npy_intp n, PyArrayObject *arr) int npy_heapsort(void *base, size_t num, size_t size, npy_comparator cmp) { - char *tmp = (char *) malloc(size); + char *tmp = malloc(size); char *a = (char *) base - size; size_t i, j, l; diff --git a/numpy/core/src/npysort/mergesort.c.src b/numpy/core/src/npysort/mergesort.c.src index 55dcab4fb..3bd6ee1a6 100644 --- a/numpy/core/src/npysort/mergesort.c.src +++ b/numpy/core/src/npysort/mergesort.c.src @@ -110,7 +110,7 @@ mergesort_@suff@(@type@ *start, npy_intp num, void *NOT_USED) pl = start; pr = pl + num; - pw = (@type@ *) malloc((num/2) * sizeof(@type@)); + pw = malloc((num/2) * sizeof(@type@)); if (pw == NULL) { return -NPY_ENOMEM; } @@ -173,7 +173,7 @@ amergesort_@suff@(@type@ *v, npy_intp *tosort, npy_intp num, void *NOT_USED) pl = tosort; pr = pl + num; - pw = (npy_intp *) malloc((num/2) * sizeof(npy_intp)); + pw = malloc((num/2) * sizeof(npy_intp)); if (pw == NULL) { return -NPY_ENOMEM; } @@ -255,12 +255,12 @@ mergesort_@suff@(@type@ *start, npy_intp num, PyArrayObject *arr) pl = start; pr = pl + num*len; - pw = (@type@ *) malloc((num/2) * elsize); + pw = malloc((num/2) * elsize); if (pw == NULL) { err = -NPY_ENOMEM; goto fail_0; } - vp = (@type@ *) malloc(elsize); + vp = malloc(elsize); if (vp == NULL) { err = -NPY_ENOMEM; goto fail_1; @@ -329,7 +329,7 @@ amergesort_@suff@(@type@ *v, npy_intp *tosort, npy_intp num, PyArrayObject *arr) pl = tosort; pr = pl + num; - pw = (npy_intp *) malloc((num/2) * sizeof(npy_intp)); + pw = malloc((num/2) * sizeof(npy_intp)); if (pw == NULL) { return -NPY_ENOMEM; } @@ -406,14 +406,14 @@ npy_mergesort(void *base, size_t num, size_t size, npy_comparator cmp) char *pl, *pr, *pw, *vp; int err = 0; - pl = (char *)base; + pl = base; pr = pl + num*size; - pw = (char *) malloc((num/2) * size); + pw = malloc((num/2) * size); if (pw == NULL) { err = -NPY_ENOMEM; goto fail_0; } - vp = (char *) malloc(size); + vp = malloc(size); if (vp == NULL) { err = -NPY_ENOMEM; goto fail_1; diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index cf4696269..a71777ce3 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -4849,6 +4849,17 @@ ufunc_reduceat(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds) return PyUFunc_GenericReduction(ufunc, args, kwds, UFUNC_REDUCEAT); } +/* Helper for ufunc_at, below */ +static NPY_INLINE PyArrayObject * +new_array_op(PyArrayObject *op_array, char *data) +{ + npy_intp dims[1] = {1}; + PyObject *r = PyArray_NewFromDescr(&PyArray_Type, PyArray_DESCR(op_array), + 1, dims, NULL, data, + NPY_ARRAY_WRITEABLE, NULL); + return (PyArrayObject *)r; +} + /* * Call ufunc only on selected array items and store result in first operand. * For add ufunc, method call is equivalent to op1[idx] += op2 with no @@ -4872,7 +4883,6 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args) PyArray_Descr *dtypes[3] = {NULL, NULL, NULL}; PyArrayObject *operands[3] = {NULL, NULL, NULL}; PyArrayObject *array_operands[3] = {NULL, NULL, NULL}; - npy_intp dims[1] = {1}; int needs_api; @@ -4912,9 +4922,9 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args) return NULL; } - op1_array = op1; + op1_array = (PyArrayObject *)op1; - iter = PyArray_MapIterArray(op1_array, idx); + iter = (PyArrayMapIterObject *)PyArray_MapIterArray(op1_array, idx); if (iter == NULL) { goto fail; } @@ -4987,31 +4997,16 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args) stride[0] = 1; Py_INCREF(PyArray_DESCR(op1_array)); - array_operands[0] = PyArray_NewFromDescr(&PyArray_Type, - PyArray_DESCR(op1_array), - 1, dims, NULL, iter->dataptr, - NPY_ARRAY_WRITEABLE, NULL); + array_operands[0] = new_array_op(op1_array, iter->dataptr); if (iter2 != NULL) { Py_INCREF(PyArray_DESCR(op2_array)); - array_operands[1] = PyArray_NewFromDescr(&PyArray_Type, - PyArray_DESCR(op2_array), - 1, dims, NULL, - PyArray_ITER_DATA(iter2), - NPY_ARRAY_WRITEABLE, NULL); + array_operands[1] = new_array_op(op2_array, PyArray_ITER_DATA(iter2)); Py_INCREF(PyArray_DESCR(op1_array)); - array_operands[2] = PyArray_NewFromDescr(&PyArray_Type, - PyArray_DESCR(op1_array), - 1, dims, NULL, - iter->dataptr, - NPY_ARRAY_WRITEABLE, NULL); + array_operands[2] = new_array_op(op1_array, iter->dataptr); } else { Py_INCREF(PyArray_DESCR(op1_array)); - array_operands[1] = PyArray_NewFromDescr(&PyArray_Type, - PyArray_DESCR(op1_array), - 1, dims, NULL, - iter->dataptr, - NPY_ARRAY_WRITEABLE, NULL); + array_operands[2] = new_array_op(op1_array, iter->dataptr); array_operands[2] = NULL; } |