diff --git a/CMakeLists.txt b/CMakeLists.txt index 80392b8..07985a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ option(RUN_TESTS "Run the test suite to verify everything is ok!" ON) string(TOLOWER ${BUILD_PLATFORM} PLATFORM_FILE) -add_library(miniffs) +add_library(miniffs STATIC) target_sources(miniffs PRIVATE platform/${PLATFORM_FILE}.c miniffs.c) target_include_directories(miniffs PRIVATE includes/) target_compile_definitions(miniffs PRIVATE BUILD_PLATFORM_${BUILD_PLATFORM}) diff --git a/includes/miniffs.h b/includes/miniffs.h index 91e78bb..57b67bf 100644 --- a/includes/miniffs.h +++ b/includes/miniffs.h @@ -12,6 +12,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + #define MINIFFS_VERSION_MAJOR (1) #define MINIFFS_VERSION_MINOR (0) #define MINIFFS_FILENAME_LENGTH (8) @@ -56,7 +60,7 @@ typedef struct miniffs_header_t /* Somewhat similar structure to the plain C FILE structure */ typedef struct file_t { - void *private; + void *private_data; fileentry_t *fent; /***< file linked to this structure */ uint32_t offset; /***< current position in the file */ } file_t; @@ -68,7 +72,8 @@ typedef struct file_t #endif #define MINIFFS_MAGIC MAKE4('M', 'F', 'F', 'S') -enum { +enum +{ MFFS_SEEK_SET, /***< Seek from beginning of file */ MFFS_SEEK_CUR, /***< Seek from current position */ MFFS_SEEK_END /***< Seek from end of file */ @@ -123,4 +128,8 @@ void miniffs_seterror(miniffs_error_t err); void *miniffs_getfileaddr(miniffs_t *fs, fileentry_t *fent); #endif /* __miniffs_internal */ +#ifdef __cplusplus +} +#endif + #endif /* MINIFFS_H */ diff --git a/miniffs.c b/miniffs.c index d0cfb2b..15660d7 100644 --- a/miniffs.c +++ b/miniffs.c @@ -25,7 +25,7 @@ file_t *miniffs_open(miniffs_t *fs, char *filename) goto exit; } - ret->private = fs; + ret->private_data = fs; ret->fent = miniffs_findfile(fs, filename); if (!ret->fent) { @@ -47,7 +47,7 @@ exit: int miniffs_close(file_t *file) { /* Let's poison the struct */ - file->private = NULL; + file->private_data = NULL; file->offset = 0; file->fent = NULL; @@ -56,13 +56,13 @@ int miniffs_close(file_t *file) void *miniffs_map(file_t *file) { - miniffs_t *fs = (miniffs_t *)file->private; + miniffs_t *fs = (miniffs_t *)file->private_data; return miniffs_getfileaddr(fs, file->fent); } uint8_t miniffs_read(file_t *file) { - miniffs_t *fs = (miniffs_t *) file->private; + miniffs_t *fs = (miniffs_t *) file->private_data; uint8_t *filePtr = miniffs_getfileaddr(fs, file->fent); uint8_t ret = filePtr[file->offset]; @@ -80,7 +80,7 @@ uint8_t miniffs_read(file_t *file) int miniffs_read_blocks(void *ptr, size_t size, size_t nmemb, file_t *file) { int i; - miniffs_t *fs = (miniffs_t *) file->private; + miniffs_t *fs = (miniffs_t *) file->private_data; uint8_t *filePtr = miniffs_getfileaddr(fs, file->fent); size_t fileOffset = file->offset; size_t bufferOffset = 0; diff --git a/platform/memory.c b/platform/memory.c index 4c27078..c9e9b3d 100644 --- a/platform/memory.c +++ b/platform/memory.c @@ -14,7 +14,15 @@ /* Public API */ miniffs_t *miniffs_openfs(uintptr_t address) { - miniffs_t *fs = (miniffs_t *)calloc(1, sizeof(miniffs_t)); + miniffs_t *fs = NULL; + + if (address == 0) + { + miniffs_seterror(MINIFFS_INVALID_FS); + goto exit; + } + + fs = (miniffs_t *)calloc(1, sizeof(miniffs_t)); if (fs == NULL) { miniffs_seterror(MINIFFS_ALLOCATION_ERROR); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 643d035..331a561 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,11 +9,22 @@ link_libraries(miniffs) set(TESTS_SRC fs_opening.cpp) add_executable(miniffs_test) +target_compile_definitions(miniffs_test PUBLIC BUILD_PLATFORM_${BUILD_PLATFORM}) target_include_directories(miniffs_test PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) target_sources(miniffs_test PRIVATE ${TESTS_SRC}) -target_link_libraries(miniffs_test gtest gtest_main Threads::Threads) +target_link_libraries(miniffs_test gtest gtest_main Threads::Threads miniffs) + +file(GLOB TEST_FSIMG *.mffs) + +add_custom_command( + TARGET miniffs_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${TEST_FSIMG} + ${CMAKE_CURRENT_BINARY_DIR}/ +) gtest_discover_tests(miniffs_test WORKING_DIRECTORY ${PROJECT_DIR} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_DIR}" ) + diff --git a/test/fs_opening.cpp b/test/fs_opening.cpp index 64e7fb2..87b7c7d 100644 --- a/test/fs_opening.cpp +++ b/test/fs_opening.cpp @@ -4,4 +4,50 @@ * * Copyright (c) 2008-2022 986-Studio. All rights reserved. * - ******************************************************************************/ \ No newline at end of file + ******************************************************************************/ + +#include + +#include +#include "get_fs.h" + +TEST(FSOpening, OpeningAFileSystem) +{ + miniffs_t *fs = get_fs("simple_test.mffs"); + ASSERT_NE(fs, nullptr); +} + +TEST(FSOpening, OpeningANonExistingFile) +{ + miniffs_t *fs = get_fs("i_do_not_exists.mffs"); + ASSERT_EQ(fs, nullptr); + ASSERT_EQ(miniffs_geterror(), MINIFFS_INVALID_FS); +} + +TEST(FSOpening, OpeningFsWithWrongMagic) +{ + miniffs_t *fs = get_fs("wrong_magic.mffs"); + ASSERT_EQ(fs, nullptr); + ASSERT_EQ(miniffs_geterror(), MINIFFS_INVALID_FS); +} + +TEST(FSOpening, OpeningFsWithWrongVersion) +{ + miniffs_t *fs = get_fs("wrong_version.mffs"); + ASSERT_EQ(fs, nullptr); + ASSERT_EQ(miniffs_geterror(), MINIFFS_INVALID_FS); +} + +TEST(FSOpening, OpeningFsWithWrongNameLen) +{ + miniffs_t *fs = get_fs("wrong_namelen.mffs"); + ASSERT_EQ(fs, nullptr); + ASSERT_EQ(miniffs_geterror(), MINIFFS_INVALID_FS); +} + +TEST(FSOpening, OpeningFsWithWrongExtLen) +{ + miniffs_t *fs = get_fs("wrong_extlen.mffs"); + ASSERT_EQ(fs, nullptr); + ASSERT_EQ(miniffs_geterror(), MINIFFS_INVALID_FS); +} \ No newline at end of file diff --git a/test/get_fs.h b/test/get_fs.h new file mode 100644 index 0000000..a3dabd5 --- /dev/null +++ b/test/get_fs.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * MiniFFS : Mini Flat File System + * This file is part of the test suite of MiniFFS + * + * This file abstract the filesystem opening, to be able to test both FILE and + * MEMORY backend. + * + * Copyright (c) 2008-2022 986-Studio. All rights reserved. + * + ******************************************************************************/ + +static miniffs_t *get_fs(const char *filename) +{ +#ifdef BUILD_PLATFORM_MEMORY + char *fs_image; + size_t fileSize; +#ifdef _WIN32 + /* As windows do not provide an easy to use mmap equivalent, let's use the fallback + * of opening the file, allocating memory and read the file in the said memory + */ + FILE *fp; + fp = fopen(filename, "rb"); + fseek(fp, 0, SEEK_END); + fileSize = ftell(fp); + fseek(fp, 0, SEEK_SET); + fs_image = (char *)calloc(1, fileSize); + fread(fs_image, 1, fileSize, fp); + fclose(fp); +#else + int fd; + struct stat FileStat; + + fd = open(filename, O_RDWR); + fstat(fd, &FileStat); + fs_image = (char *)mmap(NULL, FileStat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + close(fd); + fileSize = FileStat.st_size + if (fs_image == MAP_FAILED) + { + fs_image = NULL; + } +#endif + return miniffs_openfs((uintptr_t)fs_image); +#else + return miniffs_openfs(filename); +#endif +} diff --git a/test/simple_test.mffs b/test/simple_test.mffs new file mode 100644 index 0000000..171077c Binary files /dev/null and b/test/simple_test.mffs differ diff --git a/test/wrong_extlen.mffs b/test/wrong_extlen.mffs new file mode 100644 index 0000000..5807075 Binary files /dev/null and b/test/wrong_extlen.mffs differ diff --git a/test/wrong_magic.mffs b/test/wrong_magic.mffs new file mode 100644 index 0000000..96ef81d Binary files /dev/null and b/test/wrong_magic.mffs differ diff --git a/test/wrong_namelen.mffs b/test/wrong_namelen.mffs new file mode 100644 index 0000000..b9606a8 Binary files /dev/null and b/test/wrong_namelen.mffs differ diff --git a/test/wrong_version.mffs b/test/wrong_version.mffs new file mode 100644 index 0000000..b19dc80 Binary files /dev/null and b/test/wrong_version.mffs differ