mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Generator::throw() on a running generator is not allowed. It throws "Cannot resume an already running generator" when trying to resume the generator to handle the provided exception. However, when calling Generator::throw() on a generator with a non-Generator delegate, we release the delegate regardless. If a Fiber was suspended in the delegate, this causes use after frees when the Fiber is resumed. Fix this by throwing "Cannot resume an already running generator" earlier. Fixes GH-19326 Closes GH-19327
37 lines
589 B
PHP
37 lines
589 B
PHP
--TEST--
|
|
GH-19326: Calling Generator::throw() on a running generator with a non-Generator delegate crashes
|
|
--FILE--
|
|
<?php
|
|
|
|
class It implements IteratorAggregate {
|
|
public function getIterator(): Generator {
|
|
yield "";
|
|
Fiber::suspend();
|
|
}
|
|
}
|
|
|
|
function g() {
|
|
yield from new It();
|
|
}
|
|
|
|
$b = g();
|
|
$b->rewind();
|
|
|
|
$fiber = new Fiber(function () use ($b) {
|
|
$b->next();
|
|
});
|
|
|
|
$fiber->start();
|
|
|
|
try {
|
|
$b->throw(new Exception('test'));
|
|
} catch (Error $e) {
|
|
echo $e->getMessage(), "\n";
|
|
}
|
|
|
|
$fiber->resume();
|
|
|
|
?>
|
|
--EXPECT--
|
|
Cannot resume an already running generator
|