Skip to content

Commit 6b0e4a4

Browse files
committed
Fix #2552 - reject requests with invalid/absent chunk length
1 parent f883504 commit 6b0e4a4

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

mongoose.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3159,6 +3159,7 @@ static int skip_chunk(const char *buf, int len, int *pl, int *dl) {
31593159
int i = 0, n = 0;
31603160
if (len < 3) return 0;
31613161
while (i < len && is_hex_digit(buf[i])) i++;
3162+
if (i == 0) return -1; // Error, no length specified
31623163
if (i > (int) sizeof(int) * 2) return -1; // Chunk length is too big
31633164
if (len < i + 1 || buf[i] != '\r' || buf[i + 1] != '\n') return -1; // Error
31643165
n = (int) mg_unhexn(buf, (size_t) i); // Decode chunk length

src/http.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#include "http.h"
21
#include "arch.h"
32
#include "base64.h"
43
#include "fmt.h"
4+
#include "http.h"
55
#include "json.h"
66
#include "log.h"
77
#include "net.h"
@@ -962,6 +962,7 @@ static int skip_chunk(const char *buf, int len, int *pl, int *dl) {
962962
int i = 0, n = 0;
963963
if (len < 3) return 0;
964964
while (i < len && is_hex_digit(buf[i])) i++;
965+
if (i == 0) return -1; // Error, no length specified
965966
if (i > (int) sizeof(int) * 2) return -1; // Chunk length is too big
966967
if (len < i + 1 || buf[i] != '\r' || buf[i + 1] != '\n') return -1; // Error
967968
n = (int) mg_unhexn(buf, (size_t) i); // Decode chunk length

test/unit_test.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,22 @@ static void test_http_server(void) {
11611161
}
11621162
#endif
11631163

1164+
// #2552, reject chunks with no length
1165+
ASSERT(fetch(&mgr, buf, url,
1166+
"POST / HTTP/1.1\r\n"
1167+
"Transfer-Encoding: chunked\r\n\r\n"
1168+
"1\r\n"
1169+
"Z\r\n"
1170+
"?\r\n"
1171+
"\r\n") == 0);
1172+
ASSERT(fetch(&mgr, buf, url,
1173+
"POST / HTTP/1.1\r\n"
1174+
"Transfer-Encoding: chunked\r\n\r\n"
1175+
"1\r\n"
1176+
"Z\r\n"
1177+
"\r\n"
1178+
"\r\n") == 0);
1179+
11641180
mg_mgr_free(&mgr);
11651181
ASSERT(mgr.conns == NULL);
11661182
}
@@ -1605,11 +1621,11 @@ static void test_http_parse(void) {
16051621
ASSERT(mg_http_parse(s, strlen(s), &hm) == (int) strlen(s));
16061622
s = "a\nb:b\nc:c\n\n";
16071623
ASSERT(mg_http_parse(s, strlen(s), &hm) < 0);
1608-
s = "a b\nc: \xc0\n\n"; // Invalid UTF in the header value: accept
1624+
s = "a b\nc: \xc0\n\n"; // Invalid UTF in the header value: accept
16091625
ASSERT(mg_http_parse(s, strlen(s), &hm) == (int) strlen(s));
16101626
ASSERT((v = mg_http_get_header(&hm, "c")) != NULL);
16111627
ASSERT(mg_vcmp(v, "\xc0") == 0);
1612-
s = "a b\n\xc0: 2\n\n"; // Invalid UTF in the header name: do NOT accept
1628+
s = "a b\n\xc0: 2\n\n"; // Invalid UTF in the header name: do NOT accept
16131629
ASSERT(mg_http_parse(s, strlen(s), &hm) == -1);
16141630
}
16151631
}

0 commit comments

Comments
 (0)