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;
|
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)
|
static struct mufs_dir *mufs_opendir2(struct mufs *fs, struct mufs_dirent *entry)
|
||||||
{
|
{
|
||||||
struct mufs_dir *dir;
|
struct mufs_dir *dir;
|
||||||
|
@ -54,22 +102,19 @@ static struct mufs_tree *resolve_path(struct mufs *fs, const char *path)
|
||||||
if (!path || *path == '\0')
|
if (!path || *path == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (*path == '/')
|
if (!(s = mufs_abspath(path)))
|
||||||
++path;
|
|
||||||
|
|
||||||
if (*path == '\0')
|
|
||||||
return &fs->root;
|
|
||||||
|
|
||||||
if (!(s = strdup(path)))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (strcmp(s, "/") == 0)
|
||||||
|
return &fs->root;
|
||||||
|
|
||||||
if (!(dir = mufs_opendir2(fs, NULL)))
|
if (!(dir = mufs_opendir2(fs, NULL)))
|
||||||
goto err_free_s;
|
goto err_free_s;
|
||||||
|
|
||||||
for (p = s; *p != '\0'; p = end) {
|
for (p = s + 1; *p != '\0'; p = end) {
|
||||||
end = p + strcspn(p, "/");
|
end = p + strcspn(p, "/");
|
||||||
|
|
||||||
while (*end == '/')
|
if (*end == '/')
|
||||||
*end++ = '\0';
|
*end++ = '\0';
|
||||||
|
|
||||||
while ((ret = mufs_readdir(dir, &entry)) == 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')
|
if (!path || *path == '\0')
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* TODO: already exists. */
|
if (!(s = mufs_abspath(path)))
|
||||||
if (resolve_path(fs, path))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while (*path == '/')
|
|
||||||
++path;
|
|
||||||
|
|
||||||
if (!(s = strdup(path)))
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* TODO: already exists. */
|
||||||
|
if (resolve_path(fs, s)) {
|
||||||
|
free(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(name = strrchr(s, '/'))) {
|
if (!(name = strrchr(s, '/'))) {
|
||||||
name = s;
|
name = s;
|
||||||
s = "/";
|
s = "/";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue