]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.4' into PHP-8.0
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 18 Nov 2020 11:46:12 +0000 (12:46 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 18 Nov 2020 11:46:12 +0000 (12:46 +0100)
* PHP-7.4:
  Short-circuit get_gc for currently running generator

1  2 
Zend/zend_generators.c

index 7746c3de9ce31b7298472dffc425439711ef1622,3fbbd49c0a70b3ce393f05e87d6cf1f52a76ad35..68c1865c0002e4caa01321ce3a914a2ebef49516
@@@ -324,13 -340,30 +324,23 @@@ static HashTable *zend_generator_get_gc
                return NULL;
        }
  
+       if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) {
+               /* If the generator is currently running, we certainly won't be able to GC any values it
+                * holds on to. The execute_data state might be inconsistent during execution (e.g. because
+                * GC has been triggered in the middle of a variable reassignment), so we should not try
+                * to inspect it here. */
+               *table = NULL;
+               *n = 0;
+               return NULL;
+       }
        op_array = &EX(func)->op_array;
 -      gc_buffer_size = calc_gc_buffer_size(generator);
 -      if (generator->gc_buffer_size < gc_buffer_size) {
 -              generator->gc_buffer = safe_erealloc(generator->gc_buffer, sizeof(zval), gc_buffer_size, 0);
 -              generator->gc_buffer_size = gc_buffer_size;
 -      }
  
 -      *n = gc_buffer_size;
 -      *table = gc_buffer = generator->gc_buffer;
 -
 -      ZVAL_COPY_VALUE(gc_buffer++, &generator->value);
 -      ZVAL_COPY_VALUE(gc_buffer++, &generator->key);
 -      ZVAL_COPY_VALUE(gc_buffer++, &generator->retval);
 -      ZVAL_COPY_VALUE(gc_buffer++, &generator->values);
 +      zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
 +      zend_get_gc_buffer_add_zval(gc_buffer, &generator->value);
 +      zend_get_gc_buffer_add_zval(gc_buffer, &generator->key);
 +      zend_get_gc_buffer_add_zval(gc_buffer, &generator->retval);
 +      zend_get_gc_buffer_add_zval(gc_buffer, &generator->values);
  
        if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
                uint32_t i, num_cvs = EX(func)->op_array.last_var;