Przeglądaj źródła

Fixed several small issues

- Fixed uninitialized values found by valgrind.
- Fixed uninitialized value in lfs_dir_fetchmatch when handling revision
  counts.
- Fixed mess left by lfs_dir_find when attempting to find the root
  directory in lfs_rename and lfs_remove.
- Fixed corner case with definitions of lfs->cfg->block_cycles.
- Added test cases around different forms of the root directory.

I think all of these were found by TheLoneWolfling, so props!
Christopher Haster 6 lat temu
rodzic
commit
a0644794ca
2 zmienionych plików z 21 dodań i 8 usunięć
  1. 13 8
      lfs.c
  2. 8 0
      tests/test_paths.sh

+ 13 - 8
lfs.c

@@ -765,7 +765,7 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs,
     lfs_stag_t besttag = -1;
 
     // find the block with the most recent revision
-    uint32_t revs[2];
+    uint32_t revs[2] = {0, 0};
     int r = 0;
     for (int i = 0; i < 2; i++) {
         int err = lfs_bd_read(lfs,
@@ -776,7 +776,8 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs,
             return err;
         }
 
-        if (lfs_scmp(revs[i], revs[(i+1)%2]) > 0 || err == LFS_ERR_CORRUPT) {
+        if (err != LFS_ERR_CORRUPT &&
+                lfs_scmp(revs[i], revs[(i+1)%2]) > 0) {
             r = i;
         }
     }
@@ -2944,8 +2945,8 @@ int lfs_remove(lfs_t *lfs, const char *path) {
 
     lfs_mdir_t cwd;
     lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL);
-    if (tag < 0) {
-        return tag;
+    if (tag < 0 || lfs_tag_id(tag) == 0x3ff) {
+        return (tag < 0) ? tag : LFS_ERR_INVAL;
     }
 
     lfs_mdir_t dir;
@@ -3007,16 +3008,17 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
     // find old entry
     lfs_mdir_t oldcwd;
     lfs_stag_t oldtag = lfs_dir_find(lfs, &oldcwd, &oldpath, NULL);
-    if (oldtag < 0) {
-        return oldtag;
+    if (oldtag < 0 || lfs_tag_id(oldtag) == 0x3ff) {
+        return (oldtag < 0) ? oldtag : LFS_ERR_INVAL;
     }
 
     // find new entry
     lfs_mdir_t newcwd;
     uint16_t newid;
     lfs_stag_t prevtag = lfs_dir_find(lfs, &newcwd, &newpath, &newid);
-    if (prevtag < 0 && !(prevtag == LFS_ERR_NOENT && newid != 0x3ff)) {
-        return err;
+    if ((prevtag < 0 || lfs_tag_id(prevtag) == 0x3ff) &&
+            !(prevtag == LFS_ERR_NOENT && newid != 0x3ff)) {
+        return (prevtag < 0) ? prevtag : LFS_ERR_INVAL;
     }
 
     lfs_mdir_t prevdir;
@@ -3187,6 +3189,9 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
     LFS_ASSERT(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4))
             <= lfs->cfg->block_size);
 
+    // we don't support some corner cases
+    LFS_ASSERT(lfs->cfg->block_cycles < 0xffffffff);
+
     // setup read cache
     if (lfs->cfg->read_buffer) {
         lfs->rcache.buffer = lfs->cfg->read_buffer;

+ 8 - 0
tests/test_paths.sh

@@ -128,6 +128,14 @@ tests/test.py << TEST
     lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST;
     lfs_file_open(&lfs, &file[0], "/", LFS_O_WRONLY | LFS_O_CREAT)
         => LFS_ERR_ISDIR;
+
+    // more corner cases
+    lfs_remove(&lfs, "") => LFS_ERR_INVAL;
+    lfs_remove(&lfs, ".") => LFS_ERR_INVAL;
+    lfs_remove(&lfs, "..") => LFS_ERR_INVAL;
+    lfs_remove(&lfs, "/") => LFS_ERR_INVAL;
+    lfs_remove(&lfs, "//") => LFS_ERR_INVAL;
+    lfs_remove(&lfs, "./") => LFS_ERR_INVAL;
     lfs_unmount(&lfs) => 0;
 TEST