Skip to content

Commit

Permalink
Pulled in fixes for additional path corner cases
Browse files Browse the repository at this point in the history
Pulled in 015b86b. Merging this now avoids duplicate effort restructuring
the path lookup logic.
  • Loading branch information
geky committed Oct 16, 2018
1 parent 392b2ac commit 3914cdf
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 38 deletions.
75 changes: 37 additions & 38 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand Down Expand Up @@ -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);
Expand All @@ -1337,33 +1356,16 @@ 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;
}

pair[0] = dir->tail[0];
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;
}
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

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 3914cdf

Please sign in to comment.