Fix memory leak in fiber constructor by throwing an error (#9098)

This commit is contained in:
Martin Schröder 2022-07-22 17:47:47 +02:00 committed by GitHub
parent 9dcb0bd1dc
commit 0adbf9c2d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 2 deletions

View File

@ -0,0 +1,26 @@
--TEST--
Multiple calls to constructor are prevented after fiber terminated
--FILE--
<?php
$fiber = new Fiber(function () {
return 123;
});
var_dump($fiber->start());
var_dump($fiber->getReturn());
$fiber->__construct(function () {
return 321;
});
?>
--EXPECTF--
NULL
int(123)
Fatal error: Uncaught FiberError: Cannot call constructor twice in %scall-to-ctor-of-terminated-fiber.php:%d
Stack trace:
#0 %scall-to-ctor-of-terminated-fiber.php(%d): Fiber->__construct(Object(Closure))
#1 {main}
thrown in %scall-to-ctor-of-terminated-fiber.php on line %d

View File

@ -0,0 +1,20 @@
--TEST--
Multiple calls to constructor are prevented
--FILE--
<?php
$fiber = new Fiber(function () {
return 123;
});
$fiber->__construct(function () {
return 321;
});
?>
--EXPECTF--
Fatal error: Uncaught FiberError: Cannot call constructor twice in %smultiple-calls-to-ctor.php:%d
Stack trace:
#0 %smultiple-calls-to-ctor.php(%d): Fiber->__construct(Object(Closure))
#1 {main}
thrown in %smultiple-calls-to-ctor.php on line %d

View File

@ -647,12 +647,23 @@ static HashTable *zend_fiber_object_gc(zend_object *object, zval **table, int *n
ZEND_METHOD(Fiber, __construct)
{
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_FUNC(fiber->fci, fiber->fci_cache)
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
if (UNEXPECTED(fiber->context.status != ZEND_FIBER_STATUS_INIT || Z_TYPE(fiber->fci.function_name) != IS_UNDEF)) {
zend_throw_error(zend_ce_fiber_error, "Cannot call constructor twice");
RETURN_THROWS();
}
fiber->fci = fci;
fiber->fci_cache = fcc;
// Keep a reference to closures or callable objects while the fiber is running.
Z_TRY_ADDREF(fiber->fci.function_name);
}