From fe46191445476bfc650878a019a7d34a650844de Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 12 Jul 2016 17:23:48 -0400 Subject: [PATCH 1/2] Make HttpClient::responseBody more robust Return invalidated String if memory allocation fails or content length does not match body data length. Also, use timed reads to support responses without a content length. --- src/HttpClient.cpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/HttpClient.cpp b/src/HttpClient.cpp index 498d26c..d640bd1 100644 --- a/src/HttpClient.cpp +++ b/src/HttpClient.cpp @@ -32,7 +32,7 @@ void HttpClient::resetState() { iState = eIdle; iStatusCode = 0; - iContentLength = 0; + iContentLength = kNoContentLengthHeader; iBodyLengthConsumed = 0; iContentLengthPtr = kContentLengthPrefix; iHttpResponseTimeout = kHttpResponseTimeout; @@ -521,12 +521,35 @@ String HttpClient::responseBody() if (bodyLength > 0) { - response.reserve(bodyLength); + // try to reserve bodyLength bytes + if (response.reserve(bodyLength) == 0) { + // String reserve failed + return String((const char*)NULL); + } } - while (available()) + // keep on timedRead'ing, until: + // - we have a content length: body length equals consumed or no bytes + // available + // - no content length: no bytes are available + while (iBodyLengthConsumed != bodyLength) { - response += (char)read(); + int c = timedRead(); + + if (c == -1) { + // read timed out, done + break; + } + + if (!response.concat((char)c)) { + // adding char failed + return String((const char*)NULL); + } + } + + if (bodyLength > 0 && (unsigned int)bodyLength != response.length()) { + // failure, we did not read in reponse content length bytes + return String((const char*)NULL); } return response; From 172049e0c3c8d29799c5faec5c473025109c68de Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Fri, 12 Aug 2016 17:00:56 -0400 Subject: [PATCH 2/2] Also set iBodyLengthConsumed to zero when parsing --- src/HttpClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HttpClient.cpp b/src/HttpClient.cpp index d640bd1..e66d488 100644 --- a/src/HttpClient.cpp +++ b/src/HttpClient.cpp @@ -686,6 +686,7 @@ int HttpClient::readHeader() // Just in case we get multiple Content-Length headers, this // will ensure we just get the value of the last one iContentLength = 0; + iBodyLengthConsumed = 0; } } else if ((iContentLengthPtr == kContentLengthPrefix) && (c == '\r'))