@@ -733,6 +733,8 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
733733 uintptr_t property_offset ;
734734 const zend_property_info * prop_info = NULL ;
735735 uint32_t * guard = NULL ;
736+ bool obj_needs_deref = false;
737+ zend_object * prev_zobj ;
736738
737739#if DEBUG_OBJECT_HANDLERS
738740 fprintf (stderr , "Read object #%d property: %s\n" , zobj -> handle , ZSTR_VAL (name ));
@@ -906,12 +908,8 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
906908 goto call_getter ;
907909 }
908910
909- bool obj_is_freed = GC_REFCOUNT (zobj ) == 1 ;
910- OBJ_RELEASE (zobj );
911- if (UNEXPECTED (obj_is_freed )) {
912- retval = & EG (uninitialized_zval );
913- goto exit ;
914- }
911+ obj_needs_deref = true;
912+ prev_zobj = zobj ;
915913 } else if (zobj -> ce -> __get && !((* guard ) & IN_GET )) {
916914 goto call_getter_addref ;
917915 }
@@ -960,7 +958,7 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
960958 zobj = zend_lazy_object_init (zobj );
961959 if (!zobj ) {
962960 retval = & EG (uninitialized_zval );
963- goto exit ;
961+ goto exit_slow ;
964962 }
965963
966964 if (UNEXPECTED (guard )) {
@@ -971,11 +969,12 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
971969 (* guard ) |= guard_type ;
972970 retval = zend_std_read_property (zobj , name , type , cache_slot , rv );
973971 (* guard ) &= ~guard_type ;
974- return retval ;
972+ goto exit_slow ;
975973 }
976974 }
977975
978- return zend_std_read_property (zobj , name , type , cache_slot , rv );
976+ retval = zend_std_read_property (zobj , name , type , cache_slot , rv );
977+ goto exit_slow ;
979978 }
980979 }
981980 if (type != BP_VAR_IS ) {
@@ -987,6 +986,16 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
987986 }
988987 retval = & EG (uninitialized_zval );
989988
989+ exit_slow :
990+ if (obj_needs_deref ) {
991+ /* Move value to rv in case zobj gets destroyed. */
992+ if (retval != rv ) {
993+ ZVAL_COPY (rv , retval );
994+ retval = rv ;
995+ }
996+ OBJ_RELEASE (prev_zobj );
997+ }
998+
990999exit :
9911000 return retval ;
9921001}
0 commit comments