mufs: add mufs_abspath() to sanitise paths
This commit is contained in:
parent
d287d7616a
commit
0bc9c6fc7a
1 changed files with 61 additions and 17 deletions
|
@ -17,6 +17,54 @@ struct mufs_dir {
|
|||
uint32_t va;
|
||||
};
|
||||
|
||||
static char *mufs_abspath(const char *path)
|
||||
{
|
||||
char *s, *p, *next, *prev;
|
||||
|
||||
if (!(s = malloc(strlen(path) + 2)))
|
||||
return NULL;
|
||||
|
||||
strcpy(s, path);
|
||||
|
||||
for (p = s, next = p + strcspn(p, "/"); *p != '\0'; next = p + strcspn(p, "/")) {
|
||||
char c = *next;
|
||||
|
||||
*next = '\0';
|
||||
|
||||
if (*p == '\0' || strcmp(p, ".") == 0) {
|
||||
memmove(p, next + 1, strlen(next + 1) + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(p, "..") == 0) {
|
||||
if (!(prev = strrchr(s, '/'))) {
|
||||
memmove(p, next + 1, strlen(next + 1) + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
*prev = '\0';
|
||||
|
||||
if (!(prev = strrchr(s, '/'))) {
|
||||
memmove(s, next + 1, strlen(next + 1) + 1);
|
||||
p = s;
|
||||
continue;
|
||||
}
|
||||
|
||||
memmove(prev + 1, next + 1, strlen(next + 1) + 1);
|
||||
p = prev + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
*next = c;
|
||||
p = next + 1;
|
||||
}
|
||||
|
||||
memmove(s + 1, s, strlen(s) + 1);
|
||||
*s = '/';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static struct mufs_dir *mufs_opendir2(struct mufs *fs, struct mufs_dirent *entry)
|
||||
{
|
||||
struct mufs_dir *dir;
|
||||
|
@ -54,22 +102,19 @@ static struct mufs_tree *resolve_path(struct mufs *fs, const char *path)
|
|||
if (!path || *path == '\0')
|
||||
return NULL;
|
||||
|
||||
while (*path == '/')
|
||||
++path;
|
||||
|
||||
if (*path == '\0')
|
||||
return &fs->root;
|
||||
|
||||
if (!(s = strdup(path)))
|
||||
if (!(s = mufs_abspath(path)))
|
||||
return NULL;
|
||||
|
||||
if (strcmp(s, "/") == 0)
|
||||
return &fs->root;
|
||||
|
||||
if (!(dir = mufs_opendir2(fs, NULL)))
|
||||
goto err_free_s;
|
||||
|
||||
for (p = s; *p != '\0'; p = end) {
|
||||
for (p = s + 1; *p != '\0'; p = end) {
|
||||
end = p + strcspn(p, "/");
|
||||
|
||||
while (*end == '/')
|
||||
if (*end == '/')
|
||||
*end++ = '\0';
|
||||
|
||||
while ((ret = mufs_readdir(dir, &entry)) == 0) {
|
||||
|
@ -250,16 +295,15 @@ int mufs_mkdir(struct mufs *fs, const char *path)
|
|||
if (!path || *path == '\0')
|
||||
return -1;
|
||||
|
||||
/* TODO: already exists. */
|
||||
if (resolve_path(fs, path))
|
||||
return 0;
|
||||
|
||||
while (*path == '/')
|
||||
++path;
|
||||
|
||||
if (!(s = strdup(path)))
|
||||
if (!(s = mufs_abspath(path)))
|
||||
return -1;
|
||||
|
||||
/* TODO: already exists. */
|
||||
if (resolve_path(fs, s)) {
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(name = strrchr(s, '/'))) {
|
||||
name = s;
|
||||
s = "/";
|
||||
|
|
Loading…
Add table
Reference in a new issue