vfs: improve path normalization

This commit is contained in:
Andrei "Akari" Alexeyev 2017-05-10 20:06:51 +03:00
parent 85980989d9
commit 90ccdc9189
No known key found for this signature in database
GPG key ID: A1C351B8DB5C857B
6 changed files with 36 additions and 8 deletions

View file

@ -1,5 +1,6 @@
#include "private.h"
#include "syspath.h"
char* vfs_path_normalize(const char *path, char *out) {
const char *p = path;
@ -93,3 +94,11 @@ void vfs_path_root_prefix(char *path) {
*path = VFS_PATH_SEP;
}
}
char* vfs_syspath_normalize_inplace(char *path) {
char buf[strlen(path)+1];
strcpy(buf, path);
vfs_syspath_normalize(buf, sizeof(buf), path);
strcpy(path, buf);
return path;
}

View file

@ -19,4 +19,6 @@ 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);
char* vfs_syspath_normalize_inplace(char *path);
#endif

View file

@ -204,6 +204,7 @@ char* vfs_repr_node(VFSNode *node, bool try_syspath) {
if(try_syspath && node->funcs->syspath) {
if(r = node->funcs->syspath(node)) {
vfs_syspath_normalize_inplace(r);
return r;
}
}

View file

@ -6,5 +6,6 @@
extern char vfs_syspath_prefered_separator;
bool vfs_syspath_init(VFSNode *node, const char *path);
void vfs_syspath_normalize(char *buf, size_t bufsize, const char *path);
#endif

View file

@ -126,7 +126,25 @@ static VFSNodeFuncs vfs_funcs_syspath = {
.open = vfs_syspath_open,
};
void vfs_syspath_normalize(char *buf, size_t bufsize, const char *path) {
char *bufptr = buf;
const char *pathptr = path;
bool skip = false;
memset(buf, 0, bufsize);
while(*pathptr && bufptr < (buf + bufsize - 1)) {
if(!skip) {
*bufptr++ = *pathptr;
}
skip = (pathptr[0] == '/' && pathptr[1] == '/');
++pathptr;
}
}
static void vfs_syspath_init_internal(VFSNode *node, char *path) {
vfs_syspath_normalize_inplace(path);
node->type = VNODE_SYSPATH;
node->funcs = &vfs_funcs_syspath;
node->syspath.path = path;

View file

@ -218,21 +218,20 @@ static VFSNodeFuncs vfs_funcs_syspath = {
.open = vfs_syspath_open,
};
static void vfs_syspath_normalize(char *path) {
void vfs_syspath_normalize(char *buf, size_t bufsize, const char *path) {
// here we just remove redundant separators and convert forward slashes to back slashes.
// no need to bother with . and ..
// paths starting with two separators are a special case however (network shares)
// and are handled appropriately.
char buf[strlen(path)+1];
char *bufptr = buf;
char *pathptr = path;
const char *pathptr = path;
bool skip = false;
memset(buf, 0, sizeof(buf));
memset(buf, 0, bufsize);
while(*pathptr) {
while(*pathptr && bufptr < (buf + bufsize - 1)) {
if(!skip) {
*bufptr++ = (*pathptr == '/' ? '\\' : *pathptr);
}
@ -245,8 +244,6 @@ static void vfs_syspath_normalize(char *path) {
++pathptr;
}
strcpy(path, buf);
}
static bool vfs_syspath_validate(char *path) {
@ -266,7 +263,7 @@ static bool vfs_syspath_validate(char *path) {
}
static bool vfs_syspath_init_internal(VFSNode *node, char *path) {
vfs_syspath_normalize(path);
vfs_syspath_normalize_inplace(path);
if(!vfs_syspath_validate(path)) {
return false;