upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBitflash <btf01@proton.me>2026-07-28 15:25:15 -0300
committerGitHub <noreply@github.com>2026-07-28 15:25:15 -0300
commit1635bc34f40c76ac2943dbe6ff15dd0180b62ea6 (patch)
treec2a6057559ec93786ec5292b7a1836b972660d2b /src
parente0c00d3e1b3192efde01fba85d0831470a8fb89c (diff)
serialize: grow strings as data arrives, not to the declared length (#18)
The vector unserializer grows in 5 MB steps so a bogus length cannot make it allocate more than has actually been received. The string one resized straight to whatever ReadCompactSize returned, and ReadCompactSize has no ceiling -- nine bytes on the wire can name four gigabytes. Not reachable from the network today: the only string on a serialized type is CWalletTx::mapValue, and RelayMessage casts to CTransaction before sending, so it never leaves disk. This is a guard against the next network message that carries a string -- Bitcoin's own version message carries strSubVer -- rather than a fix for a live hole.
Diffstat (limited to 'src')
-rw-r--r--src/serialize.h22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/serialize.h b/src/serialize.h
index 0e03cf7..ce72c60 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -390,10 +390,26 @@ void Serialize(Stream& os, const basic_string<C>& str, int, int)
390template<typename Stream, typename C> 390template<typename Stream, typename C>
391void Unserialize(Stream& is, basic_string<C>& str, int, int) 391void Unserialize(Stream& is, basic_string<C>& str, int, int)
392{ 392{
393 // Grow in steps as the bytes actually arrive, the same way the vector
394 // unserializer below does. Resizing straight to the declared length lets
395 // nine bytes on the wire ask for a four-gigabyte allocation, and
396 // ReadCompactSize has no ceiling of its own.
397 //
398 // No network message carries a string today -- CWalletTx::mapValue is the
399 // only string field on a serialized type and RelayMessage casts it away --
400 // so this is a guard against the next one that does, not a live hole.
393 unsigned int nSize = ReadCompactSize(is); 401 unsigned int nSize = ReadCompactSize(is);
394 str.resize(nSize); 402 str.clear();
395 if (nSize != 0) 403 unsigned int nMid = 0;
396 is.read((char*)&str[0], nSize * sizeof(str[0])); 404 while (nMid < nSize)
405 {
406 nMid += 5000000 / sizeof(C);
407 if (nMid > nSize)
408 nMid = nSize;
409 unsigned int nOld = str.size();
410 str.resize(nMid);
411 is.read((char*)&str[nOld], (nMid - nOld) * sizeof(C));
412 }
397} 413}
398 414
399 415