Blob Blame History Raw
diff -up http-parser-2.7.1/http_parser.c.cve http-parser-2.7.1/http_parser.c
--- http-parser-2.7.1/http_parser.c.cve	2019-03-23 08:58:04.459272497 +0100
+++ http-parser-2.7.1/http_parser.c	2019-03-23 08:58:21.204279947 +0100
@@ -376,6 +376,8 @@ enum header_states
 
   , h_connection
   , h_content_length
+  , h_content_length_num
+  , h_content_length_ws
   , h_transfer_encoding
   , h_upgrade
 
@@ -1478,6 +1480,7 @@ reexecute:
 
             parser->flags |= F_CONTENTLENGTH;
             parser->content_length = ch - '0';
+            parser->header_state = h_content_length_num;
             break;
 
           case h_connection:
@@ -1565,10 +1568,18 @@ reexecute:
               break;
 
             case h_content_length:
+              if (ch == ' ') break;
+              h_state = h_content_length_num;
+              /* FALLTHROUGH */
+
+            case h_content_length_num:
             {
               uint64_t t;
 
-              if (ch == ' ') break;
+              if (ch == ' ') {
+                h_state = h_content_length_ws;
+                break;
+              }
 
               if (UNLIKELY(!IS_NUM(ch))) {
                 SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
@@ -1591,6 +1602,12 @@ reexecute:
               break;
             }
 
+            case h_content_length_ws:
+              if (ch == ' ') break;
+              SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
+              parser->header_state = h_state;
+              goto error;
+
             /* Transfer-Encoding: chunked */
             case h_matching_transfer_encoding_chunked:
               parser->index++;
diff -up http-parser-2.7.1/test.c.cve http-parser-2.7.1/test.c
--- http-parser-2.7.1/test.c.cve	2019-03-23 08:57:50.851266439 +0100
+++ http-parser-2.7.1/test.c	2019-03-23 08:58:25.545281880 +0100
@@ -3947,6 +3947,27 @@ main (void)
   test_invalid_header_field_token_error(HTTP_RESPONSE);
   test_invalid_header_field_content_error(HTTP_RESPONSE);
 
+  test_simple_type(
+      "POST / HTTP/1.1\r\n"
+      "Content-Length:  42 \r\n"  // Note the surrounding whitespace.
+      "\r\n",
+      HPE_OK,
+      HTTP_REQUEST);
+
+  test_simple_type(
+      "POST / HTTP/1.1\r\n"
+      "Content-Length: 4 2\r\n"
+      "\r\n",
+      HPE_INVALID_CONTENT_LENGTH,
+      HTTP_REQUEST);
+
+  test_simple_type(
+      "POST / HTTP/1.1\r\n"
+      "Content-Length: 13 37\r\n"
+      "\r\n",
+      HPE_INVALID_CONTENT_LENGTH,
+      HTTP_REQUEST);
+
   //// RESPONSES
 
   for (i = 0; i < response_count; i++) {