@@ -669,6 +669,23 @@ ZEND_API uint32_t *zend_get_recursion_guard(zend_object *zobj)
669669 return & Z_GUARD_P (zv );
670670}
671671
672+ static zend_always_inline zend_object * zend_lazy_proxy_get_guarded_instance (
673+ zend_object * zobj , zend_string * name , uint32_t guard_type )
674+ {
675+ if (UNEXPECTED (zend_object_is_lazy_proxy (zobj )
676+ && zend_lazy_object_initialized (zobj ))) {
677+ zend_object * instance = zend_lazy_object_get_instance (zobj );
678+ if (instance -> ce -> ce_flags & ZEND_ACC_USE_GUARDS ) {
679+ uint32_t * instance_guard = zend_get_property_guard (instance , name );
680+ if ((* instance_guard ) & guard_type ) {
681+ return instance ;
682+ }
683+ }
684+ }
685+
686+ return NULL ;
687+ }
688+
672689ZEND_COLD static void zend_typed_property_uninitialized_access (const zend_property_info * prop_info , zend_string * name )
673690{
674691 zend_throw_error (NULL , "Typed property %s::$%s must not be accessed before initialization" ,
@@ -896,21 +913,16 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
896913 * guard is already set for this property, we are inside a recursive
897914 * call from the real instance's __get/__isset. Forward directly to
898915 * the real instance to avoid double invocation. (GH-21478) */
899- if (UNEXPECTED (zend_object_is_lazy_proxy (zobj )
900- && zend_lazy_object_initialized (zobj ))) {
901- zend_object * instance = zend_lazy_object_get_instance (zobj );
902- if (instance -> ce -> ce_flags & ZEND_ACC_USE_GUARDS ) {
903- uint32_t * instance_guard = zend_get_property_guard (instance , name );
904- uint32_t guard_type = ((type == BP_VAR_IS ) && zobj -> ce -> __isset )
905- ? IN_ISSET : IN_GET ;
906- if ((* instance_guard ) & guard_type ) {
907- retval = zend_std_read_property (instance , name , type , cache_slot , rv );
908- if (retval == & EG (uninitialized_zval )) {
909- ZVAL_NULL (rv );
910- retval = rv ;
911- }
912- return retval ;
916+ {
917+ zend_object * instance = zend_lazy_proxy_get_guarded_instance (zobj , name ,
918+ ((type == BP_VAR_IS ) && zobj -> ce -> __isset ) ? IN_ISSET : IN_GET );
919+ if (instance ) {
920+ retval = zend_std_read_property (instance , name , type , cache_slot , rv );
921+ if (retval == & EG (uninitialized_zval )) {
922+ ZVAL_NULL (rv );
923+ retval = rv ;
913924 }
925+ return retval ;
914926 }
915927 }
916928
@@ -1262,14 +1274,10 @@ found:;
12621274 /* For initialized lazy proxies: if the real instance's __set guard
12631275 * is already set, we are inside a recursive call from the real
12641276 * instance's __set. Forward directly to avoid double invocation. */
1265- if (UNEXPECTED (zend_object_is_lazy_proxy (zobj )
1266- && zend_lazy_object_initialized (zobj ))) {
1267- zend_object * instance = zend_lazy_object_get_instance (zobj );
1268- if (instance -> ce -> ce_flags & ZEND_ACC_USE_GUARDS ) {
1269- uint32_t * instance_guard = zend_get_property_guard (instance , name );
1270- if ((* instance_guard ) & IN_SET ) {
1271- return zend_std_write_property (instance , name , value , cache_slot );
1272- }
1277+ {
1278+ zend_object * instance = zend_lazy_proxy_get_guarded_instance (zobj , name , IN_SET );
1279+ if (instance ) {
1280+ return zend_std_write_property (instance , name , value , cache_slot );
12731281 }
12741282 }
12751283
@@ -1670,15 +1678,11 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
16701678 /* For initialized lazy proxies: if the real instance's __unset guard
16711679 * is already set, we are inside a recursive call from the real
16721680 * instance's __unset. Forward directly to avoid double invocation. */
1673- if (UNEXPECTED (zend_object_is_lazy_proxy (zobj )
1674- && zend_lazy_object_initialized (zobj ))) {
1675- zend_object * instance = zend_lazy_object_get_instance (zobj );
1676- if (instance -> ce -> ce_flags & ZEND_ACC_USE_GUARDS ) {
1677- uint32_t * instance_guard = zend_get_property_guard (instance , name );
1678- if ((* instance_guard ) & IN_UNSET ) {
1679- zend_std_unset_property (instance , name , cache_slot );
1680- return ;
1681- }
1681+ {
1682+ zend_object * instance = zend_lazy_proxy_get_guarded_instance (zobj , name , IN_UNSET );
1683+ if (instance ) {
1684+ zend_std_unset_property (instance , name , cache_slot );
1685+ return ;
16821686 }
16831687 }
16841688
@@ -2498,14 +2502,10 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
24982502 /* For initialized lazy proxies: if the real instance's __isset guard
24992503 * is already set, we are inside a recursive call from the real
25002504 * instance's __isset. Forward directly to avoid double invocation. */
2501- if (UNEXPECTED (zend_object_is_lazy_proxy (zobj )
2502- && zend_lazy_object_initialized (zobj ))) {
2503- zend_object * instance = zend_lazy_object_get_instance (zobj );
2504- if (instance -> ce -> ce_flags & ZEND_ACC_USE_GUARDS ) {
2505- uint32_t * instance_guard = zend_get_property_guard (instance , name );
2506- if ((* instance_guard ) & IN_ISSET ) {
2507- return zend_std_has_property (instance , name , has_set_exists , cache_slot );
2508- }
2505+ {
2506+ zend_object * instance = zend_lazy_proxy_get_guarded_instance (zobj , name , IN_ISSET );
2507+ if (instance ) {
2508+ return zend_std_has_property (instance , name , has_set_exists , cache_slot );
25092509 }
25102510 }
25112511
0 commit comments