Browse Source

Import upstream version 2.9.4

Ben Noordhuis 4 years ago
parent
commit
6a521ca154
4 changed files with 19 additions and 14 deletions
  1. 1 1
      Makefile
  2. 7 4
      http_parser.c
  3. 8 7
      http_parser.h
  4. 3 2
      test.c

+ 1 - 1
Makefile

@@ -24,7 +24,7 @@ BINEXT ?=
 SOLIBNAME = libhttp_parser
 SOLIBNAME = libhttp_parser
 SOMAJOR = 2
 SOMAJOR = 2
 SOMINOR = 9
 SOMINOR = 9
-SOREV   = 3
+SOREV   = 4
 ifeq (darwin,$(PLATFORM))
 ifeq (darwin,$(PLATFORM))
 SOEXT ?= dylib
 SOEXT ?= dylib
 SONAME ?= $(SOLIBNAME).$(SOMAJOR).$(SOMINOR).$(SOEXT)
 SONAME ?= $(SOLIBNAME).$(SOMAJOR).$(SOMINOR).$(SOEXT)

+ 7 - 4
http_parser.c

@@ -731,6 +731,7 @@ reexecute:
         if (ch == CR || ch == LF)
         if (ch == CR || ch == LF)
           break;
           break;
         parser->flags = 0;
         parser->flags = 0;
+        parser->extra_flags = 0;
         parser->content_length = ULLONG_MAX;
         parser->content_length = ULLONG_MAX;
 
 
         if (ch == 'H') {
         if (ch == 'H') {
@@ -768,6 +769,7 @@ reexecute:
         if (ch == CR || ch == LF)
         if (ch == CR || ch == LF)
           break;
           break;
         parser->flags = 0;
         parser->flags = 0;
+        parser->extra_flags = 0;
         parser->content_length = ULLONG_MAX;
         parser->content_length = ULLONG_MAX;
 
 
         if (ch == 'H') {
         if (ch == 'H') {
@@ -925,6 +927,7 @@ reexecute:
         if (ch == CR || ch == LF)
         if (ch == CR || ch == LF)
           break;
           break;
         parser->flags = 0;
         parser->flags = 0;
+        parser->extra_flags = 0;
         parser->content_length = ULLONG_MAX;
         parser->content_length = ULLONG_MAX;
 
 
         if (UNLIKELY(!IS_ALPHA(ch))) {
         if (UNLIKELY(!IS_ALPHA(ch))) {
@@ -1338,7 +1341,7 @@ reexecute:
                 parser->header_state = h_general;
                 parser->header_state = h_general;
               } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
               } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
                 parser->header_state = h_transfer_encoding;
                 parser->header_state = h_transfer_encoding;
-                parser->flags |= F_TRANSFER_ENCODING;
+                parser->extra_flags |= F_TRANSFER_ENCODING >> 8;
               }
               }
               break;
               break;
 
 
@@ -1800,7 +1803,7 @@ reexecute:
 
 
         /* Cannot us transfer-encoding and a content-length header together
         /* Cannot us transfer-encoding and a content-length header together
            per the HTTP specification. (RFC 7230 Section 3.3.3) */
            per the HTTP specification. (RFC 7230 Section 3.3.3) */
-        if ((parser->flags & F_TRANSFER_ENCODING) &&
+        if ((parser->extra_flags & (F_TRANSFER_ENCODING >> 8)) &&
             (parser->flags & F_CONTENTLENGTH)) {
             (parser->flags & F_CONTENTLENGTH)) {
           /* Allow it for lenient parsing as long as `Transfer-Encoding` is
           /* Allow it for lenient parsing as long as `Transfer-Encoding` is
            * not `chunked`
            * not `chunked`
@@ -1886,7 +1889,7 @@ reexecute:
           /* chunked encoding - ignore Content-Length header,
           /* chunked encoding - ignore Content-Length header,
            * prepare for a chunk */
            * prepare for a chunk */
           UPDATE_STATE(s_chunk_size_start);
           UPDATE_STATE(s_chunk_size_start);
-        } else if (parser->flags & F_TRANSFER_ENCODING) {
+        } else if (parser->extra_flags & (F_TRANSFER_ENCODING >> 8)) {
           if (parser->type == HTTP_REQUEST && !lenient) {
           if (parser->type == HTTP_REQUEST && !lenient) {
             /* RFC 7230 3.3.3 */
             /* RFC 7230 3.3.3 */
 
 
@@ -2162,7 +2165,7 @@ http_message_needs_eof (const http_parser *parser)
   }
   }
 
 
   /* RFC 7230 3.3.3, see `s_headers_almost_done` */
   /* RFC 7230 3.3.3, see `s_headers_almost_done` */
-  if ((parser->flags & F_TRANSFER_ENCODING) &&
+  if ((parser->extra_flags & (F_TRANSFER_ENCODING >> 8)) &&
       (parser->flags & F_CHUNKED) == 0) {
       (parser->flags & F_CHUNKED) == 0) {
     return 1;
     return 1;
   }
   }

+ 8 - 7
http_parser.h

@@ -27,7 +27,7 @@ extern "C" {
 /* Also update SONAME in the Makefile whenever you change these. */
 /* Also update SONAME in the Makefile whenever you change these. */
 #define HTTP_PARSER_VERSION_MAJOR 2
 #define HTTP_PARSER_VERSION_MAJOR 2
 #define HTTP_PARSER_VERSION_MINOR 9
 #define HTTP_PARSER_VERSION_MINOR 9
-#define HTTP_PARSER_VERSION_PATCH 3
+#define HTTP_PARSER_VERSION_PATCH 4
 
 
 #include <stddef.h>
 #include <stddef.h>
 #if defined(_WIN32) && !defined(__MINGW32__) && \
 #if defined(_WIN32) && !defined(__MINGW32__) && \
@@ -225,7 +225,7 @@ enum flags
   , F_UPGRADE               = 1 << 5
   , F_UPGRADE               = 1 << 5
   , F_SKIPBODY              = 1 << 6
   , F_SKIPBODY              = 1 << 6
   , F_CONTENTLENGTH         = 1 << 7
   , F_CONTENTLENGTH         = 1 << 7
-  , F_TRANSFER_ENCODING     = 1 << 8
+  , F_TRANSFER_ENCODING     = 1 << 8  /* Never set in http_parser.flags */
   };
   };
 
 
 
 
@@ -272,13 +272,13 @@ enum flags
      "unexpected content-length header")                             \
      "unexpected content-length header")                             \
   XX(INVALID_CHUNK_SIZE,                                             \
   XX(INVALID_CHUNK_SIZE,                                             \
      "invalid character in chunk size header")                       \
      "invalid character in chunk size header")                       \
-  XX(INVALID_TRANSFER_ENCODING,                                      \
-     "request has invalid transfer-encoding")                        \
   XX(INVALID_CONSTANT, "invalid constant string")                    \
   XX(INVALID_CONSTANT, "invalid constant string")                    \
   XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
   XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
   XX(STRICT, "strict mode assertion failed")                         \
   XX(STRICT, "strict mode assertion failed")                         \
   XX(PAUSED, "parser is paused")                                     \
   XX(PAUSED, "parser is paused")                                     \
-  XX(UNKNOWN, "an unknown error occurred")
+  XX(UNKNOWN, "an unknown error occurred")                           \
+  XX(INVALID_TRANSFER_ENCODING,                                      \
+     "request has invalid transfer-encoding")                        \
 
 
 
 
 /* Define HPE_* values for each errno value above */
 /* Define HPE_* values for each errno value above */
@@ -296,11 +296,12 @@ enum http_errno {
 struct http_parser {
 struct http_parser {
   /** PRIVATE **/
   /** PRIVATE **/
   unsigned int type : 2;         /* enum http_parser_type */
   unsigned int type : 2;         /* enum http_parser_type */
+  unsigned int flags : 8;       /* F_* values from 'flags' enum; semi-public */
   unsigned int state : 7;        /* enum state from http_parser.c */
   unsigned int state : 7;        /* enum state from http_parser.c */
   unsigned int header_state : 7; /* enum header_state from http_parser.c */
   unsigned int header_state : 7; /* enum header_state from http_parser.c */
-  unsigned int index : 7;        /* index into current matcher */
+  unsigned int index : 5;        /* index into current matcher */
+  unsigned int extra_flags : 2;
   unsigned int lenient_http_headers : 1;
   unsigned int lenient_http_headers : 1;
-  unsigned int flags : 16;       /* F_* values from 'flags' enum; semi-public */
 
 
   uint32_t nread;          /* # bytes read in various scenarios */
   uint32_t nread;          /* # bytes read in various scenarios */
   uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
   uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */

+ 3 - 2
test.c

@@ -1219,8 +1219,8 @@ const struct message requests[] =
   ,.chunk_lengths= { 0x1e }
   ,.chunk_lengths= { 0x1e }
   }
   }
 
 
-#define POST_MULTI_LINE_TE_LAST_CHUNKED 43
-, {.name= "post - multi coding transfer-encoding chunked body"
+#define POST_MULTI_LINE_TE_LAST_CHUNKED 44
+, {.name= "post - multi line coding transfer-encoding chunked body"
   ,.type= HTTP_REQUEST
   ,.type= HTTP_REQUEST
   ,.raw= "POST / HTTP/1.1\r\n"
   ,.raw= "POST / HTTP/1.1\r\n"
          "Transfer-Encoding: deflate,\r\n"
          "Transfer-Encoding: deflate,\r\n"
@@ -4221,6 +4221,7 @@ main (void)
   printf("http_parser v%u.%u.%u (0x%06lx)\n", major, minor, patch, version);
   printf("http_parser v%u.%u.%u (0x%06lx)\n", major, minor, patch, version);
 
 
   printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser));
   printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser));
+  assert(sizeof(http_parser) == 4 + 4 + 8 + 2 + 2 + 4 + sizeof(void *));
 
 
   //// API
   //// API
   test_preserve_data();
   test_preserve_data();