This is an automated email from the ASF dual-hosted git repository. pengzheng pushed a commit to branch feature/refactor_bundle_cache in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to refs/heads/feature/refactor_bundle_cache by this push: new 481645ea Don't follow symbolic links when deleting directory recursively. new 3705a7cf Merge remote-tracking branch 'apache/feature/refactor_bundle_cache' into feature/refactor_bundle_cache 481645ea is described below commit 481645eaa0e8ab4e9bd6d0e573a0bd995542fd86 Author: PengZheng <howto...@gmail.com> AuthorDate: Tue Feb 28 20:09:17 2023 +0800 Don't follow symbolic links when deleting directory recursively. --- libs/utils/gtest/src/FileUtilsTestSuite.cc | 35 +++++++++++++++++++++++++++++- libs/utils/src/celix_file_utils.c | 4 +++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/libs/utils/gtest/src/FileUtilsTestSuite.cc b/libs/utils/gtest/src/FileUtilsTestSuite.cc index a2b59519..8c3c9e38 100644 --- a/libs/utils/gtest/src/FileUtilsTestSuite.cc +++ b/libs/utils/gtest/src/FileUtilsTestSuite.cc @@ -18,7 +18,9 @@ */ #include <gtest/gtest.h> +#include <string> #include <thread> +#include <unistd.h> #include "celix_file_utils.h" #include "celix_properties.h" @@ -72,7 +74,7 @@ TEST_F(FileUtilsTestSuite, CreateAndDeleteDirectory) { status = celix_utils_deleteDirectory(testDir, nullptr); EXPECT_EQ(status, CELIX_SUCCESS); - //Can i create and delete a dir with ends with a / + //Can I create and delete a dir with ends with a / status = celix_utils_createDirectory(testDir2, true, nullptr); EXPECT_EQ(status, CELIX_SUCCESS); EXPECT_TRUE(celix_utils_fileExists(testDir2)); @@ -83,6 +85,37 @@ TEST_F(FileUtilsTestSuite, CreateAndDeleteDirectory) { EXPECT_EQ(status, CELIX_SUCCESS); status = celix_utils_deleteDirectory(testDir3, nullptr); EXPECT_EQ(status, CELIX_SUCCESS); + + //Can I delete dir containing a dangling symbolic link, which will cause `stat` return ENOENT + status = celix_utils_createDirectory(testDir, true, &error); + EXPECT_EQ(status, CELIX_SUCCESS); + EXPECT_EQ(error, nullptr); + std::string symLink = testDir; + symLink += "/link"; + status = symlink("non-existent", symLink.c_str()); + EXPECT_EQ(status, CELIX_SUCCESS); + status = celix_utils_deleteDirectory(testDir, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); + + //Can I delete a dir containing a symbolic link without touch the target + status = celix_utils_createDirectory(testDir, true, &error); + EXPECT_EQ(status, CELIX_SUCCESS); + EXPECT_EQ(error, nullptr); + status = celix_utils_createDirectory(testDir2, true, &error); + EXPECT_EQ(status, CELIX_SUCCESS); + EXPECT_EQ(error, nullptr); + std::string subDir = testDir2; + subDir += "sub"; + status = celix_utils_createDirectory(subDir.c_str(), true, &error); + EXPECT_EQ(status, CELIX_SUCCESS); + status = symlink("../directory2", symLink.c_str()); // link -> ../directory2 + EXPECT_EQ(status, CELIX_SUCCESS); + status = celix_utils_deleteDirectory(testDir, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); + EXPECT_TRUE(celix_utils_fileExists(testDir2)); + EXPECT_TRUE(celix_utils_fileExists(subDir.c_str())); + status = celix_utils_deleteDirectory(testDir2, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); } TEST_F(FileUtilsTestSuite, ExtractZipFileTest) { diff --git a/libs/utils/src/celix_file_utils.c b/libs/utils/src/celix_file_utils.c index ac0b2224..8afeb3aa 100644 --- a/libs/utils/src/celix_file_utils.c +++ b/libs/utils/src/celix_file_utils.c @@ -26,6 +26,7 @@ #include <stdlib.h> #include <zip.h> #include <sys/time.h> +#include <unistd.h> #include "celix_utils.h" @@ -139,7 +140,8 @@ celix_status_t celix_utils_deleteDirectory(const char* path, const char** errorO asprintf(&subdir, "%s/%s", path, dent->d_name); struct stat st; - if (stat(subdir, &st) == 0) { + // we don't follow symbol link, remove it directly + if (lstat(subdir, &st) == 0) { if (S_ISDIR (st.st_mode)) { status = celix_utils_deleteDirectory(subdir, errorOut); } else {