@@ -5878,6 +5878,19 @@ ZEND_METHOD(ReflectionProperty, setValue)
58785878}
58795879/* }}} */
58805880
5881+ /* Return the property info being used when accessing 'ref->prop' from scope
5882+ * 'scope' on 'object'. The result may be different from 'ref->prop' when the
5883+ * property is overridden on 'object' and was not private in 'scope'.
5884+ * The effective prop may add hooks or change flags. */
5885+ static zend_property_info * reflection_property_get_effective_prop (
5886+ property_reference * ref , zend_class_entry * scope , zend_object * object ) {
5887+ zend_property_info * prop = ref -> prop ;
5888+ if (scope != object -> ce && !(prop && (prop -> flags & ZEND_ACC_PRIVATE ))) {
5889+ prop = zend_hash_find_ptr (& object -> ce -> properties_info , ref -> unmangled_name );
5890+ }
5891+ return prop ;
5892+ }
5893+
58815894ZEND_METHOD (ReflectionProperty , getRawValue )
58825895{
58835896 reflection_object * intern ;
@@ -5890,17 +5903,20 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
58905903
58915904 GET_REFLECTION_OBJECT_PTR (ref );
58925905
5893- if (prop_get_flags ( ref ) & ZEND_ACC_STATIC ) {
5894- _DO_THROW ("May not use getRawValue on static properties " );
5906+ if (! instanceof_function ( Z_OBJCE_P ( object ), intern -> ce ) ) {
5907+ _DO_THROW ("Given object is not an instance of the class this property was declared in " );
58955908 RETURN_THROWS ();
58965909 }
58975910
5898- if (!instanceof_function (Z_OBJCE_P (object ), intern -> ce )) {
5899- _DO_THROW ("Given object is not an instance of the class this property was declared in" );
5911+ zend_property_info * prop = reflection_property_get_effective_prop (ref ,
5912+ intern -> ce , Z_OBJ_P (object ));
5913+
5914+ if (UNEXPECTED (prop && (prop -> flags & ZEND_ACC_STATIC ))) {
5915+ _DO_THROW ("May not use getRawValue on static properties" );
59005916 RETURN_THROWS ();
59015917 }
59025918
5903- if (!ref -> prop || !ref -> prop -> hooks || !ref -> prop -> hooks [ZEND_PROPERTY_HOOK_GET ]) {
5919+ if (!prop || !prop -> hooks || !prop -> hooks [ZEND_PROPERTY_HOOK_GET ]) {
59045920 zval rv ;
59055921 zval * member_p = zend_read_property_ex (intern -> ce , Z_OBJ_P (object ), ref -> unmangled_name , 0 , & rv );
59065922
@@ -5913,17 +5929,19 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
59135929 RETURN_COPY_VALUE (member_p );
59145930 }
59155931 } else {
5916- zend_function * func = zend_get_property_hook_trampoline (ref -> prop , ZEND_PROPERTY_HOOK_GET , ref -> unmangled_name );
5932+ zend_function * func = zend_get_property_hook_trampoline (prop , ZEND_PROPERTY_HOOK_GET , ref -> unmangled_name );
59175933 zend_call_known_instance_method_with_0_params (func , Z_OBJ_P (object ), return_value );
59185934 }
59195935}
59205936
5921- static void reflection_property_set_raw_value (property_reference * ref , reflection_object * intern , zend_object * object , zval * value )
5937+ static void reflection_property_set_raw_value (zend_property_info * prop ,
5938+ zend_string * unmangled_name , reflection_object * intern ,
5939+ zend_object * object , zval * value )
59225940{
5923- if (!ref -> prop || !ref -> prop -> hooks || !ref -> prop -> hooks [ZEND_PROPERTY_HOOK_SET ]) {
5924- zend_update_property_ex (intern -> ce , object , ref -> unmangled_name , value );
5941+ if (!prop || !prop -> hooks || !prop -> hooks [ZEND_PROPERTY_HOOK_SET ]) {
5942+ zend_update_property_ex (intern -> ce , object , unmangled_name , value );
59255943 } else {
5926- zend_function * func = zend_get_property_hook_trampoline (ref -> prop , ZEND_PROPERTY_HOOK_SET , ref -> unmangled_name );
5944+ zend_function * func = zend_get_property_hook_trampoline (prop , ZEND_PROPERTY_HOOK_SET , unmangled_name );
59275945 zend_call_known_instance_method_with_1_params (func , object , NULL , value );
59285946 }
59295947}
@@ -5937,55 +5955,59 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
59375955
59385956 GET_REFLECTION_OBJECT_PTR (ref );
59395957
5940- if (prop_get_flags (ref ) & ZEND_ACC_STATIC ) {
5941- _DO_THROW ("May not use setRawValue on static properties" );
5958+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "oz" , & object , & value ) == FAILURE ) {
59425959 RETURN_THROWS ();
59435960 }
59445961
5945- if (zend_parse_parameters (ZEND_NUM_ARGS (), "oz" , & object , & value ) == FAILURE ) {
5962+ zend_property_info * prop = reflection_property_get_effective_prop (ref ,
5963+ intern -> ce , Z_OBJ_P (object ));
5964+
5965+ if (UNEXPECTED (prop && (prop -> flags & ZEND_ACC_STATIC ))) {
5966+ _DO_THROW ("May not use setRawValue on static properties" );
59465967 RETURN_THROWS ();
59475968 }
59485969
5949- reflection_property_set_raw_value (ref , intern , Z_OBJ_P (object ), value );
5970+ reflection_property_set_raw_value (prop , ref -> unmangled_name , intern , Z_OBJ_P (object ), value );
59505971}
59515972
5952- static zend_result reflection_property_check_lazy_compatible (reflection_object * intern ,
5953- property_reference * ref , zend_object * object , const char * method )
5973+ static zend_result reflection_property_check_lazy_compatible (
5974+ zend_property_info * prop , zend_string * unmangled_name ,
5975+ reflection_object * intern , zend_object * object , const char * method )
59545976{
5955- if (!ref -> prop ) {
5977+ if (!prop ) {
59565978 zend_throw_exception_ex (reflection_exception_ptr , 0 ,
59575979 "Can not use %s on dynamic property %s::$%s" ,
59585980 method , ZSTR_VAL (intern -> ce -> name ),
5959- ZSTR_VAL (ref -> unmangled_name ));
5981+ ZSTR_VAL (unmangled_name ));
59605982 return FAILURE ;
59615983 }
59625984
5963- if (ref -> prop -> flags & ZEND_ACC_STATIC ) {
5985+ if (prop -> flags & ZEND_ACC_STATIC ) {
59645986 zend_throw_exception_ex (reflection_exception_ptr , 0 ,
59655987 "Can not use %s on static property %s::$%s" ,
5966- method , ZSTR_VAL (intern -> ce -> name ),
5967- ZSTR_VAL (ref -> unmangled_name ));
5988+ method , ZSTR_VAL (prop -> ce -> name ),
5989+ ZSTR_VAL (unmangled_name ));
59685990 return FAILURE ;
59695991 }
59705992
5971- if (ref -> prop -> flags & ZEND_ACC_VIRTUAL ) {
5993+ if (prop -> flags & ZEND_ACC_VIRTUAL ) {
59725994 zend_throw_exception_ex (reflection_exception_ptr , 0 ,
59735995 "Can not use %s on virtual property %s::$%s" ,
5974- method , ZSTR_VAL (intern -> ce -> name ),
5975- ZSTR_VAL (ref -> unmangled_name ));
5996+ method , ZSTR_VAL (prop -> ce -> name ),
5997+ ZSTR_VAL (unmangled_name ));
59765998 return FAILURE ;
59775999 }
59786000
59796001 if (UNEXPECTED (object -> handlers -> write_property != zend_std_write_property )) {
59806002 if (!zend_class_can_be_lazy (object -> ce )) {
59816003 zend_throw_exception_ex (reflection_exception_ptr , 0 ,
59826004 "Can not use %s on internal class %s" ,
5983- method , ZSTR_VAL (intern -> ce -> name ));
6005+ method , ZSTR_VAL (object -> ce -> name ));
59846006 return FAILURE ;
59856007 }
59866008 }
59876009
5988- ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (ref -> prop -> offset ));
6010+ ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (prop -> offset ));
59896011
59906012 return SUCCESS ;
59916013}
@@ -6005,23 +6027,27 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization)
60056027 Z_PARAM_ZVAL (value )
60066028 } ZEND_PARSE_PARAMETERS_END ();
60076029
6008- if (reflection_property_check_lazy_compatible (intern , ref , object ,
6009- "setRawValueWithoutLazyInitialization" ) == FAILURE ) {
6010- RETURN_THROWS ();
6011- }
6012-
60136030 while (zend_object_is_lazy_proxy (object )
60146031 && zend_lazy_object_initialized (object )) {
60156032 object = zend_lazy_object_get_instance (object );
60166033 }
60176034
6018- zval * var_ptr = OBJ_PROP (object , ref -> prop -> offset );
6035+ zend_property_info * prop = reflection_property_get_effective_prop (ref ,
6036+ intern -> ce , object );
6037+
6038+ if (reflection_property_check_lazy_compatible (prop , ref -> unmangled_name ,
6039+ intern , object , "setRawValueWithoutLazyInitialization" ) == FAILURE ) {
6040+ RETURN_THROWS ();
6041+ }
6042+
6043+ zval * var_ptr = OBJ_PROP (object , prop -> offset );
60196044 bool prop_was_lazy = Z_PROP_FLAG_P (var_ptr ) & IS_PROP_LAZY ;
60206045
60216046 /* Do not trigger initialization */
60226047 Z_PROP_FLAG_P (var_ptr ) &= ~IS_PROP_LAZY ;
60236048
6024- reflection_property_set_raw_value (ref , intern , object , value );
6049+ reflection_property_set_raw_value (prop , ref -> unmangled_name , intern , object ,
6050+ value );
60256051
60266052 /* Mark property as lazy again if an exception prevented update */
60276053 if (EG (exception ) && prop_was_lazy && Z_TYPE_P (var_ptr ) == IS_UNDEF
@@ -6053,7 +6079,8 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization)
60536079 Z_PARAM_OBJ_OF_CLASS (object , intern -> ce )
60546080 } ZEND_PARSE_PARAMETERS_END ();
60556081
6056- if (reflection_property_check_lazy_compatible (intern , ref , object ,
6082+ if (reflection_property_check_lazy_compatible (ref -> prop ,
6083+ ref -> unmangled_name , intern , object ,
60576084 "skipLazyInitialization" ) == FAILURE ) {
60586085 RETURN_THROWS ();
60596086 }
0 commit comments