diff --git a/src/contract/variables/safeaddress.h b/src/contract/variables/safeaddress.h index 37717e1f..a660bd02 100644 --- a/src/contract/variables/safeaddress.h +++ b/src/contract/variables/safeaddress.h @@ -47,9 +47,7 @@ class SafeAddress : public SafeBase { /// Copy constructor. SafeAddress(const SafeAddress& other) : SafeBase(nullptr) { - check(); - address_ = other.address_; - addressPtr_ = std::make_unique
(*other.addressPtr_); + other.check(); addressPtr_ = std::make_unique
(*other.addressPtr_); } /// Getter for the value. Returns the value from the pointer. diff --git a/src/utils/hex.h b/src/utils/hex.h index 2f97124c..ff433bd9 100644 --- a/src/utils/hex.h +++ b/src/utils/hex.h @@ -26,23 +26,8 @@ using BytesArr = std::array; using BytesArrView = std::span; using BytesArrMutableView = std::span; - using uint256_t = boost::multiprecision::number>; -/** - * Helper struct for use with Boost's lexical_cast to convert hex strings - * to a given type (`boost::lexical_cast<%HexTo>(hexStr)`). - */ -template struct HexTo { - ElemT value; ///< The value to hold. - operator ElemT() const { return value; } ///< Operator to get the value. - /// Stream operator. - friend std::istream& operator>>(std::istream& in, HexTo& out) { - in >> std::hex >> out.value; - return in; - } -}; - /// Abstraction of a strictly hex-formatted string (`(0x)[1-9][a-f][A-F]`). class Hex { private: @@ -125,9 +110,17 @@ class Hex { /// Getter for `hex`. inline const std::string& get() const { return this->hex_; } - /// Getter for `hex`, but converts it back to an unsigned integer. + /** + * Getter for `hex`, but converts it back to an unsigned 256-bit integer. + * @throw std::length_error if hex is too big to be converted to uint256_t. + */ inline uint256_t getUint() const { - return boost::lexical_cast>(this->hex_); + Bytes b = Hex::toBytes(this->hex_); + if (b.size() > 32) throw std::length_error("Hex too big for uint conversion"); + BytesArrView bV(b.data(), b.size()); + uint256_t ret; + boost::multiprecision::import_bits(ret, bV.begin(), bV.end(), 8); + return ret; } /** diff --git a/src/utils/strings.h b/src/utils/strings.h index 2a790958..640e9933 100644 --- a/src/utils/strings.h +++ b/src/utils/strings.h @@ -35,7 +35,6 @@ See the LICENSE.txt file in the project root for more information. * This class is used as a base for both classes inheriting it * (e.g. Hash, Signature, etc.) and aliases (e.g. PrivKey, PubKey, etc.). */ - template class FixedBytes { protected: BytesArr data_; ///< Internal string data. diff --git a/src/utils/utils.h b/src/utils/utils.h index d18588fd..5cd54e8f 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -18,6 +18,7 @@ See the LICENSE.txt file in the project root for more information. #include #include #include +#include #include #include @@ -33,7 +34,6 @@ See the LICENSE.txt file in the project root for more information. #include "src/libs/json.hpp" #include "src/contract/variables/safeuint.h" #include "src/contract/variables/safeint.h" -#include /// @file utils.h diff --git a/tests/utils/hex.cpp b/tests/utils/hex.cpp index 522625a6..585ca7a1 100644 --- a/tests/utils/hex.cpp +++ b/tests/utils/hex.cpp @@ -122,10 +122,23 @@ namespace THex { SECTION("Hex GetUint") { std::string hexStr = "0x1234"; + std::string oddHexStr = "0xfffff"; + std::string evenHexStr = "0x0fffff"; + std::string tooBigHexStr = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // 33 bytes Hex hex(hexStr, false); Hex hexStrict(hexStr, true); + Hex oddHex(oddHexStr, true); + Hex evenHex(evenHexStr, true); + Hex tooBigHex(tooBigHexStr, true); REQUIRE(hex.getUint() == uint256_t(4660)); REQUIRE(hexStrict.getUint() == uint256_t(4660)); + REQUIRE(oddHex.getUint() == uint256_t(1048575)); + REQUIRE(evenHex.getUint() == uint256_t(1048575)); + try { + uint256_t wrongNumber = tooBigHex.getUint(); + } catch (std::length_error& e) { + REQUIRE(e.what() == std::string("Hex too big for uint conversion")); + } } SECTION("Hex Substr") {