]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
chase: prefix with the root directory only when it is not "/"
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 17 Apr 2023 06:28:42 +0000 (15:28 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 18 Apr 2023 18:28:34 +0000 (03:28 +0900)
src/basic/chase.c

index aff2bfc3b7c8f44df41f1376122690db4c702c83..96b59e7845ff8d90236e18037b304bde69f0d71f 100644 (file)
@@ -551,19 +551,27 @@ int chase(const char *path, const char *root, ChaseFlags flags, char **ret_path,
 
         if (ret_path) {
                 if (!FLAGS_SET(flags, CHASE_EXTRACT_FILENAME)) {
-                        _cleanup_free_ char *q = NULL;
 
-                        q = path_join(root, p);
-                        if (!q)
-                                return -ENOMEM;
+                        /* When "root" points to the root directory, the result of chaseat() is always
+                         * 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. */
+
+                        if (empty_or_root(root))
+                                assert(path_is_absolute(p));
+                        else {
+                                char *q;
 
-                        path_simplify(q);
+                                assert(!path_is_absolute(p));
 
-                        if (FLAGS_SET(flags, CHASE_TRAIL_SLASH) && ENDSWITH_SET(path, "/", "/."))
-                                if (!strextend(&q, "/"))
+                                q = path_join(root, p + (*p == '.'));
+                                if (!q)
                                         return -ENOMEM;
 
-                        free_and_replace(p, q);
+                                free_and_replace(p, q);
+                        }
                 }
 
                 *ret_path = TAKE_PTR(p);