@@ -6096,6 +6096,19 @@ ZEND_METHOD(ReflectionProperty, setValue)
60966096}
60976097/* }}} */
60986098
6099+ /* Return the property info being used when accessing 'ref->prop' from scope
6100+ * 'scope' on 'object'. The result may be different from 'ref->prop' when the
6101+ * property is overridden on 'object' and was not private in 'scope'.
6102+ * The effective prop may add hooks or change flags. */
6103+ static zend_property_info * reflection_property_get_effective_prop (
6104+ property_reference * ref , zend_class_entry * scope , zend_object * object ) {
6105+ zend_property_info * prop = ref -> prop ;
6106+ if (scope != object -> ce && !(prop && (prop -> flags & ZEND_ACC_PRIVATE ))) {
6107+ prop = zend_hash_find_ptr (& object -> ce -> properties_info , ref -> unmangled_name );
6108+ }
6109+ return prop ;
6110+ }
6111+
60996112ZEND_METHOD (ReflectionProperty , getRawValue )
61006113{
61016114 reflection_object * intern ;
@@ -6108,17 +6121,20 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
61086121
61096122 GET_REFLECTION_OBJECT_PTR (ref );
61106123
6111- if (prop_get_flags ( ref ) & ZEND_ACC_STATIC ) {
6112- _DO_THROW ("May not use getRawValue on static properties " );
6124+ if (! instanceof_function ( Z_OBJCE_P ( object ), intern -> ce ) ) {
6125+ _DO_THROW ("Given object is not an instance of the class this property was declared in " );
61136126 RETURN_THROWS ();
61146127 }
61156128
6116- if (!instanceof_function (Z_OBJCE_P (object ), intern -> ce )) {
6117- _DO_THROW ("Given object is not an instance of the class this property was declared in" );
6129+ zend_property_info * prop = reflection_property_get_effective_prop (ref ,
6130+ intern -> ce , Z_OBJ_P (object ));
6131+
6132+ if (UNEXPECTED (prop && (prop -> flags & ZEND_ACC_STATIC ))) {
6133+ _DO_THROW ("May not use getRawValue on static properties" );
61186134 RETURN_THROWS ();
61196135 }
61206136
6121- if (!ref -> prop || !ref -> prop -> hooks || !ref -> prop -> hooks [ZEND_PROPERTY_HOOK_GET ]) {
6137+ if (!prop || !prop -> hooks || !prop -> hooks [ZEND_PROPERTY_HOOK_GET ]) {
61226138 zval rv ;
61236139 zval * member_p = zend_read_property_ex (intern -> ce , Z_OBJ_P (object ), ref -> unmangled_name , 0 , & rv );
61246140
@@ -6131,17 +6147,19 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
61316147 RETURN_COPY_VALUE (member_p );
61326148 }
61336149 } else {
6134- zend_function * func = zend_get_property_hook_trampoline (ref -> prop , ZEND_PROPERTY_HOOK_GET , ref -> unmangled_name );
6150+ zend_function * func = zend_get_property_hook_trampoline (prop , ZEND_PROPERTY_HOOK_GET , ref -> unmangled_name );
61356151 zend_call_known_instance_method_with_0_params (func , Z_OBJ_P (object ), return_value );
61366152 }
61376153}
61386154
6139- static void reflection_property_set_raw_value (property_reference * ref , reflection_object * intern , zend_object * object , zval * value )
6155+ static void reflection_property_set_raw_value (zend_property_info * prop ,
6156+ zend_string * unmangled_name , reflection_object * intern ,
6157+ zend_object * object , zval * value )
61406158{
6141- if (!ref -> prop || !ref -> prop -> hooks || !ref -> prop -> hooks [ZEND_PROPERTY_HOOK_SET ]) {
6142- zend_update_property_ex (intern -> ce , object , ref -> unmangled_name , value );
6159+ if (!prop || !prop -> hooks || !prop -> hooks [ZEND_PROPERTY_HOOK_SET ]) {
6160+ zend_update_property_ex (intern -> ce , object , unmangled_name , value );
61436161 } else {
6144- zend_function * func = zend_get_property_hook_trampoline (ref -> prop , ZEND_PROPERTY_HOOK_SET , ref -> unmangled_name );
6162+ zend_function * func = zend_get_property_hook_trampoline (prop , ZEND_PROPERTY_HOOK_SET , unmangled_name );
61456163 zend_call_known_instance_method_with_1_params (func , object , NULL , value );
61466164 }
61476165}
@@ -6155,55 +6173,59 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
61556173
61566174 GET_REFLECTION_OBJECT_PTR (ref );
61576175
6158- if (prop_get_flags (ref ) & ZEND_ACC_STATIC ) {
6159- _DO_THROW ("May not use setRawValue on static properties" );
6176+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "oz" , & object , & value ) == FAILURE ) {
61606177 RETURN_THROWS ();
61616178 }
61626179
6163- if (zend_parse_parameters (ZEND_NUM_ARGS (), "oz" , & object , & value ) == FAILURE ) {
6180+ zend_property_info * prop = reflection_property_get_effective_prop (ref ,
6181+ intern -> ce , Z_OBJ_P (object ));
6182+
6183+ if (UNEXPECTED (prop && (prop -> flags & ZEND_ACC_STATIC ))) {
6184+ _DO_THROW ("May not use setRawValue on static properties" );
61646185 RETURN_THROWS ();
61656186 }
61666187
6167- reflection_property_set_raw_value (ref , intern , Z_OBJ_P (object ), value );
6188+ reflection_property_set_raw_value (prop , ref -> unmangled_name , intern , Z_OBJ_P (object ), value );
61686189}
61696190
6170- static zend_result reflection_property_check_lazy_compatible (reflection_object * intern ,
6171- property_reference * ref , zend_object * object , const char * method )
6191+ static zend_result reflection_property_check_lazy_compatible (
6192+ zend_property_info * prop , zend_string * unmangled_name ,
6193+ reflection_object * intern , zend_object * object , const char * method )
61726194{
6173- if (!ref -> prop ) {
6195+ if (!prop ) {
61746196 zend_throw_exception_ex (reflection_exception_ptr , 0 ,
61756197 "Can not use %s on dynamic property %s::$%s" ,
61766198 method , ZSTR_VAL (intern -> ce -> name ),
6177- ZSTR_VAL (ref -> unmangled_name ));
6199+ ZSTR_VAL (unmangled_name ));
61786200 return FAILURE ;
61796201 }
61806202
6181- if (ref -> prop -> flags & ZEND_ACC_STATIC ) {
6203+ if (prop -> flags & ZEND_ACC_STATIC ) {
61826204 zend_throw_exception_ex (reflection_exception_ptr , 0 ,
61836205 "Can not use %s on static property %s::$%s" ,
6184- method , ZSTR_VAL (intern -> ce -> name ),
6185- ZSTR_VAL (ref -> unmangled_name ));
6206+ method , ZSTR_VAL (prop -> ce -> name ),
6207+ ZSTR_VAL (unmangled_name ));
61866208 return FAILURE ;
61876209 }
61886210
6189- if (ref -> prop -> flags & ZEND_ACC_VIRTUAL ) {
6211+ if (prop -> flags & ZEND_ACC_VIRTUAL ) {
61906212 zend_throw_exception_ex (reflection_exception_ptr , 0 ,
61916213 "Can not use %s on virtual property %s::$%s" ,
6192- method , ZSTR_VAL (intern -> ce -> name ),
6193- ZSTR_VAL (ref -> unmangled_name ));
6214+ method , ZSTR_VAL (prop -> ce -> name ),
6215+ ZSTR_VAL (unmangled_name ));
61946216 return FAILURE ;
61956217 }
61966218
61976219 if (UNEXPECTED (object -> handlers -> write_property != zend_std_write_property )) {
61986220 if (!zend_class_can_be_lazy (object -> ce )) {
61996221 zend_throw_exception_ex (reflection_exception_ptr , 0 ,
62006222 "Can not use %s on internal class %s" ,
6201- method , ZSTR_VAL (intern -> ce -> name ));
6223+ method , ZSTR_VAL (object -> ce -> name ));
62026224 return FAILURE ;
62036225 }
62046226 }
62056227
6206- ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (ref -> prop -> offset ));
6228+ ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (prop -> offset ));
62076229
62086230 return SUCCESS ;
62096231}
@@ -6223,23 +6245,27 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization)
62236245 Z_PARAM_ZVAL (value )
62246246 } ZEND_PARSE_PARAMETERS_END ();
62256247
6226- if (reflection_property_check_lazy_compatible (intern , ref , object ,
6227- "setRawValueWithoutLazyInitialization" ) == FAILURE ) {
6228- RETURN_THROWS ();
6229- }
6230-
62316248 while (zend_object_is_lazy_proxy (object )
62326249 && zend_lazy_object_initialized (object )) {
62336250 object = zend_lazy_object_get_instance (object );
62346251 }
62356252
6236- zval * var_ptr = OBJ_PROP (object , ref -> prop -> offset );
6253+ zend_property_info * prop = reflection_property_get_effective_prop (ref ,
6254+ intern -> ce , object );
6255+
6256+ if (reflection_property_check_lazy_compatible (prop , ref -> unmangled_name ,
6257+ intern , object , "setRawValueWithoutLazyInitialization" ) == FAILURE ) {
6258+ RETURN_THROWS ();
6259+ }
6260+
6261+ zval * var_ptr = OBJ_PROP (object , prop -> offset );
62376262 bool prop_was_lazy = Z_PROP_FLAG_P (var_ptr ) & IS_PROP_LAZY ;
62386263
62396264 /* Do not trigger initialization */
62406265 Z_PROP_FLAG_P (var_ptr ) &= ~IS_PROP_LAZY ;
62416266
6242- reflection_property_set_raw_value (ref , intern , object , value );
6267+ reflection_property_set_raw_value (prop , ref -> unmangled_name , intern , object ,
6268+ value );
62436269
62446270 /* Mark property as lazy again if an exception prevented update */
62456271 if (EG (exception ) && prop_was_lazy && Z_TYPE_P (var_ptr ) == IS_UNDEF
@@ -6271,7 +6297,8 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization)
62716297 Z_PARAM_OBJ_OF_CLASS (object , intern -> ce )
62726298 } ZEND_PARSE_PARAMETERS_END ();
62736299
6274- if (reflection_property_check_lazy_compatible (intern , ref , object ,
6300+ if (reflection_property_check_lazy_compatible (ref -> prop ,
6301+ ref -> unmangled_name , intern , object ,
62756302 "skipLazyInitialization" ) == FAILURE ) {
62766303 RETURN_THROWS ();
62776304 }
0 commit comments