Stop output buffer cleanup at buffers that cannot be removed

zlib.output_compression makes its buffer non-removable once it has sent
compressed output, so ob_end_clean() raised a notice that replaced the
original exception. Fixes #704.
This commit is contained in:
dualfroz committed 2026-10-02 16:11:20 +02:00
1 parent a5b89f86ae
commit 13ce578de8
4 files changed
+73 -2

No files matched your search

+40
View File
@@ -479,6 +479,46 @@ class RunTest extends TestCase
$this->assertEquals("", ob_get_clean());
}
/**
* @covers Whoops\Run::handleException
*/
public function testOutputBufferCleanupStopsAtNonRemovableBuffer()
{
// A removable buffer on top of one that cannot be removed, like
// zlib.output_compression once it has sent compressed output.
$removable = [false, true];
$test = $this;
$system = m::mock('Whoops\Util\SystemFacade')->makePartial();
$system->shouldReceive('stopExecution');
$system->shouldReceive('getOutputBufferLevel')
->andReturnUsing(function () use (&$removable) {
return count($removable);
});
$system->shouldReceive('isOutputBufferRemovable')
->andReturnUsing(function () use (&$removable) {
return end($removable);
});
$system->shouldReceive('endOutputBuffering')
->andReturnUsing(function () use ($test, &$removable) {
if (!array_pop($removable)) {
$test->fail('Tried to end an output buffer that cannot be removed');
}
return true;
});
$run = new Run($system);
$run->pushHandler(function () {
echo "hello there";
return Handler::QUIT;
});
ob_start();
$run->handleException(new RuntimeException());
$this->assertEquals("hello there", ob_get_clean());
$this->assertEquals([false], $removable);
}
/**
* @covers Whoops\Run::sendHttpCode
*/