Skip to content

Commit 13c6331

Browse files
committed
fix: hoist lazy init check before dynamic property deprecation
Move the zend_lazy_object_must_init check in the dynamic property branch of get_property_ptr_ptr above the deprecation/error handling, so that a lazy proxy delegates to the real instance before emitting deprecation notices. This eliminates duplicate deprecation warnings that fired once on the proxy and once on the underlying object.
1 parent 400cba2 commit 13c6331

4 files changed

Lines changed: 20 additions & 37 deletions

File tree

Zend/tests/lazy_objects/gh20854.phpt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,5 @@ $obj->x;
1818
echo "Done\n";
1919
?>
2020
--EXPECTF--
21-
Deprecated: Creation of dynamic property C::$x is deprecated in %s on line %d
22-
2321
Deprecated: Creation of dynamic property C::$x is deprecated in %s on line %d
2422
Done

Zend/tests/lazy_objects/gh20873.phpt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ var_dump($obj->p);
1919
--EXPECTF--
2020
Deprecated: Creation of dynamic property A::$x is deprecated in %s on line %d
2121

22-
Deprecated: Creation of dynamic property A::$x is deprecated in %s on line %d
23-
2422
Warning: Undefined variable $a in %s on line %d
2523

2624
Notice: Indirect modification of overloaded property A::$x has no effect in %s on line %d

Zend/tests/lazy_objects/gh20875.phpt

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ var_dump($real->prop);
2121
--EXPECTF--
2222
Deprecated: Creation of dynamic property A::$b is deprecated in %s on line %d
2323

24-
Deprecated: Creation of dynamic property A::$b is deprecated in %s on line %d
25-
26-
Deprecated: Creation of dynamic property A::$f is deprecated in %s on line %d
27-
2824
Deprecated: Creation of dynamic property A::$f is deprecated in %s on line %d
2925

3026
Warning: Undefined variable $x in %s on line %d
@@ -35,16 +31,6 @@ Warning: Undefined variable $a in %s on line %d
3531

3632
Warning: Undefined variable $v in %s on line %d
3733

38-
Notice: Indirect modification of overloaded property A::$b has no effect in %s on line %d
39-
40-
Deprecated: Creation of dynamic property A::$f is deprecated in %s on line %d
41-
42-
Warning: Undefined variable $x in %s on line %d
43-
44-
Notice: Object of class stdClass could not be converted to int in %s on line %d
45-
46-
Warning: Undefined variable $v in %s on line %d
47-
4834
Notice: Indirect modification of overloaded property A::$f has no effect in %s on line %d
4935

5036
Fatal error: Uncaught Error: Cannot assign by reference to overloaded object in %s:%d

Zend/zend_object_handlers.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,26 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
14591459
return retval;
14601460
}
14611461
}
1462+
if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
1463+
bool guarded = zobj->ce->__get
1464+
&& (*zend_get_property_guard(zobj, name) & IN_GET);
1465+
zend_object *instance = zend_lazy_object_init(zobj);
1466+
if (!instance) {
1467+
return &EG(error_zval);
1468+
}
1469+
1470+
if (guarded && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
1471+
uint32_t *guard = zend_get_property_guard(instance, name);
1472+
if (!(*guard & IN_GET)) {
1473+
(*guard) |= IN_GET;
1474+
retval = zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
1475+
(*guard) &= ~IN_GET;
1476+
return retval;
1477+
}
1478+
}
1479+
1480+
return zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
1481+
}
14621482
if (EXPECTED(!zobj->ce->__get) ||
14631483
UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) {
14641484
if (UNEXPECTED(zobj->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
@@ -1470,25 +1490,6 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
14701490
return &EG(error_zval);
14711491
}
14721492
}
1473-
if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
1474-
bool guarded = (zobj->ce->__get != NULL);
1475-
zend_object *instance = zend_lazy_object_init(zobj);
1476-
if (!instance) {
1477-
return &EG(error_zval);
1478-
}
1479-
1480-
if (guarded && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
1481-
uint32_t *guard = zend_get_property_guard(instance, name);
1482-
if (!(*guard & IN_GET)) {
1483-
(*guard) |= IN_GET;
1484-
retval = zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
1485-
(*guard) &= ~IN_GET;
1486-
return retval;
1487-
}
1488-
}
1489-
1490-
return zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
1491-
}
14921493
if (UNEXPECTED(!zobj->properties)) {
14931494
rebuild_object_properties_internal(zobj);
14941495
}

0 commit comments

Comments
 (0)