diff --git a/src/streams.h b/src/streams.h --- a/src/streams.h +++ b/src/streams.h @@ -235,25 +235,35 @@ void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) { - assert(last - first >= 0); + if (last == first) { + return; + } + + assert(last - first > 0); if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) { // special case for inserting at the front when there's room nReadPos -= (last - first); memcpy(&vch[nReadPos], &first[0], last - first); - } else + } else { vch.insert(it, first, last); + } } void insert(iterator it, const char *first, const char *last) { - assert(last - first >= 0); + if (last == first) { + return; + } + + assert(last - first > 0); if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) { // special case for inserting at the front when there's room nReadPos -= (last - first); memcpy(&vch[nReadPos], &first[0], last - first); - } else + } else { vch.insert(it, first, last); + } } iterator erase(iterator it) { @@ -266,8 +276,9 @@ return vch.erase(vch.begin(), vch.end()); } return vch.begin() + nReadPos; - } else + } else { return vch.erase(it); + } } iterator erase(iterator first, iterator last) { @@ -309,6 +320,10 @@ int GetVersion() const { return nVersion; } void read(char *pch, size_t nSize) { + if (nSize == 0) { + return; + } + // Read from the beginning of the buffer unsigned int nReadPosNext = nReadPos + nSize; if (nReadPosNext >= vch.size()) { @@ -365,8 +380,8 @@ return (*this); } - void GetAndClear(CSerializeData &data) { - data.insert(data.end(), begin(), end()); + void GetAndClear(CSerializeData &d) { + d.insert(d.end(), begin(), end()); clear(); } diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -118,4 +118,22 @@ std::string(ds.begin(), ds.end())); } +BOOST_AUTO_TEST_CASE(streams_empty_vector) { + std::vector in; + CDataStream ds(in, 0, 0); + + // read 0 bytes used to cause a segfault on some older systems. + ds.read(nullptr, 0); + + // Same goes for writing 0 bytes from a vector ... + const std::vector vdata{'f', 'o', 'o', 'b', 'a', 'r'}; + ds.insert(ds.begin(), vdata.begin(), vdata.begin()); + ds.insert(ds.begin(), vdata.begin(), vdata.end()); + + // ... or an array. + const char adata[6] = {'f', 'o', 'o', 'b', 'a', 'r'}; + ds.insert(ds.begin(), &adata[0], &adata[0]); + ds.insert(ds.begin(), &adata[0], &adata[6]); +} + BOOST_AUTO_TEST_SUITE_END()