diff --git a/examples/file-transfer/server.c b/examples/file-transfer/server.c index 031b585b9b..96746d9964 100644 --- a/examples/file-transfer/server.c +++ b/examples/file-transfer/server.c @@ -59,7 +59,7 @@ static void handle_uploads(struct mg_connection *c, int ev, void *ev_data) { char fpath[MG_PATH_MAX]; snprintf(fpath, MG_PATH_MAX, "%s%c", s_upld_dir, MG_DIRSEP); strncat(fpath, hm->uri.buf + 8, hm->uri.len - 8); - if (!mg_path_is_sane(fpath)) { + if (!mg_path_is_sane(mg_str(fpath))) { mg_http_reply(c, 400, "", "Invalid path\n"); c->is_draining = 1; // Tell mongoose to close this connection } else { diff --git a/examples/file-upload-single-post/main.c b/examples/file-upload-single-post/main.c index cbf44ba338..86d4c1d4b8 100644 --- a/examples/file-upload-single-post/main.c +++ b/examples/file-upload-single-post/main.c @@ -32,7 +32,7 @@ static void handle_uploads(struct mg_connection *c, int ev, void *ev_data) { us->expected = hm->body.len; // Store number of bytes we expect mg_iobuf_del(&c->recv, 0, hm->head.len); // Delete HTTP headers c->pfn = NULL; // Silence HTTP protocol handler, we'll use MG_EV_READ - if (mg_path_is_sane(path)) { + if (mg_path_is_sane(mg_str(path))) { fs->rm(path); // Delete file if it exists us->fp = fs->op(path, MG_FS_WRITE); // Open file for writing } diff --git a/examples/http-server/main.c b/examples/http-server/main.c index 36b33eb3be..cf170f869a 100644 --- a/examples/http-server/main.c +++ b/examples/http-server/main.c @@ -37,7 +37,7 @@ static void cb(struct mg_connection *c, int ev, void *ev_data) { part.filename.buf, part.body.len)); mg_snprintf(path, sizeof(path), "%s/%.*s", s_upload_dir, part.filename.len, part.filename.buf); - if (mg_path_is_sane(path)) { + if (mg_path_is_sane(mg_str(path))) { mg_file_write(&mg_fs_posix, path, part.body.buf, part.body.len); total_bytes += part.body.len; num_files++; diff --git a/mongoose.c b/mongoose.c index 5adda6c9ec..9e8ae31d59 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2985,7 +2985,7 @@ static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm, path_size - n, 0); } path[path_size - 1] = '\0'; // Double-check - if (!mg_path_is_sane(path)) { + if (!mg_path_is_sane(mg_str_n(path, path_size))) { mg_http_reply(c, 400, "", "Invalid path"); return -1; } @@ -3143,7 +3143,7 @@ long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm, } else if (file[0] == '\0') { mg_http_reply(c, 400, "", "file required"); res = -1; - } else if (mg_path_is_sane(file) == false) { + } else if (mg_path_is_sane(mg_str(file)) == false) { mg_http_reply(c, 400, "", "%s: invalid file", file); res = -2; } else if (offset < 0) { @@ -8125,11 +8125,12 @@ void mg_unhex(const char *buf, size_t len, unsigned char *to) { } } -bool mg_path_is_sane(const char *path) { - const char *s = path; - if (path[0] == '.' && path[1] == '.') return false; // Starts with .. - for (; s[0] != '\0'; s++) { - if (s[0] == '/' || s[0] == '\\') { // Subdir? +bool mg_path_is_sane(const struct mg_str path) { + const char *s = path.buf; + size_t n = path.len; + if (path.buf[0] == '.' && path.buf[1] == '.') return false; // Starts with .. + for (; s[0] != '\0' && n > 0; s++, n--) { + if ((s[0] == '/' || s[0] == '\\') && n >= 2) { // Subdir? if (s[1] == '.' && s[2] == '.') return false; // Starts with .. } } @@ -17217,7 +17218,6 @@ static bool mg_tcpip_driver_xmc_up(struct mg_tcpip_if *ifp) { MG_DEBUG(("Link is %uM %s-duplex", speed == MG_PHY_SPEED_10M ? 10 : 100, full_duplex ? "full" : "half")); } - (void) d; return up; } diff --git a/mongoose.h b/mongoose.h index 2780af515f..d40b945976 100644 --- a/mongoose.h +++ b/mongoose.h @@ -872,7 +872,7 @@ bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char delim); char *mg_hex(const void *buf, size_t len, char *dst); void mg_unhex(const char *buf, size_t len, unsigned char *to); unsigned long mg_unhexn(const char *s, size_t len); -bool mg_path_is_sane(const char *path); +bool mg_path_is_sane(const struct mg_str path); @@ -2921,6 +2921,14 @@ struct mg_tcpip_driver_tm4c_data { #endif +#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5500) && MG_ENABLE_DRIVER_W5500 + +#undef MG_ENABLE_TCPIP_DRIVER_INIT +#define MG_ENABLE_TCPIP_DRIVER_INIT 0 + +#endif + + #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC struct mg_tcpip_driver_xmc_data { diff --git a/src/http.c b/src/http.c index ffc7ed7a46..37845820ce 100644 --- a/src/http.c +++ b/src/http.c @@ -769,7 +769,7 @@ static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm, path_size - n, 0); } path[path_size - 1] = '\0'; // Double-check - if (!mg_path_is_sane(path)) { + if (!mg_path_is_sane(mg_str_n(path, path_size))) { mg_http_reply(c, 400, "", "Invalid path"); return -1; } @@ -927,7 +927,7 @@ long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm, } else if (file[0] == '\0') { mg_http_reply(c, 400, "", "file required"); res = -1; - } else if (mg_path_is_sane(file) == false) { + } else if (mg_path_is_sane(mg_str(file)) == false) { mg_http_reply(c, 400, "", "%s: invalid file", file); res = -2; } else if (offset < 0) { diff --git a/src/str.c b/src/str.c index ed4ecadf97..26902b8fbf 100644 --- a/src/str.c +++ b/src/str.c @@ -173,11 +173,12 @@ void mg_unhex(const char *buf, size_t len, unsigned char *to) { } } -bool mg_path_is_sane(const char *path) { - const char *s = path; - if (path[0] == '.' && path[1] == '.') return false; // Starts with .. - for (; s[0] != '\0'; s++) { - if (s[0] == '/' || s[0] == '\\') { // Subdir? +bool mg_path_is_sane(const struct mg_str path) { + const char *s = path.buf; + size_t n = path.len; + if (path.buf[0] == '.' && path.buf[1] == '.') return false; // Starts with .. + for (; s[0] != '\0' && n > 0; s++, n--) { + if ((s[0] == '/' || s[0] == '\\') && n >= 2) { // Subdir? if (s[1] == '.' && s[2] == '.') return false; // Starts with .. } } diff --git a/src/str.h b/src/str.h index 89166d73ce..422fef2969 100644 --- a/src/str.h +++ b/src/str.h @@ -28,4 +28,4 @@ bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char delim); char *mg_hex(const void *buf, size_t len, char *dst); void mg_unhex(const char *buf, size_t len, unsigned char *to); unsigned long mg_unhexn(const char *s, size_t len); -bool mg_path_is_sane(const char *path); +bool mg_path_is_sane(const struct mg_str path); diff --git a/test/unit_test.c b/test/unit_test.c index b6daf9b335..b59e122b85 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -2107,20 +2107,22 @@ static void test_str(void) { ASSERT(strcmp(buf, "[164:2100:0:0:0:0:0:0]:3 7") == 0); } - ASSERT(mg_path_is_sane(".") == true); - ASSERT(mg_path_is_sane("") == true); - ASSERT(mg_path_is_sane("a.b") == true); - ASSERT(mg_path_is_sane("a..b") == true); - ASSERT(mg_path_is_sane(".a") == true); - ASSERT(mg_path_is_sane(".a.") == true); - ASSERT(mg_path_is_sane("./") == true); - ASSERT(mg_path_is_sane("a..") == true); - ASSERT(mg_path_is_sane("././a..") == true); - ASSERT(mg_path_is_sane("..") == false); - ASSERT(mg_path_is_sane("../") == false); - ASSERT(mg_path_is_sane("./..") == false); - ASSERT(mg_path_is_sane("a/../") == false); - ASSERT(mg_path_is_sane("a/../b") == false); + ASSERT(mg_path_is_sane(mg_str(".")) == true); + ASSERT(mg_path_is_sane(mg_str("")) == true); + ASSERT(mg_path_is_sane(mg_str("a.b")) == true); + ASSERT(mg_path_is_sane(mg_str("a..b")) == true); + ASSERT(mg_path_is_sane(mg_str(".a")) == true); + ASSERT(mg_path_is_sane(mg_str(".a.")) == true); + ASSERT(mg_path_is_sane(mg_str("./")) == true); + ASSERT(mg_path_is_sane(mg_str("a..")) == true); + ASSERT(mg_path_is_sane(mg_str("././a..")) == true); + ASSERT(mg_path_is_sane(mg_str("..")) == false); + ASSERT(mg_path_is_sane(mg_str("../")) == false); + ASSERT(mg_path_is_sane(mg_str("./..")) == false); + ASSERT(mg_path_is_sane(mg_str("a/../")) == false); + ASSERT(mg_path_is_sane(mg_str("a/../b")) == false); + ASSERT(mg_path_is_sane(mg_str_n("a/..", 2)) == true); + ASSERT(mg_path_is_sane(mg_str_n("a/../b", 2)) == true); } static void fn1(struct mg_connection *c, int ev, void *ev_data) {