File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -30,6 +30,9 @@ PHP NEWS
3030 for grouping. (Klaas Skelte van der Werf)
3131 . Fixed bug GH-24265 (Unwind/GracefulExit discarded in
3232 zend_fiber_execute()). (David Carlier)
33+ . Fixed bug GH-24715 (Assertion failure in zend_lazy_object_get_properties()
34+ when releasing the initializer resets the object as lazy).
35+ (Lazizbek Ergashev)
3336
3437- Date:
3538 . Fixed bug GH-20503 (Assertion failure with ext/date DateInterval property
Original file line number Diff line number Diff line change 1+ --TEST--
2+ GH-24715: Object reset as lazy by a destructor triggered when releasing the initializer
3+ --FILE--
4+ <?php
5+
6+ class C {
7+ public $ a ;
8+ }
9+
10+ class D {
11+ public $ self ;
12+ public function __construct () {
13+ $ this ->self = $ this ;
14+ }
15+ public function __destruct () {
16+ global $ obj , $ reflector ;
17+ try {
18+ $ reflector ->resetAsLazyGhost ($ obj , function () {});
19+ } catch (Error $ e ) {
20+ printf ("%s: %s \n" , $ e ::class, $ e ->getMessage ());
21+ }
22+ }
23+ }
24+
25+ new D ();
26+
27+ $ reflector = new ReflectionClass (C::class);
28+ $ obj = $ reflector ->newLazyGhost (new class {
29+ public function __invoke ($ obj ) {
30+ $ obj ->a = 1 ;
31+ }
32+ public function __destruct () {
33+ gc_collect_cycles ();
34+ }
35+ });
36+
37+ var_dump (serialize ($ obj ));
38+ var_dump ($ reflector ->isUninitializedLazyObject ($ obj ));
39+
40+ ?>
41+ --EXPECT--
42+ Error: Can not reset an object while it is being initialized
43+ string(24) "O:1:"C":1:{s:1:"a";i:1;}"
44+ bool(false)
Original file line number Diff line number Diff line change @@ -76,7 +76,9 @@ static void zend_lazy_object_info_dtor_func(zval *pElement)
7676 zend_object_release (info -> u .instance );
7777 } else {
7878 zval_ptr_dtor (& info -> u .initializer .zv );
79- zend_fcc_dtor (& info -> u .initializer .fcc );
79+ if (ZEND_FCC_INITIALIZED (info -> u .initializer .fcc )) {
80+ zend_fcc_dtor (& info -> u .initializer .fcc );
81+ }
8082 }
8183
8284 efree (info );
@@ -670,6 +672,15 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj)
670672 zend_release_properties (properties_snapshot );
671673 }
672674
675+ /* Release the initializer while the info is still registered, so that
676+ * destructors triggered by this can not reset the object */
677+ zend_lazy_object_info * info = zend_hash_index_find_ptr (& EG (lazy_objects_store ).infos , obj -> handle );
678+ zval initializer_zv ;
679+ ZVAL_COPY_VALUE (& initializer_zv , & info -> u .initializer .zv );
680+ ZVAL_UNDEF (& info -> u .initializer .zv );
681+ zend_fcc_dtor (& info -> u .initializer .fcc );
682+ zval_ptr_dtor (& initializer_zv );
683+
673684 /* Must be very last in this function, for the
674685 * zend_lazy_object_has_stale_info() check */
675686 zend_lazy_object_del_info (obj );
You can’t perform that action at this time.
0 commit comments