From 33c2cb5918ce52a1a4688becf27da829dc37b80c Mon Sep 17 00:00:00 2001 From: Maksim Denisov Date: Thu, 13 Feb 2025 10:49:46 +0100 Subject: BazelMsgFactory: CreateDirectoryDigestFromTree fail if not all symlinks are resolved. --- .../execution_api/bazel_msg/bazel_msg_factory.cpp | 36 +++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'src/buildtool/execution_api') diff --git a/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp b/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp index d35b041f..34fbccb4 100644 --- a/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp +++ b/src/buildtool/execution_api/bazel_msg/bazel_msg_factory.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -123,15 +124,26 @@ template std::vector const& symlink_names, std::vector const& symlink_digests, BazelMsgFactory::LinkDigestResolveFunc const& resolve_links) - -> std::vector { + -> std::optional> { + if (symlink_names.size() != symlink_digests.size()) { + return std::nullopt; + } + std::vector symlink_targets; + symlink_targets.reserve(symlink_digests.size()); resolve_links(symlink_digests, &symlink_targets); - auto it_name = symlink_names.begin(); - auto it_target = symlink_targets.begin(); + + // Fail if the number of resolved symlinks does not match the requested + // number. + if (symlink_targets.size() != symlink_names.size()) { + return std::nullopt; + } + std::vector symlink_nodes; - // both loops have same length - for (; it_name != symlink_names.end(); ++it_name, ++it_target) { - symlink_nodes.emplace_back(CreateSymlinkNode(*it_name, *it_target)); + symlink_nodes.reserve(symlink_targets.size()); + for (std::size_t i = 0; i < symlink_targets.size(); ++i) { + symlink_nodes.emplace_back( + CreateSymlinkNode(symlink_names[i], symlink_targets[i])); } return symlink_nodes; } @@ -283,13 +295,15 @@ struct DirectoryNodeBundle final { } } } + + auto symlink_nodes = CreateSymlinkNodesFromDigests( + symlink_names, symlink_digests, resolve_links); + if (not symlink_nodes.has_value()) { + return std::nullopt; + } return CreateDirectoryNodeBundle( root_name, - CreateDirectory( - file_nodes, - dir_nodes, - CreateSymlinkNodesFromDigests( - symlink_names, symlink_digests, resolve_links))); + CreateDirectory(file_nodes, dir_nodes, *std::move(symlink_nodes))); } catch (...) { return std::nullopt; } -- cgit v1.2.3