diff options
-rw-r--r-- | src/pubkey.h | 6 | ||||
-rw-r--r-- | src/span.h | 25 | ||||
-rw-r--r-- | src/streams.h | 12 | ||||
-rw-r--r-- | src/test/base64_tests.cpp | 10 | ||||
-rw-r--r-- | src/test/streams_tests.cpp | 6 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 23 | ||||
-rw-r--r-- | src/util/strencodings.cpp | 5 | ||||
-rw-r--r-- | src/util/strencodings.h | 4 |
8 files changed, 67 insertions, 24 deletions
diff --git a/src/pubkey.h b/src/pubkey.h index f174ad8d85..ae6356c246 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -141,7 +141,7 @@ public: template <typename Stream> void Unserialize(Stream& s) { - unsigned int len = ::ReadCompactSize(s); + const unsigned int len(::ReadCompactSize(s)); if (len <= SIZE) { s.read((char*)vch, len); if (len != size()) { @@ -149,9 +149,7 @@ public: } } else { // invalid pubkey, skip available data - char dummy; - while (len--) - s.read(&dummy, 1); + s.ignore(len); Invalidate(); } } diff --git a/src/span.h b/src/span.h index 1e347846d8..746e41f2f4 100644 --- a/src/span.h +++ b/src/span.h @@ -184,6 +184,7 @@ public: return m_data[m_size - 1]; } constexpr std::size_t size() const noexcept { return m_size; } + constexpr std::size_t size_bytes() const noexcept { return sizeof(C) * m_size; } constexpr bool empty() const noexcept { return size() == 0; } CONSTEXPR_IF_NOT_DEBUG C& operator[](std::size_t pos) const noexcept { @@ -240,11 +241,35 @@ T& SpanPopBack(Span<T>& span) return back; } +// From C++20 as_bytes and as_writeable_bytes +template <typename T> +Span<const std::byte> AsBytes(Span<T> s) noexcept +{ + return {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()}; +} +template <typename T> +Span<std::byte> AsWritableBytes(Span<T> s) noexcept +{ + return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()}; +} + +template <typename V> +Span<const std::byte> MakeByteSpan(V&& v) noexcept +{ + return AsBytes(MakeSpan(std::forward<V>(v))); +} +template <typename V> +Span<std::byte> MakeWritableByteSpan(V&& v) noexcept +{ + return AsWritableBytes(MakeSpan(std::forward<V>(v))); +} + // Helper functions to safely cast to unsigned char pointers. inline unsigned char* UCharCast(char* c) { return (unsigned char*)c; } inline unsigned char* UCharCast(unsigned char* c) { return c; } inline const unsigned char* UCharCast(const char* c) { return (unsigned char*)c; } inline const unsigned char* UCharCast(const unsigned char* c) { return c; } +inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast<const unsigned char*>(c); } // Helper function to safely convert a Span to a Span<[const] unsigned char>. template <typename T> constexpr auto UCharSpanCast(Span<T> s) -> Span<typename std::remove_pointer<decltype(UCharCast(s.data()))>::type> { return {UCharCast(s.data()), s.size()}; } diff --git a/src/streams.h b/src/streams.h index 31407287ae..9e8f379cd2 100644 --- a/src/streams.h +++ b/src/streams.h @@ -226,7 +226,7 @@ public: : nType{nTypeIn}, nVersion{nVersionIn} {} - explicit CDataStream(Span<const uint8_t> sp, int nTypeIn, int nVersionIn) + explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn) : vch(sp.data(), sp.data() + sp.size()), nType{nTypeIn}, nVersion{nVersionIn} {} @@ -254,17 +254,17 @@ public: iterator end() { return vch.end(); } size_type size() const { return vch.size() - nReadPos; } bool empty() const { return vch.size() == nReadPos; } - void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void resize(size_type n, value_type c = value_type{}) { vch.resize(n + nReadPos, c); } void reserve(size_type n) { vch.reserve(n + nReadPos); } const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } reference operator[](size_type pos) { return vch[pos + nReadPos]; } void clear() { vch.clear(); nReadPos = 0; } - iterator insert(iterator it, const uint8_t x) { return vch.insert(it, x); } - void insert(iterator it, size_type n, const uint8_t x) { vch.insert(it, n, x); } + iterator insert(iterator it, const value_type x) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const value_type x) { vch.insert(it, n, x); } value_type* data() { return vch.data() + nReadPos; } const value_type* data() const { return vch.data() + nReadPos; } - void insert(iterator it, std::vector<uint8_t>::const_iterator first, std::vector<uint8_t>::const_iterator last) + void insert(iterator it, std::vector<value_type>::const_iterator first, std::vector<value_type>::const_iterator last) { if (last == first) return; assert(last - first > 0); @@ -278,7 +278,7 @@ public: vch.insert(it, first, last); } - void insert(iterator it, const char* first, const char* last) + void insert(iterator it, const value_type* first, const value_type* last) { if (last == first) return; assert(last - first > 0); diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index 9d1dfd46f1..c5fce7bec0 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -23,6 +23,16 @@ BOOST_AUTO_TEST_CASE(base64_testvectors) BOOST_CHECK_EQUAL(strDec, vstrIn[i]); } + { + const std::vector<uint8_t> in_u{0xff, 0x01, 0xff}; + const std::vector<std::byte> in_b{std::byte{0xff}, std::byte{0x01}, std::byte{0xff}}; + const std::string in_s{"\xff\x01\xff"}; + const std::string out_exp{"/wH/"}; + BOOST_CHECK_EQUAL(EncodeBase64(in_u), out_exp); + BOOST_CHECK_EQUAL(EncodeBase64(in_b), out_exp); + BOOST_CHECK_EQUAL(EncodeBase64(in_s), out_exp); + } + // Decoding strings with embedded NUL characters should fail bool failure; (void)DecodeBase64("invalid\0"s, &failure); diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index 54f04d2e67..b8d76c9608 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) ds.Xor(key); BOOST_CHECK_EQUAL( std::string(expected_xor.begin(), expected_xor.end()), - std::string(ds.begin(), ds.end())); + ds.str()); in.push_back('\x0f'); in.push_back('\xf0'); @@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) ds.Xor(key); BOOST_CHECK_EQUAL( std::string(expected_xor.begin(), expected_xor.end()), - std::string(ds.begin(), ds.end())); + ds.str()); // Multi character key @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) ds.Xor(key); BOOST_CHECK_EQUAL( std::string(expected_xor.begin(), expected_xor.end()), - std::string(ds.begin(), ds.end())); + ds.str()); } BOOST_AUTO_TEST_CASE(streams_buffered_file) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 4f00a4d69e..76a690fd28 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -151,12 +151,25 @@ BOOST_AUTO_TEST_CASE(util_HexStr) HexStr(Span<const unsigned char>(ParseHex_expected, ParseHex_expected)), ""); - std::vector<unsigned char> ParseHex_vec(ParseHex_expected, ParseHex_expected + 5); + { + const std::vector<char> in_s{ParseHex_expected, ParseHex_expected + 5}; + const Span<const uint8_t> in_u{MakeUCharSpan(in_s)}; + const Span<const std::byte> in_b{MakeByteSpan(in_s)}; + const std::string out_exp{"04678afdb0"}; + + BOOST_CHECK_EQUAL(HexStr(in_u), out_exp); + BOOST_CHECK_EQUAL(HexStr(in_s), out_exp); + BOOST_CHECK_EQUAL(HexStr(in_b), out_exp); + } +} - BOOST_CHECK_EQUAL( - HexStr(ParseHex_vec), - "04678afdb0" - ); +BOOST_AUTO_TEST_CASE(span_write_bytes) +{ + std::array mut_arr{uint8_t{0xaa}, uint8_t{0xbb}}; + const auto mut_bytes{MakeWritableByteSpan(mut_arr)}; + mut_bytes[1] = std::byte{0x11}; + BOOST_CHECK_EQUAL(mut_arr.at(0), 0xaa); + BOOST_CHECK_EQUAL(mut_arr.at(1), 0x11); } BOOST_AUTO_TEST_CASE(util_Join) diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 5e7c99f140..430f1963ea 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -139,11 +139,6 @@ std::string EncodeBase64(Span<const unsigned char> input) return str; } -std::string EncodeBase64(const std::string& str) -{ - return EncodeBase64(MakeUCharSpan(str)); -} - std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid) { static const int decode64_table[256] = diff --git a/src/util/strencodings.h b/src/util/strencodings.h index bc0a6233ab..08a5465de1 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -67,7 +67,8 @@ bool IsHexNumber(const std::string& str); std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid = nullptr); std::string DecodeBase64(const std::string& str, bool* pf_invalid = nullptr); std::string EncodeBase64(Span<const unsigned char> input); -std::string EncodeBase64(const std::string& str); +inline std::string EncodeBase64(Span<const std::byte> input) { return EncodeBase64(MakeUCharSpan(input)); } +inline std::string EncodeBase64(const std::string& str) { return EncodeBase64(MakeUCharSpan(str)); } std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid = nullptr); std::string DecodeBase32(const std::string& str, bool* pf_invalid = nullptr); @@ -206,6 +207,7 @@ std::optional<T> ToIntegral(const std::string& str) */ std::string HexStr(const Span<const uint8_t> s); inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); } +inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); } /** * Format a paragraph of text to a fixed width, adding spaces for |