From f68e67271586125c06f33297a245a920d325584e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 9 Jan 2018 17:24:48 +1300 Subject: [PATCH] HTTP: bail out on negative Content-Length: values ... and make the max filesize check trigger if the value is too big. Updates test 178. Reported-by: Brad Spencer Fixes #2212 Closes #2223 --- lib/http.c | 44 ++++++++++++++++++++++++-------------------- tests/data/test178 | 9 ++++++++- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/lib/http.c b/lib/http.c index def51abc3..c1cdf2da0 100644 --- a/lib/http.c +++ b/lib/http.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -3505,31 +3505,35 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(!k->ignorecl && !data->set.ignorecl && checkprefix("Content-Length:", k->p)) { curl_off_t contentlength; - if(!curlx_strtoofft(k->p + 15, NULL, 10, &contentlength)) { + CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength); + + if(offt == CURL_OFFT_OK) { if(data->set.max_filesize && contentlength > data->set.max_filesize) { failf(data, "Maximum file size exceeded"); return CURLE_FILESIZE_EXCEEDED; } - if(contentlength >= 0) { - k->size = contentlength; - k->maxdownload = k->size; - /* we set the progress download size already at this point - just to make it easier for apps/callbacks to extract this - info as soon as possible */ - Curl_pgrsSetDownloadSize(data, k->size); - } - else { - /* Negative Content-Length is really odd, and we know it - happens for example when older Apache servers send large - files */ - streamclose(conn, "negative content-length"); - infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T - ", closing after transfer\n", contentlength); - } + k->size = contentlength; + k->maxdownload = k->size; + /* we set the progress download size already at this point + just to make it easier for apps/callbacks to extract this + info as soon as possible */ + Curl_pgrsSetDownloadSize(data, k->size); + } + else if(offt == CURL_OFFT_FLOW) { + /* out of range */ + if(data->set.max_filesize) { + failf(data, "Maximum file size exceeded"); + return CURLE_FILESIZE_EXCEEDED; + } + streamclose(conn, "overflow content-length"); + infof(data, "Overflow Content-Length: value!\n"); + } + else { + /* negative or just rubbish - bad HTTP */ + failf(data, "Invalid Content-Length: value"); + return CURLE_WEIRD_SERVER_REPLY; } - else - infof(data, "Illegal Content-Length: header\n"); } /* check for Content-Type: header lines to get the MIME-type */ else if(checkprefix("Content-Type:", k->p)) { diff --git a/tests/data/test178 b/tests/data/test178 index 7481467df..d22d8149f 100644 --- a/tests/data/test178 +++ b/tests/data/test178 @@ -18,6 +18,10 @@ Funny-head: yesyes moooooooooooo + +HTTP/1.1 200 OK swsclose +Date: Thu, 09 Nov 2010 14:49:00 GMT + # @@ -27,7 +31,7 @@ moooooooooooo http -simple HTTP GET with negative Content-Length +HTTP response with negative Content-Length http://%HOSTIP:%HTTPPORT/178 @@ -46,5 +50,8 @@ Host: %HOSTIP:%HTTPPORT Accept: */* + +8 +