mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-07 09:17:29 +00:00
Close generator already in dtor phase
In the added test case, the Closure ends up being freed before the generator during GC. This patch closes the generator (and thus releases the held closure / execute_data) already during dtor_obj, which will avoid ordering issues in free_obj. dtor_obj is not always called, but if it isn't, then we also won't run GC and will free_obj in reverse construction order. Fixes oss-fuzz #33947.
This commit is contained in:
1 parent
2aac616071
commit
4411026217
2 files changed
+21
-1
No files matched your search
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Close generator in dtor to avoid freeing order issues
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$gen = function() {
|
||||
yield;
|
||||
throw new Exception; // Just to create a live range
|
||||
};
|
||||
$a = new stdclass;
|
||||
$a->a = $a;
|
||||
$a->gen = $gen();
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
@@ -226,6 +226,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
||||
|
||||
if (EXPECTED(!ex) || EXPECTED(!(ex->func->op_array.fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK))
|
||||
|| CG(unclean_shutdown)) {
|
||||
zend_generator_close(generator, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -265,7 +266,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
||||
|
||||
/* TODO: If we hit another yield inside try/finally,
|
||||
* should we also jump to the next finally block? */
|
||||
return;
|
||||
break;
|
||||
} else if (op_num < try_catch->finally_end) {
|
||||
zval *fast_call =
|
||||
ZEND_CALL_VAR(ex, ex->func->op_array.opcodes[try_catch->finally_end].op1.var);
|
||||
@@ -284,6 +285,8 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
||||
|
||||
try_catch_offset--;
|
||||
}
|
||||
|
||||
zend_generator_close(generator, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
Reference in new issue
Block a user