Fix FlexBuffers Verifier tracking vectors reuse at wrong offset

See test for an example.
Found in: https://github.com/aardappel/lobster/pull/193
This commit is contained in:
Wouter van Oortmerssen 2022-08-05 10:45:01 -07:00
parent 50dd385b30
commit ec0129369c
2 changed files with 21 additions and 2 deletions

View File

@ -1740,9 +1740,9 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
if (!Check(depth_ <= max_depth_ && num_vectors_ <= max_vectors_)) if (!Check(depth_ <= max_depth_ && num_vectors_ <= max_vectors_))
return false; return false;
auto size_byte_width = r.byte_width_; auto size_byte_width = r.byte_width_;
FLEX_CHECK_VERIFIED(p,
PackedType(Builder::WidthB(size_byte_width), r.type_));
if (!VerifyBeforePointer(p, size_byte_width)) return false; if (!VerifyBeforePointer(p, size_byte_width)) return false;
FLEX_CHECK_VERIFIED(p - size_byte_width,
PackedType(Builder::WidthB(size_byte_width), r.type_));
auto sized = Sized(p, size_byte_width); auto sized = Sized(p, size_byte_width);
auto num_elems = sized.size(); auto num_elems = sized.size();
auto elem_byte_width = r.type_ == FBT_STRING || r.type_ == FBT_BLOB auto elem_byte_width = r.type_ == FBT_STRING || r.type_ == FBT_BLOB

View File

@ -3304,6 +3304,24 @@ void FlexBuffersTest() {
TEST_EQ(slb.GetSize(), 664); TEST_EQ(slb.GetSize(), 664);
} }
void FlexBuffersReuseBugTest() {
flexbuffers::Builder slb;
slb.Map([&]() {
slb.Vector("vec", [&]() {});
slb.Bool("bool", true);
});
slb.Finish();
std::vector<uint8_t> reuse_tracker;
// This would fail before, since the reuse_tracker would use the address of
// the vector reference to check for reuse, but in this case we have an empty
// vector, and since the size field is before the pointer, its address is the
// same as thing after it, the key "bool".
// We fix this by using the address of the size field for tracking reuse.
TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(),
slb.GetBuffer().size(), &reuse_tracker),
true);
}
void FlexBuffersFloatingPointTest() { void FlexBuffersFloatingPointTest() {
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
flexbuffers::Builder slb(512, flexbuffers::Builder slb(512,
@ -4568,6 +4586,7 @@ int FlatBufferTests() {
JsonDefaultTest(); JsonDefaultTest();
JsonEnumsTest(); JsonEnumsTest();
FlexBuffersTest(); FlexBuffersTest();
FlexBuffersReuseBugTest();
FlexBuffersDeprecatedTest(); FlexBuffersDeprecatedTest();
UninitializedVectorTest(); UninitializedVectorTest();
EqualOperatorTest(); EqualOperatorTest();