mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-19303: Unpacking empty packed array into uninitialized array causes assertion failure
This commit is contained in:
commit
a5219c1ecc
3 changed files with 43 additions and 22 deletions
11
Zend/tests/array_unpack/gh19303.phpt
Normal file
11
Zend/tests/array_unpack/gh19303.phpt
Normal file
|
@ -0,0 +1,11 @@
|
|||
--TEST--
|
||||
GH-19303 (Unpacking empty packed array into uninitialized array causes assertion failure)
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [0];
|
||||
unset($a[0]);
|
||||
var_dump([...$a]);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(0) {
|
||||
}
|
|
@ -6325,17 +6325,22 @@ ZEND_VM_C_LABEL(add_unpack_again):
|
|||
zval *val;
|
||||
|
||||
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
|
||||
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
|
||||
ZEND_HASH_FILL_PACKED(result_ht) {
|
||||
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
|
||||
if (UNEXPECTED(Z_ISREF_P(val)) &&
|
||||
UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
|
||||
val = Z_REFVAL_P(val);
|
||||
}
|
||||
Z_TRY_ADDREF_P(val);
|
||||
ZEND_HASH_FILL_ADD(val);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} ZEND_HASH_FILL_END();
|
||||
/* zend_hash_extend() skips initialization when the number of elements is 0,
|
||||
* but the code below expects that result_ht is initialized as packed.
|
||||
* We can just skip the work in that case. */
|
||||
if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) {
|
||||
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
|
||||
ZEND_HASH_FILL_PACKED(result_ht) {
|
||||
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
|
||||
if (UNEXPECTED(Z_ISREF_P(val)) &&
|
||||
UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
|
||||
val = Z_REFVAL_P(val);
|
||||
}
|
||||
Z_TRY_ADDREF_P(val);
|
||||
ZEND_HASH_FILL_ADD(val);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} ZEND_HASH_FILL_END();
|
||||
}
|
||||
} else {
|
||||
zend_string *key;
|
||||
|
||||
|
|
27
Zend/zend_vm_execute.h
generated
27
Zend/zend_vm_execute.h
generated
|
@ -2819,17 +2819,22 @@ add_unpack_again:
|
|||
zval *val;
|
||||
|
||||
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
|
||||
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
|
||||
ZEND_HASH_FILL_PACKED(result_ht) {
|
||||
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
|
||||
if (UNEXPECTED(Z_ISREF_P(val)) &&
|
||||
UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
|
||||
val = Z_REFVAL_P(val);
|
||||
}
|
||||
Z_TRY_ADDREF_P(val);
|
||||
ZEND_HASH_FILL_ADD(val);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} ZEND_HASH_FILL_END();
|
||||
/* zend_hash_extend() skips initialization when the number of elements is 0,
|
||||
* but the code below expects that result_ht is initialized as packed.
|
||||
* We can just skip the work in that case. */
|
||||
if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) {
|
||||
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
|
||||
ZEND_HASH_FILL_PACKED(result_ht) {
|
||||
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
|
||||
if (UNEXPECTED(Z_ISREF_P(val)) &&
|
||||
UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
|
||||
val = Z_REFVAL_P(val);
|
||||
}
|
||||
Z_TRY_ADDREF_P(val);
|
||||
ZEND_HASH_FILL_ADD(val);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} ZEND_HASH_FILL_END();
|
||||
}
|
||||
} else {
|
||||
zend_string *key;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue