Skip to content

Commit 9af9886

Browse files
committed
Fix memory leak on overflow in _php_stream_scandir()
On overflow, only the array is freed, but not the strings.
1 parent a54af45 commit 9af9886

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

main/streams/streams.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,25 +2469,19 @@ PHPAPI int _php_stream_scandir(const char *dirname, zend_string **namelist[], in
24692469
vector_size = 10;
24702470
} else {
24712471
if(vector_size*2 < vector_size) {
2472-
/* overflow */
2473-
php_stream_closedir(stream);
2474-
efree(vector);
2475-
return -1;
2472+
goto overflow;
24762473
}
24772474
vector_size *= 2;
24782475
}
2479-
vector = (zend_string **) safe_erealloc(vector, vector_size, sizeof(char *), 0);
2476+
vector = (zend_string **) safe_erealloc(vector, vector_size, sizeof(zend_string *), 0);
24802477
}
24812478

24822479
vector[nfiles] = zend_string_init(sdp.d_name, strlen(sdp.d_name), 0);
24832480

2484-
nfiles++;
2485-
if(vector_size < 10 || nfiles == 0) {
2486-
/* overflow */
2487-
php_stream_closedir(stream);
2488-
efree(vector);
2489-
return -1;
2481+
if(vector_size < 10 || nfiles + 1 == 0) {
2482+
goto overflow;
24902483
}
2484+
nfiles++;
24912485
}
24922486
php_stream_closedir(stream);
24932487

@@ -2497,5 +2491,13 @@ PHPAPI int _php_stream_scandir(const char *dirname, zend_string **namelist[], in
24972491
qsort(*namelist, nfiles, sizeof(zend_string *), (int(*)(const void *, const void *))compare);
24982492
}
24992493
return nfiles;
2494+
2495+
overflow:
2496+
php_stream_closedir(stream);
2497+
for (unsigned int i = 0; i < nfiles; i++) {
2498+
zend_string_efree(vector[i]);
2499+
}
2500+
efree(vector);
2501+
return -1;
25002502
}
25012503
/* }}} */

0 commit comments

Comments
 (0)