diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-03-16 10:38:04 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-03-16 10:42:47 +0100 |
commit | 53e9c36cd94fae193a4fcbb879b93db31a4906c3 (patch) | |
tree | 83a6f10810e1b2de2c767018397b1b15d42b2d2a /Zend | |
parent | aad283e9f33d892b77e375610fb6be32e1a10ddd (diff) | |
download | php-git-53e9c36cd94fae193a4fcbb879b93db31a4906c3.tar.gz |
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).
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_execute.c | 9 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 5 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 60 |
3 files changed, 74 insertions, 0 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 11a140e845..bfafff9e35 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1189,6 +1189,15 @@ static ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc) fbc->common.scope ? "::" : "", ZSTR_VAL(fbc->common.function_name)); } + +static void zend_verify_internal_read_property_type(zend_object *obj, zend_string *name, zval *val) +{ + zend_property_info *prop_info = + zend_get_property_info(obj->ce, name, /* silent */ true); + if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) { + zend_verify_property_type(prop_info, val, /* strict */ true); + } +} #endif ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index a81ff958f2..39f1216958 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2106,6 +2106,11 @@ ZEND_VM_C_LABEL(fetch_obj_r_fast_copy): } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (OP2_TYPE != IS_CONST) { zend_tmp_string_release(tmp_name); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4f09b31909..f133eab7db 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6286,6 +6286,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -8613,6 +8618,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -10963,6 +10973,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -15382,6 +15397,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -16802,6 +16822,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -18114,6 +18139,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -31487,6 +31517,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -33400,6 +33435,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -35899,6 +35939,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -40086,6 +40131,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -43752,6 +43802,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -48795,6 +48850,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); |