vfs: improve path normalization
This commit is contained in:
parent
85980989d9
commit
90ccdc9189
6 changed files with 36 additions and 8 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue