From 81f6faf2d48598840f3360567094760267c67527 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Thu, 6 Jun 2024 22:59:36 +0200
Subject: [PATCH 0708/1160] 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.
(cherry picked from commit 7efaab482af44e0ffcb5242d4f37cc316e705e2d)
src/basic/chase.c | 6 +++---
src/test/test-chase.c | 6 ++++++
2 files changed, 9 insertions(+), 3 deletions(-)
@@ -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;
@@ -236,6 +236,12 @@ TEST(chase) {
assert_se(streq(result, "/test-chase.fsldajfl"));
result = mfree(result);
+ r = chase("/.path/with/dot", temp, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &result, NULL);
+ assert_se(r == 0);
+ q = strjoina(temp, "/.path/with/dot");
+ assert_se(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);
--
2.33.0