mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix GH-11016: Heap buffer overflow in ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER (#11021)
Not enough space was reserved for the packed resulting array because of some confusion in the meaning of nr of used slots vs nr of elements. Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
This commit is contained in:
parent
2ef1930ad3
commit
ede8adb2e2
3 changed files with 22 additions and 2 deletions
20
Zend/tests/gh11016.phpt
Normal file
20
Zend/tests/gh11016.phpt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
--TEST--
|
||||||
|
GH-11016 (Heap buffer overflow in ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER)
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
function number() {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to use a function to trick the optimizer *not* to optimize the array to a constant
|
||||||
|
$x = [number() => 0, ...[1, 1, 1]];
|
||||||
|
print_r($x);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Array
|
||||||
|
(
|
||||||
|
[6] => 0
|
||||||
|
[7] => 1
|
||||||
|
[8] => 1
|
||||||
|
[9] => 1
|
||||||
|
)
|
|
@ -6128,7 +6128,7 @@ ZEND_VM_C_LABEL(add_unpack_again):
|
||||||
zval *val;
|
zval *val;
|
||||||
|
|
||||||
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
|
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
|
||||||
zend_hash_extend(result_ht, zend_hash_num_elements(result_ht) + zend_hash_num_elements(ht), 1);
|
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
|
||||||
ZEND_HASH_FILL_PACKED(result_ht) {
|
ZEND_HASH_FILL_PACKED(result_ht) {
|
||||||
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
|
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
|
||||||
if (UNEXPECTED(Z_ISREF_P(val)) &&
|
if (UNEXPECTED(Z_ISREF_P(val)) &&
|
||||||
|
|
2
Zend/zend_vm_execute.h
generated
2
Zend/zend_vm_execute.h
generated
|
@ -2652,7 +2652,7 @@ add_unpack_again:
|
||||||
zval *val;
|
zval *val;
|
||||||
|
|
||||||
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
|
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
|
||||||
zend_hash_extend(result_ht, zend_hash_num_elements(result_ht) + zend_hash_num_elements(ht), 1);
|
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
|
||||||
ZEND_HASH_FILL_PACKED(result_ht) {
|
ZEND_HASH_FILL_PACKED(result_ht) {
|
||||||
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
|
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
|
||||||
if (UNEXPECTED(Z_ISREF_P(val)) &&
|
if (UNEXPECTED(Z_ISREF_P(val)) &&
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue