mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
We don't expect the lazy proxy to be modified during initialization, but
this is allowed. The modification may set a property, still marked LAZY,
without removing the LAZY flag. This causes an assertion failure in GH-20174.
Both the RFC and the documentation specify that after an initialization
failure, the state of the object is reset to its pre-initialization state:
If the initializer throws an exception, the object state is reverted to
its pre-initialization state and the object is marked as lazy again. In
other words, all effects on the object itself are reverted. Other side
effects, such as effects on other objects, are not reverted. This prevents
exposing a partially initialized instance in case of failure.
This behavior would have prevented this issue, but it was not implemented
for lazy proxies (only for ghosts).
Fix by implementing the missing behavior.
Fixes GH-20174
Closes GH-20181
34 lines
577 B
PHP
34 lines
577 B
PHP
--TEST--
|
|
GH-20174: Assertion failure in ReflectionProperty::skipLazyInitialization after failed LazyProxy skipLazyInitialization
|
|
--CREDITS--
|
|
vi3tL0u1s
|
|
--FILE--
|
|
<?php
|
|
|
|
class C {
|
|
public $b;
|
|
public $c;
|
|
}
|
|
|
|
$reflector = new ReflectionClass(C::class);
|
|
|
|
$obj = $reflector->newLazyProxy(function ($obj) {
|
|
$obj->b = 4;
|
|
throw new Exception();
|
|
});
|
|
|
|
try {
|
|
$reflector->initializeLazyObject($obj);
|
|
} catch (Exception $e) {
|
|
$reflector->getProperty('b')->skipLazyInitialization($obj);
|
|
}
|
|
|
|
var_dump($obj);
|
|
|
|
?>
|
|
--EXPECTF--
|
|
lazy proxy object(C)#%d (1) {
|
|
["b"]=>
|
|
NULL
|
|
}
|