From aea3d3db46634bf26298c8df0be020c03b80daba Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 3 Jan 2018 15:00:04 -0600 Subject: [PATCH] Fixed positive seek bounds checking This bug was a result of an annoying corner case around intermingling signed and unsigned offsets. The boundary check that prevents seeking a file to a position before the file was preventing valid seeks with positive offsets. This corner case is a bit more complicated than it looks because the offset is signed, while the size of the file is unsigned. Simply casting both to signed or unsigned offsets won't handle large files. --- lfs.c | 4 ++-- tests/test_seek.sh | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lfs.c b/lfs.c index 2d0e331..4267d7c 100644 --- a/lfs.c +++ b/lfs.c @@ -1635,13 +1635,13 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file, if (whence == LFS_SEEK_SET) { file->pos = off; } else if (whence == LFS_SEEK_CUR) { - if ((lfs_off_t)-off > file->pos) { + if (off < 0 && (lfs_off_t)-off > file->pos) { return LFS_ERR_INVAL; } file->pos = file->pos + off; } else if (whence == LFS_SEEK_END) { - if ((lfs_off_t)-off > file->size) { + if (off < 0 && (lfs_off_t)-off > file->size) { return LFS_ERR_INVAL; } diff --git a/tests/test_seek.sh b/tests/test_seek.sh index 6600cb2..3b46892 100755 --- a/tests/test_seek.sh +++ b/tests/test_seek.sh @@ -133,6 +133,14 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; + lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; + lfs_file_read(&lfs, &file[0], buffer, size) => size; + memcmp(buffer, "kittycatcat", size) => 0; + + lfs_file_seek(&lfs, &file[0], size, LFS_SEEK_CUR) => 3*size; + lfs_file_read(&lfs, &file[0], buffer, size) => size; + memcmp(buffer, "kittycatcat", size) => 0; + lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos; lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; @@ -174,6 +182,14 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; + lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; + lfs_file_read(&lfs, &file[0], buffer, size) => size; + memcmp(buffer, "kittycatcat", size) => 0; + + lfs_file_seek(&lfs, &file[0], size, LFS_SEEK_CUR) => 3*size; + lfs_file_read(&lfs, &file[0], buffer, size) => size; + memcmp(buffer, "kittycatcat", size) => 0; + lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos; lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0;