Skip to content

Commit f045716

Browse files
committed
Fix incorrect HASH_FLAG_HAS_EMPTY_IND flag on userland array
Fixes GH-19839 Closes GH-19851
1 parent 4ad4d54 commit f045716

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ PHP NEWS
1010
exception are triggered). (nielsdos)
1111
. Fixed bug GH-19653 (Closure named argument unpacking between temporary
1212
closures can cause a crash). (nielsdos, Arnaud, Bob)
13+
. Fixed bug GH-19839 (Incorrect HASH_FLAG_HAS_EMPTY_IND flag on userland
14+
array). (ilutov)
1315

1416
- Date:
1517
. Fixed GH-17159: "P" format for ::createFromFormat swallows string literals.

Zend/tests/gh19839.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
GH-19839: Incorrect HASH_FLAG_HAS_EMPTY_IND flag on userland array
3+
--FILE--
4+
<?php
5+
6+
const X = 'x';
7+
8+
$x = null;
9+
unset(${X});
10+
11+
$a = $GLOBALS;
12+
sort($a);
13+
serialize($a);
14+
15+
?>
16+
===DONE===
17+
--EXPECT--
18+
===DONE===

Zend/zend_hash.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2466,6 +2466,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
24662466
target->nTableSize = HT_MIN_SIZE;
24672467
HT_SET_DATA_ADDR(target, &uninitialized_bucket);
24682468
} else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) {
2469+
ZEND_ASSERT(!(HT_FLAGS(source) & HASH_FLAG_HAS_EMPTY_IND));
24692470
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
24702471
target->nTableMask = source->nTableMask;
24712472
target->nNumUsed = source->nNumUsed;
@@ -2482,6 +2483,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
24822483
memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source));
24832484
}
24842485
} else if (HT_IS_PACKED(source)) {
2486+
ZEND_ASSERT(!(HT_FLAGS(source) & HASH_FLAG_HAS_EMPTY_IND));
24852487
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
24862488
target->nTableMask = HT_MIN_MASK;
24872489
target->nNumUsed = source->nNumUsed;
@@ -2501,7 +2503,8 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
25012503
zend_array_dup_packed_elements(source, target, 1);
25022504
}
25032505
} else {
2504-
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
2506+
/* Indirects are removed during duplication, remove HASH_FLAG_HAS_EMPTY_IND accordingly. */
2507+
HT_FLAGS(target) = HT_FLAGS(source) & (HASH_FLAG_MASK & ~HASH_FLAG_HAS_EMPTY_IND);
25052508
target->nTableMask = source->nTableMask;
25062509
target->nNextFreeElement = source->nNextFreeElement;
25072510
target->nInternalPointer =

0 commit comments

Comments
 (0)