summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r--Zend/zend_execute.c19
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;