Commit 1709689256e for php.net
commit 1709689256e2a92a7a515a3923c1e968da044a60
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date: Sun Jan 11 15:06:06 2026 +0100
Fix GH-20906: Assertion failure when messing up output buffers
Closes GH-20908.
diff --git a/NEWS b/NEWS
index 1a4b588aa1e..00f66935d9b 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.4.20
+- Standard:
+ . Fixed bug GH-20906 (Assertion failure when messing up output buffers).
+ (ndossche)
12 Mar 2026, PHP 8.4.19
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 16c34a21966..cf54fbbe651 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -1768,7 +1768,10 @@ PHP_FUNCTION(highlight_file)
}
if (i) {
- php_output_start_default();
+ if (UNEXPECTED(php_output_start_default() != SUCCESS)) {
+ zend_throw_error(NULL, "Unable to start output handler");
+ RETURN_THROWS();
+ }
}
php_get_highlight_struct(&syntax_highlighter_ini);
@@ -1803,7 +1806,10 @@ PHP_FUNCTION(php_strip_whitespace)
Z_PARAM_PATH_STR(filename)
ZEND_PARSE_PARAMETERS_END();
- php_output_start_default();
+ if (UNEXPECTED(php_output_start_default() != SUCCESS)) {
+ zend_throw_error(NULL, "Unable to start output handler");
+ RETURN_THROWS();
+ }
zend_stream_init_filename_ex(&file_handle, filename);
zend_save_lexical_state(&original_lex_state);
@@ -1840,7 +1846,10 @@ PHP_FUNCTION(highlight_string)
ZEND_PARSE_PARAMETERS_END();
if (i) {
- php_output_start_default();
+ if (UNEXPECTED(php_output_start_default() != SUCCESS)) {
+ zend_throw_error(NULL, "Unable to start output handler");
+ RETURN_THROWS();
+ }
}
EG(error_reporting) = E_ERROR;
diff --git a/ext/standard/tests/strings/gh20906_1.phpt b/ext/standard/tests/strings/gh20906_1.phpt
new file mode 100644
index 00000000000..ccb0dfbee56
--- /dev/null
+++ b/ext/standard/tests/strings/gh20906_1.phpt
@@ -0,0 +1,25 @@
+--TEST--
+GH-20906 (Assertion failure when messing up output buffers) - php_strip_whitespace
+--CREDITS--
+vi3tL0u1s
+--FILE--
+<?php
+class A {
+ function __destruct() {
+ php_strip_whitespace(__FILE__);
+ echo "x";
+ $c = new A;
+ ob_start(function () use ($c) { return '/'; }, 1);
+ ob_start(function () use (&$c) { $c = new A; return '/'; }, 1);
+ }
+}
+
+try {
+ new A;
+} catch (Throwable $e) {
+ echo $e::class, ": ", $e->getMessage(), "\n";
+}
+?>
+--EXPECTF--
+%a
+Fatal error: php_strip_whitespace(): Cannot use output buffering in output buffering display handlers in %s on line %d
diff --git a/ext/standard/tests/strings/gh20906_2.phpt b/ext/standard/tests/strings/gh20906_2.phpt
new file mode 100644
index 00000000000..b3ea5cf6ef7
--- /dev/null
+++ b/ext/standard/tests/strings/gh20906_2.phpt
@@ -0,0 +1,21 @@
+--TEST--
+GH-20906 (Assertion failure when messing up output buffers) - highlight_file
+--CREDITS--
+vi3tL0u1s
+--FILE--
+<?php
+class A {
+ function __destruct() {
+ highlight_file(__FILE__, true);
+ echo "x";
+ $c = new A;
+ ob_start(function () use ($c) { return '/'; }, 1);
+ ob_start(function () use (&$c) { $c = new A; return '/'; }, 1);
+ }
+}
+
+new A;
+?>
+--EXPECTF--
+%a
+Fatal error: highlight_file(): Cannot use output buffering in output buffering display handlers in %s on line %d
diff --git a/ext/standard/tests/strings/gh20906_3.phpt b/ext/standard/tests/strings/gh20906_3.phpt
new file mode 100644
index 00000000000..a26fc61bed6
--- /dev/null
+++ b/ext/standard/tests/strings/gh20906_3.phpt
@@ -0,0 +1,21 @@
+--TEST--
+GH-20906 (Assertion failure when messing up output buffers) - highlight_string
+--CREDITS--
+vi3tL0u1s
+--FILE--
+<?php
+class A {
+ function __destruct() {
+ highlight_string(__FILE__, true);
+ echo "x";
+ $c = new A;
+ ob_start(function () use ($c) { return '/'; }, 1);
+ ob_start(function () use (&$c) { $c = new A; return '/'; }, 1);
+ }
+}
+
+new A;
+?>
+--EXPECTF--
+%a
+Fatal error: highlight_string(): Cannot use output buffering in output buffering display handlers in %s on line %d