Merge branch 'PHP-7.4'

* PHP-7.4:
  Fixed bug #79784
This commit is contained in:
Nikita Popov 2020-07-07 14:24:39 +02:00
commit f497b69944
2 changed files with 36 additions and 3 deletions

20
Zend/tests/bug79784.phpt Normal file
View File

@ -0,0 +1,20 @@
--TEST--
Bug #79784: Use after free if changing array during undef var during array write fetch
--FILE--
<?php
set_error_handler(function () {
$GLOBALS['a'] = null;
});
$a[$c] = 'x' ;
var_dump($a);
$a[$c] .= 'x' ;
var_dump($a);
$a[$c][$c] = 'x' ;
var_dump($a);
?>
--EXPECT--
NULL
NULL
NULL

View File

@ -2016,12 +2016,25 @@ static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim
FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
}
static zend_never_inline zend_uchar slow_index_convert(const zval *dim, zend_value *value EXECUTE_DATA_DC)
static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval *dim, zend_value *value EXECUTE_DATA_DC)
{
switch (Z_TYPE_P(dim)) {
case IS_UNDEF:
case IS_UNDEF: {
/* The array may be destroyed while throwing the notice.
* Temporarily increase the refcount to detect this situation. */
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
GC_ADDREF(ht);
}
ZVAL_UNDEFINED_OP2();
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
zend_array_destroy(ht);
return IS_NULL;
}
if (EG(exception)) {
return IS_NULL;
}
/* break missing intentionally */
}
case IS_NULL:
value->str = ZSTR_EMPTY_ALLOC();
return IS_STRING;
@ -2131,7 +2144,7 @@ str_index:
goto try_again;
} else {
zend_value val;
zend_uchar t = slow_index_convert(dim, &val EXECUTE_DATA_CC);
zend_uchar t = slow_index_convert(ht, dim, &val EXECUTE_DATA_CC);
if (t == IS_STRING) {
offset_key = val.str;