From 24db85c5abf5fe00fb8ee1323f8fa8a775627fc1 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Thu, 7 Oct 2021 16:41:38 +0400 Subject: [PATCH] http: fixed Content-Length header validation Content-Length is not necesserily the last header, more headers can follow it. Closes: #41072 --- test_parse_content_length.c | 5 +++++ url.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/test_parse_content_length.c b/test_parse_content_length.c index 456bbb5..ee5041f 100644 --- a/test_parse_content_length.c +++ b/test_parse_content_length.c @@ -52,6 +52,11 @@ int main(int argc, char **argv) { "Content-Length: 1234 ", "Content-Length: 1234 ", "Content-Length: 1234 \r\n\r\n", + "Content-Length: 1234\r\n" + "Last-Modified: Sun, 12 Sep 2021 22:31:46 GMT\r\n" + "Connection: close\r\n" + "Etag: \"613e7fd2-3849a800\"\r\n" + "Accept-Ranges: bytes\r\n\r\n" }; for (i = 0; i < ARRAY_SIZE(invalid_inputs); i++) { diff --git a/url.c b/url.c index f541ccf..399043a 100644 --- a/url.c +++ b/url.c @@ -398,6 +398,7 @@ int ftp_end_data_command(int sock) static int parse_content_length(const char *headers, unsigned long *size) { const char *header_content_length = "Content-Length: "; const char *hdr = NULL, *ptr = NULL, *start = NULL, *end = NULL; + const char *nexthdr = NULL; hdr = strstr(headers, header_content_length); if (!hdr) { @@ -406,6 +407,7 @@ static int parse_content_length(const char *headers, unsigned long *size) { } start = hdr + strlen(header_content_length); + nexthdr = strstr(start, "\r\n"); errno = 0; *size = strtoul(start, (char **)&end, 10); @@ -432,7 +434,7 @@ static int parse_content_length(const char *headers, unsigned long *size) { * Note: endptr points first non-digit/space character or * end of the string */ - for (ptr = end; *ptr; ptr++) { + for (ptr = end; nexthdr ? ptr < nexthdr : *ptr != '\0'; ptr++) { if (!isspace(*ptr) && !isdigit(*ptr)) { log_message("%s: error: invalid character %c in Content-Length header '%s'", __func__, *ptr, hdr); return -1;