Skip to content

Commit 98c4a42

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Fix array clobbering by user error handler
2 parents 9a65fd0 + 2745cd9 commit 98c4a42

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,10 +730,61 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim
730730
offset_key = ZSTR_EMPTY_ALLOC();
731731
goto str_index;
732732
case IS_DOUBLE:
733-
hval = zend_dval_to_lval_safe(Z_DVAL_P(dim));
733+
hval = zend_dval_to_lval(Z_DVAL_P(dim));
734+
if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) {
735+
/* The array may be destroyed while throwing the notice.
736+
* Temporarily increase the refcount to detect this situation. */
737+
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
738+
GC_ADDREF(ht);
739+
}
740+
execute_data = EG(current_execute_data);
741+
opline = EX(opline);
742+
zend_incompatible_double_to_long_error(Z_DVAL_P(dim));
743+
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
744+
zend_array_destroy(ht);
745+
if (opline->result_type & (IS_VAR | IS_TMP_VAR)) {
746+
if (EG(exception)) {
747+
ZVAL_UNDEF(EX_VAR(opline->result.var));
748+
} else {
749+
ZVAL_NULL(EX_VAR(opline->result.var));
750+
}
751+
}
752+
return NULL;
753+
}
754+
if (EG(exception)) {
755+
if (opline->result_type & (IS_VAR | IS_TMP_VAR)) {
756+
ZVAL_UNDEF(EX_VAR(opline->result.var));
757+
}
758+
return NULL;
759+
}
760+
}
734761
goto num_index;
735762
case IS_RESOURCE:
763+
/* The array may be destroyed while throwing the notice.
764+
* Temporarily increase the refcount to detect this situation. */
765+
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
766+
GC_ADDREF(ht);
767+
}
768+
execute_data = EG(current_execute_data);
769+
opline = EX(opline);
736770
zend_use_resource_as_offset(dim);
771+
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
772+
zend_array_destroy(ht);
773+
if (opline->result_type & (IS_VAR | IS_TMP_VAR)) {
774+
if (EG(exception)) {
775+
ZVAL_UNDEF(EX_VAR(opline->result.var));
776+
} else {
777+
ZVAL_NULL(EX_VAR(opline->result.var));
778+
}
779+
}
780+
return NULL;
781+
}
782+
if (EG(exception)) {
783+
if (opline->result_type & (IS_VAR | IS_TMP_VAR)) {
784+
ZVAL_UNDEF(EX_VAR(opline->result.var));
785+
}
786+
return NULL;
787+
}
737788
hval = Z_RES_HANDLE_P(dim);
738789
goto num_index;
739790
case IS_FALSE:
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
JIT FETCH_DIM_W: 003
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
--FILE--
9+
<?php
10+
set_error_handler(function() {
11+
$GLOBALS['a']='';
12+
});
13+
$a[3E44]='';
14+
?>
15+
DONE
16+
--EXPECT--
17+
DONE

0 commit comments

Comments
 (0)