From be6038a35ef065e99f5f0bc9c916d60e509a47f1 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 27 Feb 2026 15:46:48 +0100 Subject: [PATCH 1/3] [skip ci] Also add ReflectionProperty::is{Readable,Writable}() to NEWS Also fix typo (missing and), and align message with rest of the doc. --- NEWS | 2 ++ UPGRADING | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index fd2f2fa82ec80..cf36b1bad7c7f 100644 --- a/NEWS +++ b/NEWS @@ -87,6 +87,8 @@ PHP NEWS . Fixed bug GH-20217 (ReflectionClass::isIterable() incorrectly returns true for classes with property hooks). (alexandre-daubois) . Added ReflectionConstant::inNamespace(). (Khaled Alam) + . Added ReflectionProperty::isReadable() and ReflectionProperty::isWritable(). + (ilutov) - Session: . Fixed bug 71162 (updateTimestamp never called when session data is empty). diff --git a/UPGRADING b/UPGRADING index 151b27b226788..7e47d0ba4817c 100644 --- a/UPGRADING +++ b/UPGRADING @@ -134,8 +134,8 @@ PHP 8.6 UPGRADE NOTES - Reflection: . ReflectionConstant::inNamespace() - . ReflectionProperty::isReadable() ReflectionProperty::isWritable() were - added. + . Added ReflectionProperty::isReadable() and ReflectionProperty::isWritable(). + RFC: https://wiki.php.net/rfc/isreadable-iswriteable - Standard: . `clamp()` returns the given value if in range, else return the nearest From 1709689256e2a92a7a515a3923c1e968da044a60 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 11 Jan 2026 15:06:06 +0100 Subject: [PATCH 2/3] Fix GH-20906: Assertion failure when messing up output buffers Closes GH-20908. --- NEWS | 3 +++ ext/standard/basic_functions.c | 15 +++++++++++--- ext/standard/tests/strings/gh20906_1.phpt | 25 +++++++++++++++++++++++ ext/standard/tests/strings/gh20906_2.phpt | 21 +++++++++++++++++++ ext/standard/tests/strings/gh20906_3.phpt | 21 +++++++++++++++++++ 5 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 ext/standard/tests/strings/gh20906_1.phpt create mode 100644 ext/standard/tests/strings/gh20906_2.phpt create mode 100644 ext/standard/tests/strings/gh20906_3.phpt diff --git a/NEWS b/NEWS index 1a4b588aa1e02..00f66935d9b3e 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 16c34a21966e9..cf54fbbe651c5 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 0000000000000..ccb0dfbee5669 --- /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-- +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 0000000000000..b3ea5cf6ef74b --- /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-- + +--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 0000000000000..a26fc61bed654 --- /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-- + +--EXPECTF-- +%a +Fatal error: highlight_string(): Cannot use output buffering in output buffering display handlers in %s on line %d From 27e12b50f4d430c8f98bc58f534e438bfa2ecd62 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 26 Feb 2026 20:24:24 +0000 Subject: [PATCH 3/3] ext/pcre: drop negative-length match tests Newer PCRE2 rejects \K in lookarounds at compile time, so the negative-length match code path can no longer be triggered from userland PHP. The PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK flag that would re-enable it is only settable via the C compile context API. --- .../tests/preg_match_all_negative_length_match.phpt | 10 ---------- ext/pcre/tests/preg_match_negative_length_match.phpt | 10 ---------- 2 files changed, 20 deletions(-) delete mode 100644 ext/pcre/tests/preg_match_all_negative_length_match.phpt delete mode 100644 ext/pcre/tests/preg_match_negative_length_match.phpt diff --git a/ext/pcre/tests/preg_match_all_negative_length_match.phpt b/ext/pcre/tests/preg_match_all_negative_length_match.phpt deleted file mode 100644 index b18007cd32562..0000000000000 --- a/ext/pcre/tests/preg_match_all_negative_length_match.phpt +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -preg_match_all() resource cleanup when \K in lookahead causes negative-length match ---FILE-- - ---EXPECTF-- -Warning: preg_match_all(): Compilation failed: \K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) at offset %d in %s -bool(false) diff --git a/ext/pcre/tests/preg_match_negative_length_match.phpt b/ext/pcre/tests/preg_match_negative_length_match.phpt deleted file mode 100644 index 221ea4fb9e54c..0000000000000 --- a/ext/pcre/tests/preg_match_negative_length_match.phpt +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -preg_match() resource cleanup when \K in lookahead causes negative-length match ---FILE-- - ---EXPECTF-- -Warning: preg_match(): Compilation failed: \K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) at offset %d in %s -bool(false)