diff options
-rw-r--r-- | src/bench/checkblock.cpp | 8 | ||||
-rw-r--r-- | src/bench/rpc_blockchain.cpp | 4 | ||||
-rw-r--r-- | src/common/bloom.cpp | 4 | ||||
-rw-r--r-- | src/dbwrapper.h | 6 | ||||
-rw-r--r-- | src/hash.h | 15 | ||||
-rw-r--r-- | src/net.cpp | 4 | ||||
-rw-r--r-- | src/node/blockstorage.cpp | 2 | ||||
-rw-r--r-- | src/psbt.cpp | 2 | ||||
-rw-r--r-- | src/pubkey.h | 4 | ||||
-rw-r--r-- | src/script/bitcoinconsensus.cpp | 17 | ||||
-rw-r--r-- | src/script/interpreter.cpp | 4 | ||||
-rw-r--r-- | src/serialize.h | 77 | ||||
-rw-r--r-- | src/span.h | 9 | ||||
-rw-r--r-- | src/streams.h | 86 | ||||
-rw-r--r-- | src/support/allocators/zeroafterfree.h | 2 | ||||
-rw-r--r-- | src/test/bloom_tests.cpp | 12 | ||||
-rw-r--r-- | src/test/fuzz/autofile.cpp | 8 | ||||
-rw-r--r-- | src/test/fuzz/buffered_file.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/integer.cpp | 5 | ||||
-rw-r--r-- | src/test/fuzz/rpc.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/util.h | 6 | ||||
-rw-r--r-- | src/test/script_tests.cpp | 18 | ||||
-rw-r--r-- | src/test/serialize_tests.cpp | 52 | ||||
-rw-r--r-- | src/test/streams_tests.cpp | 10 | ||||
-rw-r--r-- | src/uint256.h | 6 | ||||
-rw-r--r-- | src/validation.cpp | 2 | ||||
-rw-r--r-- | src/wallet/bdb.cpp | 6 | ||||
-rw-r--r-- | src/wallet/dump.cpp | 12 | ||||
-rw-r--r-- | src/wallet/sqlite.cpp | 18 |
29 files changed, 208 insertions, 199 deletions
diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp index a9f3f5f84d..52e5cb743f 100644 --- a/src/bench/checkblock.cpp +++ b/src/bench/checkblock.cpp @@ -17,8 +17,8 @@ static void DeserializeBlockTest(benchmark::Bench& bench) { CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION); - char a = '\0'; - stream.write(&a, 1); // Prevent compaction + std::byte a{0}; + stream.write({&a, 1}); // Prevent compaction bench.unit("block").run([&] { CBlock block; @@ -31,8 +31,8 @@ static void DeserializeBlockTest(benchmark::Bench& bench) static void DeserializeAndCheckBlockTest(benchmark::Bench& bench) { CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION); - char a = '\0'; - stream.write(&a, 1); // Prevent compaction + std::byte a{0}; + stream.write({&a, 1}); // Prevent compaction ArgsManager bench_args; const auto chainParams = CreateChainParams(bench_args, CBaseChainParams::MAIN); diff --git a/src/bench/rpc_blockchain.cpp b/src/bench/rpc_blockchain.cpp index 9bc31461d2..2143bcf950 100644 --- a/src/bench/rpc_blockchain.cpp +++ b/src/bench/rpc_blockchain.cpp @@ -23,8 +23,8 @@ struct TestBlockAndIndex { TestBlockAndIndex() { CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION); - char a = '\0'; - stream.write(&a, 1); // Prevent compaction + std::byte a{0}; + stream.write({&a, 1}); // Prevent compaction stream >> block; diff --git a/src/common/bloom.cpp b/src/common/bloom.cpp index 0bb72dbcbb..c744d05a0e 100644 --- a/src/common/bloom.cpp +++ b/src/common/bloom.cpp @@ -62,7 +62,7 @@ void CBloomFilter::insert(const COutPoint& outpoint) { CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << outpoint; - insert(stream); + insert(MakeUCharSpan(stream)); } bool CBloomFilter::contains(Span<const unsigned char> vKey) const @@ -83,7 +83,7 @@ bool CBloomFilter::contains(const COutPoint& outpoint) const { CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << outpoint; - return contains(stream); + return contains(MakeUCharSpan(stream)); } bool CBloomFilter::IsWithinSizeConstraints() const diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 12db0fffcc..1109cb5888 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -147,7 +147,7 @@ public: template<typename K> bool GetKey(K& key) { leveldb::Slice slKey = piter->key(); try { - CDataStream ssKey(MakeUCharSpan(slKey), SER_DISK, CLIENT_VERSION); + CDataStream ssKey{MakeByteSpan(slKey), SER_DISK, CLIENT_VERSION}; ssKey >> key; } catch (const std::exception&) { return false; @@ -158,7 +158,7 @@ public: template<typename V> bool GetValue(V& value) { leveldb::Slice slValue = piter->value(); try { - CDataStream ssValue(MakeUCharSpan(slValue), SER_DISK, CLIENT_VERSION); + CDataStream ssValue{MakeByteSpan(slValue), SER_DISK, CLIENT_VERSION}; ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent)); ssValue >> value; } catch (const std::exception&) { @@ -244,7 +244,7 @@ public: dbwrapper_private::HandleError(status); } try { - CDataStream ssValue(MakeUCharSpan(strValue), SER_DISK, CLIENT_VERSION); + CDataStream ssValue{MakeByteSpan(strValue), SER_DISK, CLIENT_VERSION}; ssValue.Xor(obfuscate_key); ssValue >> value; } catch (const std::exception&) { diff --git a/src/hash.h b/src/hash.h index 1456a899d8..9f582842c1 100644 --- a/src/hash.h +++ b/src/hash.h @@ -111,8 +111,9 @@ public: int GetType() const { return nType; } int GetVersion() const { return nVersion; } - void write(const char *pch, size_t size) { - ctx.Write((const unsigned char*)pch, size); + void write(Span<const std::byte> src) + { + ctx.Write(UCharCast(src.data()), src.size()); } /** Compute the double-SHA256 hash of all data written to this object. @@ -162,18 +163,18 @@ private: public: explicit CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {} - void read(char* pch, size_t nSize) + void read(Span<std::byte> dst) { - source->read(pch, nSize); - this->write(pch, nSize); + source->read(dst); + this->write(dst); } void ignore(size_t nSize) { - char data[1024]; + std::byte data[1024]; while (nSize > 0) { size_t now = std::min<size_t>(nSize, 1024); - read(data, now); + read({data, now}); nSize -= now; } } diff --git a/src/net.cpp b/src/net.cpp index 0260e14da7..be56d1e2d2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3091,11 +3091,11 @@ void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Spa CAutoFile f(fsbridge::fopen(path, "ab"), SER_DISK, CLIENT_VERSION); ser_writedata64(f, now.count()); - f.write(msg_type.data(), msg_type.length()); + f.write(MakeByteSpan(msg_type)); for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) { f << uint8_t{'\0'}; } uint32_t size = data.size(); ser_writedata32(f, size); - f.write((const char*)data.data(), data.size()); + f.write(AsBytes(data)); } diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 62be9f9aac..7691c9a5ce 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -813,7 +813,7 @@ bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, c } block.resize(blk_size); // Zeroing of memory is intentional here - filein.read((char*)block.data(), blk_size); + filein.read(MakeWritableByteSpan(block)); } catch (const std::exception& e) { return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString()); } diff --git a/src/psbt.cpp b/src/psbt.cpp index 8248609ba6..c8c73e130b 100644 --- a/src/psbt.cpp +++ b/src/psbt.cpp @@ -399,7 +399,7 @@ bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base6 bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error) { - CDataStream ss_data(MakeUCharSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION); + CDataStream ss_data(MakeByteSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION); try { ss_data >> psbt; if (!ss_data.empty()) { diff --git a/src/pubkey.h b/src/pubkey.h index 349081205b..dfe06f834c 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -142,14 +142,14 @@ public: { unsigned int len = size(); ::WriteCompactSize(s, len); - s.write((char*)vch, len); + s.write(AsBytes(Span{vch, len})); } template <typename Stream> void Unserialize(Stream& s) { const unsigned int len(::ReadCompactSize(s)); if (len <= SIZE) { - s.read((char*)vch, len); + s.read(AsWritableBytes(Span{vch, len})); if (len != size()) { Invalidate(); } diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index dd15e6104c..f7f9dfc262 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -22,20 +22,23 @@ public: m_remaining(txToLen) {} - void read(char* pch, size_t nSize) + void read(Span<std::byte> dst) { - if (nSize > m_remaining) + if (dst.size() > m_remaining) { throw std::ios_base::failure(std::string(__func__) + ": end of data"); + } - if (pch == nullptr) + if (dst.data() == nullptr) { throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer"); + } - if (m_data == nullptr) + if (m_data == nullptr) { throw std::ios_base::failure(std::string(__func__) + ": bad source buffer"); + } - memcpy(pch, m_data, nSize); - m_remaining -= nSize; - m_data += nSize; + memcpy(dst.data(), m_data, dst.size()); + m_remaining -= dst.size(); + m_data += dst.size(); } template<typename T> diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 07b44971b7..11b1a1c887 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1303,12 +1303,12 @@ public: it = itBegin; while (scriptCode.GetOp(it, opcode)) { if (opcode == OP_CODESEPARATOR) { - s.write((char*)&itBegin[0], it-itBegin-1); + s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin - 1)})); itBegin = it; } } if (itBegin != scriptCode.end()) - s.write((char*)&itBegin[0], it-itBegin); + s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin)})); } /** Serialize an input of txTo */ diff --git a/src/serialize.h b/src/serialize.h index 4cc4b0338c..44bb471f25 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -47,79 +47,72 @@ static const unsigned int MAX_VECTOR_ALLOCATE = 5000000; struct deserialize_type {}; constexpr deserialize_type deserialize {}; -//! Safely convert odd char pointer types to standard ones. -inline char* CharCast(char* c) { return c; } -inline char* CharCast(unsigned char* c) { return (char*)c; } -inline const char* CharCast(const char* c) { return c; } -inline const char* CharCast(const unsigned char* c) { return (const char*)c; } - /* * Lowest-level serialization and conversion. - * @note Sizes of these types are verified in the tests */ template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj) { - s.write((char*)&obj, 1); + s.write(AsBytes(Span{&obj, 1})); } template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj) { obj = htole16(obj); - s.write((char*)&obj, 2); + s.write(AsBytes(Span{&obj, 1})); } template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj) { obj = htobe16(obj); - s.write((char*)&obj, 2); + s.write(AsBytes(Span{&obj, 1})); } template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj) { obj = htole32(obj); - s.write((char*)&obj, 4); + s.write(AsBytes(Span{&obj, 1})); } template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj) { obj = htobe32(obj); - s.write((char*)&obj, 4); + s.write(AsBytes(Span{&obj, 1})); } template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj) { obj = htole64(obj); - s.write((char*)&obj, 8); + s.write(AsBytes(Span{&obj, 1})); } template<typename Stream> inline uint8_t ser_readdata8(Stream &s) { uint8_t obj; - s.read((char*)&obj, 1); + s.read(AsWritableBytes(Span{&obj, 1})); return obj; } template<typename Stream> inline uint16_t ser_readdata16(Stream &s) { uint16_t obj; - s.read((char*)&obj, 2); + s.read(AsWritableBytes(Span{&obj, 1})); return le16toh(obj); } template<typename Stream> inline uint16_t ser_readdata16be(Stream &s) { uint16_t obj; - s.read((char*)&obj, 2); + s.read(AsWritableBytes(Span{&obj, 1})); return be16toh(obj); } template<typename Stream> inline uint32_t ser_readdata32(Stream &s) { uint32_t obj; - s.read((char*)&obj, 4); + s.read(AsWritableBytes(Span{&obj, 1})); return le32toh(obj); } template<typename Stream> inline uint32_t ser_readdata32be(Stream &s) { uint32_t obj; - s.read((char*)&obj, 4); + s.read(AsWritableBytes(Span{&obj, 1})); return be32toh(obj); } template<typename Stream> inline uint64_t ser_readdata64(Stream &s) { uint64_t obj; - s.read((char*)&obj, 8); + s.read(AsWritableBytes(Span{&obj, 1})); return le64toh(obj); } @@ -127,7 +120,7 @@ template<typename Stream> inline uint64_t ser_readdata64(Stream &s) ///////////////////////////////////////////////////////////////// // // Templates for serializing to anything that looks like a stream, -// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t) +// i.e. anything that supports .read(Span<std::byte>) and .write(Span<const std::byte>) // class CSizeComputer; @@ -196,7 +189,7 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; } FORMATTER_METHODS(cls, obj) #ifndef CHAR_EQUALS_INT8 -template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char +template <typename Stream> void Serialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t #endif template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); } template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); } @@ -206,13 +199,13 @@ template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_wri template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); } template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); } template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); } -template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(a, N); } -template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(CharCast(a), N); } -template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(CharCast(span.data()), span.size()); } -template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(CharCast(span.data()), span.size()); } +template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(MakeByteSpan(a)); } +template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(MakeByteSpan(a)); } +template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(AsBytes(span)); } +template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(AsBytes(span)); } #ifndef CHAR_EQUALS_INT8 -template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char +template <typename Stream> void Unserialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t #endif template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); } template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); } @@ -222,9 +215,9 @@ template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a = template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); } template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); } template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); } -template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); } -template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); } -template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(CharCast(span.data()), span.size()); } +template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(MakeWritableByteSpan(a)); } +template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(MakeWritableByteSpan(a)); } +template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(AsWritableBytes(span)); } template <typename Stream> inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); } template <typename Stream> inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; } @@ -479,10 +472,10 @@ struct CustomUintFormatter if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range"); if (BigEndian) { uint64_t raw = htobe64(v); - s.write(((const char*)&raw) + 8 - Bytes, Bytes); + s.write({BytePtr(&raw) + 8 - Bytes, Bytes}); } else { uint64_t raw = htole64(v); - s.write((const char*)&raw, Bytes); + s.write({BytePtr(&raw), Bytes}); } } @@ -492,10 +485,10 @@ struct CustomUintFormatter static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small"); uint64_t raw = 0; if (BigEndian) { - s.read(((char*)&raw) + 8 - Bytes, Bytes); + s.read({BytePtr(&raw) + 8 - Bytes, Bytes}); v = static_cast<I>(be64toh(raw)); } else { - s.read((char*)&raw, Bytes); + s.read({BytePtr(&raw), Bytes}); v = static_cast<I>(le64toh(raw)); } } @@ -551,7 +544,7 @@ struct LimitedStringFormatter throw std::ios_base::failure("String length limit exceeded"); } v.resize(size); - if (size != 0) s.read((char*)v.data(), size); + if (size != 0) s.read(MakeWritableByteSpan(v)); } template<typename Stream> @@ -715,7 +708,7 @@ void Serialize(Stream& os, const std::basic_string<C>& str) { WriteCompactSize(os, str.size()); if (!str.empty()) - os.write((char*)str.data(), str.size() * sizeof(C)); + os.write(MakeByteSpan(str)); } template<typename Stream, typename C> @@ -724,7 +717,7 @@ void Unserialize(Stream& is, std::basic_string<C>& str) unsigned int nSize = ReadCompactSize(is); str.resize(nSize); if (nSize != 0) - is.read((char*)str.data(), nSize * sizeof(C)); + is.read(MakeWritableByteSpan(str)); } @@ -737,7 +730,7 @@ void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&) { WriteCompactSize(os, v.size()); if (!v.empty()) - os.write((char*)v.data(), v.size() * sizeof(T)); + os.write(MakeByteSpan(v)); } template<typename Stream, unsigned int N, typename T, typename V> @@ -764,7 +757,7 @@ void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&) { unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); v.resize_uninitialized(i + blk); - is.read((char*)&v[i], blk * sizeof(T)); + is.read(AsWritableBytes(Span{&v[i], blk})); i += blk; } } @@ -791,7 +784,7 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char& { WriteCompactSize(os, v.size()); if (!v.empty()) - os.write((char*)v.data(), v.size() * sizeof(T)); + os.write(MakeByteSpan(v)); } template<typename Stream, typename T, typename A> @@ -830,7 +823,7 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&) { unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); v.resize(i + blk); - is.read((char*)&v[i], blk * sizeof(T)); + is.read(AsWritableBytes(Span{&v[i], blk})); i += blk; } } @@ -995,9 +988,9 @@ protected: public: explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {} - void write(const char *psz, size_t _nSize) + void write(Span<const std::byte> src) { - this->nSize += _nSize; + this->nSize += src.size(); } /** Pretend _nSize bytes are written, without specifying them. */ diff --git a/src/span.h b/src/span.h index 47390a5bb2..b627b993c2 100644 --- a/src/span.h +++ b/src/span.h @@ -243,16 +243,21 @@ T& SpanPopBack(Span<T>& span) return back; } +//! Convert a data pointer to a std::byte data pointer. +//! Where possible, please use the safer AsBytes helpers. +inline const std::byte* BytePtr(const void* data) { return reinterpret_cast<const std::byte*>(data); } +inline std::byte* BytePtr(void* data) { return reinterpret_cast<std::byte*>(data); } + // 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()}; + return {BytePtr(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()}; + return {BytePtr(s.data()), s.size_bytes()}; } template <typename V> diff --git a/src/streams.h b/src/streams.h index 384bb632b0..2f26be6dd8 100644 --- a/src/streams.h +++ b/src/streams.h @@ -49,14 +49,14 @@ public: return (*this); } - void write(const char* pch, size_t nSize) + void write(Span<const std::byte> src) { - stream->write(pch, nSize); + stream->write(src); } - void read(char* pch, size_t nSize) + void read(Span<std::byte> dst) { - stream->read(pch, nSize); + stream->read(dst); } int GetVersion() const { return nVersion; } @@ -94,17 +94,17 @@ class CVectorWriter { ::SerializeMany(*this, std::forward<Args>(args)...); } - void write(const char* pch, size_t nSize) + void write(Span<const std::byte> src) { assert(nPos <= vchData.size()); - size_t nOverwrite = std::min(nSize, vchData.size() - nPos); + size_t nOverwrite = std::min(src.size(), vchData.size() - nPos); if (nOverwrite) { - memcpy(vchData.data() + nPos, reinterpret_cast<const unsigned char*>(pch), nOverwrite); + memcpy(vchData.data() + nPos, src.data(), nOverwrite); } - if (nOverwrite < nSize) { - vchData.insert(vchData.end(), reinterpret_cast<const unsigned char*>(pch) + nOverwrite, reinterpret_cast<const unsigned char*>(pch) + nSize); + if (nOverwrite < src.size()) { + vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite, UCharCast(src.end())); } - nPos += nSize; + nPos += src.size(); } template<typename T> CVectorWriter& operator<<(const T& obj) @@ -161,18 +161,18 @@ public: size_t size() const { return m_data.size(); } bool empty() const { return m_data.empty(); } - void read(char* dst, size_t n) + void read(Span<std::byte> dst) { - if (n == 0) { + if (dst.size() == 0) { return; } // Read from the beginning of the buffer - if (n > m_data.size()) { + if (dst.size() > m_data.size()) { throw std::ios_base::failure("SpanReader::read(): end of data"); } - memcpy(dst, m_data.data(), n); - m_data = m_data.subspan(n); + memcpy(dst.data(), m_data.data(), dst.size()); + m_data = m_data.subspan(dst.size()); } }; @@ -206,6 +206,7 @@ public: : nType{nTypeIn}, nVersion{nVersionIn} {} + explicit CDataStream(Span<const uint8_t> sp, int type, int version) : CDataStream{AsBytes(sp), type, version} {} explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn) : vch(sp.data(), sp.data() + sp.size()), nType{nTypeIn}, @@ -221,7 +222,7 @@ public: std::string str() const { - return (std::string(begin(), end())); + return std::string{UCharCast(data()), UCharCast(data() + size())}; } @@ -342,16 +343,16 @@ public: void SetVersion(int n) { nVersion = n; } int GetVersion() const { return nVersion; } - void read(char* pch, size_t nSize) + void read(Span<value_type> dst) { - if (nSize == 0) return; + if (dst.size() == 0) return; // Read from the beginning of the buffer - unsigned int nReadPosNext = nReadPos + nSize; + unsigned int nReadPosNext = nReadPos + dst.size(); if (nReadPosNext > vch.size()) { throw std::ios_base::failure("CDataStream::read(): end of data"); } - memcpy(pch, &vch[nReadPos], nSize); + memcpy(dst.data(), &vch[nReadPos], dst.size()); if (nReadPosNext == vch.size()) { nReadPos = 0; @@ -379,10 +380,10 @@ public: nReadPos = nReadPosNext; } - void write(const char* pch, size_t nSize) + void write(Span<const value_type> src) { // Write to the end of the buffer - vch.insert(vch.end(), pch, pch + nSize); + vch.insert(vch.end(), src.begin(), src.end()); } template<typename Stream> @@ -390,7 +391,7 @@ public: { // Special case: stream << stream concatenates like stream += stream if (!vch.empty()) - s.write((char*)vch.data(), vch.size() * sizeof(value_type)); + s.write(MakeByteSpan(vch)); } template<typename T> @@ -421,7 +422,7 @@ public: } for (size_type i = 0, j = 0; i != size(); i++) { - vch[i] ^= key[j++]; + vch[i] ^= std::byte{key[j++]}; // This potentially acts on very many bytes of data, so it's // important that we calculate `j`, i.e. the `key` index in this @@ -594,12 +595,13 @@ public: int GetType() const { return nType; } int GetVersion() const { return nVersion; } - void read(char* pch, size_t nSize) + void read(Span<std::byte> dst) { if (!file) throw std::ios_base::failure("CAutoFile::read: file handle is nullptr"); - if (fread(pch, 1, nSize, file) != nSize) + if (fread(dst.data(), 1, dst.size(), file) != dst.size()) { throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed"); + } } void ignore(size_t nSize) @@ -615,12 +617,13 @@ public: } } - void write(const char* pch, size_t nSize) + void write(Span<const std::byte> src) { if (!file) throw std::ios_base::failure("CAutoFile::write: file handle is nullptr"); - if (fwrite(pch, 1, nSize, file) != nSize) + if (fwrite(src.data(), 1, src.size(), file) != src.size()) { throw std::ios_base::failure("CAutoFile::write: write failed"); + } } template<typename T> @@ -661,7 +664,7 @@ private: uint64_t nReadPos; //!< how many bytes have been read from this uint64_t nReadLimit; //!< up to which position we're allowed to read uint64_t nRewind; //!< how many bytes we guarantee to rewind - std::vector<char> vchBuf; //!< the buffer + std::vector<std::byte> vchBuf; //!< the buffer protected: //! read data from the source to fill the buffer @@ -682,8 +685,8 @@ protected: } public: - CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) : - nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, 0) + CBufferedFile(FILE* fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) + : nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, std::byte{0}) { if (nRewindIn >= nBufSize) throw std::ios_base::failure("Rewind limit must be less than buffer size"); @@ -716,22 +719,23 @@ public: } //! read a number of bytes - void read(char *pch, size_t nSize) { - if (nSize + nReadPos > nReadLimit) + void read(Span<std::byte> dst) + { + if (dst.size() + nReadPos > nReadLimit) { throw std::ios_base::failure("Read attempted past buffer limit"); - while (nSize > 0) { + } + while (dst.size() > 0) { if (nReadPos == nSrcPos) Fill(); unsigned int pos = nReadPos % vchBuf.size(); - size_t nNow = nSize; + size_t nNow = dst.size(); if (nNow + pos > vchBuf.size()) nNow = vchBuf.size() - pos; if (nNow + nReadPos > nSrcPos) nNow = nSrcPos - nReadPos; - memcpy(pch, &vchBuf[pos], nNow); + memcpy(dst.data(), &vchBuf[pos], nNow); nReadPos += nNow; - pch += nNow; - nSize -= nNow; + dst = dst.subspan(nNow); } } @@ -774,12 +778,14 @@ public: } //! search for a given byte in the stream, and remain positioned on it - void FindByte(char ch) { + void FindByte(uint8_t ch) + { while (true) { if (nReadPos == nSrcPos) Fill(); - if (vchBuf[nReadPos % vchBuf.size()] == ch) + if (vchBuf[nReadPos % vchBuf.size()] == std::byte{ch}) { break; + } nReadPos++; } } diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h index bc9c95eb53..0befe0ffcd 100644 --- a/src/support/allocators/zeroafterfree.h +++ b/src/support/allocators/zeroafterfree.h @@ -41,6 +41,6 @@ struct zero_after_free_allocator : public std::allocator<T> { }; /** Byte-vector that clears its contents before deletion. */ -using SerializeData = std::vector<uint8_t, zero_after_free_allocator<uint8_t>>; +using SerializeData = std::vector<std::byte, zero_after_free_allocator<std::byte>>; #endif // BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index bd579db205..35c4108caa 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -43,8 +43,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize) stream << filter; std::vector<uint8_t> expected = ParseHex("03614e9b050000000000000001"); + auto result{MakeUCharSpan(stream)}; - BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); + BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter doesn't contain just-inserted object!"); } @@ -69,8 +70,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak) stream << filter; std::vector<uint8_t> expected = ParseHex("03ce4299050000000100008001"); + auto result{MakeUCharSpan(stream)}; - BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); + BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); } BOOST_AUTO_TEST_CASE(bloom_create_insert_key) @@ -89,8 +91,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_key) stream << filter; std::vector<unsigned char> expected = ParseHex("038fc16b080000000000000001"); + auto result{MakeUCharSpan(stream)}; - BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); + BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); } BOOST_AUTO_TEST_CASE(bloom_match) @@ -341,8 +344,9 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) merkleStream << merkleBlock; std::vector<uint8_t> expected = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101"); + auto result{MakeUCharSpan(merkleStream)}; - BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), merkleStream.begin(), merkleStream.end()); + BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), result.begin(), result.end()); } BOOST_AUTO_TEST_CASE(merkle_block_4) diff --git a/src/test/fuzz/autofile.cpp b/src/test/fuzz/autofile.cpp index 0cc2d12d29..3b410930ed 100644 --- a/src/test/fuzz/autofile.cpp +++ b/src/test/fuzz/autofile.cpp @@ -23,16 +23,16 @@ FUZZ_TARGET(autofile) CallOneOf( fuzzed_data_provider, [&] { - std::array<uint8_t, 4096> arr{}; + std::array<std::byte, 4096> arr{}; try { - auto_file.read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)); + auto_file.read({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)}); } catch (const std::ios_base::failure&) { } }, [&] { - const std::array<uint8_t, 4096> arr{}; + const std::array<std::byte, 4096> arr{}; try { - auto_file.write((const char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)); + auto_file.write({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)}); } catch (const std::ios_base::failure&) { } }, diff --git a/src/test/fuzz/buffered_file.cpp b/src/test/fuzz/buffered_file.cpp index c3c2e4050f..a8c3318629 100644 --- a/src/test/fuzz/buffered_file.cpp +++ b/src/test/fuzz/buffered_file.cpp @@ -33,9 +33,9 @@ FUZZ_TARGET(buffered_file) CallOneOf( fuzzed_data_provider, [&] { - std::array<uint8_t, 4096> arr{}; + std::array<std::byte, 4096> arr{}; try { - opt_buffered_file->read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)); + opt_buffered_file->read({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)}); } catch (const std::ios_base::failure&) { } }, @@ -53,7 +53,7 @@ FUZZ_TARGET(buffered_file) return; } try { - opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<char>()); + opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<uint8_t>()); } catch (const std::ios_base::failure&) { } }, diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index 3087f11771..72574612a2 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -206,11 +206,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer) stream >> deserialized_i8; assert(i8 == deserialized_i8 && stream.empty()); - char deserialized_ch; - stream << ch; - stream >> deserialized_ch; - assert(ch == deserialized_ch && stream.empty()); - bool deserialized_b; stream << b; stream >> deserialized_b; diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp index b6ecf1c492..73bfb7ff55 100644 --- a/src/test/fuzz/rpc.cpp +++ b/src/test/fuzz/rpc.cpp @@ -271,7 +271,7 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider) } CDataStream data_stream{SER_NETWORK, PROTOCOL_VERSION}; data_stream << *opt_psbt; - r = EncodeBase64({data_stream.begin(), data_stream.end()}); + r = EncodeBase64(data_stream); }, [&] { // base58 encoded key diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index fd7f40c01d..3bc62878bd 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -328,7 +328,6 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe CallOneOf( fuzzed_data_provider, WRITE_TO_STREAM_CASE(bool, fuzzed_data_provider.ConsumeBool()), - WRITE_TO_STREAM_CASE(char, fuzzed_data_provider.ConsumeIntegral<char>()), WRITE_TO_STREAM_CASE(int8_t, fuzzed_data_provider.ConsumeIntegral<int8_t>()), WRITE_TO_STREAM_CASE(uint8_t, fuzzed_data_provider.ConsumeIntegral<uint8_t>()), WRITE_TO_STREAM_CASE(int16_t, fuzzed_data_provider.ConsumeIntegral<int16_t>()), @@ -338,7 +337,7 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe WRITE_TO_STREAM_CASE(int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>()), WRITE_TO_STREAM_CASE(uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>()), WRITE_TO_STREAM_CASE(std::string, fuzzed_data_provider.ConsumeRandomLengthString(32)), - WRITE_TO_STREAM_CASE(std::vector<char>, ConsumeRandomLengthIntegralVector<char>(fuzzed_data_provider))); + WRITE_TO_STREAM_CASE(std::vector<uint8_t>, ConsumeRandomLengthIntegralVector<uint8_t>(fuzzed_data_provider))); } catch (const std::ios_base::failure&) { break; } @@ -358,7 +357,6 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no CallOneOf( fuzzed_data_provider, READ_FROM_STREAM_CASE(bool), - READ_FROM_STREAM_CASE(char), READ_FROM_STREAM_CASE(int8_t), READ_FROM_STREAM_CASE(uint8_t), READ_FROM_STREAM_CASE(int16_t), @@ -368,7 +366,7 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no READ_FROM_STREAM_CASE(int64_t), READ_FROM_STREAM_CASE(uint64_t), READ_FROM_STREAM_CASE(std::string), - READ_FROM_STREAM_CASE(std::vector<char>)); + READ_FROM_STREAM_CASE(std::vector<uint8_t>)); } catch (const std::ios_base::failure&) { break; } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 0da296495f..4906bd2386 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -155,10 +155,10 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript if (libconsensus_flags == flags) { int expectedSuccessCode = expect ? 1 : 0; if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); } else { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); } } #endif @@ -1520,7 +1520,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_returns_true) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 1); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK); } @@ -1543,7 +1543,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_index_err) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX); } @@ -1566,7 +1566,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_size) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size() * 2, nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size() * 2, nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); } @@ -1589,7 +1589,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_serialization) stream << 0xffffffff; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE); } @@ -1612,7 +1612,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_amount_required_err) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED); } @@ -1635,7 +1635,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_invalid_flags) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS); } diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index e91c203c26..8b8133b689 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -61,7 +61,7 @@ public: BOOST_AUTO_TEST_CASE(sizes) { - BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0)); + BOOST_CHECK_EQUAL(sizeof(unsigned char), GetSerializeSize((unsigned char)0, 0)); BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0)); BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0)); BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0)); @@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(sizes) BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(bool(0), 0)); // Sanity-check GetSerializeSize and c++ type matching - BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1U); + BOOST_CHECK_EQUAL(GetSerializeSize((unsigned char)0, 0), 1U); BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1U); BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1U); BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2U); @@ -186,76 +186,78 @@ BOOST_AUTO_TEST_CASE(noncanonical) std::vector<char>::size_type n; // zero encoded with three bytes: - ss.write("\xfd\x00\x00", 3); + ss.write(MakeByteSpan("\xfd\x00\x00").first(3)); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // 0xfc encoded with three bytes: - ss.write("\xfd\xfc\x00", 3); + ss.write(MakeByteSpan("\xfd\xfc\x00").first(3)); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // 0xfd encoded with three bytes is OK: - ss.write("\xfd\xfd\x00", 3); + ss.write(MakeByteSpan("\xfd\xfd\x00").first(3)); n = ReadCompactSize(ss); BOOST_CHECK(n == 0xfd); // zero encoded with five bytes: - ss.write("\xfe\x00\x00\x00\x00", 5); + ss.write(MakeByteSpan("\xfe\x00\x00\x00\x00").first(5)); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // 0xffff encoded with five bytes: - ss.write("\xfe\xff\xff\x00\x00", 5); + ss.write(MakeByteSpan("\xfe\xff\xff\x00\x00").first(5)); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // zero encoded with nine bytes: - ss.write("\xff\x00\x00\x00\x00\x00\x00\x00\x00", 9); + ss.write(MakeByteSpan("\xff\x00\x00\x00\x00\x00\x00\x00\x00").first(9)); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // 0x01ffffff encoded with nine bytes: - ss.write("\xff\xff\xff\xff\x01\x00\x00\x00\x00", 9); + ss.write(MakeByteSpan("\xff\xff\xff\xff\x01\x00\x00\x00\x00").first(9)); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); } BOOST_AUTO_TEST_CASE(insert_delete) { + constexpr auto B2I{[](std::byte b) { return std::to_integer<uint8_t>(b); }}; + // Test inserting/deleting bytes. CDataStream ss(SER_DISK, 0); BOOST_CHECK_EQUAL(ss.size(), 0U); - ss.write("\x00\x01\x02\xff", 4); + ss.write(MakeByteSpan("\x00\x01\x02\xff").first(4)); BOOST_CHECK_EQUAL(ss.size(), 4U); - char c = (char)11; + uint8_t c{11}; // Inserting at beginning/end/middle: - ss.insert(ss.begin(), c); + ss.insert(ss.begin(), std::byte{c}); BOOST_CHECK_EQUAL(ss.size(), 5U); - BOOST_CHECK_EQUAL(ss[0], c); - BOOST_CHECK_EQUAL(ss[1], 0); + BOOST_CHECK_EQUAL(B2I(ss[0]), c); + BOOST_CHECK_EQUAL(B2I(ss[1]), 0); - ss.insert(ss.end(), c); + ss.insert(ss.end(), std::byte{c}); BOOST_CHECK_EQUAL(ss.size(), 6U); - BOOST_CHECK_EQUAL(ss[4], 0xff); - BOOST_CHECK_EQUAL(ss[5], c); + BOOST_CHECK_EQUAL(B2I(ss[4]), 0xff); + BOOST_CHECK_EQUAL(B2I(ss[5]), c); - ss.insert(ss.begin()+2, c); + ss.insert(ss.begin() + 2, std::byte{c}); BOOST_CHECK_EQUAL(ss.size(), 7U); - BOOST_CHECK_EQUAL(ss[2], c); + BOOST_CHECK_EQUAL(B2I(ss[2]), c); // Delete at beginning/end/middle ss.erase(ss.begin()); BOOST_CHECK_EQUAL(ss.size(), 6U); - BOOST_CHECK_EQUAL(ss[0], 0); + BOOST_CHECK_EQUAL(B2I(ss[0]), 0); ss.erase(ss.begin()+ss.size()-1); BOOST_CHECK_EQUAL(ss.size(), 5U); - BOOST_CHECK_EQUAL(ss[4], 0xff); + BOOST_CHECK_EQUAL(B2I(ss[4]), 0xff); ss.erase(ss.begin()+1); BOOST_CHECK_EQUAL(ss.size(), 4U); - BOOST_CHECK_EQUAL(ss[0], 0); - BOOST_CHECK_EQUAL(ss[1], 1); - BOOST_CHECK_EQUAL(ss[2], 2); - BOOST_CHECK_EQUAL(ss[3], 0xff); + BOOST_CHECK_EQUAL(B2I(ss[0]), 0); + BOOST_CHECK_EQUAL(B2I(ss[1]), 1); + BOOST_CHECK_EQUAL(B2I(ss[2]), 2); + BOOST_CHECK_EQUAL(B2I(ss[3]), 0xff); } BOOST_AUTO_TEST_CASE(class_methods) diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index 3571927397..a8f6cdd4a0 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(bitstream_reader_writer) BOOST_AUTO_TEST_CASE(streams_serializedata_xor) { - std::vector<uint8_t> in; + std::vector<std::byte> in; std::vector<char> expected_xor; std::vector<unsigned char> key; CDataStream ds(in, 0, 0); @@ -174,8 +174,8 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) std::string(expected_xor.begin(), expected_xor.end()), ds.str()); - in.push_back('\x0f'); - in.push_back('\xf0'); + in.push_back(std::byte{0x0f}); + in.push_back(std::byte{0xf0}); expected_xor.push_back('\xf0'); expected_xor.push_back('\x0f'); @@ -195,8 +195,8 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) in.clear(); expected_xor.clear(); - in.push_back('\xf0'); - in.push_back('\x0f'); + in.push_back(std::byte{0xf0}); + in.push_back(std::byte{0x0f}); expected_xor.push_back('\x0f'); expected_xor.push_back('\x00'); diff --git a/src/uint256.h b/src/uint256.h index 72681d09c9..5c3a2f5409 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_UINT256_H #define BITCOIN_UINT256_H +#include <span.h> + #include <assert.h> #include <cstring> #include <stdint.h> @@ -96,13 +98,13 @@ public: template<typename Stream> void Serialize(Stream& s) const { - s.write((char*)m_data, sizeof(m_data)); + s.write(MakeByteSpan(m_data)); } template<typename Stream> void Unserialize(Stream& s) { - s.read((char*)m_data, sizeof(m_data)); + s.read(MakeWritableByteSpan(m_data)); } }; diff --git a/src/validation.cpp b/src/validation.cpp index 1b1d01a4c2..5fca1551c8 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4104,7 +4104,7 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp) try { // locate a header unsigned char buf[CMessageHeader::MESSAGE_START_SIZE]; - blkdat.FindByte(char(m_params.MessageStart()[0])); + blkdat.FindByte(m_params.MessageStart()[0]); nRewind = blkdat.GetPos() + 1; blkdat >> buf; if (memcmp(buf, m_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) { diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp index e0be914a2b..cea120a81e 100644 --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -681,10 +681,10 @@ bool BerkeleyBatch::ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& // Convert to streams ssKey.SetType(SER_DISK); ssKey.clear(); - ssKey.write((char*)datKey.get_data(), datKey.get_size()); + ssKey.write({BytePtr(datKey.get_data()), datKey.get_size()}); ssValue.SetType(SER_DISK); ssValue.clear(); - ssValue.write((char*)datValue.get_data(), datValue.get_size()); + ssValue.write({BytePtr(datValue.get_data()), datValue.get_size()}); return true; } @@ -756,7 +756,7 @@ bool BerkeleyBatch::ReadKey(CDataStream&& key, CDataStream& value) SafeDbt datValue; int ret = pdb->get(activeTxn, datKey, datValue, 0); if (ret == 0 && datValue.get_data() != nullptr) { - value.write((char*)datValue.get_data(), datValue.get_size()); + value.write({BytePtr(datValue.get_data()), datValue.get_size()}); return true; } return false; diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp index 7dfb1d8839..3e34a2f776 100644 --- a/src/wallet/dump.cpp +++ b/src/wallet/dump.cpp @@ -47,12 +47,12 @@ bool DumpWallet(CWallet& wallet, bilingual_str& error) // Write out a magic string with version std::string line = strprintf("%s,%u\n", DUMP_MAGIC, DUMP_VERSION); dump_file.write(line.data(), line.size()); - hasher.write(line.data(), line.size()); + hasher.write(MakeByteSpan(line)); // Write out the file format line = strprintf("%s,%s\n", "format", db.Format()); dump_file.write(line.data(), line.size()); - hasher.write(line.data(), line.size()); + hasher.write(MakeByteSpan(line)); if (ret) { @@ -73,7 +73,7 @@ bool DumpWallet(CWallet& wallet, bilingual_str& error) std::string value_str = HexStr(ss_value); line = strprintf("%s,%s\n", key_str, value_str); dump_file.write(line.data(), line.size()); - hasher.write(line.data(), line.size()); + hasher.write(MakeByteSpan(line)); } } @@ -150,7 +150,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling return false; } std::string magic_hasher_line = strprintf("%s,%s\n", magic_key, version_value); - hasher.write(magic_hasher_line.data(), magic_hasher_line.size()); + hasher.write(MakeByteSpan(magic_hasher_line)); // Get the stored file format std::string format_key; @@ -181,7 +181,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling warnings.push_back(strprintf(_("Warning: Dumpfile wallet format \"%s\" does not match command line specified format \"%s\"."), format_value, file_format)); } std::string format_hasher_line = strprintf("%s,%s\n", format_key, format_value); - hasher.write(format_hasher_line.data(), format_hasher_line.size()); + hasher.write(MakeByteSpan(format_hasher_line)); DatabaseOptions options; DatabaseStatus status; @@ -225,7 +225,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling } std::string line = strprintf("%s,%s\n", key, value); - hasher.write(line.data(), line.size()); + hasher.write(MakeByteSpan(line)); if (key.empty() || value.empty()) { continue; diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp index 07e387f177..2b2181e70b 100644 --- a/src/wallet/sqlite.cpp +++ b/src/wallet/sqlite.cpp @@ -395,9 +395,9 @@ bool SQLiteBatch::ReadKey(CDataStream&& key, CDataStream& value) return false; } // Leftmost column in result is index 0 - const char* data = reinterpret_cast<const char*>(sqlite3_column_blob(m_read_stmt, 0)); - int data_size = sqlite3_column_bytes(m_read_stmt, 0); - value.write(data, data_size); + const std::byte* data{BytePtr(sqlite3_column_blob(m_read_stmt, 0))}; + size_t data_size(sqlite3_column_bytes(m_read_stmt, 0)); + value.write({data, data_size}); sqlite3_clear_bindings(m_read_stmt); sqlite3_reset(m_read_stmt); @@ -512,12 +512,12 @@ bool SQLiteBatch::ReadAtCursor(CDataStream& key, CDataStream& value, bool& compl } // Leftmost column in result is index 0 - const char* key_data = reinterpret_cast<const char*>(sqlite3_column_blob(m_cursor_stmt, 0)); - int key_data_size = sqlite3_column_bytes(m_cursor_stmt, 0); - key.write(key_data, key_data_size); - const char* value_data = reinterpret_cast<const char*>(sqlite3_column_blob(m_cursor_stmt, 1)); - int value_data_size = sqlite3_column_bytes(m_cursor_stmt, 1); - value.write(value_data, value_data_size); + const std::byte* key_data{BytePtr(sqlite3_column_blob(m_cursor_stmt, 0))}; + size_t key_data_size(sqlite3_column_bytes(m_cursor_stmt, 0)); + key.write({key_data, key_data_size}); + const std::byte* value_data{BytePtr(sqlite3_column_blob(m_cursor_stmt, 1))}; + size_t value_data_size(sqlite3_column_bytes(m_cursor_stmt, 1)); + value.write({value_data, value_data_size}); return true; } |