From 75cc8d7c42ad2ad9b793bbdd96302a04e5d40a65 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 11 Apr 2023 04:09:55 +0900 Subject: [PATCH 1/2] path-util: introduce path_prefix_root_cwd() --- src/basic/path-util.c | 28 ++++++++++++++++++++++++++++ src/basic/path-util.h | 1 + src/test/test-path-util.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 0b0f0da760..fa2e26789f 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -100,6 +100,34 @@ int path_make_absolute_cwd(const char *p, char **ret) { return 0; } +int path_prefix_root_cwd(const char *p, const char *root, char **ret) { + _cleanup_free_ char *root_abs = NULL; + char *c; + int r; + + assert(p); + assert(ret); + + /* Unlike path_make_absolute(), this always prefixes root path if specified. + * The root path is always simplified, but the provided path will not. + * This is useful for prefixing the result of chaseat(). */ + + if (empty_or_root(root)) + return path_make_absolute_cwd(p, ret); + + r = path_make_absolute_cwd(root, &root_abs); + if (r < 0) + return r; + + path_simplify(root_abs); + c = path_join(root_abs, p); + if (!c) + return -ENOMEM; + + *ret = c; + return 0; +} + int path_make_relative(const char *from, const char *to, char **ret) { _cleanup_free_ char *result = NULL; unsigned n_parents; diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 7843599816..a0af9de674 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -60,6 +60,7 @@ int path_split_and_make_absolute(const char *p, char ***ret); char* path_make_absolute(const char *p, const char *prefix); int safe_getcwd(char **ret); int path_make_absolute_cwd(const char *p, char **ret); +int path_prefix_root_cwd(const char *p, const char *root, char **ret); int path_make_relative(const char *from, const char *to, char **ret); int path_make_relative_parent(const char *from_child, const char *to, char **ret); char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) _pure_; diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index e40ffea4d5..22e8f3481a 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -494,6 +494,45 @@ TEST(fsck_exists) { assert_se(fsck_exists_for_fstype("/../bin/") == 0); } +TEST(path_prefix_root_cwd) { + _cleanup_free_ char *cwd = NULL, *ret = NULL, *expected = NULL; + + assert_se(safe_getcwd(&cwd) >= 0); + + assert_se(path_prefix_root_cwd("hoge", NULL, &ret) >= 0); + assert_se(expected = path_join(cwd, "hoge")); + assert_se(streq(ret, expected)); + + ret = mfree(ret); + expected = mfree(expected); + + assert_se(path_prefix_root_cwd("/hoge", NULL, &ret) >= 0); + assert_se(streq(ret, "/hoge")); + + ret = mfree(ret); + + assert_se(path_prefix_root_cwd("hoge", "/a/b//./c///", &ret) >= 0); + assert_se(streq(ret, "/a/b/c/hoge")); + + ret = mfree(ret); + + assert_se(path_prefix_root_cwd("hoge", "a/b//./c///", &ret) >= 0); + assert_se(expected = path_join(cwd, "a/b/c/hoge")); + assert_se(streq(ret, expected)); + + ret = mfree(ret); + expected = mfree(expected); + + assert_se(path_prefix_root_cwd("/../hoge/aaa/../././b", "/a/b//./c///", &ret) >= 0); + assert_se(streq(ret, "/a/b/c/../hoge/aaa/../././b")); + + ret = mfree(ret); + + assert_se(path_prefix_root_cwd("/../hoge/aaa/../././b", "a/b//./c///", &ret) >= 0); + assert_se(expected = path_join(cwd, "a/b/c/../hoge/aaa/../././b")); + assert_se(streq(ret, expected)); +} + static void test_path_make_relative_one(const char *from, const char *to, const char *expected) { _cleanup_free_ char *z = NULL; int r; From fb4d9bf47fcc647c3b43f0b61c6bcf0424397f03 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 11 Apr 2023 04:57:34 +0900 Subject: [PATCH 2/2] find-esp: use path_prefix_root_cwd() Unlikely, but even if find_esp() or friends called with unnormalized or relative 'root', let's make the result path normalized and absolute. Note, before 63105f33edad423691e2d53bf7071f99c83799ba, these functions returned an absolute and normalized path. But the commit made the result path simply concatenated with root. Follow-up for 63105f33edad423691e2d53bf7071f99c83799ba. --- src/shared/find-esp.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c index 0d45249d63..6a0002a2bd 100644 --- a/src/shared/find-esp.c +++ b/src/shared/find-esp.c @@ -540,11 +540,9 @@ int find_esp_and_warn( return r; if (ret_path) { - char *q = path_join(empty_to_root(root), p); - if (!q) - return -ENOMEM; - - *ret_path = TAKE_PTR(q); + r = path_prefix_root_cwd(p, root, ret_path); + if (r < 0) + return r; } if (ret_part) *ret_part = part; @@ -861,11 +859,9 @@ int find_xbootldr_and_warn( return r; if (ret_path) { - char *q = path_join(empty_to_root(root), p); - if (!q) - return -ENOMEM; - - *ret_path = TAKE_PTR(q); + r = path_prefix_root_cwd(p, root, ret_path); + if (r < 0) + return r; } if (ret_uuid) *ret_uuid = uuid;