summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2023-07-17 13:15:27 +0200
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2023-08-07 17:01:01 +0200
commitc0226e230601972e0b4bf55f74a6514409d47bfe (patch)
treef6b13a9dfdec3b728a201c63b49b2ff1d97c46bc
parent317cb72c64330036f23fd19a7caf65637bac5bc1 (diff)
downloadjustbuild-c0226e230601972e0b4bf55f74a6514409d47bfe.tar.gz
utils: Add function to check for confined paths
-rw-r--r--src/utils/cpp/path.hpp17
-rw-r--r--test/utils/cpp/path.test.cpp8
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
+}