@@ -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