Skip to content

Commit cb88dd2

Browse files
committed
feedback
1 parent 1e27ead commit cb88dd2

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Array duplication updates iterators at both a hole and the next defined element
3+
--FILE--
4+
<?php
5+
function test(array $values): void {
6+
$outerVisits = [];
7+
$innerVisits = [];
8+
$first = true;
9+
foreach ($values as $outerKey => &$outerValue) {
10+
$outerVisits[] = "$outerKey=>$outerValue";
11+
if ($first) {
12+
$first = false;
13+
foreach ($values as $innerKey => &$innerValue) {
14+
$innerVisits[] = "$innerKey=>$innerValue";
15+
if ($innerValue === 11) {
16+
// The outer cursor is at a hole, the inner at the next value.
17+
unset($values['a'], $values['b']);
18+
$copy = $values;
19+
// Trigger copy-on-write duplication, which compacts the holes.
20+
$values['i'] = 18;
21+
}
22+
}
23+
unset($innerValue);
24+
}
25+
}
26+
unset($outerValue);
27+
echo 'outer: ', implode(' ', $outerVisits), "\n";
28+
echo 'inner: ', implode(' ', $innerVisits), "\n";
29+
}
30+
31+
test(['a' => 10, 'b' => 11, 'c' => 12, 'd' => 13,
32+
'e' => 14, 'f' => 15, 'g' => 16, 'h' => 17]);
33+
?>
34+
--EXPECT--
35+
outer: a=>10 c=>12 d=>13 e=>14 f=>15 g=>16 h=>17 i=>18
36+
inner: a=>10 b=>11 c=>12 d=>13 e=>14 f=>15 g=>16 h=>17 i=>18

Zend/zend_hash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2428,7 +2428,7 @@ static zend_always_inline uint32_t zend_array_dup_elements(HashTable *source, Ha
24282428
do {
24292429
zend_hash_iterators_update(target, iter_pos, target_idx);
24302430
iter_pos = zend_hash_iterators_lower_pos(target, iter_pos + 1);
2431-
} while (iter_pos < idx);
2431+
} while (iter_pos <= idx);
24322432
}
24332433
target_idx++; q++;
24342434
}

0 commit comments

Comments
 (0)