Commit 7ff3af0f428 for php
commit 7ff3af0f428b3848c9cca6a13cdd6c6633d015dc
Author: Martin Mirchev <mmirchev@comp.nus.edu.sg>
Date: Thu Oct 22 14:05:08 2026 +0000
Fix infinite loop in sapi_header_op() for headers of 4 GiB or more (#24540)
The new line/NUL check uses a uint32_t index to scan a header whose length
is size_t. For header lines of 4 GiB or more, the index wraps around and
the request never finishes. This also affects session_start() when a
cookie path, domain or session ID produces a header of that size.
Use size_t for the index so it can reach the full header length. Add a
resource-heavy regression test using header() directly, with a newline
after 4 GiB to verify that header validation completes and emits the
usual warning. The test requires a 64-bit platform and runs only when
RUN_RESOURCE_HEAVY_TESTS is enabled and SKIP_SLOW_TESTS is unset.
Closes #24540
diff --git a/NEWS b/NEWS
index b2a90382e70..883c9d7dee3 100644
--- a/NEWS
+++ b/NEWS
@@ -104,6 +104,10 @@ PHP NEWS
. Fixed a crash in readline_info() when completion_append_character
contains a non-ASCII byte. (Weilin Du)
+- SAPI:
+ . Fixed infinite loop in sapi_header_op() for headers of 4 GiB or more.
+ (Martin Mirchev)
+
- SOAP:
. Fixed use of uninitialized func in do_request() on OOM bailout.
(David Carlier)
diff --git a/ext/standard/tests/general_functions/header_over_4gib.phpt b/ext/standard/tests/general_functions/header_over_4gib.phpt
new file mode 100644
index 00000000000..a2075dfb27c
--- /dev/null
+++ b/ext/standard/tests/general_functions/header_over_4gib.phpt
@@ -0,0 +1,20 @@
+--TEST--
+header() with a header line longer than 4 GiB
+--SKIPIF--
+<?php
+if (!getenv('RUN_RESOURCE_HEAVY_TESTS')) die('skip resource-heavy test');
+if (PHP_INT_SIZE != 8) die('skip this test is for 64bit platforms only');
+if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request');
+?>
+--INI--
+memory_limit=-1
+--FILE--
+<?php
+// The new line/NUL check in sapi_header_op() used a 32-bit index, so a header
+// line of 4 GiB or more made it loop forever.
+header('X-Foo: ' . str_repeat('a', 2**32) . "\nX-Bar: b");
+echo "Done\n";
+?>
+--EXPECTF--
+Warning: Header may not contain more than a single header, new line detected in %s on line %d
+Done
diff --git a/main/SAPI.c b/main/SAPI.c
index dbc6ed16330..4b6b7b0c90e 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -742,7 +742,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg)
return SUCCESS;
} else {
/* new line/NUL character safety check */
- uint32_t i;
+ size_t i;
for (i = 0; i < header_line_len; i++) {
/* RFC 7230 ch. 3.2.4 deprecates folding support */
if (header_line[i] == '\n' || header_line[i] == '\r') {