@@ -429,6 +429,9 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
429
429
ZEND_ASSERT (zend_object_is_lazy_proxy (obj ));
430
430
ZEND_ASSERT (!zend_lazy_object_initialized (obj ));
431
431
432
+ /* Prevent object from being released during initialization */
433
+ GC_ADDREF (obj );
434
+
432
435
zend_lazy_object_info * info = zend_lazy_object_get_info (obj );
433
436
434
437
/* prevent reentrant initialization */
@@ -447,6 +450,7 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
447
450
448
451
if (UNEXPECTED (EG (exception ))) {
449
452
OBJ_EXTRA_FLAGS (obj ) |= IS_OBJ_LAZY_UNINITIALIZED |IS_OBJ_LAZY_PROXY ;
453
+ GC_DELREF (obj );
450
454
return NULL ;
451
455
}
452
456
@@ -456,6 +460,7 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
456
460
ZSTR_VAL (obj -> ce -> name ),
457
461
zend_zval_value_name (& retval ));
458
462
zval_ptr_dtor (& retval );
463
+ GC_DELREF (obj );
459
464
return NULL ;
460
465
461
466
}
@@ -466,13 +471,15 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
466
471
zend_zval_value_name (& retval ),
467
472
ZSTR_VAL (obj -> ce -> name ));
468
473
zval_ptr_dtor (& retval );
474
+ GC_DELREF (obj );
469
475
return NULL ;
470
476
}
471
477
472
478
if (UNEXPECTED (Z_OBJ (retval ) == obj || zend_object_is_lazy (Z_OBJ (retval )))) {
473
479
OBJ_EXTRA_FLAGS (obj ) |= IS_OBJ_LAZY_UNINITIALIZED |IS_OBJ_LAZY_PROXY ;
474
480
zend_throw_error (NULL , "Lazy proxy factory must return a non-lazy object" );
475
481
zval_ptr_dtor (& retval );
482
+ GC_DELREF (obj );
476
483
return NULL ;
477
484
}
478
485
@@ -495,6 +502,14 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
495
502
}
496
503
}
497
504
505
+ if (UNEXPECTED (GC_DELREF (obj ) == 0 )) {
506
+ zend_throw_error (NULL , "Object was released during initialization" );
507
+ zend_objects_store_del (obj );
508
+ return NULL ;
509
+ } else {
510
+ gc_check_possible_root ((zend_refcounted * ) obj );
511
+ }
512
+
498
513
return Z_OBJ (retval );
499
514
}
500
515
@@ -529,6 +544,9 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj)
529
544
return zend_lazy_object_init_proxy (obj );
530
545
}
531
546
547
+ /* Prevent object from being released during initialization */
548
+ GC_ADDREF (obj );
549
+
532
550
zend_fcall_info_cache * initializer = zend_lazy_object_get_initializer_fcc (obj );
533
551
534
552
/* Prevent reentrant initialization */
@@ -569,13 +587,15 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj)
569
587
570
588
if (EG (exception )) {
571
589
zend_lazy_object_revert_init (obj , properties_table_snapshot , properties_snapshot );
590
+ GC_DELREF (obj );
572
591
return NULL ;
573
592
}
574
593
575
594
if (Z_TYPE (retval ) != IS_NULL ) {
576
595
zend_lazy_object_revert_init (obj , properties_table_snapshot , properties_snapshot );
577
596
zval_ptr_dtor (& retval );
578
597
zend_type_error ("Lazy object initializer must return NULL or no value" );
598
+ GC_DELREF (obj );
579
599
return NULL ;
580
600
}
581
601
@@ -598,6 +618,14 @@ ZEND_API zend_object *zend_lazy_object_init(zend_object *obj)
598
618
* zend_lazy_object_has_stale_info() check */
599
619
zend_lazy_object_del_info (obj );
600
620
621
+ if (UNEXPECTED (GC_DELREF (obj ) == 0 )) {
622
+ zend_throw_error (NULL , "Object was released during initialization" );
623
+ zend_objects_store_del (obj );
624
+ return NULL ;
625
+ } else {
626
+ gc_check_possible_root ((zend_refcounted * ) obj );
627
+ }
628
+
601
629
return obj ;
602
630
}
603
631
0 commit comments