diff --git a/mongoose.c b/mongoose.c index 440feb28..fb252310 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1021,11 +1021,13 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm, if (!mg_is_dir(root)) { mg_http_reply(c, 400, "", "Bad web root [%s]\n", root); } else { + char dec[PATH_MAX]; // NOTE(lsm): Xilinx snprintf does not 0-terminate the detination for // the %.*s specifier, if the length is zero. Make sure hm->uri.len > 0 bool is_index = false; - size_t n = snprintf(path, sizeof(path), "%s%.*s", root, (int) hm->uri.len, - hm->uri.ptr); + int ndec = mg_url_decode(hm->uri.ptr, hm->uri.len, dec, sizeof(dec), 0); + size_t n = + snprintf(path, sizeof(path), "%s%.*s", root, ndec < 0 ? 0 : ndec, dec); while (n > 0 && n < sizeof(path) && path[n - 1] == '/') path[--n] = 0; if (realpath(path, real) == NULL) LOG(LL_DEBUG, ("realpath(%s): %d", path, errno)); diff --git a/src/http.c b/src/http.c index 9870a577..c09b4f8f 100644 --- a/src/http.c +++ b/src/http.c @@ -606,11 +606,13 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm, if (!mg_is_dir(root)) { mg_http_reply(c, 400, "", "Bad web root [%s]\n", root); } else { + char dec[PATH_MAX]; // NOTE(lsm): Xilinx snprintf does not 0-terminate the detination for // the %.*s specifier, if the length is zero. Make sure hm->uri.len > 0 bool is_index = false; - size_t n = snprintf(path, sizeof(path), "%s%.*s", root, (int) hm->uri.len, - hm->uri.ptr); + int ndec = mg_url_decode(hm->uri.ptr, hm->uri.len, dec, sizeof(dec), 0); + size_t n = + snprintf(path, sizeof(path), "%s%.*s", root, ndec < 0 ? 0 : ndec, dec); while (n > 0 && n < sizeof(path) && path[n - 1] == '/') path[--n] = 0; if (realpath(path, real) == NULL) LOG(LL_DEBUG, ("realpath(%s): %d", path, errno)); diff --git a/test/unit_test.c b/test/unit_test.c index aab6becb..e3136d63 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -459,6 +459,9 @@ static void test_http_server(void) { ASSERT(fetch(&mgr, buf, url, "GET /a.txt HTTP/1.0\n\n") == 200); ASSERT(cmpbody(buf, "hello\n") == 0); + ASSERT(fetch(&mgr, buf, url, "GET /%%61.txt HTTP/1.0\n\n") == 200); + ASSERT(cmpbody(buf, "hello\n") == 0); + { extern char *mg_http_etag(char *, size_t, struct stat *); char etag[100];