diff options
author | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2023-06-13 17:35:05 +0200 |
---|---|---|
committer | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2023-06-26 17:57:29 +0200 |
commit | c11e9142d2a1b04004dcbed282dc1e04d116e03f (patch) | |
tree | b1c72fa8f9491f35b3c631ce98acbf00e627a59d /src/buildtool/file_system/git_tree.cpp | |
parent | d2e3ad946b35a72a94b2d125550daf5d5e4c9904 (diff) | |
download | justbuild-c11e9142d2a1b04004dcbed282dc1e04d116e03f.tar.gz |
ReadTree: Add check for non-upwards symlinks...
...as early as possible. This ensures that callers always receive
only the tree entries for the supported object types.
For the symlinks non-upwardness check we pass a lambda capturing
the real backend of the tree entries, such that the symlinks can
be read.
Updates git_tree tests accordingly.
Diffstat (limited to 'src/buildtool/file_system/git_tree.cpp')
-rw-r--r-- | src/buildtool/file_system/git_tree.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/buildtool/file_system/git_tree.cpp b/src/buildtool/file_system/git_tree.cpp index d594e638..a3c441d9 100644 --- a/src/buildtool/file_system/git_tree.cpp +++ b/src/buildtool/file_system/git_tree.cpp @@ -16,8 +16,9 @@ #include <sstream> +#include "src/buildtool/common/artifact_digest.hpp" #include "src/buildtool/logging/logger.hpp" -#include "src/utils/cpp/hex_string.hpp" +#include "src/utils/cpp/path.hpp" extern "C" { #include <git2.h> @@ -68,11 +69,24 @@ auto GitTree::Read(std::filesystem::path const& repo_path, auto GitTree::Read(gsl::not_null<GitCASPtr> const& cas, std::string const& tree_id, bool ignore_special) noexcept -> std::optional<GitTree> { + // create symlinks checker + auto check_symlinks = [&cas](std::vector<bazel_re::Digest> const& ids) { + for (auto const& id : ids) { + auto content = + cas->ReadObject(ArtifactDigest(id).hash(), /*is_hex_id=*/true); + if (not content or not PathIsNonUpwards(*content)) { + return false; + } + } + return true; + }; if (auto raw_id = FromHexString(tree_id)) { auto repo = GitRepo::Open(cas); if (repo != std::nullopt) { - if (auto entries = repo->ReadTree( - *raw_id, /*is_hex_id=*/false, ignore_special)) { + if (auto entries = repo->ReadTree(*raw_id, + check_symlinks, + /*is_hex_id=*/false, + ignore_special)) { // the raw_id value is NOT recomputed when ignore_special==true, // so we set it to empty to signal that it should not be used! return GitTree::FromEntries(cas, @@ -133,8 +147,22 @@ auto GitTreeEntry::Tree(bool ignore_special) const& noexcept if (repo == std::nullopt) { return std::nullopt; } - if (auto entries = repo->ReadTree( - raw_id_, /*is_hex_id=*/false, ignore_special)) { + // create symlinks checker + auto check_symlinks = + [cas = cas_](std::vector<bazel_re::Digest> const& ids) { + for (auto const& id : ids) { + auto content = cas->ReadObject( + ArtifactDigest(id).hash(), /*is_hex_id=*/true); + if (not content or not PathIsNonUpwards(*content)) { + return false; + } + } + return true; + }; + if (auto entries = repo->ReadTree(raw_id_, + check_symlinks, + /*is_hex_id=*/false, + ignore_special)) { // the raw_id value is not used when ignore_special==true return GitTree::FromEntries( cas_, std::move(*entries), raw_id_, ignore_special); |