Browse Source

Add missing boundary check when seeking in a file.

Godzil 1 year ago
parent
commit
8a604309bb
3 changed files with 82 additions and 15 deletions
  1. 1 0
      includes/miniffs.h
  2. 36 14
      miniffs.c
  3. 45 1
      test/file_operations.cpp

+ 1 - 0
includes/miniffs.h

@@ -101,6 +101,7 @@ typedef enum miniffs_error_t
     MINIFFS_INVALID_PARAMS,
     MINIFFS_FILE_NOT_FOUND,
     MINIFFS_ALLOCATION_ERROR,
+    MINIFFS_SEEK_OUT_OF_BOUNDARIES,
     MINIFFS_END_OF_FILE,
     //MINIFFS_,
 } miniffs_error_t;

+ 36 - 14
miniffs.c

@@ -116,23 +116,45 @@ int miniffs_read_blocks(void *ptr, size_t size, size_t nmemb, file_t *file)
 
 int miniffs_seek(file_t *file, size_t offset, int whence)
 {
-    switch(whence)
+    bool noError = true;
+    switch(whence) {
+        default:
+            miniffs_seterror(MINIFFS_INVALID_PARAMS);
+            return -1;
+
+        case MFFS_SEEK_SET:
+            file->offset = offset;
+            break;
+        case MFFS_SEEK_CUR:
+            file->offset += offset;
+            break;
+        case MFFS_SEEK_END:
+            if (file->fent->size <= offset)
+            {
+                /* Negative boundary check */
+                noError = false;
+                miniffs_seterror(MINIFFS_SEEK_OUT_OF_BOUNDARIES);
+                file->offset = 0;
+            }
+            else
+            {
+                file->offset = file->fent->size - 1 - offset;
+            }
+        break;
+    }
+
+    if (file->offset >= file->fent->size)
     {
-    default:
-        miniffs_seterror(MINIFFS_INVALID_PARAMS);
-        return -1;
+        /* Positive Boundary check */
+        noError = false;
+        miniffs_seterror(MINIFFS_SEEK_OUT_OF_BOUNDARIES);
+        file->offset = file->fent->size - 1;
+    }
 
-    case MFFS_SEEK_SET:
-        file->offset = offset;
-        break;
-    case MFFS_SEEK_CUR:
-        file->offset += offset;
-        break;
-    case MFFS_SEEK_END:
-        file->offset = file->fent->size - 1 - offset;
-        break;
+    if (noError)
+    {
+        miniffs_seterror(MINIFFS_NOERROR);
     }
-    miniffs_seterror(MINIFFS_NOERROR);
 }
 
 size_t miniffs_tell(file_t *file)

+ 45 - 1
test/file_operations.cpp

@@ -97,6 +97,51 @@ TEST(FileOperations, TestingSeek)
     ASSERT_EQ(miniffs_read(fp), '!');
 }
 
+TEST(FileOperations, LargeOutOfBoundarySeeks)
+{
+    miniffs_t *fs = get_fs("simple_test.mffs");
+    file_t *fp = miniffs_open(fs, "HELLO.TXT");
+
+    miniffs_seek(fp, 100, MFFS_SEEK_SET);
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_SEEK_OUT_OF_BOUNDARIES);
+    ASSERT_EQ(miniffs_read(fp), '!');
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_END_OF_FILE);
+
+    miniffs_seek(fp, 100, MFFS_SEEK_END);
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_SEEK_OUT_OF_BOUNDARIES);
+    ASSERT_EQ(miniffs_read(fp), 'H');
+}
+
+TEST(FileOperations, SeekingAroundBoundaries)
+{
+    miniffs_t *fs = get_fs("simple_test.mffs");
+    file_t *fp = miniffs_open(fs, "HELLO.TXT");
+
+    miniffs_seek(fp, 10, MFFS_SEEK_SET);
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_NOERROR);
+    ASSERT_EQ(miniffs_read(fp), 'd');
+
+    miniffs_seek(fp, 11, MFFS_SEEK_SET);
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_NOERROR);
+    ASSERT_EQ(miniffs_read(fp), '!');
+
+    miniffs_seek(fp, 12, MFFS_SEEK_SET);
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_SEEK_OUT_OF_BOUNDARIES);
+    ASSERT_EQ(miniffs_read(fp), '!');
+
+    miniffs_seek(fp, 10, MFFS_SEEK_END);
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_NOERROR);
+    ASSERT_EQ(miniffs_read(fp), 'e');
+
+    miniffs_seek(fp, 11, MFFS_SEEK_END);
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_NOERROR);
+    ASSERT_EQ(miniffs_read(fp), 'H');
+
+    miniffs_seek(fp, 12, MFFS_SEEK_END);
+    ASSERT_EQ(miniffs_geterror(), MINIFFS_SEEK_OUT_OF_BOUNDARIES);
+    ASSERT_EQ(miniffs_read(fp), 'H');
+}
+
 TEST(FileOperations, TestingEndOfFileBoundary)
 {
     miniffs_t *fs = get_fs("simple_test.mffs");
@@ -197,5 +242,4 @@ TEST(FileOperations, ReadTooManyBlocks)
     ASSERT_EQ(buffer[9], 'l');
     ASSERT_EQ(buffer[10], 'd');
     ASSERT_EQ(buffer[11], '!');
-
 }