Explorar el Código

Fixed accidental truncate after seek on inline files

The cause was mistakenly setting file->ctz.size directly instead of
file->pos, which file->ctz.size gets overwritten with later in
lfs_file_flush.

Also added better seek test cases specifically for inline files. This
should also catch most of the inline corner cases related to
lfs_file_size/lfs_file_tell.

Found by ebinans
Christopher Haster hace 6 años
padre
commit
614f7b1e68
Se han modificado 2 ficheros con 59 adiciones y 1 borrados
  1. 1 1
      lfs.c
  2. 58 0
      tests/test_seek.sh

+ 1 - 1
lfs.c

@@ -2548,7 +2548,7 @@ relocate:
                 }
             }
         } else {
-            file->ctz.size = lfs_max(file->pos, file->ctz.size);
+            file->pos = lfs_max(file->pos, file->ctz.size);
         }
 
         // actual file updates

+ 58 - 0
tests/test_seek.sh

@@ -357,5 +357,63 @@ tests/test.py << TEST
     lfs_unmount(&lfs) => 0;
 TEST
 
+echo "--- Inline write and seek ---"
+for SIZE in $SMALLSIZE $MEDIUMSIZE $LARGESIZE
+do
+tests/test.py << TEST
+    lfs_mount(&lfs, &cfg) => 0;
+    lfs_file_open(&lfs, &file[0], "hello/tinykitty$SIZE",
+            LFS_O_RDWR | LFS_O_CREAT) => 0;
+    int j = 0;
+    int k = 0;
+
+    memcpy(buffer, "abcdefghijklmnopqrstuvwxyz", 26);
+    for (unsigned i = 0; i < $SIZE; i++) {
+        lfs_file_write(&lfs, &file[0], &buffer[j++ % 26], 1) => 1;
+        lfs_file_tell(&lfs, &file[0]) => i+1;
+        lfs_file_size(&lfs, &file[0]) => i+1;
+    }
+
+    lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_SET) => 0;
+    lfs_file_tell(&lfs, &file[0]) => 0;
+    lfs_file_size(&lfs, &file[0]) => $SIZE;
+    for (unsigned i = 0; i < $SIZE; i++) {
+        uint8_t c;
+        lfs_file_read(&lfs, &file[0], &c, 1) => 1;
+        c => buffer[k++ % 26];
+    }
+
+    lfs_file_sync(&lfs, &file[0]) => 0;
+    lfs_file_tell(&lfs, &file[0]) => $SIZE;
+    lfs_file_size(&lfs, &file[0]) => $SIZE;
+
+    lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_SET) => 0;
+    for (unsigned i = 0; i < $SIZE; i++) {
+        lfs_file_write(&lfs, &file[0], &buffer[j++ % 26], 1) => 1;
+        lfs_file_tell(&lfs, &file[0]) => i+1;
+        lfs_file_size(&lfs, &file[0]) => $SIZE;
+        lfs_file_sync(&lfs, &file[0]) => 0;
+        lfs_file_tell(&lfs, &file[0]) => i+1;
+        lfs_file_size(&lfs, &file[0]) => $SIZE;
+    }
+
+    lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_SET) => 0;
+    lfs_file_tell(&lfs, &file[0]) => 0;
+    lfs_file_size(&lfs, &file[0]) => $SIZE;
+    for (unsigned i = 0; i < $SIZE; i++) {
+        uint8_t c;
+        lfs_file_read(&lfs, &file[0], &c, 1) => 1;
+        c => buffer[k++ % 26];
+    }
+
+    lfs_file_sync(&lfs, &file[0]) => 0;
+    lfs_file_tell(&lfs, &file[0]) => $SIZE;
+    lfs_file_size(&lfs, &file[0]) => $SIZE;
+
+    lfs_file_close(&lfs, &file[0]) => 0;
+    lfs_unmount(&lfs) => 0;
+TEST
+done
+
 echo "--- Results ---"
 tests/stats.py