diff options
author | Christopher Haster <chaster@utexas.edu> | 2019-05-28 21:55:03 +0300 |
---|---|---|
committer | Christopher Haster <chaster@utexas.edu> | 2019-07-01 23:11:53 +0300 |
commit | 614f7b1e68ca796af6074fd21ceb812f3c609fa1 (patch) | |
tree | 59923e6e9172c5c56a510fab0d5a73a8c13278d5 | |
parent | a9a61a3e7860deaabc8645cbf586ad9ce85de3bc (diff) |
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
-rw-r--r-- | lfs.c | 2 | ||||
-rwxr-xr-x | tests/test_seek.sh | 58 |
2 files changed, 59 insertions, 1 deletions
@@ -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 diff --git a/tests/test_seek.sh b/tests/test_seek.sh index 2cd711a..1803317 100755 --- a/tests/test_seek.sh +++ b/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 |