mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-24 06:22:44 +00:00
BUG/MINOR: h1: the HTTP/1 make status code parser check for digits
The H1 parser used by the H2 gateway was a bit lax and could validate non-numbers in the status code. Since it computes the code on the fly it's problematic, as "30:" is read as status code 310. Let's properly check that it's a number now. No backport needed.
This commit is contained in:
parent
ddfbd83780
commit
1b4cf9b754
@ -52,6 +52,7 @@ int h1_measure_trailers(const struct buffer *buf);
|
|||||||
#define H1_FLG_CRLF 0x10
|
#define H1_FLG_CRLF 0x10
|
||||||
#define H1_FLG_TOK 0x20
|
#define H1_FLG_TOK 0x20
|
||||||
#define H1_FLG_VER 0x40
|
#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_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)
|
#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_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_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_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
|
/* Macros used in the HTTP/1 parser, to check for the expected presence of
|
||||||
|
27
src/h1.c
27
src/h1.c
@ -75,16 +75,16 @@ const unsigned char h1_char_classes[256] = {
|
|||||||
['-'] = H1_FLG_TOK,
|
['-'] = H1_FLG_TOK,
|
||||||
['.'] = H1_FLG_TOK | H1_FLG_VER,
|
['.'] = H1_FLG_TOK | H1_FLG_VER,
|
||||||
['/'] = H1_FLG_SEP | H1_FLG_VER,
|
['/'] = H1_FLG_SEP | H1_FLG_VER,
|
||||||
['0'] = H1_FLG_TOK | H1_FLG_VER,
|
['0'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['1'] = H1_FLG_TOK | H1_FLG_VER,
|
['1'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['2'] = H1_FLG_TOK | H1_FLG_VER,
|
['2'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['3'] = H1_FLG_TOK | H1_FLG_VER,
|
['3'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['4'] = H1_FLG_TOK | H1_FLG_VER,
|
['4'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['5'] = H1_FLG_TOK | H1_FLG_VER,
|
['5'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['6'] = H1_FLG_TOK | H1_FLG_VER,
|
['6'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['7'] = H1_FLG_TOK | H1_FLG_VER,
|
['7'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['8'] = H1_FLG_TOK | H1_FLG_VER,
|
['8'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
['9'] = H1_FLG_TOK | H1_FLG_VER,
|
['9'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG,
|
||||||
[':'] = H1_FLG_SEP,
|
[':'] = H1_FLG_SEP,
|
||||||
[';'] = H1_FLG_SEP,
|
[';'] = 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:
|
case HTTP_MSG_RPCODE:
|
||||||
http_msg_rpcode:
|
http_msg_rpcode:
|
||||||
if (likely(!HTTP_IS_LWS(*ptr))) {
|
if (likely(HTTP_IS_DIGIT(*ptr))) {
|
||||||
code = code * 10 + *ptr - '0';
|
code = code * 10 + *ptr - '0';
|
||||||
EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_rpcode, http_msg_ood, state, HTTP_MSG_RPCODE);
|
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))) {
|
if (likely(HTTP_IS_SPHT(*ptr))) {
|
||||||
st_c_l = ptr - start - st_c;
|
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);
|
EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_rpcode_sp, http_msg_ood, state, HTTP_MSG_RPCODE_SP);
|
||||||
|
Loading…
Reference in New Issue
Block a user