From: Daan De Meyer Date: Thu, 6 Jun 2024 20:59:36 +0000 (+0200) Subject: chase: Tighten "." and "./" check X-Git-Tag: v256~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7efaab482af44e0ffcb5242d4f37cc316e705e2d;p=thirdparty%2Fsystemd.git chase: Tighten "." and "./" check 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. --- diff --git a/src/basic/chase.c b/src/basic/chase.c index 245dd0800ef..4576e4b0588 100644 --- a/src/basic/chase.c +++ b/src/basic/chase.c @@ -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; diff --git a/src/test/test-chase.c b/src/test/test-chase.c index 5d3ee7aceec..13ee7028c87 100644 --- a/src/test/test-chase.c +++ b/src/test/test-chase.c @@ -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);