vfs: make vfs_path_normalize more robust and consistent
* Correctly process trailing . and .. without / * Fix potential read past the input buffer * Always strip trailing /
This commit is contained in:
parent
62f55854aa
commit
2a31511588
6 changed files with 19 additions and 23 deletions
|
@ -144,11 +144,6 @@ char* strftimealloc(const char *fmt, const struct tm *timeinfo) {
|
|||
};
|
||||
}
|
||||
|
||||
void strip_trailing_slashes(char *buf) {
|
||||
for(char *c = buf + strlen(buf) - 1; c >= buf && (*c == '/' || *c == '\\'); c--)
|
||||
*c = 0;
|
||||
}
|
||||
|
||||
char* strappend(char **dst, char *src) {
|
||||
if(!*dst) {
|
||||
return *dst = strdup(src);
|
||||
|
|
|
@ -48,7 +48,6 @@ void stralloc(char **dest, const char *src);
|
|||
char* strjoin(const char *first, ...) attr_sentinel attr_returns_allocated;
|
||||
char* vstrfmt(const char *fmt, va_list args) attr_returns_allocated;
|
||||
char* strfmt(const char *fmt, ...) attr_printf(1, 2) attr_returns_allocated;
|
||||
void strip_trailing_slashes(char *buf);
|
||||
char* strtok_r(char *str, const char *delim, char **nextp);
|
||||
char* strappend(char **dst, char *src);
|
||||
char* strftimealloc(const char *fmt, const struct tm *timeinfo) attr_returns_allocated;
|
||||
|
|
|
@ -17,6 +17,8 @@ char *vfs_path_normalize(const char *path, char *out) {
|
|||
char *last_sep = out - 1;
|
||||
char *path_end = strchr(path, 0);
|
||||
|
||||
#define IS_SEP_OR_NUL(chr) (VFS_IS_PATH_SEPARATOR(chr) || (chr == '\0'))
|
||||
|
||||
while(p < path_end) {
|
||||
if(VFS_IS_PATH_SEPARATOR(*p)) {
|
||||
if(o > out && !VFS_IS_PATH_SEPARATOR(o[-1])) {
|
||||
|
@ -27,13 +29,13 @@ char *vfs_path_normalize(const char *path, char *out) {
|
|||
do {
|
||||
++p;
|
||||
} while(p < path_end && VFS_IS_PATH_SEPARATOR(*p));
|
||||
} else if(*p == '.' && VFS_IS_PATH_SEPARATOR(p[1])) {
|
||||
} else if(*p == '.' && IS_SEP_OR_NUL(p[1])) {
|
||||
p += 2;
|
||||
} else if(!strncmp(p, "..", 2) && VFS_IS_PATH_SEPARATOR(p[2])) {
|
||||
} else if(p + 1 < path_end && !strncmp(p, "..", 2) && IS_SEP_OR_NUL(p[2])) {
|
||||
if(last_sep >= out) {
|
||||
do {
|
||||
--last_sep;
|
||||
} while(!VFS_IS_PATH_SEPARATOR(*last_sep) && last_sep >= out);
|
||||
} while(last_sep >= out && !VFS_IS_PATH_SEPARATOR(*last_sep));
|
||||
|
||||
o = last_sep-- + 1;
|
||||
}
|
||||
|
@ -44,9 +46,18 @@ char *vfs_path_normalize(const char *path, char *out) {
|
|||
}
|
||||
}
|
||||
|
||||
#undef IS_SEP_OR_NUL
|
||||
|
||||
// remove trailing slash
|
||||
if(o > out && VFS_IS_PATH_SEPARATOR(o[-1])) {
|
||||
--o;
|
||||
assert(o == out || !VFS_IS_PATH_SEPARATOR(o[-1]));
|
||||
}
|
||||
|
||||
*o = 0;
|
||||
|
||||
// log_debug("[%s] --> [%s]", path, out);
|
||||
// log_debug("[%s] --> [%s]", path, out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -124,7 +135,7 @@ void vfs_path_root_prefix(char *path) {
|
|||
}
|
||||
}
|
||||
|
||||
char* vfs_syspath_normalize_inplace(char *path) {
|
||||
char *vfs_syspath_normalize_inplace(char *path) {
|
||||
char buf[strlen(path)+1];
|
||||
strcpy(buf, path);
|
||||
vfs_syspath_normalize(buf, sizeof(buf), path);
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
static_assert(sizeof(VFS_PATH_SEPARATOR_STR) == 2, "No more than one VFS path separator, please");
|
||||
|
||||
char* vfs_path_normalize(const char *path, char *out);
|
||||
char* vfs_path_normalize_alloc(const char *path);
|
||||
char* vfs_path_normalize_inplace(char *path);
|
||||
char *vfs_path_normalize(const char *path, char *out);
|
||||
char *vfs_path_normalize_alloc(const char *path);
|
||||
char *vfs_path_normalize_inplace(char *path);
|
||||
void vfs_path_split_left(char *path, char **lpath, char **rpath);
|
||||
void vfs_path_split_right(char *path, char **lpath, char **rpath);
|
||||
void vfs_path_root_prefix(char *path);
|
||||
|
|
|
@ -282,7 +282,6 @@ int vfs_dir_list_order_descending(const void *a, const void *b) {
|
|||
void* vfs_dir_walk(const char *path, void* (*visit)(const char *path, void *arg), void *arg) {
|
||||
char npath[strlen(path) + 1];
|
||||
vfs_path_normalize(path, npath);
|
||||
strip_trailing_slashes(npath);
|
||||
|
||||
VFSDir *dir = vfs_dir_open(npath);
|
||||
void *result = NULL;
|
||||
|
|
|
@ -294,16 +294,8 @@ static void vfs_zipfile_init_pathmap(VFSNode *node) {
|
|||
for(zip_int64_t i = 0; i < num; ++i) {
|
||||
const char *original = zip_get_name(tls->zip, i, 0);
|
||||
char normalized[strlen(original) + 1];
|
||||
|
||||
vfs_path_normalize(original, normalized);
|
||||
|
||||
if(*normalized) {
|
||||
char *c = strchr(normalized, 0) - 1;
|
||||
if(*c == '/') {
|
||||
*c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(strcmp(original, normalized)) {
|
||||
ht_set(&zdata->pathmap, normalized, i);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue