diff options
author | Maksim Denisov <denisov.maksim@huawei.com> | 2024-08-30 18:41:39 +0200 |
---|---|---|
committer | Maksim Denisov <denisov.maksim@huawei.com> | 2024-09-09 13:07:13 +0200 |
commit | ff456d3f2fcfdb0bfa6edaa4823c1337ce7eeb51 (patch) | |
tree | 87303cfacf5e0cc023ea486a8d7f737b9fdfc95f /src/buildtool/common | |
parent | dbe0cbbab5d86bd795810e4f57ea788cd42b2caf (diff) | |
download | justbuild-ff456d3f2fcfdb0bfa6edaa4823c1337ce7eeb51.tar.gz |
Validate bazel_re::Digests in BazelDigestFactory
Diffstat (limited to 'src/buildtool/common')
-rw-r--r-- | src/buildtool/common/TARGETS | 4 | ||||
-rw-r--r-- | src/buildtool/common/bazel_digest_factory.cpp | 49 | ||||
-rw-r--r-- | src/buildtool/common/bazel_digest_factory.hpp | 44 |
3 files changed, 85 insertions, 12 deletions
diff --git a/src/buildtool/common/TARGETS b/src/buildtool/common/TARGETS index e2db528c..88364386 100644 --- a/src/buildtool/common/TARGETS +++ b/src/buildtool/common/TARGETS @@ -43,12 +43,16 @@ { "type": ["@", "rules", "CC", "library"] , "name": ["bazel_digest_factory"] , "hdrs": ["bazel_digest_factory.hpp"] + , "srcs": ["bazel_digest_factory.cpp"] , "deps": [ "bazel_types" , ["src/buildtool/crypto", "hash_function"] + , ["src/buildtool/crypto", "hash_info"] , ["src/buildtool/file_system", "object_type"] , ["src/utils/cpp", "gsl"] + , ["src/utils/cpp", "expected"] ] + , "private-deps": [["src/buildtool/crypto", "hasher"]] , "stage": ["src", "buildtool", "common"] } , "common": diff --git a/src/buildtool/common/bazel_digest_factory.cpp b/src/buildtool/common/bazel_digest_factory.cpp new file mode 100644 index 00000000..4ff885aa --- /dev/null +++ b/src/buildtool/common/bazel_digest_factory.cpp @@ -0,0 +1,49 @@ +// Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/buildtool/common/bazel_digest_factory.hpp" + +#include <utility> + +#include "src/buildtool/crypto/hasher.hpp" + +auto BazelDigestFactory::Create(HashInfo const& hash_info, + std::int64_t size) noexcept + -> bazel_re::Digest { + auto hash = hash_info.HashType() == HashFunction::Type::GitSHA1 + ? Prefix(hash_info.Hash(), hash_info.IsTree()) + : hash_info.Hash(); + + bazel_re::Digest digest{}; + digest.set_hash(std::move(hash)); + digest.set_size_bytes(size); + return digest; +} + +auto BazelDigestFactory::ToHashInfo(HashFunction::Type hash_type, + bazel_re::Digest const& digest) noexcept + -> expected<HashInfo, std::string> { + bool const is_prefixed = IsPrefixed(hash_type, digest.hash()); + + auto hash = is_prefixed ? Unprefix(digest.hash()) : digest.hash(); + auto const is_tree = is_prefixed and digest.hash().starts_with(kTreeTag); + return HashInfo::Create(hash_type, std::move(hash), is_tree); +} + +auto BazelDigestFactory::IsPrefixed(HashFunction::Type hash_type, + std::string const& hash) noexcept -> bool { + auto const tagged_length = + HashFunction{hash_type}.MakeHasher().GetHashLength() + kTagLength; + return hash.size() == tagged_length; +} diff --git a/src/buildtool/common/bazel_digest_factory.hpp b/src/buildtool/common/bazel_digest_factory.hpp index e08eabb7..67ee35cb 100644 --- a/src/buildtool/common/bazel_digest_factory.hpp +++ b/src/buildtool/common/bazel_digest_factory.hpp @@ -22,13 +22,33 @@ #include "gsl/gsl" #include "src/buildtool/common/bazel_types.hpp" #include "src/buildtool/crypto/hash_function.hpp" +#include "src/buildtool/crypto/hash_info.hpp" #include "src/buildtool/file_system/object_type.hpp" +#include "src/utils/cpp/expected.hpp" class BazelDigestFactory final { static constexpr auto kBlobTag = "62"; static constexpr auto kTreeTag = "74"; + static constexpr std::size_t kTagLength = 2; public: + /// \brief Create bazel_re::Digest from preliminarily validated data. + /// \param hash_data Validated hash + /// \param size Size of the content + [[nodiscard]] static auto Create(HashInfo const& hash_info, + std::int64_t size) noexcept + -> bazel_re::Digest; + + /// \brief Validate bazel_re::Digest + /// \param hash_type Type of the hash function that was used for creation + /// of the hash + /// \param digest Digest to be validated + /// \return Validated hash on success or an error message on failure. + [[nodiscard]] static auto ToHashInfo( + HashFunction::Type hash_type, + bazel_re::Digest const& digest) noexcept + -> expected<HashInfo, std::string>; + /// \brief Hash content using hash function and return a valid /// bazel_re::Digest /// \tparam kType Type of the hashing algorithm to be used @@ -39,18 +59,9 @@ class BazelDigestFactory final { [[nodiscard]] static auto HashDataAs(HashFunction hash_function, std::string const& content) -> bazel_re::Digest { - static constexpr bool kIsTree = IsTreeObject(kType); - auto const hash_digest = kIsTree ? hash_function.HashTreeData(content) - : hash_function.HashBlobData(content); - - auto hash = hash_function.GetType() == HashFunction::Type::GitSHA1 - ? Prefix(hash_digest.HexString(), kIsTree) - : hash_digest.HexString(); - - bazel_re::Digest digest{}; - digest.set_hash(std::move(hash)); - digest.set_size_bytes(gsl::narrow<std::int64_t>(content.size())); - return digest; + auto const hash_info = + HashInfo::HashData(hash_function, content, IsTreeObject(kType)); + return Create(hash_info, gsl::narrow<std::int64_t>(content.size())); } private: @@ -58,6 +69,15 @@ class BazelDigestFactory final { bool is_tree) noexcept -> std::string { return (is_tree ? kTreeTag : kBlobTag) + hash; } + + [[nodiscard]] static auto Unprefix(std::string const& hash) noexcept + -> std::string { + return hash.substr(kTagLength); + } + + [[nodiscard]] static auto IsPrefixed(HashFunction::Type hash_type, + std::string const& hash) noexcept + -> bool; }; #endif // INCLUDED_SRC_BUILDTOOL_COMMON_BAZEL_DIGEST_FACTORY_HPP |