Skip to content

Commit 0660fb5

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

File tree

7 files changed

+63
-38
lines changed

7 files changed

+63
-38
lines changed

Zend/Optimizer/zend_inference.c

Lines changed: 6 additions & 0 deletions
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
const 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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3106,7 +3106,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags(
31063106
return 1;
31073107
}
31083108

3109-
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)
3109+
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)
31103110
{
31113111
zval *ptr;
31123112
zend_object *zobj;
@@ -3226,9 +3226,6 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
32263226
}
32273227
}
32283228
}
3229-
if (init_undef && UNEXPECTED(Z_TYPE_P(ptr) == IS_UNDEF)) {
3230-
ZVAL_NULL(ptr);
3231-
}
32323229

32333230
end:
32343231
if (prop_op_type != IS_CONST) {
@@ -3243,7 +3240,7 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container
32433240
zend_refcounted *garbage = NULL;
32443241

32453242
zend_fetch_property_address(variable_ptr, container, container_op_type, prop_ptr, prop_op_type,
3246-
cache_addr, BP_VAR_W, 0, 0 OPLINE_CC EXECUTE_DATA_CC);
3243+
cache_addr, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
32473244

32483245
if (EXPECTED(Z_TYPE_P(variable_ptr) == IS_INDIRECT)) {
32493246
variable_ptr = Z_INDIRECT_P(variable_ptr);

Zend/zend_object_handlers.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,8 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
11081108
} else if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) {
11091109
/* Readonly property, delegate to read_property + write_property. */
11101110
retval = NULL;
1111+
} else if (!prop_info || !ZEND_TYPE_IS_SET(prop_info->type)) {
1112+
ZVAL_NULL(retval);
11111113
}
11121114
} else {
11131115
/* we do have getter - fail and let it try again with usual get/set */

Zend/zend_vm_def.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,7 +2169,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH
21692169
zend_fetch_property_address(
21702170
result, container, OP1_TYPE, property, OP2_TYPE,
21712171
((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
2172-
BP_VAR_W, opline->extended_value, 1 OPLINE_CC EXECUTE_DATA_CC);
2172+
BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC);
21732173
FREE_OP2();
21742174
if (OP1_TYPE == IS_VAR) {
21752175
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -2186,7 +2186,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACH
21862186
container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
21872187
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
21882188
result = EX_VAR(opline->result.var);
2189-
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);
2189+
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);
21902190
FREE_OP2();
21912191
if (OP1_TYPE == IS_VAR) {
21922192
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -2332,7 +2332,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, C
23322332
container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET);
23332333
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
23342334
result = EX_VAR(opline->result.var);
2335-
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);
2335+
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);
23362336
FREE_OP2();
23372337
if (OP1_TYPE == IS_VAR) {
23382338
FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);

0 commit comments

Comments
 (0)