Skip to content

Commit 1195ab8

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Add test ws Fix array object clobbering by user error handler
2 parents f22e29a + e52f57c commit 1195ab8

File tree

5 files changed

+965
-141
lines changed

5 files changed

+965
-141
lines changed

Zend/tests/objects_034.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Array object clobbering by user error handler
3+
--FILE--
4+
<?php
5+
class A {
6+
}
7+
8+
set_error_handler(function () {
9+
$GLOBALS['a'] = null;
10+
});
11+
12+
$a = new A;
13+
$a[$c] = 'x' ;
14+
var_dump($a);
15+
16+
$a = new A;
17+
$a[$c] .= 'x' ;
18+
var_dump($a);
19+
20+
$a = new A;
21+
$a[$c][$c] = 'x' ;
22+
var_dump($a);
23+
?>
24+
--EXPECT--
25+
NULL
26+
NULL
27+
NULL

Zend/zend_execute.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,9 +2391,15 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *
23912391
ZVAL_UNDEF(result);
23922392
} else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
23932393
if (ZEND_CONST_COND(dim_type == IS_CV, dim != NULL) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
2394+
zend_object *obj = Z_OBJ_P(container);
2395+
GC_ADDREF(obj);
23942396
dim = ZVAL_UNDEFINED_OP2();
2395-
}
2396-
if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
2397+
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
2398+
zend_objects_store_del(obj);
2399+
ZVAL_NULL(result);
2400+
return;
2401+
}
2402+
} else if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
23972403
dim++;
23982404
}
23992405
retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, type, result);

Zend/zend_vm_def.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,8 +1203,16 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
12031203
}
12041204

12051205
if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
1206-
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
1207-
if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
1206+
dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1207+
if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
1208+
zend_object *obj = Z_OBJ_P(container);
1209+
GC_ADDREF(obj);
1210+
dim = ZVAL_UNDEFINED_OP2();
1211+
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
1212+
zend_objects_store_del(obj);
1213+
ZEND_VM_C_GOTO(assign_dim_op_ret_null);
1214+
}
1215+
} else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
12081216
dim++;
12091217
}
12101218
zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC);
@@ -2586,12 +2594,32 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
25862594
}
25872595
}
25882596
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
2589-
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
2590-
value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R);
2591-
2592-
if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
2597+
dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
2598+
if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
2599+
zend_object *obj = Z_OBJ_P(object_ptr);
2600+
GC_ADDREF(obj);
2601+
dim = ZVAL_UNDEFINED_OP2();
2602+
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
2603+
zend_objects_store_del(obj);
2604+
ZEND_VM_C_GOTO(assign_dim_error);
2605+
}
2606+
} else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
25932607
dim++;
25942608
}
2609+
2610+
value = GET_OP_DATA_ZVAL_PTR_UNDEF(BP_VAR_R);
2611+
if (OP_DATA_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
2612+
zend_object *obj = Z_OBJ_P(object_ptr);
2613+
GC_ADDREF(obj);
2614+
value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
2615+
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
2616+
zend_objects_store_del(obj);
2617+
ZEND_VM_C_GOTO(assign_dim_error);
2618+
}
2619+
} else if (OP_DATA_TYPE & (IS_CV|IS_VAR)) {
2620+
ZVAL_DEREF(value);
2621+
}
2622+
25952623
zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
25962624

25972625
FREE_OP_DATA();

0 commit comments

Comments
 (0)