Skip to content

Commit add3738

Browse files
committed
Fix all fragmentation tests
1 parent e81dbcb commit add3738

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

src/HttpParser.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,15 @@ struct HttpParser {
290290
}
291291

292292
/* Puts method as key, target as value and returns non-null (or nullptr on error). */
293-
static inline char *consumeRequestLine(char *data, HttpRequest::Header &header) {
293+
static inline char *consumeRequestLine(char *data, char *end, HttpRequest::Header &header) {
294294
/* Scan until single SP, assume next is / (origin request) */
295295
char *start = data;
296296
/* This catches the post padded CR and fails */
297297
while (data[0] > 32) data++;
298-
if (data[0] == 32 && data[1] == '/') {
298+
if (&data[1] == end) [[unlikely]] {
299+
return nullptr;
300+
}
301+
if (data[0] == 32 && data[1] == '/') [[likely]] {
299302
header.key = {start, (size_t) (data - start)};
300303
data++;
301304
/* Scan for less than 33 (catches post padded CR and fails) */
@@ -308,6 +311,13 @@ struct HttpParser {
308311
/* Now we stand on space */
309312
header.value = {start, (size_t) (data - start)};
310313
/* Check that the following is http 1.1 */
314+
if (data + 11 >= end) {
315+
/* Whatever we have must be part of the version string */
316+
if (memcmp(" HTTP/1.1\r\n", data, std::min<unsigned int>(11, (unsigned int) (end - data))) == 0) {
317+
return nullptr;
318+
}
319+
return (char *) 0x1;
320+
}
311321
if (memcmp(" HTTP/1.1\r\n", data, 11) == 0) {
312322
return data + 11;
313323
}
@@ -373,7 +383,7 @@ struct HttpParser {
373383
* which is then removed, and our counters to flip due to overflow and we end up with a crash */
374384

375385
/* The request line is different from the field names / field values */
376-
if ((char *) 2 > (postPaddedBuffer = consumeRequestLine(postPaddedBuffer, headers[0]))) {
386+
if ((char *) 2 > (postPaddedBuffer = consumeRequestLine(postPaddedBuffer, end, headers[0]))) {
377387
/* Error - invalid request line */
378388
/* Assuming it is 505 HTTP Version Not Supported */
379389
err = postPaddedBuffer ? HTTP_ERROR_505_HTTP_VERSION_NOT_SUPPORTED : 0;
@@ -389,6 +399,10 @@ struct HttpParser {
389399

390400
/* We should not accept whitespace between key and colon, so colon must foloow immediately */
391401
if (postPaddedBuffer[0] != ':') {
402+
/* If we stand at the end, we are fragmented */
403+
if (postPaddedBuffer == end) {
404+
return 0;
405+
}
392406
/* Error: invalid chars in field name */
393407
err = HTTP_ERROR_400_BAD_REQUEST;
394408
return 0;
@@ -439,7 +453,7 @@ struct HttpParser {
439453
return (unsigned int) ((postPaddedBuffer + 2) - start);
440454
} else {
441455
/* \r\n\r plus non-\n letter is malformed request, or simply out of search space */
442-
if (postPaddedBuffer != end) {
456+
if (postPaddedBuffer + 1 < end) {
443457
err = HTTP_ERROR_400_BAD_REQUEST;
444458
}
445459
return 0;

0 commit comments

Comments
 (0)