aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfanquake <fanquake@gmail.com>2024-02-26 11:34:10 +0000
committerfanquake <fanquake@gmail.com>2024-02-26 11:54:29 +0000
commit1ce5accc325cd7d3382f67a314dec018cfdc0a3e (patch)
treeffc2f9987ce3c0cf73e5ba550e0b578fc21e422f /src
parent8087626cbda97f6def4fb51cdac6f204486ee6fb (diff)
parent9f13dc1ed3020d55ba79b1a62ca0db6b510357ab (diff)
Merge bitcoin/bitcoin#29464: [25.2] Final backports and changes for 25.2rc1v25.2rc1
9f13dc1ed3020d55ba79b1a62ca0db6b510357ab doc: Update release notes for 25.2rc1 (Ava Chow) a27662b16a626ade5f26613e9f5323edcd6e9105 doc: update manpages for 25.2rc1 (Ava Chow) 65c617178420d5904fd43399eb3c87e00aff524e build: Bump to 25.2rc1 (Ava Chow) cf0f43ee42f0bf8d345b109b0ba552faf7cb62e1 wallet: Fix use-after-free in WalletBatch::EraseRecords (MarcoFalke) 6acfc4324cc98a10e083e5f391435bbfde4d8f69 Use only Span{} constructor for byte-like types where possible (MarcoFalke) b40d10787b2dc161e236e50eb296bdf02f93933f util: Allow std::byte and char Span serialization (MarcoFalke) Pull request description: Backport: * #29176 * #27927 #29176 does not cleanly backport, and it also requires 27927 to work. Both are still fairly simple backports. Also does the rest of the version bump tasks for 25.2rc1. ACKs for top commit: fanquake: ACK 9f13dc1ed3020d55ba79b1a62ca0db6b510357ab Tree-SHA512: 9d9dbf415f8559410eba9a431b61a8fc94216898d2d1fd8398e1f7a22a04790faade810e65324c7a797456b33396c3a58f991e81319aaaa63d3ab441e5e20dbc
Diffstat (limited to 'src')
-rw-r--r--src/bench/load_external.cpp2
-rw-r--r--src/net.cpp4
-rw-r--r--src/pubkey.h4
-rw-r--r--src/serialize.h7
-rw-r--r--src/test/fuzz/p2p_transport_serialization.cpp2
-rw-r--r--src/test/serialize_tests.cpp23
-rw-r--r--src/uint256.h2
-rw-r--r--src/wallet/dump.cpp12
-rw-r--r--src/wallet/wallet.cpp4
-rw-r--r--src/wallet/walletdb.cpp4
10 files changed, 36 insertions, 28 deletions
diff --git a/src/bench/load_external.cpp b/src/bench/load_external.cpp
index 0fd842c7c3..c6883af6d1 100644
--- a/src/bench/load_external.cpp
+++ b/src/bench/load_external.cpp
@@ -33,7 +33,7 @@ static void LoadExternalBlockFile(benchmark::Bench& bench)
ss << static_cast<uint32_t>(benchmark::data::block413567.size());
// We can't use the streaming serialization (ss << benchmark::data::block413567)
// because that first writes a compact size.
- ss.write(MakeByteSpan(benchmark::data::block413567));
+ ss << Span{benchmark::data::block413567};
// Create the test file.
{
diff --git a/src/net.cpp b/src/net.cpp
index 903fedb2fb..39b6200a0e 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2939,13 +2939,13 @@ void CaptureMessageToFile(const CAddress& addr,
AutoFile f{fsbridge::fopen(path, "ab")};
ser_writedata64(f, now.count());
- f.write(MakeByteSpan(msg_type));
+ f << Span{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(AsBytes(data));
+ f << data;
}
std::function<void(const CAddress& addr,
diff --git a/src/pubkey.h b/src/pubkey.h
index b3edafea7f..d7337453ab 100644
--- a/src/pubkey.h
+++ b/src/pubkey.h
@@ -142,14 +142,14 @@ public:
{
unsigned int len = size();
::WriteCompactSize(s, len);
- s.write(AsBytes(Span{vch, len}));
+ s << Span{vch, len};
}
template <typename Stream>
void Unserialize(Stream& s)
{
const unsigned int len(::ReadCompactSize(s));
if (len <= SIZE) {
- s.read(AsWritableBytes(Span{vch, len}));
+ s >> Span{vch, len};
if (len != size()) {
Invalidate();
}
diff --git a/src/serialize.h b/src/serialize.h
index 7bc7b10779..348a6ae4f1 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -188,6 +188,7 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
} \
FORMATTER_METHODS(cls, obj)
+// clang-format off
#ifndef CHAR_EQUALS_INT8
template <typename Stream> void Serialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t
#endif
@@ -201,8 +202,7 @@ template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_wri
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(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)); }
+template <typename Stream, typename B> void Serialize(Stream& s, Span<B> span) { (void)/* force byte-type */UCharCast(span.data()); s.write(AsBytes(span)); }
#ifndef CHAR_EQUALS_INT8
template <typename Stream> void Unserialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t
@@ -217,10 +217,11 @@ template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a =
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(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, typename B> void Unserialize(Stream& s, Span<B> span) { (void)/* force byte-type */UCharCast(span.data()); 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; }
+// clang-format on
/**
diff --git a/src/test/fuzz/p2p_transport_serialization.cpp b/src/test/fuzz/p2p_transport_serialization.cpp
index 96254aa222..098498bffd 100644
--- a/src/test/fuzz/p2p_transport_serialization.cpp
+++ b/src/test/fuzz/p2p_transport_serialization.cpp
@@ -76,7 +76,7 @@ FUZZ_TARGET_INIT(p2p_transport_serialization, initialize_p2p_transport_serializa
assert(msg.m_time == m_time);
std::vector<unsigned char> header;
- auto msg2 = CNetMsgMaker{msg.m_recv.GetVersion()}.Make(msg.m_type, MakeUCharSpan(msg.m_recv));
+ auto msg2 = CNetMsgMaker{msg.m_recv.GetVersion()}.Make(msg.m_type, Span{msg.m_recv});
serializer.prepareForTransport(msg2, header);
}
}
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index 09f77d2b61..b445ff8ffc 100644
--- a/src/test/serialize_tests.cpp
+++ b/src/test/serialize_tests.cpp
@@ -186,32 +186,32 @@ BOOST_AUTO_TEST_CASE(noncanonical)
std::vector<char>::size_type n;
// zero encoded with three bytes:
- ss.write(MakeByteSpan("\xfd\x00\x00").first(3));
+ ss << Span{"\xfd\x00\x00"}.first(3);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xfc encoded with three bytes:
- ss.write(MakeByteSpan("\xfd\xfc\x00").first(3));
+ ss << Span{"\xfd\xfc\x00"}.first(3);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xfd encoded with three bytes is OK:
- ss.write(MakeByteSpan("\xfd\xfd\x00").first(3));
+ ss << Span{"\xfd\xfd\x00"}.first(3);
n = ReadCompactSize(ss);
BOOST_CHECK(n == 0xfd);
// zero encoded with five bytes:
- ss.write(MakeByteSpan("\xfe\x00\x00\x00\x00").first(5));
+ ss << Span{"\xfe\x00\x00\x00\x00"}.first(5);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xffff encoded with five bytes:
- ss.write(MakeByteSpan("\xfe\xff\xff\x00\x00").first(5));
+ ss << Span{"\xfe\xff\xff\x00\x00"}.first(5);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// zero encoded with nine bytes:
- ss.write(MakeByteSpan("\xff\x00\x00\x00\x00\x00\x00\x00\x00").first(9));
+ ss << Span{"\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(MakeByteSpan("\xff\xff\xff\xff\x01\x00\x00\x00\x00").first(9));
+ ss << Span{"\xff\xff\xff\xff\x01\x00\x00\x00\x00"}.first(9);
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
}
@@ -241,6 +241,15 @@ BOOST_AUTO_TEST_CASE(class_methods)
ss2 << intval << boolval << stringval << charstrval << txval;
ss2 >> methodtest3;
BOOST_CHECK(methodtest3 == methodtest4);
+ {
+ DataStream ds;
+ const std::string in{"ab"};
+ ds << Span{in};
+ std::array<std::byte, 2> out;
+ ds >> Span{out};
+ BOOST_CHECK_EQUAL(out.at(0), std::byte{'a'});
+ BOOST_CHECK_EQUAL(out.at(1), std::byte{'b'});
+ }
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/uint256.h b/src/uint256.h
index 1cc3721487..135907dcf7 100644
--- a/src/uint256.h
+++ b/src/uint256.h
@@ -77,7 +77,7 @@ public:
template<typename Stream>
void Serialize(Stream& s) const
{
- s.write(MakeByteSpan(m_data));
+ s << Span(m_data);
}
template<typename Stream>
diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
index 31b6eb4ae1..15a3d2b7e1 100644
--- a/src/wallet/dump.cpp
+++ b/src/wallet/dump.cpp
@@ -57,12 +57,12 @@ bool DumpWallet(const ArgsManager& args, 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(MakeByteSpan(line));
+ hasher << Span{line};
// Write out the file format
line = strprintf("%s,%s\n", "format", db.Format());
dump_file.write(line.data(), line.size());
- hasher.write(MakeByteSpan(line));
+ hasher << Span{line};
if (ret) {
@@ -83,7 +83,7 @@ bool DumpWallet(const ArgsManager& args, 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(MakeByteSpan(line));
+ hasher << Span{line};
}
}
@@ -160,7 +160,7 @@ bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::
return false;
}
std::string magic_hasher_line = strprintf("%s,%s\n", magic_key, version_value);
- hasher.write(MakeByteSpan(magic_hasher_line));
+ hasher << Span{magic_hasher_line};
// Get the stored file format
std::string format_key;
@@ -191,7 +191,7 @@ bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::
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(MakeByteSpan(format_hasher_line));
+ hasher << Span{format_hasher_line};
DatabaseOptions options;
DatabaseStatus status;
@@ -236,7 +236,7 @@ bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::
}
std::string line = strprintf("%s,%s\n", key, value);
- hasher.write(MakeByteSpan(line));
+ hasher << Span{line};
if (key.empty() || value.empty()) {
continue;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 07bc742090..0d664a4539 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3863,9 +3863,7 @@ bool CWallet::MigrateToSQLite(bilingual_str& error)
bool began = batch->TxnBegin();
assert(began); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution.
for (const auto& [key, value] : records) {
- DataStream ss_key{key};
- DataStream ss_value{value};
- if (!batch->Write(ss_key, ss_value)) {
+ if (!batch->Write(Span{key}, Span{value})) {
batch->TxnAbort();
m_database->Close();
fs::remove(m_database->Filename());
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index c8e8ce4614..4f04cdf912 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -1132,13 +1132,13 @@ bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& types)
}
// Make a copy of key to avoid data being deleted by the following read of the type
- Span<const unsigned char> key_data = MakeUCharSpan(key);
+ const SerializeData key_data{key.begin(), key.end()};
std::string type;
key >> type;
if (types.count(type) > 0) {
- m_batch->Erase(key_data);
+ m_batch->Erase(Span{key_data});
}
}
return true;