[php-src] PHP-8.5: Fix GH-24265: zend_fiber_execute() discards exit() in a destroyed fiber

From: Date: Sat, 24 Oct 2026 14:17:46 +0000
Subject: [php-src] PHP-8.5: Fix GH-24265: zend_fiber_execute() discards exit() in a destroyed fiber
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142674@lists.php.net to get a copy of this message
Author: David Carlier (devnexen) Date: 2026-10-24T15:11:10+01:00 Commit: https://github.com/php/php-src/commit/afd156921e54ba889db59ae423b28721f17113b6 Raw diff: https://github.com/php/php-src/commit/afd156921e54ba889db59ae423b28721f17113b6.diff Fix GH-24265: zend_fiber_execute() discards exit() in a destroyed fiber A destroyed fiber swallowed UnwindExit along with the GracefulExit used to unwind it, so exit() in a finally block or destructor was lost. Only the GracefulExit is swallowed now. Close GH-24285 Changed paths: A Zend/tests/fibers/gh24265-001.phpt A Zend/tests/fibers/gh24265-002.phpt M NEWS M Zend/zend_fibers.c Diff: diff --git a/NEWS b/NEWS index b52fdfe6dc81..fb54e6dd3e6c 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,8 @@ PHP NEWS (David Carlier) . Fix function and constant imports in compile_to_ast and add support for grouping. (Klaas Skelte van der Werf) + . Fixed bug GH-24265 (Unwind/GracefulExit discarded in + zend_fiber_execute()). (David Carlier) - Date: . Fixed bug GH-20503 (Assertion failure with ext/date DateInterval property diff --git a/Zend/tests/fibers/gh24265-001.phpt b/Zend/tests/fibers/gh24265-001.phpt new file mode 100644 index 000000000000..d4eed32fc624 --- /dev/null +++ b/Zend/tests/fibers/gh24265-001.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-24265 (exit() in a finally block of a destroyed fiber is discarded) +--CREDITS-- +iluuu1994 +--FILE-- +<?php + +$fiber = new Fiber(function () { + try { + Fiber::suspend(); + } finally { + exit(1); + } +}); + +$fiber->start(); +echo "Before destroy", PHP_EOL; +unset($fiber); + +echo "Not reached", PHP_EOL; + +?> +--EXPECT-- +Before destroy diff --git a/Zend/tests/fibers/gh24265-002.phpt b/Zend/tests/fibers/gh24265-002.phpt new file mode 100644 index 000000000000..2a794bc3d02f --- /dev/null +++ b/Zend/tests/fibers/gh24265-002.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-24265 (exit() in a destroyed fiber is discarded while an exception is pending) +--FILE-- +<?php + +function test() { + $fiber = new Fiber(function () { + try { + Fiber::suspend(); + } finally { + exit(1); + } + }); + + $fiber->start(); + echo "Before destroy", PHP_EOL; + throw new Exception("pending"); +} + +try { + test(); +} catch (Exception $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +echo "Not reached", PHP_EOL; + +?> +--EXPECT-- +Before destroy diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index 2bebdd8d87f6..8c3a080f44fa 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -645,9 +645,7 @@ static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer) zend_fiber_release_callable(fiber); if (EG(exception)) { - if (!(fiber->flags & ZEND_FIBER_FLAG_DESTROYED) - || !(zend_is_graceful_exit(EG(exception)) || zend_is_unwind_exit(EG(exception))) - ) { + if (!(fiber->flags & ZEND_FIBER_FLAG_DESTROYED) || !zend_is_graceful_exit(EG(exception))) { fiber->flags |= ZEND_FIBER_FLAG_THREW; transfer->flags = ZEND_FIBER_TRANSFER_FLAG_ERROR;

« previous php.cvs (#142674) next »