From 334ea87d25fe1e9ca0186c126a420b521c69b15e Mon Sep 17 00:00:00 2001 From: Godzil Date: Fri, 27 May 2022 12:02:15 +0100 Subject: [PATCH] Add missing boundary check when seeking in a file. --- includes/miniffs.h | 1 + miniffs.c | 50 +++++++++++++++++++++++++++++----------- test/file_operations.cpp | 46 +++++++++++++++++++++++++++++++++++- 3 files changed, 82 insertions(+), 15 deletions(-) diff --git a/includes/miniffs.h b/includes/miniffs.h index 1c1adba..e255ea4 100644 --- a/includes/miniffs.h +++ b/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; diff --git a/miniffs.c b/miniffs.c index 9c1b403..3803cd6 100644 --- a/miniffs.c +++ b/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) - { - default: - miniffs_seterror(MINIFFS_INVALID_PARAMS); - return -1; + 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: - file->offset = file->fent->size - 1 - offset; + 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; } - miniffs_seterror(MINIFFS_NOERROR); + + if (file->offset >= file->fent->size) + { + /* Positive Boundary check */ + noError = false; + miniffs_seterror(MINIFFS_SEEK_OUT_OF_BOUNDARIES); + file->offset = file->fent->size - 1; + } + + if (noError) + { + miniffs_seterror(MINIFFS_NOERROR); + } } size_t miniffs_tell(file_t *file) diff --git a/test/file_operations.cpp b/test/file_operations.cpp index a36ad04..f41efd6 100644 --- a/test/file_operations.cpp +++ b/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], '!'); - } \ No newline at end of file