mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-24 02:59:01 +08:00
Merge pull request #2718 from cesanta/pathissane
change mg_path_is_sane()
This commit is contained in:
commit
10029d6a8d
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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++;
|
||||
|
15
mongoose.c
15
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 ..
|
||||
}
|
||||
}
|
||||
|
10
mongoose.h
10
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);
|
||||
|
||||
|
||||
|
||||
@ -2922,6 +2922,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 {
|
||||
|
@ -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) {
|
||||
|
11
src/str.c
11
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 ..
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user