Skip to content

Commit

Permalink
Bug fix: CDataStream::GetAndClear() when nReadPos > 0
Browse files Browse the repository at this point in the history
Changed CDataStream::GetAndClear() to use the most obvious
get get and clear instead of a tricky swap().

Added a unit test for CDataStream insert/erase/GetAndClear.

Note: GetAndClear() is not performance critical, it is used only
by the send-a-message-to-the-network code. Bug was not noticed
before now because the send-a-message code never erased from the
stream.
  • Loading branch information
gavinandresen committed Oct 29, 2013
1 parent cd1fc24 commit d5d1425
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/serialize.h
Expand Up @@ -1104,8 +1104,8 @@ class CDataStream
}

void GetAndClear(CSerializeData &data) {
vch.swap(data);
CSerializeData().swap(vch);
data.insert(data.end(), begin(), end());
clear();
}
};

Expand Down
48 changes: 48 additions & 0 deletions src/test/serialize_tests.cpp
Expand Up @@ -102,4 +102,52 @@ BOOST_AUTO_TEST_CASE(noncanonical)
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
}

BOOST_AUTO_TEST_CASE(insert_delete)
{
// Test inserting/deleting bytes.
CDataStream ss(SER_DISK, 0);
BOOST_CHECK_EQUAL(ss.size(), 0);

ss.write("\x00\x01\x02\xff", 4);
BOOST_CHECK_EQUAL(ss.size(), 4);

char c = (char)11;

// Inserting at beginning/end/middle:
ss.insert(ss.begin(), c);
BOOST_CHECK_EQUAL(ss.size(), 5);
BOOST_CHECK_EQUAL(ss[0], c);
BOOST_CHECK_EQUAL(ss[1], 0);

ss.insert(ss.end(), c);
BOOST_CHECK_EQUAL(ss.size(), 6);
BOOST_CHECK_EQUAL(ss[4], (char)0xff);
BOOST_CHECK_EQUAL(ss[5], c);

ss.insert(ss.begin()+2, c);
BOOST_CHECK_EQUAL(ss.size(), 7);
BOOST_CHECK_EQUAL(ss[2], c);

// Delete at beginning/end/middle
ss.erase(ss.begin());
BOOST_CHECK_EQUAL(ss.size(), 6);
BOOST_CHECK_EQUAL(ss[0], 0);

ss.erase(ss.begin()+ss.size()-1);
BOOST_CHECK_EQUAL(ss.size(), 5);
BOOST_CHECK_EQUAL(ss[4], (char)0xff);

ss.erase(ss.begin()+1);
BOOST_CHECK_EQUAL(ss.size(), 4);
BOOST_CHECK_EQUAL(ss[0], 0);
BOOST_CHECK_EQUAL(ss[1], 1);
BOOST_CHECK_EQUAL(ss[2], 2);
BOOST_CHECK_EQUAL(ss[3], (char)0xff);

// Make sure GetAndClear does the right thing:
CSerializeData d;
ss.GetAndClear(d);
BOOST_CHECK_EQUAL(ss.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit d5d1425

Please sign in to comment.