Skip to content

Commit a08df32

Browse files
committed
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Fix GH-19303: Unpacking empty packed array into uninitialized array causes assertion failure
2 parents 28ed4e6 + 5bd5f35 commit a08df32

File tree

4 files changed

+45
-22
lines changed

4 files changed

+45
-22
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ PHP NEWS
1515
binary const expr). (ilutov)
1616
. Fixed bug GH-19305 (Operands may be being released during comparison).
1717
(Arnaud)
18+
. Fixed bug GH-19303 (Unpacking empty packed array into uninitialized array
19+
causes assertion failure). (nielsdos)
1820

1921
- FTP:
2022
. Fix theoretical issues with hrtime() not being available. (nielsdos)

Zend/tests/array_unpack/gh19303.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
GH-19303 (Unpacking empty packed array into uninitialized array causes assertion failure)
3+
--FILE--
4+
<?php
5+
$a = [0];
6+
unset($a[0]);
7+
var_dump([...$a]);
8+
?>
9+
--EXPECT--
10+
array(0) {
11+
}

Zend/zend_vm_def.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6262,17 +6262,22 @@ ZEND_VM_C_LABEL(add_unpack_again):
62626262
zval *val;
62636263

62646264
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
6265-
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
6266-
ZEND_HASH_FILL_PACKED(result_ht) {
6267-
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
6268-
if (UNEXPECTED(Z_ISREF_P(val)) &&
6269-
UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
6270-
val = Z_REFVAL_P(val);
6271-
}
6272-
Z_TRY_ADDREF_P(val);
6273-
ZEND_HASH_FILL_ADD(val);
6274-
} ZEND_HASH_FOREACH_END();
6275-
} ZEND_HASH_FILL_END();
6265+
/* zend_hash_extend() skips initialization when the number of elements is 0,
6266+
* but the code below expects that result_ht is initialized as packed.
6267+
* We can just skip the work in that case. */
6268+
if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) {
6269+
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
6270+
ZEND_HASH_FILL_PACKED(result_ht) {
6271+
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
6272+
if (UNEXPECTED(Z_ISREF_P(val)) &&
6273+
UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
6274+
val = Z_REFVAL_P(val);
6275+
}
6276+
Z_TRY_ADDREF_P(val);
6277+
ZEND_HASH_FILL_ADD(val);
6278+
} ZEND_HASH_FOREACH_END();
6279+
} ZEND_HASH_FILL_END();
6280+
}
62766281
} else {
62776282
zend_string *key;
62786283

Zend/zend_vm_execute.h

Lines changed: 16 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)