Commit 93f4d05d authored by Wez Furlong's avatar Wez Furlong Committed by Facebook Github Bot

fixup decode logic for fragmented IOBufs

Summary:
D6635325 exposed a long standing issue with the way
that we were consuming Cursor::length, so let's fix it up!

More details are in the new unit test for this!

Reviewed By: spalamarchuk

Differential Revision: D6755842

fbshipit-source-id: f8b20406c32682892791e7375be577d54d52e0ad
parent 6374f552
......@@ -61,7 +61,10 @@ static std::string decodeString(Cursor& curs) {
}
str.reserve(size_t(len));
size_t available = curs.length();
// peekBytes will advance over any "empty" IOBuf elements until
// it reaches the next one with data, so do that to obtain the
// true remaining length.
size_t available = curs.peekBytes().size();
while (available < (size_t)len) {
if (available == 0) {
// Saw this case when we decodeHeader was returning the incorrect length
......@@ -74,7 +77,7 @@ static std::string decodeString(Cursor& curs) {
str.append(reinterpret_cast<const char*>(curs.data()), available);
curs.skipAtMost(available);
len -= available;
available = curs.length();
available = curs.peekBytes().size();
}
str.append(reinterpret_cast<const char*>(curs.data()), size_t(len));
......
......@@ -118,5 +118,32 @@ TEST(Bser, PduLength) {
EXPECT_EQ(len, 44) << "PduLength should be 44, got " << len;
}
TEST(Bser, CursorLength) {
folly::bser::serialization_opts opts;
std::string inputStr("hello there please break");
// This test is exercising the decode logic for pathological
// fragmentation cases. We try a few permutations with the
// BSER header being fragmented to tickle boundary conditions
auto longSerialized = folly::bser::toBser(inputStr, opts);
for (uint32_t i = 1; i < longSerialized.size(); ++i) {
folly::IOBufQueue q;
q.append(folly::IOBuf::wrapBuffer(longSerialized.data(), i));
uint32_t j = i;
while (j < longSerialized.size()) {
q.append(folly::IOBuf::wrapBuffer(&longSerialized[j], 1));
++j;
}
auto pdu_len = folly::bser::decodePduLength(q.front());
auto buf = q.split(pdu_len);
auto hello = folly::bser::parseBser(buf.get());
EXPECT_EQ(inputStr, hello.asString());
}
}
/* vim:ts=2:sw=2:et:
*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment