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++) {