Skip to content

Commit bad7d1c

Browse files
committed
Fix infi loop when buffer ends with \r (fhessel#123) (#3)
1 parent cf4fad1 commit bad7d1c

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

src/HTTPConnection.cpp

+17-17
Original file line numberDiff line numberDiff line change
@@ -290,26 +290,26 @@ 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+
}
299+
else {
300+
// Line has not been terminated by \r\n
301+
HTTPS_LOGW("Line without \\r\\n (got only \\r). FID=%d", _socket);
302+
raiseError(400, "Bad Request");
307303
}
308-
} else {
304+
return;
305+
}
306+
if ( newChar == '\r') {
307+
partialTerminationParsed = true;
308+
}
309+
else {
309310
_parserLine.text += newChar;
310-
_bufferProcessed += 1;
311311
}
312-
312+
313313
// Check that the max request string size is not exceeded
314314
if (_parserLine.text.length() > lengthLimit) {
315315
HTTPS_LOGW("Header length exceeded. FID=%d", _socket);

src/HTTPConnection.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ class HTTPConnection : private ConnectionContext {
132132
int _bufferProcessed;
133133
// The index on the receive_buffer that is the first one which is empty at the end.
134134
int _bufferUnusedIdx;
135-
135+
// If \r character has been read, in this case we expect \n to terminate the line
136+
bool partialTerminationParsed = false;
137+
136138
// Socket address, length etc for the connection
137139
struct sockaddr _sockAddr;
138140
socklen_t _addrLen;

0 commit comments

Comments
 (0)