diff --git a/include/proto/h1.h b/include/proto/h1.h index 4463ad069..ef405c49f 100644 --- a/include/proto/h1.h +++ b/include/proto/h1.h @@ -52,6 +52,7 @@ int h1_measure_trailers(const struct buffer *buf); #define H1_FLG_CRLF 0x10 #define H1_FLG_TOK 0x20 #define H1_FLG_VER 0x40 +#define H1_FLG_DIG 0x80 #define HTTP_IS_CTL(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_CTL) #define HTTP_IS_SEP(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_SEP) @@ -60,6 +61,7 @@ int h1_measure_trailers(const struct buffer *buf); #define HTTP_IS_CRLF(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_CRLF) #define HTTP_IS_TOKEN(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_TOK) #define HTTP_IS_VER_TOKEN(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_VER) +#define HTTP_IS_DIGIT(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_DIG) /* Macros used in the HTTP/1 parser, to check for the expected presence of diff --git a/src/h1.c b/src/h1.c index f4d77e38d..d3a20c2ed 100644 --- a/src/h1.c +++ b/src/h1.c @@ -75,16 +75,16 @@ const unsigned char h1_char_classes[256] = { ['-'] = H1_FLG_TOK, ['.'] = H1_FLG_TOK | H1_FLG_VER, ['/'] = H1_FLG_SEP | H1_FLG_VER, - ['0'] = H1_FLG_TOK | H1_FLG_VER, - ['1'] = H1_FLG_TOK | H1_FLG_VER, - ['2'] = H1_FLG_TOK | H1_FLG_VER, - ['3'] = H1_FLG_TOK | H1_FLG_VER, - ['4'] = H1_FLG_TOK | H1_FLG_VER, - ['5'] = H1_FLG_TOK | H1_FLG_VER, - ['6'] = H1_FLG_TOK | H1_FLG_VER, - ['7'] = H1_FLG_TOK | H1_FLG_VER, - ['8'] = H1_FLG_TOK | H1_FLG_VER, - ['9'] = H1_FLG_TOK | H1_FLG_VER, + ['0'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['1'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['2'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['3'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['4'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['5'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['6'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['7'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['8'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, + ['9'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, [':'] = H1_FLG_SEP, [';'] = H1_FLG_SEP, ['<'] = H1_FLG_SEP, @@ -909,11 +909,16 @@ int h1_headers_to_hdr_list(char *start, const char *stop, case HTTP_MSG_RPCODE: http_msg_rpcode: - if (likely(!HTTP_IS_LWS(*ptr))) { + if (likely(HTTP_IS_DIGIT(*ptr))) { code = code * 10 + *ptr - '0'; EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_rpcode, http_msg_ood, state, HTTP_MSG_RPCODE); } + if (unlikely(!HTTP_IS_LWS(*ptr))) { + state = HTTP_MSG_RPCODE; + goto http_msg_invalid; + } + if (likely(HTTP_IS_SPHT(*ptr))) { st_c_l = ptr - start - st_c; EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_rpcode_sp, http_msg_ood, state, HTTP_MSG_RPCODE_SP);