Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 39 additions & 39 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,23 @@ ZEND_API uint32_t *zend_get_recursion_guard(zend_object *zobj)
return &Z_GUARD_P(zv);
}

static zend_always_inline zend_object *zend_lazy_proxy_get_guarded_instance(
zend_object *zobj, zend_string *name, uint32_t guard_type)
{
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
&& zend_lazy_object_initialized(zobj))) {
zend_object *instance = zend_lazy_object_get_instance(zobj);
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
uint32_t *instance_guard = zend_get_property_guard(instance, name);
if ((*instance_guard) & guard_type) {
return instance;
}
}
}

return NULL;
}

ZEND_COLD static void zend_typed_property_uninitialized_access(const zend_property_info *prop_info, zend_string *name)
{
zend_throw_error(NULL, "Typed property %s::$%s must not be accessed before initialization",
Expand Down Expand Up @@ -896,21 +913,16 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
* guard is already set for this property, we are inside a recursive
* call from the real instance's __get/__isset. Forward directly to
* the real instance to avoid double invocation. (GH-21478) */
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
&& zend_lazy_object_initialized(zobj))) {
zend_object *instance = zend_lazy_object_get_instance(zobj);
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
uint32_t *instance_guard = zend_get_property_guard(instance, name);
uint32_t guard_type = ((type == BP_VAR_IS) && zobj->ce->__isset)
? IN_ISSET : IN_GET;
if ((*instance_guard) & guard_type) {
retval = zend_std_read_property(instance, name, type, cache_slot, rv);
if (retval == &EG(uninitialized_zval)) {
ZVAL_NULL(rv);
retval = rv;
}
return retval;
{
zend_object *instance = zend_lazy_proxy_get_guarded_instance(zobj, name,
((type == BP_VAR_IS) && zobj->ce->__isset) ? IN_ISSET : IN_GET);
if (instance) {
retval = zend_std_read_property(instance, name, type, cache_slot, rv);
if (retval == &EG(uninitialized_zval)) {
ZVAL_NULL(rv);
retval = rv;
}
return retval;
}
}

Expand Down Expand Up @@ -1262,14 +1274,10 @@ found:;
/* For initialized lazy proxies: if the real instance's __set guard
* is already set, we are inside a recursive call from the real
* instance's __set. Forward directly to avoid double invocation. */
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
&& zend_lazy_object_initialized(zobj))) {
zend_object *instance = zend_lazy_object_get_instance(zobj);
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
uint32_t *instance_guard = zend_get_property_guard(instance, name);
if ((*instance_guard) & IN_SET) {
return zend_std_write_property(instance, name, value, cache_slot);
}
{
zend_object *instance = zend_lazy_proxy_get_guarded_instance(zobj, name, IN_SET);
if (instance) {
return zend_std_write_property(instance, name, value, cache_slot);
}
}

Expand Down Expand Up @@ -1670,15 +1678,11 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
/* For initialized lazy proxies: if the real instance's __unset guard
* is already set, we are inside a recursive call from the real
* instance's __unset. Forward directly to avoid double invocation. */
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
&& zend_lazy_object_initialized(zobj))) {
zend_object *instance = zend_lazy_object_get_instance(zobj);
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
uint32_t *instance_guard = zend_get_property_guard(instance, name);
if ((*instance_guard) & IN_UNSET) {
zend_std_unset_property(instance, name, cache_slot);
return;
}
{
zend_object *instance = zend_lazy_proxy_get_guarded_instance(zobj, name, IN_UNSET);
if (instance) {
zend_std_unset_property(instance, name, cache_slot);
return;
}
}

Expand Down Expand Up @@ -2498,14 +2502,10 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
/* For initialized lazy proxies: if the real instance's __isset guard
* is already set, we are inside a recursive call from the real
* instance's __isset. Forward directly to avoid double invocation. */
if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
&& zend_lazy_object_initialized(zobj))) {
zend_object *instance = zend_lazy_object_get_instance(zobj);
if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
uint32_t *instance_guard = zend_get_property_guard(instance, name);
if ((*instance_guard) & IN_ISSET) {
return zend_std_has_property(instance, name, has_set_exists, cache_slot);
}
{
zend_object *instance = zend_lazy_proxy_get_guarded_instance(zobj, name, IN_ISSET);
if (instance) {
return zend_std_has_property(instance, name, has_set_exists, cache_slot);
}
}

Expand Down
Loading