diff --git a/src/config.c b/src/config.c index 79de627b9..63e7fb3fa 100644 --- a/src/config.c +++ b/src/config.c @@ -947,11 +947,35 @@ load_ports(void) #endif } +static char * +memrmem(char *src, char *start, char *what) +{ + if ((src == NULL) || (what == NULL)) + return NULL; + + while (1) { + if (memcmp(src, what, strlen(what)) == 0) + return src; + src--; + if (src < start) + return NULL; + } +} + static int load_image_file(char *dest, char *p, uint8_t *ui_wp) { char *prefix = ""; int ret = 0; + char *slash = NULL; + char *above = NULL; + char *use = NULL; + + if ((slash = memrmem(usr_path + strlen(usr_path) - 2, usr_path, "/")) != NULL) { + slash++; + above = (char *) calloc(1, slash - usr_path + 1); + memcpy(above, usr_path, slash - usr_path); + } if (strstr(p, "wp://") == p) { p += 5; @@ -968,6 +992,13 @@ load_image_file(char *dest, char *p, uint8_t *ui_wp) else snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s%s%s", prefix, exe_path, path_get_slash(exe_path), p + strlen("/")); + } else if (memcmp(p, "../", strlen("../")) == 0) { + use = (above == NULL) ? usr_path : above; + if ((strlen(prefix) + strlen(use) + strlen(path_get_slash(use)) + strlen(p + strlen("../"))) > + (MAX_IMAGE_PATH_LEN - 11)) + ret = 1; + else + snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s%s%s", prefix, use, path_get_slash(use), p + strlen("../")); } else if (path_abs(p)) { if ((strlen(prefix) + strlen(p)) > (MAX_IMAGE_PATH_LEN - 11)) ret = 1; @@ -982,6 +1013,9 @@ load_image_file(char *dest, char *p, uint8_t *ui_wp) path_normalize(dest); + if (above != NULL) + free(above); + return ret; } @@ -3060,6 +3094,14 @@ save_image_file(char *cat, char *var, char *src) { char temp[2048] = { 0 }; char *prefix = ""; + char *slash = NULL; + char *above = NULL; + + if ((slash = memrmem(usr_path + strlen(usr_path) - 2, usr_path, "/")) != NULL) { + slash++; + above = (char *) calloc(1, slash - usr_path + 1); + memcpy(above, usr_path, slash - usr_path); + } path_normalize(src); @@ -3070,12 +3112,17 @@ save_image_file(char *cat, char *var, char *src) if (!strnicmp(src, usr_path, strlen(usr_path))) sprintf(temp, "%s%s", prefix, &src[strlen(usr_path)]); + else if ((above != NULL) && !strnicmp(src, above, strlen(above))) + sprintf(temp, "../%s%s", prefix, &src[strlen(above)]); else if (!strnicmp(src, exe_path, strlen(exe_path))) sprintf(temp, "/%s%s", prefix, &src[strlen(exe_path)]); else sprintf(temp, "%s%s", prefix, src); ini_section_set_string(cat, var, temp); + + if (above != NULL) + free(above); } /* Save "Storage Controllers" section. */