Fix GH-15181: Disabled output handler is flushed again

When an `PHP_OUTPUT_HANDLER_FAILURE` occurs, the output handler becomes
disabled (i.e. the `PHP_OUTPUT_HANDLER_DISABLED` flag is set).  However,
there is no guard for disabled handlers in `php_output_handler_op()`
what may cause serious issues (as reported, UB due to passing `NULL` as
the 2nd argument of `memcpy`, because the handler's buffer has already
been `NULL`ed).  Therefore, we add a respective guard for disabled
handlers, and return `PHP_OUTPUT_HANDLER_FAILURE` right away.

Closes GH-15183.
This commit is contained in:
Christoph M. Becker 2024-07-31 21:46:53 +02:00
parent bc8909aac3
commit 887e6b9c45
No known key found for this signature in database
GPG Key ID: D66C9593118BCCB6
3 changed files with 20 additions and 0 deletions

1
NEWS
View File

@ -8,6 +8,7 @@ PHP NEWS
. Fixed bug GH-15240 (Infinite recursion in trait hook). (ilutov)
. Fixed bug GH-15140 (Missing variance check for abstract set with asymmetric
type). (ilutov)
. Fixed bug GH-15181 (Disabled output handler is flushed again). (cmb)
- Date:
. Constants SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING, and SUNFUNCS_RET_DOUBLE

View File

@ -925,6 +925,10 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl
);
#endif
if (handler->flags & PHP_OUTPUT_HANDLER_DISABLED) {
return PHP_OUTPUT_HANDLER_FAILURE;
}
if (php_output_lock_error(context->op)) {
/* fatal error */
return PHP_OUTPUT_HANDLER_FAILURE;

15
tests/output/gh15181.phpt Normal file
View File

@ -0,0 +1,15 @@
--TEST--
Fix GH-15181 (Disabled output handler is flushed again)
--FILE--
<?php
ob_start(function () {
throw new Exception('ob_start');
});
try {
ob_flush();
} catch (Throwable) {}
ob_flush();
?>
===DONE===
--EXPECT--
===DONE===