Skip to content

Commit 9e94f22

Browse files
Fix infinite loop when the buffer ends with \r fhessel#123 (#2)
* Fix infinite loop when the buffer ends with \r * Properly check for end of line across buffers --------- Co-authored-by: vvigilante <info@vvigilante.com>
1 parent 930053c commit 9e94f22

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

src/HTTPConnection.cpp

+14-16
Original file line numberDiff line numberDiff line change
@@ -290,26 +290,24 @@ void HTTPConnection::raiseError(uint16_t code, std::string reason) {
290290
void HTTPConnection::readLine(int lengthLimit) {
291291
while(_bufferProcessed < _bufferUnusedIdx) {
292292
char newChar = _receiveBuffer[_bufferProcessed];
293-
294-
if ( newChar == '\r') {
295-
// Look ahead for \n (if not possible, wait for next round
296-
if (_bufferProcessed+1 < _bufferUnusedIdx) {
297-
if (_receiveBuffer[_bufferProcessed+1] == '\n') {
298-
_bufferProcessed += 2;
299-
_parserLine.parsingFinished = true;
300-
return;
301-
} else {
302-
// Line has not been terminated by \r\n
303-
HTTPS_LOGW("Line without \\r\\n (got only \\r). FID=%d", _socket);
304-
raiseError(400, "Bad Request");
305-
return;
306-
}
293+
_bufferProcessed++;
294+
if ( partialTerminationParsed ){
295+
partialTerminationParsed = false;
296+
if (newChar == '\n') {
297+
_parserLine.parsingFinished = true;
298+
} else {
299+
// Line has not been terminated by \r\n
300+
HTTPS_LOGW("Line without \\r\\n (got only \\r). FID=%d", _socket);
301+
raiseError(400, "Bad Request");
307302
}
303+
return;
304+
}
305+
if ( newChar == '\r') {
306+
partialTerminationParsed = true;
308307
} else {
309308
_parserLine.text += newChar;
310-
_bufferProcessed += 1;
311309
}
312-
310+
313311
// Check that the max request string size is not exceeded
314312
if (_parserLine.text.length() > lengthLimit) {
315313
HTTPS_LOGW("Header length exceeded. FID=%d", _socket);

src/HTTPConnection.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class HTTPConnection : private ConnectionContext {
134134
int _bufferProcessed;
135135
// The index on the receive_buffer that is the first one which is empty at the end.
136136
int _bufferUnusedIdx;
137+
// If \r character has been read, in this case we expect \n to terminate the line
138+
bool partialTerminationParsed = false;
137139

138140
// Socket address, length etc for the connection
139141
struct sockaddr _sockAddr;

0 commit comments

Comments
 (0)