Skip to content

Commit

Permalink
Merge pull request #2343 from cesanta/fuz
Browse files Browse the repository at this point in the history
Add http serve to fuzzer
  • Loading branch information
cpq authored Aug 16, 2023
2 parents 54be13d + ea39686 commit 66e022c
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 16 deletions.
17 changes: 9 additions & 8 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -1976,15 +1976,17 @@ static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm,
int flags, tmp;
// Append URI to the root_dir, and sanitize it
size_t n = mg_snprintf(path, path_size, "%.*s", (int) dir.len, dir.ptr);
if (n > path_size) {
if (n + 2 >= path_size) {
mg_http_reply(c, 400, "", "Exceeded path size");
return -1;
}
path[path_size - 1] = '\0';
// Terminate root dir with /
if (n + 2 < path_size && path[n - 1] != '/') path[n++] = '/', path[n] = '\0';
mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n,
path_size - n, 0);
// Terminate root dir with slash
if (n > 0 && path[n - 1] != '/') path[n++] = '/', path[n] = '\0';
if (url.len < hm->uri.len) {
mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n,
path_size - n, 0);
}
path[path_size - 1] = '\0'; // Double-check
if (!mg_path_is_sane(path)) {
mg_http_reply(c, 400, "", "Invalid path");
Expand Down Expand Up @@ -2033,7 +2035,7 @@ static int uri_to_path(struct mg_connection *c, struct mg_http_message *hm,
struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
struct mg_str k, v, s = mg_str(opts->root_dir), u = {0, 0}, p = {0, 0};
while (mg_commalist(&s, &k, &v)) {
if (v.len == 0) v = k, k = mg_str("/");
if (v.len == 0) v = k, k = mg_str("/"), u = k, p = v;
if (hm->uri.len < k.len) continue;
if (mg_strcmp(k, mg_str_n(hm->uri.ptr, k.len)) != 0) continue;
u = k, p = v;
Expand Down Expand Up @@ -2274,7 +2276,6 @@ static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
if (ev == MG_EV_READ || ev == MG_EV_CLOSE) {
struct mg_http_message hm;
// mg_hexdump(c->recv.buf, c->recv.len);
while (c->recv.buf != NULL && c->recv.len > 0) {
bool next = false;
int hlen = mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
Expand Down Expand Up @@ -8906,7 +8907,7 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
rx_ip(ifp, &pkt);
} else {
MG_DEBUG(("Unknown eth type %x", mg_htons(pkt.eth->type)));
mg_hexdump(buf, len >= 32 ? 32 : len);
//mg_hexdump(buf, len >= 32 ? 32 : len);
}
}

Expand Down
15 changes: 8 additions & 7 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -744,15 +744,17 @@ static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm,
int flags, tmp;
// Append URI to the root_dir, and sanitize it
size_t n = mg_snprintf(path, path_size, "%.*s", (int) dir.len, dir.ptr);
if (n > path_size) {
if (n + 2 >= path_size) {
mg_http_reply(c, 400, "", "Exceeded path size");
return -1;
}
path[path_size - 1] = '\0';
// Terminate root dir with /
if (n + 2 < path_size && path[n - 1] != '/') path[n++] = '/', path[n] = '\0';
mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n,
path_size - n, 0);
// Terminate root dir with slash
if (n > 0 && path[n - 1] != '/') path[n++] = '/', path[n] = '\0';
if (url.len < hm->uri.len) {
mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n,
path_size - n, 0);
}
path[path_size - 1] = '\0'; // Double-check
if (!mg_path_is_sane(path)) {
mg_http_reply(c, 400, "", "Invalid path");
Expand Down Expand Up @@ -801,7 +803,7 @@ static int uri_to_path(struct mg_connection *c, struct mg_http_message *hm,
struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
struct mg_str k, v, s = mg_str(opts->root_dir), u = {0, 0}, p = {0, 0};
while (mg_commalist(&s, &k, &v)) {
if (v.len == 0) v = k, k = mg_str("/");
if (v.len == 0) v = k, k = mg_str("/"), u = k, p = v;
if (hm->uri.len < k.len) continue;
if (mg_strcmp(k, mg_str_n(hm->uri.ptr, k.len)) != 0) continue;
u = k, p = v;
Expand Down Expand Up @@ -1042,7 +1044,6 @@ static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
if (ev == MG_EV_READ || ev == MG_EV_CLOSE) {
struct mg_http_message hm;
// mg_hexdump(c->recv.buf, c->recv.len);
while (c->recv.buf != NULL && c->recv.len > 0) {
bool next = false;
int hlen = mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
Expand Down
2 changes: 1 addition & 1 deletion src/tcpip/tcpip.c
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
rx_ip(ifp, &pkt);
} else {
MG_DEBUG(("Unknown eth type %x", mg_htons(pkt.eth->type)));
mg_hexdump(buf, len >= 32 ? 32 : len);
//mg_hexdump(buf, len >= 32 ? 32 : len);
}
}

Expand Down
15 changes: 15 additions & 0 deletions test/fuzz.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *, size_t);
int LLVMFuzzerTestOneInput(const uint8_t *, size_t);
#endif

static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
struct mg_http_serve_opts opts = {.root_dir = "."};
if (ev == MG_EV_HTTP_MSG) {
mg_http_serve_dir(c, (struct mg_http_message *) ev_data, &opts);
}
(void) fn_data;
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
mg_log_set(MG_LL_NONE);

Expand Down Expand Up @@ -96,6 +104,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}

mg_tcpip_rx(&mif, pkt, size);

// Test HTTP serving
const char *url = "http://localhost:12345";
struct mg_connection *c = mg_http_connect(&mgr, url, fn, NULL);
mg_iobuf_add(&c->recv, 0, data, size);
c->pfn(c, MG_EV_READ, NULL, NULL);

mg_mgr_free(&mgr);
free(pkt);
mg_tcpip_free(&mif);
Expand Down
5 changes: 5 additions & 0 deletions test/unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,21 +134,26 @@ static void test_commalist(void) {
struct mg_str s4 = mg_str("a=123"), s5 = mg_str("a,b=123");
ASSERT(mg_commalist(&s1, &k, &v) == false);

v.len = k.len = 42;
ASSERT(mg_commalist(&s2, &k, &v) == true);
ASSERT(v.len == 0 && mg_vcmp(&k, "a") == 0);
ASSERT(mg_commalist(&s2, &k, &v) == false);

v.len = k.len = 42;
ASSERT(mg_commalist(&s3, &k, &v) == true);
ASSERT(v.len == 0 && mg_vcmp(&k, "a") == 0);
v.len = k.len = 42;
ASSERT(mg_commalist(&s3, &k, &v) == true);
ASSERT(v.len == 0 && mg_vcmp(&k, "b") == 0);
ASSERT(mg_commalist(&s3, &k, &v) == false);

v.len = k.len = 42;
ASSERT(mg_commalist(&s4, &k, &v) == true);
ASSERT(mg_vcmp(&k, "a") == 0 && mg_vcmp(&v, "123") == 0);
ASSERT(mg_commalist(&s4, &k, &v) == false);
ASSERT(mg_commalist(&s4, &k, &v) == false);

v.len = k.len = 42;
ASSERT(mg_commalist(&s5, &k, &v) == true);
ASSERT(v.len == 0 && mg_vcmp(&k, "a") == 0);
ASSERT(mg_commalist(&s5, &k, &v) == true);
Expand Down

0 comments on commit 66e022c

Please sign in to comment.