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 {

Reply via email to