]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
chase: Tighten "." and "./" check
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 6 Jun 2024 20:59:36 +0000 (22:59 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 11 Jun 2024 12:55:35 +0000 (13:55 +0100)
Currently the check also succeeds if the input path starts with a dot, whereas
we only want it to succeed for "." and "./". Tighten the check and add a test.

src/basic/chase.c
src/test/test-chase.c

index 245dd0800ef74ce3abb9c6ad57f33cf53bae3005..4576e4b0588919df46b2eb9a5e414e8c1e78bbfe 100644 (file)
@@ -641,8 +641,8 @@ int chase(const char *path, const char *root, ChaseFlags flags, char **ret_path,
                          * absolute, hence it is not necessary to prefix with the root. When "root" points to
                          * a non-root directory, the result path is always normalized and relative, hence
                          * we can simply call path_join() and not necessary to call path_simplify().
-                         * Note that the result of chaseat() may start with "." (more specifically, it may be
-                         * "." or "./"), and we need to drop "." in that case. */
+                         * As a special case, chaseat() may return "." or "./", which are normalized too,
+                         * but we need to drop "." before merging with root. */
 
                         if (empty_or_root(root))
                                 assert(path_is_absolute(p));
@@ -651,7 +651,7 @@ int chase(const char *path, const char *root, ChaseFlags flags, char **ret_path,
 
                                 assert(!path_is_absolute(p));
 
-                                q = path_join(root, p + (*p == '.'));
+                                q = path_join(root, p + STR_IN_SET(p, ".", "./"));
                                 if (!q)
                                         return -ENOMEM;
 
index 5d3ee7aceecc43146dbe55368189c24bc54d5c1c..13ee7028c87dc142d22a5b6d661d956a7ed9d781 100644 (file)
@@ -236,6 +236,12 @@ TEST(chase) {
         ASSERT_STREQ(result, "/test-chase.fsldajfl");
         result = mfree(result);
 
+        r = chase("/.path/with/dot", temp, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &result, NULL);
+        ASSERT_OK(r);
+        q = strjoina(temp, "/.path/with/dot");
+        ASSERT_STREQ(result, q);
+        result = mfree(result);
+
         r = chase("/etc/machine-id/foo", NULL, 0, &result, NULL);
         assert_se(IN_SET(r, -ENOTDIR, -ENOENT));
         result = mfree(result);