Skip to content

Commit 75cca9f

Browse files
committed
Fix memory leaks in array_any() / array_all()
The return value is overwritten, but if the key was not an interned string we should destroy it. Closes GH-17977.
1 parent b2e49c8 commit 75cca9f

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ PHP NEWS
1212
. Fixed bug GH-17913 (ReflectionFunction::isDeprecated() returns incorrect
1313
results for closures created from magic __call()). (timwolla)
1414

15+
- Standard:
16+
. Fix memory leaks in array_any() / array_all(). (nielsdos)
17+
1518
- Treewide:
1619
. Fixed bug GH-17736 (Assertion failure zend_reference_destroy()). (nielsdos)
1720

ext/standard/array.c

+13-4
Original file line numberDiff line numberDiff line change
@@ -6628,7 +6628,8 @@ static zend_result php_array_find(const HashTable *array, zend_fcall_info fci, z
66286628
ZVAL_COPY(&args[0], operand);
66296629

66306630
zend_result result = zend_call_function(&fci, &fci_cache);
6631-
if (EXPECTED(result == SUCCESS)) {
6631+
ZEND_ASSERT(result == SUCCESS);
6632+
if (EXPECTED(!Z_ISUNDEF(retval))) {
66326633
int retval_true;
66336634

66346635
retval_true = zend_is_true(&retval);
@@ -6656,7 +6657,7 @@ static zend_result php_array_find(const HashTable *array, zend_fcall_info fci, z
66566657
zval_ptr_dtor(&args[0]);
66576658
zval_ptr_dtor(&args[1]);
66586659

6659-
if (UNEXPECTED(result != SUCCESS)) {
6660+
if (UNEXPECTED(Z_ISUNDEF(retval))) {
66606661
return FAILURE;
66616662
}
66626663
} ZEND_HASH_FOREACH_END();
@@ -6725,7 +6726,11 @@ PHP_FUNCTION(array_any)
67256726
RETURN_THROWS();
67266727
}
67276728

6728-
RETURN_BOOL(Z_TYPE_P(return_value) != IS_UNDEF);
6729+
bool retval = !Z_ISUNDEF_P(return_value);
6730+
if (Z_TYPE_P(return_value) == IS_STRING) {
6731+
zval_ptr_dtor_str(return_value);
6732+
}
6733+
RETURN_BOOL(retval);
67296734
}
67306735
/* }}} */
67316736

@@ -6745,7 +6750,11 @@ PHP_FUNCTION(array_all)
67456750
RETURN_THROWS();
67466751
}
67476752

6748-
RETURN_BOOL(Z_TYPE_P(return_value) == IS_UNDEF);
6753+
bool retval = Z_ISUNDEF_P(return_value);
6754+
if (Z_TYPE_P(return_value) == IS_STRING) {
6755+
zval_ptr_dtor_str(return_value);
6756+
}
6757+
RETURN_BOOL(retval);
67496758
}
67506759
/* }}} */
67516760

ext/standard/tests/array/gh17977.phpt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
array_any() / array_all() leak
3+
--DESCRIPTION--
4+
Found in GH-16831#issuecomment-2700410631
5+
--FILE--
6+
<?php
7+
8+
// Don't touch this str_repeat + random_int combination,
9+
// this is to circumvent SCCP and interning
10+
$key = str_repeat('abc', random_int(3, 3));
11+
12+
var_dump(array_any([$key => 1], static fn () => true));
13+
var_dump(array_all([$key => 1], static fn () => false));
14+
15+
?>
16+
--EXPECT--
17+
bool(true)
18+
bool(false)

0 commit comments

Comments
 (0)