diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/standard/http_fopen_wrapper.c | 18 | ||||
-rw-r--r-- | ext/standard/tests/http/bug78719.phpt | 26 |
3 files changed, 33 insertions, 13 deletions
@@ -26,6 +26,8 @@ PHP NEWS - Standard: . Fixed bug #80771 (phpinfo(INFO_CREDITS) displays nothing in CLI). (cmb) + . Fixed bug #78719 (http wrapper silently ignores long Location headers). + (cmb) 04 Mar 2021, php 7.4.16 diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index bf0363fd3c..4f702bf75f 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -732,24 +732,16 @@ finish: /* read past HTTP headers */ - http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE); - while (!php_stream_eof(stream)) { size_t http_header_line_length; - if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') { + if (http_header_line != NULL) { + efree(http_header_line); + } + if ((http_header_line = php_stream_get_line(stream, NULL, 0, &http_header_line_length)) && *http_header_line != '\n' && *http_header_line != '\r') { char *e = http_header_line + http_header_line_length - 1; char *http_header_value; - if (*e != '\n') { - do { /* partial header */ - if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) == NULL) { - php_stream_wrapper_log_error(wrapper, options, "Failed to read HTTP headers"); - goto out; - } - e = http_header_line + http_header_line_length - 1; - } while (*e != '\n'); - continue; - } + while (e >= http_header_line && (*e == '\n' || *e == '\r')) { e--; } diff --git a/ext/standard/tests/http/bug78719.phpt b/ext/standard/tests/http/bug78719.phpt new file mode 100644 index 0000000000..b12bd3951e --- /dev/null +++ b/ext/standard/tests/http/bug78719.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #78719 (http wrapper silently ignores long Location headers) +--SKIPIF-- +<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?> +--INI-- +allow_url_fopen=1 +--FILE-- +<?php +require 'server.inc'; + +$url = str_repeat('*', 2000); +$responses = array( + "data://text/plain,HTTP/1.0 302 Ok\r\nLocation: $url\r\n\r\nBody", +); +$pid = http_server("tcp://127.0.0.1:12342", $responses, $output); + +$context = stream_context_create(['http' => ['follow_location' => 0]]); +$stream = fopen('http://127.0.0.1:12342/', 'r', false, $context); +var_dump(stream_get_contents($stream)); +var_dump(stream_get_meta_data($stream)['wrapper_data'][1] === "Location: $url"); + +http_server_kill($pid); +?> +--EXPECTF-- +string(4) "Body" +bool(true) |