mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-16 08:24:42 +00:00
BUG/MEDIUM: h1: Really skip all updates when incomplete messages are parsed
In h1_headers_to_hdr_list, when an incomplete message is parsed, all updates must be skipped until the end of the message is found. Then the parsing is restarted from the beginning. But not all updates were skipped, leading to invalid rewritting or segfault. No backport is needed.
This commit is contained in:
parent
f147479bd5
commit
2912f87443
89
src/h1.c
89
src/h1.c
@ -1240,9 +1240,11 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
|
||||
http_msg_hdr_name:
|
||||
/* assumes sol points to the first char */
|
||||
if (likely(HTTP_IS_TOKEN(*ptr))) {
|
||||
/* turn it to lower case if needed */
|
||||
if (isupper((unsigned char)*ptr) && h1m->flags & H1_MF_TOLOWER)
|
||||
*ptr = tolower(*ptr);
|
||||
if (!skip_update) {
|
||||
/* turn it to lower case if needed */
|
||||
if (isupper((unsigned char)*ptr) && h1m->flags & H1_MF_TOLOWER)
|
||||
*ptr = tolower(*ptr);
|
||||
}
|
||||
EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_hdr_name, http_msg_ood, state, H1_MSG_HDR_NAME);
|
||||
}
|
||||
|
||||
@ -1287,9 +1289,11 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
|
||||
case H1_MSG_HDR_L1_LWS:
|
||||
http_msg_hdr_l1_lws:
|
||||
if (likely(HTTP_IS_SPHT(*ptr))) {
|
||||
/* replace HT,CR,LF with spaces */
|
||||
for (; start + sov < ptr; sov++)
|
||||
start[sov] = ' ';
|
||||
if (!skip_update) {
|
||||
/* replace HT,CR,LF with spaces */
|
||||
for (; start + sov < ptr; sov++)
|
||||
start[sov] = ' ';
|
||||
}
|
||||
goto http_msg_hdr_l1_sp;
|
||||
}
|
||||
/* we had a header consisting only in spaces ! */
|
||||
@ -1348,9 +1352,11 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
|
||||
case H1_MSG_HDR_L2_LWS:
|
||||
http_msg_hdr_l2_lws:
|
||||
if (unlikely(HTTP_IS_SPHT(*ptr))) {
|
||||
/* LWS: replace HT,CR,LF with spaces */
|
||||
for (; start + eol < ptr; eol++)
|
||||
start[eol] = ' ';
|
||||
if (!skip_update) {
|
||||
/* LWS: replace HT,CR,LF with spaces */
|
||||
for (; start + eol < ptr; eol++)
|
||||
start[eol] = ' ';
|
||||
}
|
||||
goto http_msg_hdr_val;
|
||||
}
|
||||
http_msg_complete_header:
|
||||
@ -1363,47 +1369,50 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
|
||||
* adjusting <eol> and <sov> which are no more used after this.
|
||||
* We can add the header field to the list.
|
||||
*/
|
||||
while (sov < eol && HTTP_IS_LWS(start[sov]))
|
||||
sov++;
|
||||
if (likely(!skip_update)) {
|
||||
while (sov < eol && HTTP_IS_LWS(start[sov]))
|
||||
sov++;
|
||||
|
||||
while (eol - 1 > sov && HTTP_IS_LWS(start[eol - 1]))
|
||||
eol--;
|
||||
while (eol - 1 > sov && HTTP_IS_LWS(start[eol - 1]))
|
||||
eol--;
|
||||
|
||||
|
||||
n = ist2(start + sol, col - sol);
|
||||
v = ist2(start + sov, eol - sov);
|
||||
n = ist2(start + sol, col - sol);
|
||||
v = ist2(start + sov, eol - sov);
|
||||
|
||||
if (likely(!skip_update)) do {
|
||||
int ret;
|
||||
do {
|
||||
int ret;
|
||||
|
||||
if (unlikely(hdr_count >= hdr_num)) {
|
||||
state = H1_MSG_HDR_L2_LWS;
|
||||
goto http_output_full;
|
||||
}
|
||||
|
||||
if (isteqi(n, ist("transfer-encoding"))) {
|
||||
h1_parse_xfer_enc_header(h1m, v);
|
||||
}
|
||||
else if (isteqi(n, ist("content-length"))) {
|
||||
ret = h1_parse_cont_len_header(h1m, &v);
|
||||
|
||||
if (ret < 0) {
|
||||
if (unlikely(hdr_count >= hdr_num)) {
|
||||
state = H1_MSG_HDR_L2_LWS;
|
||||
goto http_msg_invalid;
|
||||
goto http_output_full;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
/* skip it */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (isteqi(n, ist("connection"))) {
|
||||
h1_parse_connection_header(h1m, v);
|
||||
}
|
||||
|
||||
http_set_hdr(&hdr[hdr_count++], n, v);
|
||||
} while (0);
|
||||
if (isteqi(n, ist("transfer-encoding"))) {
|
||||
h1_parse_xfer_enc_header(h1m, v);
|
||||
}
|
||||
else if (isteqi(n, ist("content-length"))) {
|
||||
ret = h1_parse_cont_len_header(h1m, &v);
|
||||
|
||||
if (ret < 0) {
|
||||
state = H1_MSG_HDR_L2_LWS;
|
||||
goto http_msg_invalid;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
/* skip it */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (isteqi(n, ist("connection"))) {
|
||||
h1_parse_connection_header(h1m, v);
|
||||
}
|
||||
|
||||
http_set_hdr(&hdr[hdr_count++], n, v);
|
||||
} while (0);
|
||||
}
|
||||
|
||||
sol = ptr - start;
|
||||
|
||||
if (likely(!HTTP_IS_CRLF(*ptr)))
|
||||
goto http_msg_hdr_name;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user