Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Haster <chaster@utexas.edu>2018-07-28 20:07:18 +0300
committerChristopher Haster <chaster@utexas.edu>2018-10-16 14:36:00 +0300
commit3914cdf39febd4132a0926af105f85abb816dbbd (patch)
tree010896082ed076c5b0696e29160e2d4c22bb365d
parent392b2ac79f428affebf19a05234b01e461292fef (diff)
Pulled in fixes for additional path corner cases
Pulled in 015b86b. Merging this now avoids duplicate effort restructuring the path lookup logic.
-rw-r--r--lfs.c75
-rwxr-xr-xtests/test_paths.sh16
2 files changed, 53 insertions, 38 deletions
diff --git a/lfs.c b/lfs.c
index 6ff4c80..bccb27e 100644
--- a/lfs.c
+++ b/lfs.c
@@ -1273,21 +1273,19 @@ static int32_t lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir,
}
static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
- lfs_block_t pair[2] = {lfs->root[0], lfs->root[1]};
+ // we reduce path to a single name if we can find it
const char *name = *path;
- lfs_size_t namelen;
- int32_t tag;
+ *path = NULL;
+
+ // default to root dir
+ int32_t tag = LFS_MKTAG(LFS_TYPE_DIR, 0x3ff, 0);
+ lfs_block_t pair[2] = {lfs->root[0], lfs->root[1]};
while (true) {
- nextname:
+nextname:
// skip slashes
name += strspn(name, "/");
- namelen = strcspn(name, "/");
-
- if (name[0] == '\0') {
- // special case for root dir
- return LFS_MKTAG(LFS_TYPE_DIR, 0x3ff, 0);
- }
+ lfs_size_t namelen = strcspn(name, "/");
// skip '.' and root '..'
if ((namelen == 1 && memcmp(name, ".", 1) == 0) ||
@@ -1320,10 +1318,31 @@ static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
suffix += sufflen;
}
- // update what we've found
- *path = name;
+ // found path
+ if (name[0] == '\0') {
+ return tag;
+ }
- // find path
+ // update what we've found if path is only a name
+ if (strchr(name, '/') == NULL) {
+ *path = name;
+ }
+
+ // only continue if we hit a directory
+ if (lfs_tagtype(tag) != LFS_TYPE_DIR) {
+ return LFS_ERR_NOTDIR;
+ }
+
+ // grab the entry data
+ if (lfs_tagid(tag) != 0x3ff) {
+ int32_t res = lfs_dir_get(lfs, dir, 0x7c3ff000,
+ LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tagid(tag), 8), pair);
+ if (res < 0) {
+ return res;
+ }
+ }
+
+ // find entry matching name
while (true) {
tag = lfs_dir_find(lfs, dir, pair, 0x7c000fff,
LFS_MKTAG(LFS_TYPE_NAME, 0, namelen), name);
@@ -1337,6 +1356,7 @@ static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
}
if (!dir->split) {
+ // couldn't find it
return LFS_ERR_NOENT;
}
@@ -1344,26 +1364,8 @@ static int32_t lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, const char **path) {
pair[1] = dir->tail[1];
}
+ // to next name
name += namelen;
- name += strspn(name, "/");
- if (name[0] == '\0') {
- return tag;
- }
-
- // don't continue on if we didn't hit a directory
- // TODO update with what's on master?
- if (lfs_tagtype(tag) != LFS_TYPE_DIR) {
- return LFS_ERR_NOTDIR;
- }
-
- // TODO optimize grab for inline files and like?
- // TODO would this mean more code?
- // grab the entry data
- int32_t res = lfs_dir_get(lfs, dir, 0x7c3ff000,
- LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tagid(tag), 8), pair);
- if (res < 0) {
- return res;
- }
}
}
@@ -1408,11 +1410,8 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
lfs_mdir_t cwd;
int32_t res = lfs_dir_lookup(lfs, &cwd, &path);
- if (res != LFS_ERR_NOENT || strchr(path, '/') != NULL) {
- if (res >= 0) {
- return LFS_ERR_EXIST;
- }
- return res;
+ if (res != LFS_ERR_NOENT || !path) {
+ return (res < 0) ? res : LFS_ERR_EXIST;
}
// check that name fits
@@ -1806,7 +1805,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
// allocate entry for file if it doesn't exist
lfs_mdir_t cwd;
int32_t tag = lfs_dir_lookup(lfs, &cwd, &path);
- if (tag < 0 && (tag != LFS_ERR_NOENT || strchr(path, '/') != NULL)) {
+ if (tag < 0 && (tag != LFS_ERR_NOENT || !path)) {
return tag;
}
diff --git a/tests/test_paths.sh b/tests/test_paths.sh
index 3384329..ea5eb21 100755
--- a/tests/test_paths.sh
+++ b/tests/test_paths.sh
@@ -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;