Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CoDeLib/FileUtils/src/FileUtils.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ bool RecursiveRmdir(const char *const pDirname) {
return false;
}

const size_t dirnameLength =
strnlen(pDirname, MAX_PATH_LENGTH_WTH_TERMINATOR);
if (dirnameLength == 0 || dirnameLength >= MAX_PATH_LENGTH_WTH_TERMINATOR) {
return false;
}

const char lastChar = pDirname[dirnameLength - 1];
if (lastChar != '/' && lastChar != '\\') {
return false;
}

const int maxOpenFiles = 64;
const int flags = FTW_DEPTH | FTW_PHYS;
int status = nftw(pDirname, _HandleFtwCallback_Remove, maxOpenFiles, flags);
Expand Down
59 changes: 59 additions & 0 deletions CoDeLib/Test/src/TestFileUtils.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,49 @@ TEST(TestFileUtils, test_RecursiveRmdir_ReturnsFalseIfDirnameIsNull) {
TEST_ASSERT_FALSE(success);
}

TEST(TestFileUtils, test_RecursiveRmdir_ReturnsFalseIfDirnameIsEmpty) {
bool success = RecursiveRmdir("");
TEST_ASSERT_FALSE(success);
}

TEST(TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfDirnameIsLargerThanMaxPath) {
char localBuffer[MAX_PATH_LENGTH_WTH_TERMINATOR + 1];
memset(localBuffer, 'a', MAX_PATH_LENGTH_WTH_TERMINATOR);
localBuffer[MAX_PATH_LENGTH_WTH_TERMINATOR] = '\0';

bool success = RecursiveRmdir(localBuffer);
TEST_ASSERT_FALSE(success);
}

TEST(
TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfRelativePathDoesNotEndInSlash_WindowsStyle) {
bool success = RecursiveRmdir(".\\NonExisting\\other");
TEST_ASSERT_FALSE(success);
}

TEST(
TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfRelativePathDoesNotEndInSlash_PosixStyle) {
bool success = RecursiveRmdir("./NonExisting/other");
TEST_ASSERT_FALSE(success);
}

TEST(
TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfAbsolutePathDoesNotEndInSlash_WindowsStyle) {
bool success = RecursiveRmdir("C:\\NonExisting\\other");
TEST_ASSERT_FALSE(success);
}

TEST(
TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfAbsolutePathDoesNotEndInSlash_PosixStyle) {
bool success = RecursiveRmdir("/NonExisting/other");
TEST_ASSERT_FALSE(success);
}

TEST(TestFileUtils, test_RecursiveRmdir_CanDeleteAbsolutePath) {
RAII_STRING tmpPath =
RaiiStringCreateFromCString(g_pFullPathToBenchmarkTestFiles);
Expand Down Expand Up @@ -723,6 +766,22 @@ TEST_GROUP_RUNNER(TestFileUtils) {
// RecursiveRmdir(...)
RUN_TEST_CASE(TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfDirnameIsNull);
RUN_TEST_CASE(TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfDirnameIsEmpty);
RUN_TEST_CASE(TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfDirnameIsLargerThanMaxPath);
RUN_TEST_CASE(
TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfRelativePathDoesNotEndInSlash_WindowsStyle);
RUN_TEST_CASE(
TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfRelativePathDoesNotEndInSlash_PosixStyle);
RUN_TEST_CASE(
TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfAbsolutePathDoesNotEndInSlash_WindowsStyle);
RUN_TEST_CASE(
TestFileUtils,
test_RecursiveRmdir_ReturnsFalseIfAbsolutePathDoesNotEndInSlash_PosixStyle);
RUN_TEST_CASE(TestFileUtils, test_RecursiveRmdir_CanDeleteAbsolutePath);
RUN_TEST_CASE(TestFileUtils,
test_RecursiveRmdir_CanDeleteRecursiveAbsolutePath);
Expand Down
3 changes: 2 additions & 1 deletion CoDeLib/include/CoDeLib/FileUtils/FileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ bool RecursiveMkdir(const char *const pDirname);
/*!
@brief Recursively deletes a directory and all files. If the directory does not
exist, nothing happens.
@param pDirname The directory to delete. The directory needs to end in '/'.
@param pDirname The directory to delete. The directory needs to end in '/' or
'\\' ('\' escaped).
@return true if the directory was deleted or did not exist, false otherwise.
*/
bool RecursiveRmdir(const char *const pDirname);
Expand Down