Skip to content

Commit f497b69

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fixed bug #79784
2 parents 3595ebc + 62bec0e commit f497b69

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

Zend/tests/bug79784.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Bug #79784: Use after free if changing array during undef var during array write fetch
3+
--FILE--
4+
<?php
5+
set_error_handler(function () {
6+
$GLOBALS['a'] = null;
7+
});
8+
9+
$a[$c] = 'x' ;
10+
var_dump($a);
11+
$a[$c] .= 'x' ;
12+
var_dump($a);
13+
$a[$c][$c] = 'x' ;
14+
var_dump($a);
15+
16+
?>
17+
--EXPECT--
18+
NULL
19+
NULL
20+
NULL

Zend/zend_execute.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,12 +2016,25 @@ static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim
20162016
FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
20172017
}
20182018

2019-
static zend_never_inline zend_uchar slow_index_convert(const zval *dim, zend_value *value EXECUTE_DATA_DC)
2019+
static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval *dim, zend_value *value EXECUTE_DATA_DC)
20202020
{
20212021
switch (Z_TYPE_P(dim)) {
2022-
case IS_UNDEF:
2022+
case IS_UNDEF: {
2023+
/* The array may be destroyed while throwing the notice.
2024+
* Temporarily increase the refcount to detect this situation. */
2025+
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
2026+
GC_ADDREF(ht);
2027+
}
20232028
ZVAL_UNDEFINED_OP2();
2029+
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
2030+
zend_array_destroy(ht);
2031+
return IS_NULL;
2032+
}
2033+
if (EG(exception)) {
2034+
return IS_NULL;
2035+
}
20242036
/* break missing intentionally */
2037+
}
20252038
case IS_NULL:
20262039
value->str = ZSTR_EMPTY_ALLOC();
20272040
return IS_STRING;
@@ -2131,7 +2144,7 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht
21312144
goto try_again;
21322145
} else {
21332146
zend_value val;
2134-
zend_uchar t = slow_index_convert(dim, &val EXECUTE_DATA_CC);
2147+
zend_uchar t = slow_index_convert(ht, dim, &val EXECUTE_DATA_CC);
21352148

21362149
if (t == IS_STRING) {
21372150
offset_key = val.str;

0 commit comments

Comments
 (0)