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.
This commit is contained in:
@@ -770,12 +770,12 @@ public:
|
||||
void Serialize(Stream &s, int nType, int nVersion) const {
|
||||
std::vector<unsigned char> 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<typename Stream>
|
||||
@@ -784,13 +784,13 @@ public:
|
||||
s >> VARINT(nSize);
|
||||
if (nSize < nSpecialScripts) {
|
||||
std::vector<unsigned char> 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));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user