diff options
author | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2023-07-17 13:15:27 +0200 |
---|---|---|
committer | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2023-08-07 17:01:01 +0200 |
commit | c0226e230601972e0b4bf55f74a6514409d47bfe (patch) | |
tree | f6b13a9dfdec3b728a201c63b49b2ff1d97c46bc | |
parent | 317cb72c64330036f23fd19a7caf65637bac5bc1 (diff) | |
download | justbuild-c0226e230601972e0b4bf55f74a6514409d47bfe.tar.gz |
utils: Add function to check for confined paths
-rw-r--r-- | src/utils/cpp/path.hpp | 17 | ||||
-rw-r--r-- | test/utils/cpp/path.test.cpp | 8 |
2 files changed, 25 insertions, 0 deletions
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 +} |