diff options
author | MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> | 2024-07-18 22:38:14 +0200 |
---|---|---|
committer | MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> | 2024-07-24 17:38:06 +0200 |
commit | fad2991ba073de0bd1f12e42bf0fbaca4a265508 (patch) | |
tree | 0889ecf0db4868751eed32460dfd808ab33cf407 /src/uint256.h | |
parent | fa103db2bb736bce4440f0bde564e6671e36311d (diff) |
refactor: Implement strict uint256::FromHex()
This is a safe replacement of the previous SetHex, which now returns an
optional to indicate success or failure.
The code is similar to the ParseHashStr helper, which will be removed in
a later commit.
Diffstat (limited to 'src/uint256.h')
-rw-r--r-- | src/uint256.h | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/uint256.h b/src/uint256.h index 3f7dce6983..f8e78b820f 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2022 The Bitcoin Core developers +// Copyright (c) 2009-present The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,12 +8,14 @@ #include <crypto/common.h> #include <span.h> +#include <util/strencodings.h> #include <algorithm> #include <array> #include <cassert> +#include <cstdint> #include <cstring> -#include <stdint.h> +#include <optional> #include <string> /** Template base class for fixed-sized opaque blobs. */ @@ -59,6 +61,7 @@ public: // Hex string representations are little-endian. std::string GetHex() const; + /** Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated */ void SetHexDeprecated(std::string_view str); std::string ToString() const; @@ -88,12 +91,30 @@ public: } }; +namespace detail { +/** + * Writes the hex string (treated as little-endian) into a new uintN_t object + * and only returns a value iff all of the checks pass: + * - Input length is uintN_t::size()*2 + * - All characters are hex + */ +template <class uintN_t> +std::optional<uintN_t> FromHex(std::string_view str) +{ + if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt; + uintN_t rv; + rv.SetHexDeprecated(str); + return rv; +} +} // namespace detail + /** 160-bit opaque blob. * @note This type is called uint160 for historical reasons only. It is an opaque * blob of 160 bits and has no integer operations. */ class uint160 : public base_blob<160> { public: + static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); } constexpr uint160() = default; constexpr explicit uint160(Span<const unsigned char> vch) : base_blob<160>(vch) {} }; @@ -105,6 +126,7 @@ public: */ class uint256 : public base_blob<256> { public: + static std::optional<uint256> FromHex(std::string_view str) { return detail::FromHex<uint256>(str); } constexpr uint256() = default; constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {} @@ -113,8 +135,7 @@ public: }; /* uint256 from std::string_view, treated as little-endian. - * This is not a uint256 constructor because of historical fears of uint256(0) - * resolving to a NULL string and crashing. + * DEPRECATED. Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated! */ inline uint256 uint256S(std::string_view str) { |