Browse Source

Merge pull request #4293

fa126ef Avoid undefined behavior using CFlatData in CScript serialization (Wladimir J. van der Laan)
0.10
Wladimir J. van der Laan 11 years ago
parent
commit
5459116d61
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 8
      src/script.h
  2. 34
      src/serialize.h

8
src/script.h

@ -770,12 +770,12 @@ public:
void Serialize(Stream &s, int nType, int nVersion) const { void Serialize(Stream &s, int nType, int nVersion) const {
std::vector<unsigned char> compr; std::vector<unsigned char> compr;
if (Compress(compr)) { if (Compress(compr)) {
s << CFlatData(&compr[0], &compr[compr.size()]); s << CFlatData(compr);
return; return;
} }
unsigned int nSize = script.size() + nSpecialScripts; unsigned int nSize = script.size() + nSpecialScripts;
s << VARINT(nSize); s << VARINT(nSize);
s << CFlatData(&script[0], &script[script.size()]); s << CFlatData(script);
} }
template<typename Stream> template<typename Stream>
@ -784,13 +784,13 @@ public:
s >> VARINT(nSize); s >> VARINT(nSize);
if (nSize < nSpecialScripts) { if (nSize < nSpecialScripts) {
std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00); std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00);
s >> REF(CFlatData(&vch[0], &vch[vch.size()])); s >> REF(CFlatData(vch));
Decompress(nSize, vch); Decompress(nSize, vch);
return; return;
} }
nSize -= nSpecialScripts; nSize -= nSpecialScripts;
script.resize(nSize); script.resize(nSize);
s >> REF(CFlatData(&script[0], &script[script.size()])); s >> REF(CFlatData(script));
} }
}; };

34
src/serialize.h

@ -37,6 +37,34 @@ inline T& REF(const T& val)
return const_cast<T&>(val); return const_cast<T&>(val);
} }
/** Get begin pointer of vector (non-const version).
* @note These functions avoid the undefined case of indexing into an empty
* vector, as well as that of indexing after the end of the vector.
*/
template <class T, class TAl>
inline T* begin_ptr(std::vector<T,TAl>& v)
{
return v.empty() ? NULL : &v[0];
}
/** Get begin pointer of vector (const version) */
template <class T, class TAl>
inline const T* begin_ptr(const std::vector<T,TAl>& v)
{
return v.empty() ? NULL : &v[0];
}
/** Get end pointer of vector (non-const version) */
template <class T, class TAl>
inline T* end_ptr(std::vector<T,TAl>& v)
{
return v.empty() ? NULL : (&v[0] + v.size());
}
/** Get end pointer of vector (const version) */
template <class T, class TAl>
inline const T* end_ptr(const std::vector<T,TAl>& v)
{
return v.empty() ? NULL : (&v[0] + v.size());
}
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// //
// Templates for serializing to anything that looks like a stream, // Templates for serializing to anything that looks like a stream,
@ -318,6 +346,12 @@ protected:
char* pend; char* pend;
public: public:
CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { } CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
template <class T, class TAl>
explicit CFlatData(std::vector<T,TAl> &v)
{
pbegin = (char*)begin_ptr(v);
pend = (char*)end_ptr(v);
}
char* begin() { return pbegin; } char* begin() { return pbegin; }
const char* begin() const { return pbegin; } const char* begin() const { return pbegin; }
char* end() { return pend; } char* end() { return pend; }

Loading…
Cancel
Save