From fa126effc2a03e22708960344e62fc21259deb23 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 5 Jun 2014 10:10:52 +0200 Subject: Avoid undefined behavior using CFlatData in CScript serialization `&vch[vch.size()]` and even `&vch[0]` on vectors can cause assertion errors with VC in debug mode. This is the problem mentioned in #4239. The deeper problem with this is that we rely on undefined behavior. - Add `begin_ptr` and `end_ptr` functions that get the beginning and end pointer of vector in a reliable way that copes with empty vectors and doesn't reference outside the vector (see https://stackoverflow.com/questions/1339470/how-to-get-the-address-of-the-stdvector-buffer-start-most-elegantly/1339767#1339767). - Add a convenience constructor to CFlatData that wraps a vector. I added `begin_ptr` and `end_ptr` as separate functions as I imagine they will be useful in more places. --- src/script.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/script.h') diff --git a/src/script.h b/src/script.h index bd6574627..ea988f0e4 100644 --- a/src/script.h +++ b/src/script.h @@ -770,12 +770,12 @@ public: void Serialize(Stream &s, int nType, int nVersion) const { std::vector compr; if (Compress(compr)) { - s << CFlatData(&compr[0], &compr[compr.size()]); + s << CFlatData(compr); return; } unsigned int nSize = script.size() + nSpecialScripts; s << VARINT(nSize); - s << CFlatData(&script[0], &script[script.size()]); + s << CFlatData(script); } template @@ -784,13 +784,13 @@ public: s >> VARINT(nSize); if (nSize < nSpecialScripts) { std::vector vch(GetSpecialSize(nSize), 0x00); - s >> REF(CFlatData(&vch[0], &vch[vch.size()])); + s >> REF(CFlatData(vch)); Decompress(nSize, vch); return; } nSize -= nSpecialScripts; script.resize(nSize); - s >> REF(CFlatData(&script[0], &script[script.size()])); + s >> REF(CFlatData(script)); } }; -- cgit v1.2.3