summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Berg <sebastianb@nvidia.com>2023-02-21 12:10:07 +0100
committerSebastian Berg <sebastianb@nvidia.com>2023-02-21 12:10:07 +0100
commitce7faad619c3457eb3ca48bafaedc7ae44712c29 (patch)
treeba5f0bbcf94590a990ec2f7148e1e024069b5b13
parentcafd35cf47ba6fc677d4a4136d810cbc3c00faf0 (diff)
downloadnumpy-ce7faad619c3457eb3ca48bafaedc7ae44712c29.tar.gz
BUG,MAINT: Avoid malloc(0) in linalg and improve error paths.
-rw-r--r--numpy/linalg/umath_linalg.cpp36
1 files changed, 28 insertions, 8 deletions
diff --git a/numpy/linalg/umath_linalg.cpp b/numpy/linalg/umath_linalg.cpp
index 639de6ee0..014b480b7 100644
--- a/numpy/linalg/umath_linalg.cpp
+++ b/numpy/linalg/umath_linalg.cpp
@@ -1149,7 +1149,7 @@ slogdet(char **args,
void *NPY_UNUSED(func))
{
fortran_int m;
- npy_uint8 *tmp_buff = NULL;
+ char *tmp_buff = NULL;
size_t matrix_size;
size_t pivot_size;
size_t safe_m;
@@ -1163,10 +1163,11 @@ slogdet(char **args,
*/
INIT_OUTER_LOOP_3
m = (fortran_int) dimensions[0];
- safe_m = m;
+ /* avoid empty malloc (buffers likely unused) and ensure m is `size_t` */
+ safe_m = m != 0 ? m : 1;
matrix_size = safe_m * safe_m * sizeof(typ);
pivot_size = safe_m * sizeof(fortran_int);
- tmp_buff = (npy_uint8 *)malloc(matrix_size + pivot_size);
+ tmp_buff = (char *)malloc(matrix_size + pivot_size);
if (tmp_buff) {
LINEARIZE_DATA_t lin_data;
@@ -1183,6 +1184,13 @@ slogdet(char **args,
free(tmp_buff);
}
+ else {
+ /* TODO: Requires use of new ufunc API to indicate error return */
+ NPY_ALLOW_C_API_DEF
+ NPY_ALLOW_C_API;
+ PyErr_NoMemory();
+ NPY_DISABLE_C_API;
+ }
}
template<typename typ, typename basetyp>
@@ -1193,7 +1201,7 @@ det(char **args,
void *NPY_UNUSED(func))
{
fortran_int m;
- npy_uint8 *tmp_buff;
+ char *tmp_buff;
size_t matrix_size;
size_t pivot_size;
size_t safe_m;
@@ -1207,10 +1215,11 @@ det(char **args,
*/
INIT_OUTER_LOOP_2
m = (fortran_int) dimensions[0];
- safe_m = m;
+ /* avoid empty malloc (buffers likely unused) and ensure m is `size_t` */
+ safe_m = m != 0 ? m : 1;
matrix_size = safe_m * safe_m * sizeof(typ);
pivot_size = safe_m * sizeof(fortran_int);
- tmp_buff = (npy_uint8 *)malloc(matrix_size + pivot_size);
+ tmp_buff = (char *)malloc(matrix_size + pivot_size);
if (tmp_buff) {
LINEARIZE_DATA_t lin_data;
@@ -1231,6 +1240,13 @@ det(char **args,
free(tmp_buff);
}
+ else {
+ /* TODO: Requires use of new ufunc API to indicate error return */
+ NPY_ALLOW_C_API_DEF
+ NPY_ALLOW_C_API;
+ PyErr_NoMemory();
+ NPY_DISABLE_C_API;
+ }
}
@@ -3738,7 +3754,8 @@ scalar_trait)
fortran_int lda = fortran_int_max(1, m);
fortran_int ldb = fortran_int_max(1, fortran_int_max(m,n));
- mem_buff = (npy_uint8 *)malloc(a_size + b_size + s_size);
+ size_t msize = a_size + b_size + s_size;
+ mem_buff = (npy_uint8 *)malloc(msize != 0 ? msize : 1);
if (!mem_buff)
goto error;
@@ -3790,11 +3807,14 @@ scalar_trait)
return 1;
error:
- TRACE_TXT("%s failed init\n", __FUNCTION__);
free(mem_buff);
free(mem_buff2);
memset(params, 0, sizeof(*params));
+ NPY_ALLOW_C_API_DEF
+ NPY_ALLOW_C_API;
+ PyErr_NoMemory();
+ NPY_DISABLE_C_API;
return 0;
}