Skip to content

Commit c9a6140

Browse files
j-bowhaytylerjereddy
authored andcommitted
BUG: special: Fix unchecked malloc in stirling2.h (scipy#22339)
Use std::unique_ptr and new (std::nothrow) instead of malloc. Closes scipygh-22336.
1 parent 732832a commit c9a6140

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

scipy/special/stirling2.h

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ using std::isinf;
1111
#include <stdio.h>
1212
#include <stdint.h>
1313
#include <stdlib.h>
14+
#include <memory>
15+
#include <limits>
1416

1517
#include "xsf/binom.h"
1618
#include "xsf/lambertw.h"
19+
#include "sf_error.h"
1720

1821

1922
/* Stirling numbers of the second kind
@@ -32,53 +35,56 @@ using std::isinf;
3235

3336
// Dynamic programming
3437

35-
double _stirling2_dp(double n, double k){
38+
double _stirling2_dp(double n, double k) {
3639
if ((n == 0 && k == 0) || (n==1 && k==1)) {
3740
return 1.;
3841
}
39-
if (k <= 0 || k > n || n < 0){
42+
if (k <= 0 || k > n || n < 0) {
4043
return 0.;
4144
}
4245
int arraySize = k <= n - k + 1 ? k : n - k + 1;
43-
double *curr = (double *) malloc(arraySize * sizeof(double));
44-
for (int i = 0; i < arraySize; i++){
46+
auto curr = std::unique_ptr<double[]>{new (std::nothrow) double[arraySize]};
47+
if (curr == nullptr) {
48+
sf_error("stirling2", SF_ERROR_MEMORY, NULL);
49+
return std::numeric_limits<double>::quiet_NaN();
50+
}
51+
for (int i = 0; i < arraySize; i++) {
4552
curr[i] = 1.;
4653
}
4754
if (k <= n - k + 1) {
48-
for (int i = 1; i < n - k + 1; i++){
49-
for (int j = 1; j < k; j++){
55+
for (int i = 1; i < n - k + 1; i++) {
56+
for (int j = 1; j < k; j++) {
5057
curr[j] = (j + 1) * curr[j] + curr[j - 1];
51-
if (isinf(curr[j])){
52-
free(curr);
58+
if (isinf(curr[j])) {
59+
sf_error("stirling2", SF_ERROR_OVERFLOW, NULL);
5360
return INFINITY; // numeric overflow
5461
}
5562
}
5663
}
5764
} else {
58-
for (int i = 1; i < k; i++){
59-
for (int j = 1; j < n - k + 1; j++){
65+
for (int i = 1; i < k; i++) {
66+
for (int j = 1; j < n - k + 1; j++) {
6067
curr[j] = (i + 1) * curr[j - 1] + curr[j];
61-
if (isinf(curr[j])){
62-
free(curr);
68+
if (isinf(curr[j])) {
69+
sf_error("stirling2", SF_ERROR_OVERFLOW, NULL);
6370
return INFINITY; // numeric overflow
6471
}
6572
}
6673
}
6774
}
6875
double output = curr[arraySize - 1];
69-
free(curr);
7076
return output;
7177
}
7278

7379

7480

7581
// second order Temme approximation
7682

77-
double _stirling2_temme(double n, double k){
78-
if ((n == k && n >= 0) || (n > 0 && k==1)){
83+
double _stirling2_temme(double n, double k) {
84+
if ((n == k && n >= 0) || (n > 0 && k==1)) {
7985
return 1.;
8086
}
81-
if (k <= 0 || k > n || n < 0){
87+
if (k <= 0 || k > n || n < 0) {
8288
return 0.;
8389
}
8490
double mu = (double)k / (double)n;

0 commit comments

Comments
 (0)