From efaa0efecb6effa98dd681d2afa6a0a8dffea6f1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 14 Jul 2021 14:50:29 +0200 Subject: [PATCH 1/3] Fix #80849: HTTP Status header truncation While truncating the contents of a header is okay, we must never omit the trailing CRLF. --- sapi/cgi/cgi_main.c | 9 +++++---- sapi/cgi/tests/bug80849-cgi.phpt | 10 ++++++++++ sapi/fpm/fpm/fpm_main.c | 9 +++++---- sapi/fpm/tests/bug80849-fpm.phpt | 10 ++++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 sapi/cgi/tests/bug80849-cgi.phpt create mode 100644 sapi/fpm/tests/bug80849-fpm.phpt diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index cd79475fde4d0..a36f426d266b0 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -387,7 +387,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers) if (CGIG(rfc2616_headers) && SG(sapi_headers).http_status_line) { char *s; - len = slprintf(buf, SAPI_CGI_MAX_HEADER_LENGTH, "%s\r\n", SG(sapi_headers).http_status_line); + len = slprintf(buf, SAPI_CGI_MAX_HEADER_LENGTH, "%s", SG(sapi_headers).http_status_line); if ((s = strchr(SG(sapi_headers).http_status_line, ' '))) { response_status = atoi((s + 1)); } @@ -404,7 +404,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers) (s - SG(sapi_headers).http_status_line) >= 5 && strncasecmp(SG(sapi_headers).http_status_line, "HTTP/", 5) == 0 ) { - len = slprintf(buf, sizeof(buf), "Status:%s\r\n", s); + len = slprintf(buf, sizeof(buf), "Status:%s", s); response_status = atoi((s + 1)); } else { h = (sapi_header_struct*)zend_llist_get_first_ex(&sapi_headers->headers, &pos); @@ -427,9 +427,9 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers) err++; } if (err->str) { - len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->str); + len = slprintf(buf, sizeof(buf), "Status: %d %s", SG(sapi_headers).http_response_code, err->str); } else { - len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code); + len = slprintf(buf, sizeof(buf), "Status: %d", SG(sapi_headers).http_response_code); } } } @@ -437,6 +437,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers) if (!has_status) { PHPWRITE_H(buf, len); + PHPWRITE_H("\r\n", 2); ignore_status = 1; } } diff --git a/sapi/cgi/tests/bug80849-cgi.phpt b/sapi/cgi/tests/bug80849-cgi.phpt new file mode 100644 index 0000000000000..b2abaed731d7c --- /dev/null +++ b/sapi/cgi/tests/bug80849-cgi.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #80849 (HTTP Status header truncation) +--CGI-- +--FILE-- + +--EXPECTHEADERS-- +Status: 201 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +--EXPECT-- diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 7505afde76cb8..d43b4adfab12a 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -328,7 +328,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers) /* {{{ */ if (CGIG(rfc2616_headers) && SG(sapi_headers).http_status_line) { char *s; - len = slprintf(buf, SAPI_CGI_MAX_HEADER_LENGTH, "%s\r\n", SG(sapi_headers).http_status_line); + len = slprintf(buf, SAPI_CGI_MAX_HEADER_LENGTH, "%s", SG(sapi_headers).http_status_line); if ((s = strchr(SG(sapi_headers).http_status_line, ' '))) { response_status = atoi((s + 1)); } @@ -345,7 +345,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers) /* {{{ */ (s - SG(sapi_headers).http_status_line) >= 5 && strncasecmp(SG(sapi_headers).http_status_line, "HTTP/", 5) == 0 ) { - len = slprintf(buf, sizeof(buf), "Status:%s\r\n", s); + len = slprintf(buf, sizeof(buf), "Status:%s", s); response_status = atoi((s + 1)); } else { h = (sapi_header_struct*)zend_llist_get_first_ex(&sapi_headers->headers, &pos); @@ -368,9 +368,9 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers) /* {{{ */ err++; } if (err->str) { - len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->str); + len = slprintf(buf, sizeof(buf), "Status: %d %s", SG(sapi_headers).http_response_code, err->str); } else { - len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code); + len = slprintf(buf, sizeof(buf), "Status: %d", SG(sapi_headers).http_response_code); } } } @@ -378,6 +378,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers) /* {{{ */ if (!has_status) { PHPWRITE_H(buf, len); + PHPWRITE_H("\r\n", 2); ignore_status = 1; } } diff --git a/sapi/fpm/tests/bug80849-fpm.phpt b/sapi/fpm/tests/bug80849-fpm.phpt new file mode 100644 index 0000000000000..b2abaed731d7c --- /dev/null +++ b/sapi/fpm/tests/bug80849-fpm.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #80849 (HTTP Status header truncation) +--CGI-- +--FILE-- + +--EXPECTHEADERS-- +Status: 201 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +--EXPECT-- From f16cd3fdfb890f0279160bcbc7435262daca7a64 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 15 Jul 2021 17:17:23 +0200 Subject: [PATCH 2/3] Properly test under FPM --- sapi/fpm/tests/bug80849-fpm.phpt | 36 +++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/sapi/fpm/tests/bug80849-fpm.phpt b/sapi/fpm/tests/bug80849-fpm.phpt index b2abaed731d7c..57d748267c74f 100644 --- a/sapi/fpm/tests/bug80849-fpm.phpt +++ b/sapi/fpm/tests/bug80849-fpm.phpt @@ -1,10 +1,40 @@ --TEST-- Bug #80849 (HTTP Status header truncation) ---CGI-- +--SKIPIF-- + --FILE-- start(); +$tester->expectLogStartNotices(); +$tester + ->request() + ->expectHeader('Status', '201 ' . str_repeat('A', 1011)); +$tester->terminate(); +$tester->close(); +?> +--CLEAN-- + ---EXPECTHEADERS-- -Status: 201 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --EXPECT-- From d719efb20e74a0fa96b09810df86f68e63371c97 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 15 Jul 2021 17:50:44 +0200 Subject: [PATCH 3/3] Use longer strings to actually demonstrate the truncation --- sapi/cgi/tests/bug80849-cgi.phpt | 2 +- sapi/fpm/tests/bug80849-fpm.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sapi/cgi/tests/bug80849-cgi.phpt b/sapi/cgi/tests/bug80849-cgi.phpt index b2abaed731d7c..ed396aea55dd2 100644 --- a/sapi/cgi/tests/bug80849-cgi.phpt +++ b/sapi/cgi/tests/bug80849-cgi.phpt @@ -3,7 +3,7 @@ Bug #80849 (HTTP Status header truncation) --CGI-- --FILE-- --EXPECTHEADERS-- Status: 201 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA diff --git a/sapi/fpm/tests/bug80849-fpm.phpt b/sapi/fpm/tests/bug80849-fpm.phpt index 57d748267c74f..abe179368b7ee 100644 --- a/sapi/fpm/tests/bug80849-fpm.phpt +++ b/sapi/fpm/tests/bug80849-fpm.phpt @@ -20,7 +20,7 @@ EOT; $code = <<