Skip to content

Commit e14ac1c

Browse files
committed
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1: Allow FETCH_OBJ_W and FETCH_STATIC_PROP_W to return INDIRECT/UNDEF zval for uninitialized typed properties (#11048)
2 parents 7cef7cb + 0c65b39 commit e14ac1c

File tree

7 files changed

+63
-38
lines changed

7 files changed

+63
-38
lines changed

Zend/Optimizer/zend_inference.c

+6
Original file line numberDiff line numberDiff line change
@@ -3472,6 +3472,9 @@ static zend_always_inline zend_result _zend_update_type_info(
34723472
tmp |= zend_fetch_prop_type(script, prop_info, &ce);
34733473
if (opline->opcode != ZEND_FETCH_OBJ_R && opline->opcode != ZEND_FETCH_OBJ_IS) {
34743474
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
3475+
if ((opline->extended_value & ZEND_FETCH_OBJ_FLAGS) == ZEND_FETCH_DIM_WRITE) {
3476+
tmp |= MAY_BE_UNDEF;
3477+
}
34753478
ce = NULL;
34763479
} else if (!(opline->op1_type & (IS_VAR|IS_TMP_VAR)) || !(t1 & MAY_BE_RC1)) {
34773480
zend_class_entry *ce = NULL;
@@ -3511,6 +3514,9 @@ static zend_always_inline zend_result _zend_update_type_info(
35113514
if (opline->opcode != ZEND_FETCH_STATIC_PROP_R
35123515
&& opline->opcode != ZEND_FETCH_STATIC_PROP_IS) {
35133516
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
3517+
if ((opline->extended_value & ZEND_FETCH_OBJ_FLAGS) == ZEND_FETCH_DIM_WRITE) {
3518+
tmp |= MAY_BE_UNDEF;
3519+
}
35143520
ce = NULL;
35153521
} else {
35163522
if (!result_may_be_separated(ssa, ssa_op)) {

Zend/zend_execute.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -3050,7 +3050,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags(
30503050
return 1;
30513051
}
30523052

3053-
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags, bool init_undef OPLINE_DC EXECUTE_DATA_DC)
3053+
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags OPLINE_DC EXECUTE_DATA_DC)
30543054
{
30553055
zval *ptr;
30563056
zend_object *zobj;
@@ -3168,9 +3168,6 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
31683168
}
31693169
}
31703170
}
3171-
if (init_undef && UNEXPECTED(Z_TYPE_P(ptr) == IS_UNDEF)) {
3172-
ZVAL_NULL(ptr);
3173-
}
31743171

31753172
end:
31763173
if (prop_op_type != IS_CONST) {
@@ -3184,7 +3181,7 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container
31843181
void **cache_addr = (prop_op_type == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_RETURNS_FUNCTION) : NULL;
31853182

31863183
zend_fetch_property_address(variable_ptr, container, container_op_type, prop_ptr, prop_op_type,
3187-
cache_addr, BP_VAR_W, 0, 0 OPLINE_CC EXECUTE_DATA_CC);
3184+
cache_addr, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
31883185

31893186
if (EXPECTED(Z_TYPE_P(variable_ptr) == IS_INDIRECT)) {
31903187
variable_ptr = Z_INDIRECT_P(variable_ptr);

Zend/zend_object_handlers.c

+2
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,8 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
10641064
} else if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) {
10651065
/* Readonly property, delegate to read_property + write_property. */
10661066
retval = NULL;
1067+
} else if (!prop_info || !ZEND_TYPE_IS_SET(prop_info->type)) {
1068+
ZVAL_NULL(retval);
10671069
}
10681070
} else {
10691071
/* we do have getter - fail and let it try again with usual get/set */

Zend/zend_vm_def.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -2166,7 +2166,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH
21662166
zend_fetch_property_address(
21672167
result, container, OP1_TYPE, property, OP2_TYPE,
21682168
((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
2169-
BP_VAR_W, opline->extended_value, 1 OPLINE_CC EXECUTE_DATA_CC);
2169+
BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC);
21702170
FREE_OP2();
21712171
if (OP1_TYPE == IS_VAR) {
21722172
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -2183,7 +2183,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACH
21832183
container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
21842184
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
21852185
result = EX_VAR(opline->result.var);
2186-
zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
2186+
zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC);
21872187
FREE_OP2();
21882188
if (OP1_TYPE == IS_VAR) {
21892189
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -2329,7 +2329,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, C
23292329
container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
23302330
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
23312331
result = EX_VAR(opline->result.var);
2332-
zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
2332+
zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC);
23332333
FREE_OP2();
23342334
if (OP1_TYPE == IS_VAR) {
23352335
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);

0 commit comments

Comments
 (0)