}
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
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));
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:
*/