@@ -6096,6 +6096,19 @@ ZEND_METHOD(ReflectionProperty, setValue)
6096
6096
}
6097
6097
/* }}} */
6098
6098
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
+
6099
6112
ZEND_METHOD (ReflectionProperty , getRawValue )
6100
6113
{
6101
6114
reflection_object * intern ;
@@ -6108,17 +6121,20 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
6108
6121
6109
6122
GET_REFLECTION_OBJECT_PTR (ref );
6110
6123
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 " );
6113
6126
RETURN_THROWS ();
6114
6127
}
6115
6128
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" );
6118
6134
RETURN_THROWS ();
6119
6135
}
6120
6136
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 ]) {
6122
6138
zval rv ;
6123
6139
zval * member_p = zend_read_property_ex (intern -> ce , Z_OBJ_P (object ), ref -> unmangled_name , 0 , & rv );
6124
6140
@@ -6131,17 +6147,19 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
6131
6147
RETURN_COPY_VALUE (member_p );
6132
6148
}
6133
6149
} 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 );
6135
6151
zend_call_known_instance_method_with_0_params (func , Z_OBJ_P (object ), return_value );
6136
6152
}
6137
6153
}
6138
6154
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 )
6140
6158
{
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 );
6143
6161
} 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 );
6145
6163
zend_call_known_instance_method_with_1_params (func , object , NULL , value );
6146
6164
}
6147
6165
}
@@ -6155,55 +6173,59 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
6155
6173
6156
6174
GET_REFLECTION_OBJECT_PTR (ref );
6157
6175
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 ) {
6160
6177
RETURN_THROWS ();
6161
6178
}
6162
6179
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" );
6164
6185
RETURN_THROWS ();
6165
6186
}
6166
6187
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 );
6168
6189
}
6169
6190
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 )
6172
6194
{
6173
- if (!ref -> prop ) {
6195
+ if (!prop ) {
6174
6196
zend_throw_exception_ex (reflection_exception_ptr , 0 ,
6175
6197
"Can not use %s on dynamic property %s::$%s" ,
6176
6198
method , ZSTR_VAL (intern -> ce -> name ),
6177
- ZSTR_VAL (ref -> unmangled_name ));
6199
+ ZSTR_VAL (unmangled_name ));
6178
6200
return FAILURE ;
6179
6201
}
6180
6202
6181
- if (ref -> prop -> flags & ZEND_ACC_STATIC ) {
6203
+ if (prop -> flags & ZEND_ACC_STATIC ) {
6182
6204
zend_throw_exception_ex (reflection_exception_ptr , 0 ,
6183
6205
"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 ));
6186
6208
return FAILURE ;
6187
6209
}
6188
6210
6189
- if (ref -> prop -> flags & ZEND_ACC_VIRTUAL ) {
6211
+ if (prop -> flags & ZEND_ACC_VIRTUAL ) {
6190
6212
zend_throw_exception_ex (reflection_exception_ptr , 0 ,
6191
6213
"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 ));
6194
6216
return FAILURE ;
6195
6217
}
6196
6218
6197
6219
if (UNEXPECTED (object -> handlers -> write_property != zend_std_write_property )) {
6198
6220
if (!zend_class_can_be_lazy (object -> ce )) {
6199
6221
zend_throw_exception_ex (reflection_exception_ptr , 0 ,
6200
6222
"Can not use %s on internal class %s" ,
6201
- method , ZSTR_VAL (intern -> ce -> name ));
6223
+ method , ZSTR_VAL (object -> ce -> name ));
6202
6224
return FAILURE ;
6203
6225
}
6204
6226
}
6205
6227
6206
- ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (ref -> prop -> offset ));
6228
+ ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (prop -> offset ));
6207
6229
6208
6230
return SUCCESS ;
6209
6231
}
@@ -6223,23 +6245,27 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization)
6223
6245
Z_PARAM_ZVAL (value )
6224
6246
} ZEND_PARSE_PARAMETERS_END ();
6225
6247
6226
- if (reflection_property_check_lazy_compatible (intern , ref , object ,
6227
- "setRawValueWithoutLazyInitialization" ) == FAILURE ) {
6228
- RETURN_THROWS ();
6229
- }
6230
-
6231
6248
while (zend_object_is_lazy_proxy (object )
6232
6249
&& zend_lazy_object_initialized (object )) {
6233
6250
object = zend_lazy_object_get_instance (object );
6234
6251
}
6235
6252
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 );
6237
6262
bool prop_was_lazy = Z_PROP_FLAG_P (var_ptr ) & IS_PROP_LAZY ;
6238
6263
6239
6264
/* Do not trigger initialization */
6240
6265
Z_PROP_FLAG_P (var_ptr ) &= ~IS_PROP_LAZY ;
6241
6266
6242
- reflection_property_set_raw_value (ref , intern , object , value );
6267
+ reflection_property_set_raw_value (prop , ref -> unmangled_name , intern , object ,
6268
+ value );
6243
6269
6244
6270
/* Mark property as lazy again if an exception prevented update */
6245
6271
if (EG (exception ) && prop_was_lazy && Z_TYPE_P (var_ptr ) == IS_UNDEF
@@ -6271,7 +6297,8 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization)
6271
6297
Z_PARAM_OBJ_OF_CLASS (object , intern -> ce )
6272
6298
} ZEND_PARSE_PARAMETERS_END ();
6273
6299
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 ,
6275
6302
"skipLazyInitialization" ) == FAILURE ) {
6276
6303
RETURN_THROWS ();
6277
6304
}
0 commit comments