What changed, and why it matters
This commit adds a convenience feature to Bitcoin Core's serialization code: it lets a lightweight read-only string type (std::string_view) be written directly to a data stream, instead of first copying it into a std::string. It also explicitly deletes the matching 'Unserialize' function, because you cannot deserialize into a read-only string_view. The change is a small, safe API improvement with no obvious security relevance.
No security action required. Treat as a normal code-quality/API enhancement. Reviewers may optionally confirm that no call sites pass a string_view whose backing data could become invalid before serialization completes, though the serialization is synchronous.
Security signals we found
No memory-unsafe operations observed: serialization uses MakeByteSpan and the existing WriteCompactSize/os.write path
Unserialize explicitly deleted to prevent misuse of a non-owning view type
No changes to consensus, network, or wallet code
No bug fix, bounds-check correction, or input-validation change
Evidence from the diff
The patch adds a Serialize() overload for std::basic_string_view
Changed components
src/serialize.hsrc/test/serialize_tests.cppInspect captured patch +28 / −1
diff --git a/src/serialize.h b/src/serialize.h
index 5cef72a9..2681b098 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -24,6 +24,7 @@
#include <set>
#include <span>
#include <string>
+#include <string_view>
#include <utility>
#include <vector>
@@ -705,6 +706,12 @@ struct VectorFormatter
template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str);
template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str);
+/**
+ * string_view
+ */
+template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string_view<C>& str);
+template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string_view<C>& str) = delete;
+
/**
* prevector
*/
@@ -807,7 +814,17 @@ void Unserialize(Stream& is, std::basic_string<C>& str)
is.read(MakeWritableByteSpan(str));
}
-
+/**
+ * string_view
+ */
+template<typename Stream, typename C>
+void Serialize(Stream& os, const std::basic_string_view<C>& str)
+{
+ WriteCompactSize(os, str.size());
+ if (!str.empty()) {
+ os.write(MakeByteSpan(str));
+ }
+}
/**
* prevector
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index f646ba5f..dd2c8cdd 100644
--- a/src/test/serialize_tests.cpp
+++ b/src/test/serialize_tests.cpp
@@ -241,6 +241,16 @@ BOOST_AUTO_TEST_CASE(noncanonical)
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
}
+BOOST_AUTO_TEST_CASE(string_view)
+{
+ const std::string_view sv{"hello, world"};
+ DataStream ss;
+ ss << sv;
+ std::string s;
+ ss >> s;
+ BOOST_CHECK_EQUAL(sv, s);
+}
+
BOOST_AUTO_TEST_CASE(class_methods)
{
int intval(100);
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.