From 50ad2945275def8ff9d6ccc956f365dfeab520b5 Mon Sep 17 00:00:00 2001 From: Ben Wiederhake Date: Sat, 11 Sep 2021 12:55:07 +0200 Subject: [PATCH] AK: Implement a way to resolve relative paths lexically --- AK/LexicalPath.cpp | 8 ++++++++ AK/LexicalPath.h | 1 + Tests/AK/TestLexicalPath.cpp | 13 +++++++++++++ 3 files changed, 22 insertions(+) diff --git a/AK/LexicalPath.cpp b/AK/LexicalPath.cpp index f1bd4c5a72..7a4afdf2ec 100644 --- a/AK/LexicalPath.cpp +++ b/AK/LexicalPath.cpp @@ -121,6 +121,14 @@ String LexicalPath::canonicalized_path(String path) return builder.to_string(); } +String LexicalPath::absolute_path(String dir_path, String target) +{ + if (LexicalPath(target).is_absolute()) { + return LexicalPath::canonicalized_path(target); + } + return LexicalPath::canonicalized_path(join(dir_path, target).string()); +} + String LexicalPath::relative_path(StringView const& a_path, StringView const& a_prefix) { if (!a_path.starts_with('/') || !a_prefix.starts_with('/')) { diff --git a/AK/LexicalPath.h b/AK/LexicalPath.h index a14795d6bf..562adbe83b 100644 --- a/AK/LexicalPath.h +++ b/AK/LexicalPath.h @@ -33,6 +33,7 @@ public: [[nodiscard]] LexicalPath parent() const; [[nodiscard]] static String canonicalized_path(String); + [[nodiscard]] static String absolute_path(String dir_path, String target); [[nodiscard]] static String relative_path(StringView const& absolute_path, StringView const& prefix); template diff --git a/Tests/AK/TestLexicalPath.cpp b/Tests/AK/TestLexicalPath.cpp index be6f9f43e6..f4959f73f3 100644 --- a/Tests/AK/TestLexicalPath.cpp +++ b/Tests/AK/TestLexicalPath.cpp @@ -128,6 +128,19 @@ TEST_CASE(trailing_slash) EXPECT_EQ(path.parts_view().size(), 2u); } +TEST_CASE(resolve_absolute_path) +{ + EXPECT_EQ(LexicalPath::absolute_path("/home/anon", "foo.txt"), "/home/anon/foo.txt"); + EXPECT_EQ(LexicalPath::absolute_path("/home/anon/", "foo.txt"), "/home/anon/foo.txt"); + EXPECT_EQ(LexicalPath::absolute_path("/home/anon", "././foo.txt"), "/home/anon/foo.txt"); + EXPECT_EQ(LexicalPath::absolute_path("/home/anon/quux", "../foo.txt"), "/home/anon/foo.txt"); + EXPECT_EQ(LexicalPath::absolute_path("/home/anon/quux", "../test/foo.txt"), "/home/anon/test/foo.txt"); + EXPECT_EQ(LexicalPath::absolute_path("quux", "../test/foo.txt"), "test/foo.txt"); + EXPECT_EQ(LexicalPath::absolute_path("quux", "../../test/foo.txt"), "../test/foo.txt"); + EXPECT_EQ(LexicalPath::absolute_path("quux/bar", "../../test/foo.txt"), "test/foo.txt"); + EXPECT_EQ(LexicalPath::absolute_path("quux/bar/", "../../test/foo.txt"), "test/foo.txt"); +} + TEST_CASE(has_extension) { {