From 36c0df230bd247bd8b6c55169fa0253cf374c9ad Mon Sep 17 00:00:00 2001 From: vvigilante Date: Mon, 19 Apr 2021 17:29:52 +0200 Subject: [PATCH 1/2] Fix infinite loop when the buffer ends with \r --- src/HTTPConnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HTTPConnection.cpp b/src/HTTPConnection.cpp index 0ab739c..ada5e2e 100644 --- a/src/HTTPConnection.cpp +++ b/src/HTTPConnection.cpp @@ -306,8 +306,8 @@ void HTTPConnection::readLine(int lengthLimit) { } } else { _parserLine.text += newChar; - _bufferProcessed += 1; } + _bufferProcessed += 1; // Check that the max request string size is not exceeded if (_parserLine.text.length() > lengthLimit) { From 85a05b5ac634bc92aecfb7af433bc0c23844fd51 Mon Sep 17 00:00:00 2001 From: vvigilante Date: Mon, 19 Apr 2021 17:47:05 +0200 Subject: [PATCH 2/2] Properly check for end of line across buffers --- src/HTTPConnection.cpp | 30 ++++++++++++++---------------- src/HTTPConnection.hpp | 2 ++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/HTTPConnection.cpp b/src/HTTPConnection.cpp index ada5e2e..a4b3f9b 100644 --- a/src/HTTPConnection.cpp +++ b/src/HTTPConnection.cpp @@ -289,26 +289,24 @@ void HTTPConnection::raiseError(uint16_t code, std::string reason) { void HTTPConnection::readLine(int lengthLimit) { while(_bufferProcessed < _bufferUnusedIdx) { char newChar = _receiveBuffer[_bufferProcessed]; - - if ( newChar == '\r') { - // Look ahead for \n (if not possible, wait for next round - if (_bufferProcessed+1 < _bufferUnusedIdx) { - if (_receiveBuffer[_bufferProcessed+1] == '\n') { - _bufferProcessed += 2; - _parserLine.parsingFinished = true; - return; - } else { - // Line has not been terminated by \r\n - HTTPS_LOGW("Line without \\r\\n (got only \\r). FID=%d", _socket); - raiseError(400, "Bad Request"); - return; - } + _bufferProcessed++; + if ( partialTerminationParsed ){ + partialTerminationParsed = false; + if (newChar == '\n') { + _parserLine.parsingFinished = true; + } else { + // Line has not been terminated by \r\n + HTTPS_LOGW("Line without \\r\\n (got only \\r). FID=%d", _socket); + raiseError(400, "Bad Request"); } + return; + } + if ( newChar == '\r') { + partialTerminationParsed = true; } else { _parserLine.text += newChar; } - _bufferProcessed += 1; - + // Check that the max request string size is not exceeded if (_parserLine.text.length() > lengthLimit) { HTTPS_LOGW("Header length exceeded. FID=%d", _socket); diff --git a/src/HTTPConnection.hpp b/src/HTTPConnection.hpp index fb15d7a..ddc7fa9 100644 --- a/src/HTTPConnection.hpp +++ b/src/HTTPConnection.hpp @@ -131,6 +131,8 @@ class HTTPConnection : private ConnectionContext { int _bufferProcessed; // The index on the receive_buffer that is the first one which is empty at the end. int _bufferUnusedIdx; + // If \r character has been read, in this case we expect \n to terminate the line + bool partialTerminationParsed = false; // Socket address, length etc for the connection struct sockaddr _sockAddr;