diff --git a/include/haproxy/h1.h b/include/haproxy/h1.h index 3c085801b..858db7d02 100644 --- a/include/haproxy/h1.h +++ b/include/haproxy/h1.h @@ -244,12 +244,12 @@ static inline int h1_skip_chunk_crlf(const struct buffer *buf, int start, int st * start of the body and the start of the data. Note: this function is designed * to parse wrapped CRLF at the end of the buffer. */ -static inline int h1_parse_chunk_size(const struct buffer *buf, int start, int stop, unsigned int *res) +static inline int h1_parse_chunk_size(const struct buffer *buf, int start, int stop, uint64_t *res) { const char *ptr = b_peek(buf, start); const char *ptr_old = ptr; const char *end = b_wrap(buf); - unsigned int chunk = 0; + uint64_t chunk = 0; stop -= start; // bytes left start = stop; // bytes to transfer @@ -267,9 +267,13 @@ static inline int h1_parse_chunk_size(const struct buffer *buf, int start, int s break; if (unlikely(++ptr >= end)) ptr = b_orig(buf); - if (unlikely(chunk & 0xF8000000)) /* integer overflow will occur if result >= 2GB */ - goto error; chunk = (chunk << 4) + c; + if (unlikely(chunk & 0xF0000000000000)) { + /* Don't get more than 13 hexa-digit (2^52 - 1) to never fed possibly + * bogus values from languages that use floats for their integers + */ + goto error; + } stop--; } diff --git a/src/h1_htx.c b/src/h1_htx.c index e11db04f2..1a1c89732 100644 --- a/src/h1_htx.c +++ b/src/h1_htx.c @@ -477,7 +477,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx **dsthtx, total += ret; } if (h1m->state == H1_MSG_CHUNK_SIZE) { - unsigned int chksz; + uint64_t chksz; ret = h1_parse_chunk_size(srcbuf, ofs, b_data(srcbuf), &chksz); if (ret <= 0)