Skip to content

Commit

Permalink
Fixed issue with trailing dots in file paths
Browse files Browse the repository at this point in the history
Paths such as the following were causing issues:
/tea/hottea/.
/tea/hottea/..

Unfortunately the existing structure for path lookup didn't make it very
easy to introduce proper handling in this case without duplicating the
entire skip logic for paths. So the lfs_dir_find function had to be
restructured a bit.

One odd side-effect of this is that now lfs_dir_find includes the
initial fetch operation. This kinda breaks the fetch -> op pattern of
the dir functions, but does come with a nice code size reduction.
  • Loading branch information
geky committed Apr 22, 2018
1 parent 9637b96 commit 015b86b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 70 deletions.
100 changes: 30 additions & 70 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,26 +783,19 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
lfs_entry_t *entry, const char **path) {
const char *pathname = *path;
size_t pathlen;
entry->d.type = LFS_TYPE_DIR;
entry->d.elen = sizeof(entry->d) - 4;
entry->d.alen = 0;
entry->d.nlen = 0;
entry->d.u.dir[0] = lfs->root[0];
entry->d.u.dir[1] = lfs->root[1];

while (true) {
nextname:
nextname:
// skip slashes
pathname += strspn(pathname, "/");
pathlen = strcspn(pathname, "/");

// special case for root dir
if (pathname[0] == '\0') {
*entry = (lfs_entry_t){
.d.type = LFS_TYPE_DIR,
.d.elen = sizeof(entry->d) - 4,
.d.alen = 0,
.d.nlen = 0,
.d.u.dir[0] = lfs->root[0],
.d.u.dir[1] = lfs->root[1],
};
return 0;
}

// skip '.' and root '..'
if ((pathlen == 1 && memcmp(pathname, ".", 1) == 0) ||
(pathlen == 2 && memcmp(pathname, "..", 2) == 0)) {
Expand Down Expand Up @@ -834,10 +827,25 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
suffix += sufflen;
}

// found path
if (pathname[0] == '\0') {
return 0;
}

// update what we've found
*path = pathname;

// find path
// continue on if we hit a directory
if (entry->d.type != LFS_TYPE_DIR) {
return LFS_ERR_NOTDIR;
}

int err = lfs_dir_fetch(lfs, dir, entry->d.u.dir);
if (err) {
return err;
}

// find entry matching name
while (true) {
int err = lfs_dir_next(lfs, dir, entry);
if (err) {
Expand Down Expand Up @@ -873,21 +881,8 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
entry->d.type &= ~0x80;
}

// to next name
pathname += pathlen;
pathname += strspn(pathname, "/");
if (pathname[0] == '\0') {
return 0;
}

// continue on if we hit a directory
if (entry->d.type != LFS_TYPE_DIR) {
return LFS_ERR_NOTDIR;
}

int err = lfs_dir_fetch(lfs, dir, entry->d.u.dir);
if (err) {
return err;
}
}
}

Expand All @@ -904,13 +899,8 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {

// fetch parent directory
lfs_dir_t cwd;
int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
if (err) {
return err;
}

lfs_entry_t entry;
err = lfs_dir_find(lfs, &cwd, &entry, &path);
int err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) {
return err ? err : LFS_ERR_EXIST;
}
Expand Down Expand Up @@ -954,13 +944,8 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
dir->pair[0] = lfs->root[0];
dir->pair[1] = lfs->root[1];

int err = lfs_dir_fetch(lfs, dir, dir->pair);
if (err) {
return err;
}

lfs_entry_t entry;
err = lfs_dir_find(lfs, dir, &entry, &path);
int err = lfs_dir_find(lfs, dir, &entry, &path);
if (err) {
return err;
} else if (entry.d.type != LFS_TYPE_DIR) {
Expand Down Expand Up @@ -1302,13 +1287,8 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,

// allocate entry for file if it doesn't exist
lfs_dir_t cwd;
int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
if (err) {
return err;
}

lfs_entry_t entry;
err = lfs_dir_find(lfs, &cwd, &entry, &path);
int err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err && (err != LFS_ERR_NOENT || strchr(path, '/') != NULL)) {
return err;
}
Expand Down Expand Up @@ -1814,13 +1794,8 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
/// General fs operations ///
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
lfs_dir_t cwd;
int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
if (err) {
return err;
}

lfs_entry_t entry;
err = lfs_dir_find(lfs, &cwd, &entry, &path);
int err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err) {
return err;
}
Expand Down Expand Up @@ -1855,13 +1830,8 @@ int lfs_remove(lfs_t *lfs, const char *path) {
}

lfs_dir_t cwd;
int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
if (err) {
return err;
}

lfs_entry_t entry;
err = lfs_dir_find(lfs, &cwd, &entry, &path);
int err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err) {
return err;
}
Expand Down Expand Up @@ -1916,24 +1886,14 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {

// find old entry
lfs_dir_t oldcwd;
int err = lfs_dir_fetch(lfs, &oldcwd, lfs->root);
if (err) {
return err;
}

lfs_entry_t oldentry;
err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
int err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
if (err) {
return err;
}

// allocate new entry
lfs_dir_t newcwd;
err = lfs_dir_fetch(lfs, &newcwd, lfs->root);
if (err) {
return err;
}

lfs_entry_t preventry;
err = lfs_dir_find(lfs, &newcwd, &preventry, &newpath);
if (err && (err != LFS_ERR_NOENT || strchr(newpath, '/') != NULL)) {
Expand Down
16 changes: 16 additions & 0 deletions tests/test_paths.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ tests/test.py << TEST
lfs_unmount(&lfs) => 0;
TEST

echo "--- Trailing dot path tests ---"
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "tea/hottea/", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs_stat(&lfs, "tea/hottea/.", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs_stat(&lfs, "tea/hottea/./.", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs_stat(&lfs, "tea/hottea/..", &info) => 0;
strcmp(info.name, "tea") => 0;
lfs_stat(&lfs, "tea/hottea/../.", &info) => 0;
strcmp(info.name, "tea") => 0;
lfs_unmount(&lfs) => 0;
TEST

echo "--- Root dot dot path tests ---"
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
Expand Down

0 comments on commit 015b86b

Please sign in to comment.