Skip to content

Commit 53e9c36

Browse files
committed
Add sanity check for type of read_property return value
If an internal class overrides read_property and declared property types, make sure that the returned value matches the declared type (in debug builds).
1 parent aad283e commit 53e9c36

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

Zend/zend_execute.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,15 @@ static ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc)
11891189
fbc->common.scope ? "::" : "",
11901190
ZSTR_VAL(fbc->common.function_name));
11911191
}
1192+
1193+
static void zend_verify_internal_read_property_type(zend_object *obj, zend_string *name, zval *val)
1194+
{
1195+
zend_property_info *prop_info =
1196+
zend_get_property_info(obj->ce, name, /* silent */ true);
1197+
if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
1198+
zend_verify_property_type(prop_info, val, /* strict */ true);
1199+
}
1200+
}
11921201
#endif
11931202

11941203
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data)

Zend/zend_vm_def.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,6 +2106,11 @@ ZEND_VM_C_LABEL(fetch_obj_r_fast_copy):
21062106
}
21072107

21082108
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
2109+
#if ZEND_DEBUG
2110+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
2111+
zend_verify_internal_read_property_type(zobj, name, retval);
2112+
}
2113+
#endif
21092114

21102115
if (OP2_TYPE != IS_CONST) {
21112116
zend_tmp_string_release(tmp_name);

Zend/zend_vm_execute.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6286,6 +6286,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
62866286
}
62876287

62886288
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
6289+
#if ZEND_DEBUG
6290+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
6291+
zend_verify_internal_read_property_type(zobj, name, retval);
6292+
}
6293+
#endif
62896294

62906295
if (IS_CONST != IS_CONST) {
62916296
zend_tmp_string_release(tmp_name);
@@ -8613,6 +8618,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
86138618
}
86148619

86158620
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
8621+
#if ZEND_DEBUG
8622+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
8623+
zend_verify_internal_read_property_type(zobj, name, retval);
8624+
}
8625+
#endif
86168626

86178627
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
86188628
zend_tmp_string_release(tmp_name);
@@ -10963,6 +10973,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
1096310973
}
1096410974

1096510975
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
10976+
#if ZEND_DEBUG
10977+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
10978+
zend_verify_internal_read_property_type(zobj, name, retval);
10979+
}
10980+
#endif
1096610981

1096710982
if (IS_CV != IS_CONST) {
1096810983
zend_tmp_string_release(tmp_name);
@@ -15382,6 +15397,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_
1538215397
}
1538315398

1538415399
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
15400+
#if ZEND_DEBUG
15401+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
15402+
zend_verify_internal_read_property_type(zobj, name, retval);
15403+
}
15404+
#endif
1538515405

1538615406
if (IS_CONST != IS_CONST) {
1538715407
zend_tmp_string_release(tmp_name);
@@ -16802,6 +16822,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR
1680216822
}
1680316823

1680416824
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
16825+
#if ZEND_DEBUG
16826+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
16827+
zend_verify_internal_read_property_type(zobj, name, retval);
16828+
}
16829+
#endif
1680516830

1680616831
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
1680716832
zend_tmp_string_release(tmp_name);
@@ -18114,6 +18139,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HAN
1811418139
}
1811518140

1811618141
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
18142+
#if ZEND_DEBUG
18143+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
18144+
zend_verify_internal_read_property_type(zobj, name, retval);
18145+
}
18146+
#endif
1811718147

1811818148
if (IS_CV != IS_CONST) {
1811918149
zend_tmp_string_release(tmp_name);
@@ -31487,6 +31517,11 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R
3148731517
}
3148831518

3148931519
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
31520+
#if ZEND_DEBUG
31521+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
31522+
zend_verify_internal_read_property_type(zobj, name, retval);
31523+
}
31524+
#endif
3149031525

3149131526
if (IS_CONST != IS_CONST) {
3149231527
zend_tmp_string_release(tmp_name);
@@ -33400,6 +33435,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
3340033435
}
3340133436

3340233437
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
33438+
#if ZEND_DEBUG
33439+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
33440+
zend_verify_internal_read_property_type(zobj, name, retval);
33441+
}
33442+
#endif
3340333443

3340433444
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
3340533445
zend_tmp_string_release(tmp_name);
@@ -35899,6 +35939,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN
3589935939
}
3590035940

3590135941
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
35942+
#if ZEND_DEBUG
35943+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
35944+
zend_verify_internal_read_property_type(zobj, name, retval);
35945+
}
35946+
#endif
3590235947

3590335948
if (IS_CV != IS_CONST) {
3590435949
zend_tmp_string_release(tmp_name);
@@ -40086,6 +40131,11 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R
4008640131
}
4008740132

4008840133
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
40134+
#if ZEND_DEBUG
40135+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
40136+
zend_verify_internal_read_property_type(zobj, name, retval);
40137+
}
40138+
#endif
4008940139

4009040140
if (IS_CONST != IS_CONST) {
4009140141
zend_tmp_string_release(tmp_name);
@@ -43752,6 +43802,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
4375243802
}
4375343803

4375443804
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
43805+
#if ZEND_DEBUG
43806+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
43807+
zend_verify_internal_read_property_type(zobj, name, retval);
43808+
}
43809+
#endif
4375543810

4375643811
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
4375743812
zend_tmp_string_release(tmp_name);
@@ -48795,6 +48850,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER
4879548850
}
4879648851

4879748852
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
48853+
#if ZEND_DEBUG
48854+
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
48855+
zend_verify_internal_read_property_type(zobj, name, retval);
48856+
}
48857+
#endif
4879848858

4879948859
if (IS_CV != IS_CONST) {
4880048860
zend_tmp_string_release(tmp_name);

0 commit comments

Comments
 (0)