소스 검색

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.
Christopher Haster 8 년 전
부모
커밋
aea3d3db46
2개의 변경된 파일18개의 추가작업 그리고 2개의 파일을 삭제
  1. 2 2
      lfs.c
  2. 16 0
      tests/test_seek.sh

+ 2 - 2
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;
         }
 

+ 16 - 0
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;