From c0226e230601972e0b4bf55f74a6514409d47bfe Mon Sep 17 00:00:00 2001 From: Paul Cristian Sarbu Date: Mon, 17 Jul 2023 13:15:27 +0200 Subject: utils: Add function to check for confined paths --- src/utils/cpp/path.hpp | 17 +++++++++++++++++ test/utils/cpp/path.test.cpp | 8 ++++++++ 2 files changed, 25 insertions(+) diff --git a/src/utils/cpp/path.hpp b/src/utils/cpp/path.hpp index 3b44748a..bbbbfbf6 100644 --- a/src/utils/cpp/path.hpp +++ b/src/utils/cpp/path.hpp @@ -42,4 +42,21 @@ return *path.lexically_normal().begin() != ".."; } +/// \brief Perform a confined condition check on a path with respect to +/// another path. A path is confined wrt another if it is relative and results +/// in a non-upwards path when applied from the directory of the other path. +/// This models the situation when a symlink is being resolved inside a tree. +/// NOTE: No explicit check is done whether applied_to is actually a relative +/// path, as this is implicit by the non-upwardness condition. +[[nodiscard]] static auto PathIsConfined( + std::filesystem::path const& path, + std::filesystem::path const& applied_to) noexcept -> bool { + if (path.is_absolute()) { + return false; + } + // check confined upwards condition; this call also handles the case when + // applied_to is an absolute path + return PathIsNonUpwards(applied_to.parent_path() / path); +} + #endif diff --git a/test/utils/cpp/path.test.cpp b/test/utils/cpp/path.test.cpp index 5a450fd5..7a0ac1fe 100644 --- a/test/utils/cpp/path.test.cpp +++ b/test/utils/cpp/path.test.cpp @@ -40,3 +40,11 @@ TEST_CASE("non-upwards condition", "[path]") { CHECK_FALSE(PathIsNonUpwards( "foo/../bar/../../foo")); // relative with non-upwards indirection } + +TEST_CASE("confined upwards condition", "[path]") { + CHECK_FALSE(PathIsConfined("/foo", "dummy")); // absolute path + CHECK(PathIsConfined("foo", "dummy")); // relative non-upwards + CHECK(PathIsConfined("../foo", "dummy/bar")); // upwards, but confined + CHECK_FALSE(PathIsConfined("foo/../bar/../../../foo", + "dummy")); // upwards, not confined +} -- cgit v1.2.3