diff --git a/lfs.c b/lfs.c index 76a1b19..194d0f8 100644 --- a/lfs.c +++ b/lfs.c @@ -709,6 +709,9 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, suffix += sufflen; } + // update what we've found + *path = pathname; + // find path while (true) { int err = lfs_dir_next(lfs, dir, entry); @@ -750,8 +753,6 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, if (err) { return err; } - - *path = pathname; } return 0; @@ -769,7 +770,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { lfs_entry_t entry; err = lfs_dir_find(lfs, &cwd, &entry, &path); - if (err != LFS_ERR_NOENT) { + if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) { return err ? err : LFS_ERR_EXISTS; } @@ -817,8 +818,8 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) { return err; } + // check for root, can only be something like '/././../.' if (strspn(path, "/.") == strlen(path)) { - // can only be something like '/././../.' dir->head[0] = dir->pair[0]; dir->head[1] = dir->pair[1]; dir->pos = sizeof(dir->d) - 2; @@ -1118,7 +1119,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, lfs_entry_t entry; err = lfs_dir_find(lfs, &cwd, &entry, &path); - if (err && err != LFS_ERR_NOENT) { + if (err && (err != LFS_ERR_NOENT || strchr(path, '/') != NULL)) { return err; } @@ -1533,6 +1534,14 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) { /// General fs oprations /// int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { + // check for root, can only be something like '/././../.' + if (strspn(path, "/.") == strlen(path)) { + memset(info, 0, sizeof(*info)); + info->type = LFS_TYPE_DIR; + strcpy(info->name, "/"); + return 0; + } + lfs_dir_t cwd; int err = lfs_dir_fetch(lfs, &cwd, lfs->root); if (err) { @@ -1640,7 +1649,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { lfs_entry_t preventry; err = lfs_dir_find(lfs, &newcwd, &preventry, &newpath); - if (err && err != LFS_ERR_NOENT) { + if (err && (err != LFS_ERR_NOENT || strchr(newpath, '/') != NULL)) { return err; } bool prevexists = (err != LFS_ERR_NOENT); diff --git a/tests/test_paths.sh b/tests/test_paths.sh index 769f37f..9bc1f5b 100755 --- a/tests/test_paths.sh +++ b/tests/test_paths.sh @@ -31,6 +31,10 @@ tests/test.py << TEST strcmp(info.name, "hottea") => 0; lfs_stat(&lfs, "/tea/hottea", &info) => 0; strcmp(info.name, "hottea") => 0; + + lfs_mkdir(&lfs, "/milk1") => 0; + lfs_stat(&lfs, "/milk1", &info) => 0; + strcmp(info.name, "milk1") => 0; lfs_unmount(&lfs) => 0; TEST @@ -43,6 +47,10 @@ tests/test.py << TEST strcmp(info.name, "hottea") => 0; lfs_stat(&lfs, "///tea///hottea", &info) => 0; strcmp(info.name, "hottea") => 0; + + lfs_mkdir(&lfs, "///milk2") => 0; + lfs_stat(&lfs, "///milk2", &info) => 0; + strcmp(info.name, "milk2") => 0; lfs_unmount(&lfs) => 0; TEST @@ -57,6 +65,10 @@ tests/test.py << TEST strcmp(info.name, "hottea") => 0; lfs_stat(&lfs, "/./tea/./hottea", &info) => 0; strcmp(info.name, "hottea") => 0; + + lfs_mkdir(&lfs, "/./milk3") => 0; + lfs_stat(&lfs, "/./milk3", &info) => 0; + strcmp(info.name, "milk3") => 0; lfs_unmount(&lfs) => 0; TEST @@ -71,6 +83,10 @@ tests/test.py << TEST strcmp(info.name, "hottea") => 0; lfs_stat(&lfs, "coffee/../soda/../tea/hottea", &info) => 0; strcmp(info.name, "hottea") => 0; + + lfs_mkdir(&lfs, "coffee/../milk4") => 0; + lfs_stat(&lfs, "coffee/../milk4", &info) => 0; + strcmp(info.name, "milk4") => 0; lfs_unmount(&lfs) => 0; TEST @@ -79,6 +95,27 @@ tests/test.py << TEST lfs_mount(&lfs, &cfg) => 0; lfs_stat(&lfs, "coffee/../../../../../../tea/hottea", &info) => 0; strcmp(info.name, "hottea") => 0; + + lfs_mkdir(&lfs, "coffee/../../../../../../milk5") => 0; + lfs_stat(&lfs, "coffee/../../../../../../milk5", &info) => 0; + strcmp(info.name, "milk5") => 0; + lfs_unmount(&lfs) => 0; +TEST + +echo "--- Root tests ---" +tests/test.py << TEST + lfs_mount(&lfs, &cfg) => 0; + lfs_stat(&lfs, "/", &info) => 0; + info.type => LFS_TYPE_DIR; + strcmp(info.name, "/") => 0; + lfs_unmount(&lfs) => 0; +TEST + +echo "--- Sketchy path tests ---" +tests/test.py << TEST + lfs_mount(&lfs, &cfg) => 0; + lfs_mkdir(&lfs, "dirt/ground") => LFS_ERR_NOENT; + lfs_mkdir(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT; lfs_unmount(&lfs) => 0; TEST