Repository: bitcoin/bitcoin
File: src/uint256.cpp (C++)

Code before:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <uint256.h>

#include <util/strencodings.h>

template <unsigned int BITS>
std::string base_blob<BITS>::GetHex() const
{
    uint8_t m_data_rev[WIDTH];
    for (int i = 0; i < WIDTH; ++i) {
        m_data_rev[i] = m_data[WIDTH - 1 - i];
    }
    return HexStr(m_data_rev);
}

template <unsigned int BITS>
void base_blob<BITS>::SetHex(const char* psz)
{
    std::fill(m_data.begin(), m_data.end(), 0);

    // skip leading spaces
    while (IsSpace(*psz))
        psz++;

    // skip 0x
    if (psz[0] == '0' && ToLower(psz[1]) == 'x')
        psz += 2;

    // hex string to uint
    size_t digits = 0;
    while (::HexDigit(psz[digits]) != -1)
        digits++;
    unsigned char* p1 = m_data.data();
    unsigned char* pend = p1 + WIDTH;
    while (digits > 0 && p1 < pend) {
        *p1 = ::HexDigit(psz[--digits]);
        if (digits > 0) {
            *p1 |= ((unsigned char)::HexDigit(psz[--digits]) << 4);
            p1++;
        }
    }
}

template <unsigned int BITS>
void base_blob<BITS>::SetHex(const std::string& str)
{

Review comment (suggestion):
Both sides are trimmed. My recommendation would be to drop the first commit and instead add a unit test:

```diff
diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp
index b7892a2139..5602b33e17 100644
--- a/src/test/uint256_tests.cpp
+++ b/src/test/uint256_tests.cpp
@@ -102,6 +102,8 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
     BOOST_CHECK(uint256S("0x"+MaxL.ToString()) == MaxL);
     BOOST_CHECK(uint256S(R1L.ToString()) == R1L);
     BOOST_CHECK(uint256S("   0x"+R1L.ToString()+"   ") == R1L);
+    BOOST_CHECK(uint256S("   0x" + R1L.ToString() + "-trash;%^&   ") == R1L);
+    BOOST_CHECK(uint256S("\t \n  \n \f\n\r\t\v\t   0x" + R1L.ToString() + "  \t \n  \n \f\n\r\t\v\t ") == R1L);
     BOOST_CHECK(uint256S("") == ZeroL);
     BOOST_CHECK(R1L == uint256S(R1ArrayHex));
     BOOST_CHECK(uint256(R1L) == R1L);
@@ -115,6 +117,8 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
     BOOST_CHECK(uint160S("0x"+MaxS.ToString()) == MaxS);
     BOOST_CHECK(uint160S(R1S.ToString()) == R1S);
     BOOST_CHECK(uint160S("   0x"+R1S.ToString()+"   ") == R1S);
+    BOOST_CHECK(uint160S("   0x" + R1S.ToString() + "-trash;%^&   ") == R1S);
+    BOOST_CHECK(uint160S(" \t \n  \n \f\n\r\t\v\t  0x" + R1S.ToString() + "   \t \n  \n \f\n\r\t\v\t") == R1S);
     BOOST_CHECK(uint160S("") == ZeroS);
     BOOST_CHECK(R1S == uint160S(R1ArrayHex));
 
```

Then, you can replace this call in the second commit with the existing string view Trim function.

(The unit test also checks that trailing trash is ignored. (Which is sad, but existing behavior, so probably good to keep for now))

Code after:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <uint256.h>

#include <util/strencodings.h>

template <unsigned int BITS>
std::string base_blob<BITS>::GetHex() const
{
    uint8_t m_data_rev[WIDTH];
    for (int i = 0; i < WIDTH; ++i) {
        m_data_rev[i] = m_data[WIDTH - 1 - i];
    }
    return HexStr(m_data_rev);
}

template <unsigned int BITS>
void base_blob<BITS>::SetHex(const std::string_view str)
{
    std::fill(m_data.begin(), m_data.end(), 0);

    const auto trimmed = util::RemovePrefixView(util::TrimStringView(str), "0x");

    // Note: if we are passed a greater number of digits than would fit as bytes
    // in m_data, we will be discarding the leftmost ones.
    // str="12bc" in a WIDTH=1 m_data => m_data[] == "\0xbc", not "0x12".
    size_t digits = 0;
    for (const char c : trimmed) {
        if (::HexDigit(c) == -1) break;
        ++digits;
    }
    unsigned char* p1 = m_data.data();
    unsigned char* pend = p1 + WIDTH;
    while (digits > 0 && p1 < pend) {
        *p1 = ::HexDigit(trimmed[--digits]);
        if (digits > 0) {
            *p1 |= ((unsigned char)::HexDigit(trimmed[--digits]) << 4);
            p1++;
        }
    }
}

template <unsigned int BITS>
std::string base_blob<BITS>::ToString() const
{
    return (GetHex());
}