Skip to content

Commit 0afa04a

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix stale nInternalPosition on rehashing
2 parents e43074a + 5d40592 commit 0afa04a

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

Zend/tests/gh19280.phpt

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
--TEST--
2+
GH-19280: Stale nInternalPosition on rehashing
3+
--FILE--
4+
<?php
5+
6+
function rehash_packed() {
7+
$a = range(0, 63);
8+
for ($i = 0; $i <= 47; $i++) {
9+
next($a);
10+
}
11+
for ($i = 16; $i < 62; $i++) {
12+
unset($a[$i]);
13+
}
14+
var_dump(key($a));
15+
$a[64] = 64;
16+
var_dump(key($a));
17+
}
18+
19+
function rehash_packed_iterated() {
20+
$a = range(0, 63);
21+
for ($i = 0; $i <= 47; $i++) {
22+
next($a);
23+
}
24+
for ($i = 16; $i < 62; $i++) {
25+
unset($a[$i]);
26+
}
27+
var_dump(key($a));
28+
foreach ($a as &$_) {
29+
$a[64] = 64;
30+
break;
31+
}
32+
var_dump(key($a));
33+
}
34+
35+
function rehash_string() {
36+
$a = [];
37+
for ($i = 0; $i < 64; $i++) {
38+
$a[md5($i)] = $i;
39+
}
40+
for ($i = 0; $i <= 47; $i++) {
41+
next($a);
42+
}
43+
for ($i = 16; $i < 62; $i++) {
44+
unset($a[md5($i)]);
45+
}
46+
var_dump(key($a));
47+
$a[md5(64)] = 64;
48+
var_dump(key($a));
49+
}
50+
51+
function rehash_int() {
52+
$a = [];
53+
for ($i = 63; $i >= 0; $i--) {
54+
$a[$i] = $i;
55+
}
56+
for ($i = 0; $i <= 47; $i++) {
57+
next($a);
58+
}
59+
for ($i = 48; $i >= 2; $i--) {
60+
unset($a[$i]);
61+
}
62+
var_dump(key($a));
63+
$a[64] = 64;
64+
var_dump(key($a));
65+
}
66+
67+
rehash_packed();
68+
rehash_packed_iterated();
69+
rehash_string();
70+
rehash_int();
71+
72+
?>
73+
--EXPECT--
74+
int(62)
75+
int(62)
76+
int(62)
77+
int(62)
78+
string(32) "44f683a84163b3523afe57c2e008bc8c"
79+
string(32) "44f683a84163b3523afe57c2e008bc8c"
80+
int(1)
81+
int(1)

Zend/zend_hash.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
13781378
q->key = p->key;
13791379
Z_NEXT(q->val) = HT_HASH(ht, nIndex);
13801380
HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(j);
1381-
if (UNEXPECTED(ht->nInternalPointer == i)) {
1381+
if (UNEXPECTED(ht->nInternalPointer > j && ht->nInternalPointer <= i)) {
13821382
ht->nInternalPointer = j;
13831383
}
13841384
q++;
@@ -1397,7 +1397,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
13971397
q->key = p->key;
13981398
Z_NEXT(q->val) = HT_HASH(ht, nIndex);
13991399
HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(j);
1400-
if (UNEXPECTED(ht->nInternalPointer == i)) {
1400+
if (UNEXPECTED(ht->nInternalPointer > j && ht->nInternalPointer <= i)) {
14011401
ht->nInternalPointer = j;
14021402
}
14031403
if (UNEXPECTED(i >= iter_pos)) {

0 commit comments

Comments
 (0)