Ah sorry for missing this, but this doesn’t work at all. A nullptr can never point to an object, so it is always invalid to create a non-zero span from it.
libc++ also complains about this.
You can reproduce via:
rm -rf ./bld-cmake && cmake -B ./bld-cmake -DCMAKE_C_COMPILER='clang' -DCMAKE_CXX_COMPILER='clang++;-stdlib=libc++;-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG' -DBUILD_GUI=OFF -DBUILD_FUZZ_BINARY=OFF -DBUILD_BENCH=OFF -DBUILD_KERNEL_LIB=ON -DENABLE_WALLET=OFF -DENABLE_IPC=OFF && cmake --build ./bld-cmake --parallel $( nproc ) && valgrind --tool=none ./bld-cmake/bin/test_kernel --catch_system_error=no
0/cxx_build/include/c++/v1/span:451: libc++ Hardening assertion __count == 0 || std::to_address(__first) != nullptr failed: passed nullptr with non-zero length in span's constructor (iterator, len)
I think the options are:
- Always treat nullptr as invalid, because even if the span is empty, I fail to see how deserialization can do something meaningful with an empty span.
0diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp
1index 0b9ea5137f..1695920f2b 100644
2--- a/src/kernel/bitcoinkernel.cpp
3+++ b/src/kernel/bitcoinkernel.cpp
4@@ -497,7 +497,7 @@ struct btck_Txid: Handle<btck_Txid, Txid> {};
5
6 btck_Transaction* btck_transaction_create(const void* raw_transaction, size_t raw_transaction_len)
7 {
8- if (raw_transaction == nullptr && raw_transaction_len != 0) {
9+ if (raw_transaction == nullptr) {
10 return nullptr;
11 }
12 try {
0diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp
1index 0b9ea5137f..6545e02b84 100644
2--- a/src/kernel/bitcoinkernel.cpp
3+++ b/src/kernel/bitcoinkernel.cpp
4@@ -497,9 +497,6 @@ struct btck_Txid: Handle<btck_Txid, Txid> {};
5
6 btck_Transaction* btck_transaction_create(const void* raw_transaction, size_t raw_transaction_len)
7 {
8- if (raw_transaction == nullptr && raw_transaction_len != 0) {
9- return nullptr;
10- }
11 try {
12 DataStream stream{std::span{reinterpret_cast<const std::byte*>(raw_transaction), raw_transaction_len}};
13 return btck_Transaction::create(std::make_shared<const CTransaction>(deserialize, TX_WITH_WITNESS, stream));