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

Fix GH-12826: Weird pointers issue in nested loops

This regressed in cd53ce838a.
The loop with `zend_hash_iterators_update` hangs forever because
`iter_pos` can't advance to idx. This is because the
`zend_hash_iterators_lower_pos` upper bound is `target->nNumUsed`,
but that is set to `source->nNumOfElements`.
That means that if there are holes in the array, we still loop over all
the buckets but the number of bucket slots will not match.
Fix it by changing the assignment.

Closes GH-12831.
This commit is contained in:
Niels Dossche
2023-11-29 20:35:13 +01:00
parent c46fd35f7b
commit b175ea4215
3 changed files with 32 additions and 1 deletions

1
NEWS
View File

@@ -8,6 +8,7 @@ PHP NEWS
. Fix various missing NULL checks. (nielsdos, dstogov)
. Fixed bug GH-12835 (Leak of call->extra_named_params on internal __call).
(ilutov)
. Fixed bug GH-12826 (Weird pointers issue in nested loops). (nielsdos)
- FPM:
. Fixed bug GH-12705 (Segmentation fault in fpm_status_export_to_zval).

30
Zend/tests/gh12826.phpt Normal file
View File

@@ -0,0 +1,30 @@
--TEST--
GH-12826 (Weird pointers issue in nested loops)
--FILE--
<?php
$test = array(
'a' => 1,
'b' => 2,
'c' => 3,
'd' => 4,
);
unset($test['a']);
unset($test['b']);
foreach($test as $k => &$v) { // Mind the reference!
echo "Pass $k : ";
foreach($test as $kk => $vv) {
echo $test[$kk];
if ($kk == $k) $test[$kk] = 0;
}
echo "\n";
}
unset($v);
?>
--EXPECT--
Pass c : 34
Pass d : 04

View File

@@ -2407,7 +2407,7 @@ static zend_always_inline uint32_t zend_array_dup_elements(HashTable *source, Ha
idx++; p++;
}
} else {
target->nNumUsed = source->nNumOfElements;
target->nNumUsed = source->nNumUsed;
uint32_t iter_pos = zend_hash_iterators_lower_pos(target, idx);
while (p != end) {