]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.2' into PHP-7.3
authorDmitry Stogov <dmitry@zend.com>
Fri, 9 Aug 2019 14:47:06 +0000 (17:47 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 9 Aug 2019 14:47:06 +0000 (17:47 +0300)
* PHP-7.2:
  Fixed handling of references in nested data of objects with destructor

1  2 
Zend/zend_gc.c

diff --cc Zend/zend_gc.c
index d1fcbf00ca6348c2b94ab54df4bef6dac9b57c47,d98598cc48f87f5cf24ee27d425a7176ebe98378..b6510153f096a245b71018105a8f8bb733834526
@@@ -1350,16 -953,28 +1350,24 @@@ static void gc_remove_nested_data_from_
        zval *zv;
  
  tail_call:
-       if (root ||
-           (GC_REF_ADDRESS(ref) != 0 &&
-            GC_REF_CHECK_COLOR(ref, GC_BLACK))) {
-               GC_TRACE_REF(ref, "removing from buffer");
+       do {
                if (root) {
 -                      if (EXPECTED(GC_ADDRESS(GC_INFO(root->ref)) < GC_ROOT_BUFFER_MAX_ENTRIES)) {
 -                              gc_remove_from_roots(root);
 -                      } else {
 -                              gc_remove_from_additional_roots(root);
 -                      }
 -                      GC_INFO(ref) = 0;
+                       GC_TRACE_REF(ref, "removing from buffer");
 +                      gc_remove_from_roots(root);
 +                      GC_REF_SET_INFO(ref, 0);
                        root = NULL;
-               } else {
 -              } else if (GC_ADDRESS(GC_INFO(ref)) != 0
 -               && GC_REF_GET_COLOR(ref) == GC_BLACK) {
++              } else if (GC_REF_ADDRESS(ref) != 0
++               && GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
+                       GC_TRACE_REF(ref, "removing from buffer");
                        GC_REMOVE_FROM_BUFFER(ref);
+               } else if (GC_TYPE(ref) == IS_REFERENCE) {
+                       if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
+                               ref = Z_COUNTED(((zend_reference*)ref)->val);
+                               goto tail_call;
+                       }
+                       return;
+               } else {
+                       return;
                }
  
                if (GC_TYPE(ref) == IS_OBJECT) {