1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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.
This commit is contained in:
Niels Dossche
2025-03-05 18:40:22 +01:00
parent b2e49c80bf
commit 75cca9f19e
3 changed files with 34 additions and 4 deletions

3
NEWS
View File

@@ -12,6 +12,9 @@ PHP NEWS
. Fixed bug GH-17913 (ReflectionFunction::isDeprecated() returns incorrect
results for closures created from magic __call()). (timwolla)
- Standard:
. Fix memory leaks in array_any() / array_all(). (nielsdos)
- Treewide:
. Fixed bug GH-17736 (Assertion failure zend_reference_destroy()). (nielsdos)

View File

@@ -6628,7 +6628,8 @@ static zend_result php_array_find(const HashTable *array, zend_fcall_info fci, z
ZVAL_COPY(&args[0], operand);
zend_result result = zend_call_function(&fci, &fci_cache);
if (EXPECTED(result == SUCCESS)) {
ZEND_ASSERT(result == SUCCESS);
if (EXPECTED(!Z_ISUNDEF(retval))) {
int retval_true;
retval_true = zend_is_true(&retval);
@@ -6656,7 +6657,7 @@ static zend_result php_array_find(const HashTable *array, zend_fcall_info fci, z
zval_ptr_dtor(&args[0]);
zval_ptr_dtor(&args[1]);
if (UNEXPECTED(result != SUCCESS)) {
if (UNEXPECTED(Z_ISUNDEF(retval))) {
return FAILURE;
}
} ZEND_HASH_FOREACH_END();
@@ -6725,7 +6726,11 @@ PHP_FUNCTION(array_any)
RETURN_THROWS();
}
RETURN_BOOL(Z_TYPE_P(return_value) != IS_UNDEF);
bool retval = !Z_ISUNDEF_P(return_value);
if (Z_TYPE_P(return_value) == IS_STRING) {
zval_ptr_dtor_str(return_value);
}
RETURN_BOOL(retval);
}
/* }}} */
@@ -6745,7 +6750,11 @@ PHP_FUNCTION(array_all)
RETURN_THROWS();
}
RETURN_BOOL(Z_TYPE_P(return_value) == IS_UNDEF);
bool retval = Z_ISUNDEF_P(return_value);
if (Z_TYPE_P(return_value) == IS_STRING) {
zval_ptr_dtor_str(return_value);
}
RETURN_BOOL(retval);
}
/* }}} */

View File

@@ -0,0 +1,18 @@
--TEST--
array_any() / array_all() leak
--DESCRIPTION--
Found in GH-16831#issuecomment-2700410631
--FILE--
<?php
// Don't touch this str_repeat + random_int combination,
// this is to circumvent SCCP and interning
$key = str_repeat('abc', random_int(3, 3));
var_dump(array_any([$key => 1], static fn () => true));
var_dump(array_all([$key => 1], static fn () => false));
?>
--EXPECT--
bool(true)
bool(false)