From 40ab1d28c496957040b646f0651c236a4a0a7bc0 Mon Sep 17 00:00:00 2001 From: lazerg Date: Thu, 22 Oct 2026 19:40:32 +0500 Subject: [PATCH 1/2] Fix GH-24536: Built-in server crashes on a huge chunk size or Content-Length --- NEWS | 4 ++++ sapi/cli/php_cli_server.c | 4 ---- sapi/cli/tests/gh24536.phpt | 41 +++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 sapi/cli/tests/gh24536.phpt diff --git a/NEWS b/NEWS index 599891f3b598..5a9cf6372657 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,10 @@ PHP NEWS so an in-process engine restart keeps growing the map_ptr table). (David Carlier) +- CLI: + . Fixed bug GH-24536 (Built-in server crashes on a huge chunk size or + Content-Length). (lazerg) + - Date: . Fixed bug GH-20503 (Assertion failure with ext/date DateInterval property hash construction). (heathdutton) diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 6b17f083c125..64ea5ba39bc1 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -1803,10 +1803,6 @@ static int php_cli_server_client_read_request_on_headers_complete(php_http_parse static int php_cli_server_client_read_request_on_body(php_http_parser *parser, const char *at, size_t length) { php_cli_server_client *client = parser->data; - if (!client->request.content) { - client->request.content = pemalloc(parser->content_length, 1); - client->request.content_len = 0; - } client->request.content = perealloc(client->request.content, client->request.content_len + length, 1); memmove(client->request.content + client->request.content_len, at, length); client->request.content_len += length; diff --git a/sapi/cli/tests/gh24536.phpt b/sapi/cli/tests/gh24536.phpt new file mode 100644 index 000000000000..1f3a0caefd69 --- /dev/null +++ b/sapi/cli/tests/gh24536.phpt @@ -0,0 +1,41 @@ +--TEST-- +GH-24536 (Built-in server crashes on a huge chunk size or Content-Length) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +string(0) "" +string(0) "" +HTTP/1.1 200 OK +Host: %s +Date: %s +Connection: close +X-Powered-By: PHP/%s +Content-type: text/html; charset=UTF-8 + +Hello world From f7cebcb3823eb8c834c3a94a5b4d9af52fbfac89 Mon Sep 17 00:00:00 2001 From: lazerg Date: Thu, 22 Oct 2026 19:47:32 +0500 Subject: [PATCH 2/2] Reject chunk sizes and Content-Length values that overflow ssize_t --- sapi/cli/php_http_parser.c | 4 ++++ sapi/cli/tests/gh24536.phpt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sapi/cli/php_http_parser.c b/sapi/cli/php_http_parser.c index c7c2ad0caaea..3c492d364213 100644 --- a/sapi/cli/php_http_parser.c +++ b/sapi/cli/php_http_parser.c @@ -27,6 +27,8 @@ # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif +#define MAX_CONTENT_LENGTH ((ssize_t)(SIZE_MAX >> 1)) + #define CALLBACK2(FOR) \ do { \ @@ -1228,6 +1230,7 @@ size_t php_http_parser_execute (php_http_parser *parser, case h_content_length: if (ch == ' ') break; if (ch < '0' || ch > '9') goto error; + if (parser->content_length > (MAX_CONTENT_LENGTH - (ch - '0')) / 10) goto error; parser->content_length *= 10; parser->content_length += ch - '0'; break; @@ -1433,6 +1436,7 @@ size_t php_http_parser_execute (php_http_parser *parser, goto error; } + if (parser->content_length > (MAX_CONTENT_LENGTH - c) / 16) goto error; parser->content_length *= 16; parser->content_length += c; break; diff --git a/sapi/cli/tests/gh24536.phpt b/sapi/cli/tests/gh24536.phpt index 1f3a0caefd69..7b4be3d4e08f 100644 --- a/sapi/cli/tests/gh24536.phpt +++ b/sapi/cli/tests/gh24536.phpt @@ -18,7 +18,7 @@ var_dump(stream_get_contents($fp)); fclose($fp); $fp = php_cli_server_connect(); -fwrite($fp, "POST / HTTP/1.1\r\nHost: {$host}\r\nContent-Length: 9000000000000000000\r\n\r\nAAAAAAAA"); +fwrite($fp, "POST / HTTP/1.1\r\nHost: {$host}\r\nContent-Length: " . PHP_INT_MAX . "\r\n\r\nAAAAAAAA"); stream_socket_shutdown($fp, STREAM_SHUT_WR); var_dump(stream_get_contents($fp)); fclose($fp);