Skip to content

Commit

Permalink
Fix #768: 1. Replace 'int' with 'long' for chunks size. 2. Add check …
Browse files Browse the repository at this point in the history
…for 'signed long' overflow.
  • Loading branch information
aleksostapenko committed Aug 24, 2017
1 parent 9df1d21 commit ddf4fd5
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
4 changes: 2 additions & 2 deletions tempesta_fw/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,12 @@ typedef struct {
typedef struct {
unsigned short to_go;
unsigned short _cnt;
unsigned int _hdr_tag;
int state;
int _i_st;
int to_read;
long to_read;
unsigned long _acc;
time_t _date;
unsigned int _hdr_tag;
TfwStr _tmp_chunk;
TfwStr hdr;
TfwHttpHbhHdrs hbh_parser;
Expand Down
13 changes: 7 additions & 6 deletions tempesta_fw/http_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,13 +483,14 @@ parse_int_hex(unsigned char *data, size_t len, unsigned long *acc, unsigned shor
unsigned char *p;

for (p = data; p - data < len; ++p) {
if (unlikely(IS_CRLF(*p) || (*p == ';')))
if (unlikely(IS_CRLF(*p) || (*p == ';'))) {
if (unlikely(*acc > LONG_MAX))
return CSTR_BADLEN;
return p - data;
}
if (unlikely(!isxdigit(*p)))
return CSTR_NEQ;
if (unlikely(*acc > (UINT_MAX - 16) / 16))
return CSTR_BADLEN;
if (unlikely(*cnt >= (sizeof(int) * 2)))
if (unlikely(*cnt >= (sizeof(long) * 2)))
return CSTR_BADLEN;
*acc = (*acc << 4) + (*p & 0xf) + (*p >> 6) * 9;
++*cnt;
Expand Down Expand Up @@ -995,7 +996,7 @@ __FSM_STATE(RGen_BodyStart) { \
/* Fall through. */ \
} \
__FSM_STATE(RGen_BodyChunk) { \
TFW_DBG3("read body: to_read=%d\n", parser->to_read); \
TFW_DBG3("read body: to_read=%ld\n", parser->to_read); \
if (parser->to_read == -1) { \
/* Prevent @parse_int_hex false positives. */ \
if (!isxdigit(c)) \
Expand All @@ -1006,7 +1007,7 @@ __FSM_STATE(RGen_BodyChunk) { \
} \
__FSM_STATE(RGen_BodyReadChunk) { \
BUG_ON(parser->to_read < 0); \
__fsm_sz = min_t(int, parser->to_read, __data_remain(p)); \
__fsm_sz = min_t(long, parser->to_read, __data_remain(p)); \
parser->to_read -= __fsm_sz; \
if (parser->to_read) \
__FSM_MOVE_nf(RGen_BodyReadChunk, __fsm_sz, &msg->body); \
Expand Down
15 changes: 12 additions & 3 deletions tempesta_fw/t/unit/test_http_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,7 @@ TEST(http_parser, chunk_size)
"Host:\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"000000007\r\n"
"00000000000000007\r\n"
"abcdefg\r\n"
"0\n"
"\r\n");
Expand All @@ -1142,14 +1142,23 @@ TEST(http_parser, chunk_size)
"\r\n"
"7\r\n"
"abcdefg\r\n"
"000000000\r\n"
"00000000000000000\r\n"
"\r\n");

EXPECT_BLOCK_REQ("POST / HTTP/1.1\r\n"
"Host:\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"8000000000000000\r\n"
"abcdefg\r\n"
"0\r\n"
"\r\n");

FOR_REQ("POST / HTTP/1.1\r\n"
"Host:\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"00000007\r\n"
"0000000000000007\r\n"
"abcdefg\r\n"
"0\r\n"
"\r\n");
Expand Down

0 comments on commit ddf4fd5

Please sign in to comment.