]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
path-util: move empty_or_root_to_null() from chase.c
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 28 Jun 2025 11:55:11 +0000 (20:55 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 29 Jun 2025 18:45:29 +0000 (03:45 +0900)
And rename it to empty_or_root_harder_to_null(), as it also checks if
the input path effectively points to the root by calling path_is_root().
This also adds simple test cases for the function.

src/basic/chase.c
src/basic/path-util.c
src/basic/path-util.h
src/test/test-path-util.c

index 34423cc3004d17b1b256665656e9bdeebfb5cc6d..8fd7e67559e100f2ef42c6cc6fad7f7724d52bdf 100644 (file)
@@ -565,27 +565,6 @@ chased_one:
         return 0;
 }
 
-static int empty_or_root_to_null(const char **path) {
-        int r;
-
-        assert(path);
-
-        /* This nullifies the input path when the path is empty or points to "/". */
-
-        if (empty_or_root(*path)) {
-                *path = NULL;
-                return 0;
-        }
-
-        r = path_is_root(*path);
-        if (r < 0)
-                return r;
-        if (r > 0)
-                *path = NULL;
-
-        return 0;
-}
-
 int chase(const char *path, const char *root, ChaseFlags flags, char **ret_path, int *ret_fd) {
         _cleanup_free_ char *root_abs = NULL, *absolute = NULL, *p = NULL;
         _cleanup_close_ int fd = -EBADF, pfd = -EBADF;
@@ -596,7 +575,7 @@ int chase(const char *path, const char *root, ChaseFlags flags, char **ret_path,
         if (isempty(path))
                 return -EINVAL;
 
-        r = empty_or_root_to_null(&root);
+        r = empty_or_root_harder_to_null(&root);
         if (r < 0)
                 return r;
 
@@ -696,7 +675,7 @@ int chaseat_prefix_root(const char *path, const char *root, char **ret) {
         if (!path_is_absolute(path)) {
                 _cleanup_free_ char *root_abs = NULL;
 
-                r = empty_or_root_to_null(&root);
+                r = empty_or_root_harder_to_null(&root);
                 if (r < 0 && r != -ENOENT)
                         return r;
 
@@ -735,7 +714,7 @@ int chase_extract_filename(const char *path, const char *root, char **ret) {
         if (!path_is_absolute(path))
                 return -EINVAL;
 
-        r = empty_or_root_to_null(&root);
+        r = empty_or_root_harder_to_null(&root);
         if (r < 0 && r != -ENOENT)
                 return r;
 
index dd23d3f6ab09276b639a05d31c15f761d5750287..36cf9a16491a53ff1c416a211b7999da5b63b05d 100644 (file)
@@ -1406,6 +1406,27 @@ const char* empty_to_root(const char *path) {
         return isempty(path) ? "/" : path;
 }
 
+int empty_or_root_harder_to_null(const char **path) {
+        int r;
+
+        assert(path);
+
+        /* This nullifies the input path when the path is empty or points to "/". */
+
+        if (empty_or_root(*path)) {
+                *path = NULL;
+                return 0;
+        }
+
+        r = path_is_root(*path);
+        if (r < 0)
+                return r;
+        if (r > 0)
+                *path = NULL;
+
+        return 0;
+}
+
 bool path_strv_contains(char * const *l, const char *path) {
         assert(path);
 
index a209223bccd404d46715433b3f7a45a87a0c6532..45518c07e50cefb19403d934bd962c3d46fbeec2 100644 (file)
@@ -179,6 +179,7 @@ static inline const char* skip_dev_prefix(const char *p) {
 
 bool empty_or_root(const char *path) _pure_;
 const char* empty_to_root(const char *path) _pure_;
+int empty_or_root_harder_to_null(const char **path);
 
 bool path_strv_contains(char * const *l, const char *path);
 bool prefixed_path_strv_contains(char * const *l, const char *path);
index ea025cb13541b65d4a014679401a63fc159f596f..cbe0341fe4b9c9bff648ea49fb049183657ccbf4 100644 (file)
@@ -1238,6 +1238,42 @@ TEST(empty_or_root) {
         assert_se(!empty_or_root("//yy//"));
 }
 
+TEST(empty_or_root_harder_to_null) {
+        const char *p;
+
+        p = NULL;
+        ASSERT_OK(empty_or_root_harder_to_null(&p));
+        ASSERT_NULL(p);
+
+        p = "/";
+        ASSERT_OK(empty_or_root_harder_to_null(&p));
+        ASSERT_NULL(p);
+
+        p = "////////";
+        ASSERT_OK(empty_or_root_harder_to_null(&p));
+        ASSERT_NULL(p);
+
+        p = "/../../././//";
+        ASSERT_OK(empty_or_root_harder_to_null(&p));
+        ASSERT_NULL(p);
+
+        p = "/usr";
+        ASSERT_OK(empty_or_root_harder_to_null(&p));
+        ASSERT_STREQ(p, "/usr");
+
+        p = "/usr/../../../";
+        ASSERT_OK(empty_or_root_harder_to_null(&p));
+        ASSERT_NULL(p);
+
+        p = "/usr/";
+        ASSERT_OK(empty_or_root_harder_to_null(&p));
+        ASSERT_STREQ(p, "/usr/");
+
+        p = "///././/../../usr////";
+        ASSERT_OK(empty_or_root_harder_to_null(&p));
+        ASSERT_STREQ(p, "///././/../../usr////");
+}
+
 TEST(path_startswith_set) {
         ASSERT_STREQ(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo/bar", "/zzz"), "");
         ASSERT_STREQ(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo/", "/zzz"), "bar");