From: Yu Watanabe Date: Mon, 17 Apr 2023 06:28:42 +0000 (+0900) Subject: chase: prefix with the root directory only when it is not "/" X-Git-Tag: v254-rc1~681^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a0dcf03faaf73527085c470f0ddf77e0457aecf;p=thirdparty%2Fsystemd.git chase: prefix with the root directory only when it is not "/" --- diff --git a/src/basic/chase.c b/src/basic/chase.c index aff2bfc3b7c..96b59e7845f 100644 --- a/src/basic/chase.c +++ b/src/basic/chase.c @@ -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);