@@ -5878,6 +5878,19 @@ ZEND_METHOD(ReflectionProperty, setValue)
5878
5878
}
5879
5879
/* }}} */
5880
5880
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
+
5881
5894
ZEND_METHOD (ReflectionProperty , getRawValue )
5882
5895
{
5883
5896
reflection_object * intern ;
@@ -5890,17 +5903,20 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
5890
5903
5891
5904
GET_REFLECTION_OBJECT_PTR (ref );
5892
5905
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 " );
5895
5908
RETURN_THROWS ();
5896
5909
}
5897
5910
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" );
5900
5916
RETURN_THROWS ();
5901
5917
}
5902
5918
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 ]) {
5904
5920
zval rv ;
5905
5921
zval * member_p = zend_read_property_ex (intern -> ce , Z_OBJ_P (object ), ref -> unmangled_name , 0 , & rv );
5906
5922
@@ -5913,17 +5929,19 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
5913
5929
RETURN_COPY_VALUE (member_p );
5914
5930
}
5915
5931
} 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 );
5917
5933
zend_call_known_instance_method_with_0_params (func , Z_OBJ_P (object ), return_value );
5918
5934
}
5919
5935
}
5920
5936
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 )
5922
5940
{
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 );
5925
5943
} 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 );
5927
5945
zend_call_known_instance_method_with_1_params (func , object , NULL , value );
5928
5946
}
5929
5947
}
@@ -5937,55 +5955,59 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
5937
5955
5938
5956
GET_REFLECTION_OBJECT_PTR (ref );
5939
5957
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 ) {
5942
5959
RETURN_THROWS ();
5943
5960
}
5944
5961
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" );
5946
5967
RETURN_THROWS ();
5947
5968
}
5948
5969
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 );
5950
5971
}
5951
5972
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 )
5954
5976
{
5955
- if (!ref -> prop ) {
5977
+ if (!prop ) {
5956
5978
zend_throw_exception_ex (reflection_exception_ptr , 0 ,
5957
5979
"Can not use %s on dynamic property %s::$%s" ,
5958
5980
method , ZSTR_VAL (intern -> ce -> name ),
5959
- ZSTR_VAL (ref -> unmangled_name ));
5981
+ ZSTR_VAL (unmangled_name ));
5960
5982
return FAILURE ;
5961
5983
}
5962
5984
5963
- if (ref -> prop -> flags & ZEND_ACC_STATIC ) {
5985
+ if (prop -> flags & ZEND_ACC_STATIC ) {
5964
5986
zend_throw_exception_ex (reflection_exception_ptr , 0 ,
5965
5987
"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 ));
5968
5990
return FAILURE ;
5969
5991
}
5970
5992
5971
- if (ref -> prop -> flags & ZEND_ACC_VIRTUAL ) {
5993
+ if (prop -> flags & ZEND_ACC_VIRTUAL ) {
5972
5994
zend_throw_exception_ex (reflection_exception_ptr , 0 ,
5973
5995
"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 ));
5976
5998
return FAILURE ;
5977
5999
}
5978
6000
5979
6001
if (UNEXPECTED (object -> handlers -> write_property != zend_std_write_property )) {
5980
6002
if (!zend_class_can_be_lazy (object -> ce )) {
5981
6003
zend_throw_exception_ex (reflection_exception_ptr , 0 ,
5982
6004
"Can not use %s on internal class %s" ,
5983
- method , ZSTR_VAL (intern -> ce -> name ));
6005
+ method , ZSTR_VAL (object -> ce -> name ));
5984
6006
return FAILURE ;
5985
6007
}
5986
6008
}
5987
6009
5988
- ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (ref -> prop -> offset ));
6010
+ ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (prop -> offset ));
5989
6011
5990
6012
return SUCCESS ;
5991
6013
}
@@ -6005,23 +6027,27 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization)
6005
6027
Z_PARAM_ZVAL (value )
6006
6028
} ZEND_PARSE_PARAMETERS_END ();
6007
6029
6008
- if (reflection_property_check_lazy_compatible (intern , ref , object ,
6009
- "setRawValueWithoutLazyInitialization" ) == FAILURE ) {
6010
- RETURN_THROWS ();
6011
- }
6012
-
6013
6030
while (zend_object_is_lazy_proxy (object )
6014
6031
&& zend_lazy_object_initialized (object )) {
6015
6032
object = zend_lazy_object_get_instance (object );
6016
6033
}
6017
6034
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 );
6019
6044
bool prop_was_lazy = Z_PROP_FLAG_P (var_ptr ) & IS_PROP_LAZY ;
6020
6045
6021
6046
/* Do not trigger initialization */
6022
6047
Z_PROP_FLAG_P (var_ptr ) &= ~IS_PROP_LAZY ;
6023
6048
6024
- reflection_property_set_raw_value (ref , intern , object , value );
6049
+ reflection_property_set_raw_value (prop , ref -> unmangled_name , intern , object ,
6050
+ value );
6025
6051
6026
6052
/* Mark property as lazy again if an exception prevented update */
6027
6053
if (EG (exception ) && prop_was_lazy && Z_TYPE_P (var_ptr ) == IS_UNDEF
@@ -6053,7 +6079,8 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization)
6053
6079
Z_PARAM_OBJ_OF_CLASS (object , intern -> ce )
6054
6080
} ZEND_PARSE_PARAMETERS_END ();
6055
6081
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 ,
6057
6084
"skipLazyInitialization" ) == FAILURE ) {
6058
6085
RETURN_THROWS ();
6059
6086
}
0 commit comments