diff options
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r-- | Zend/zend_execute.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 7b27c5a3a5..5aed92ff45 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2067,12 +2067,25 @@ static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim FREE_OP(free_op_data1); } -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; @@ -2182,7 +2195,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; |