From ec0129369cd7a7adc40bd8f234c5ba84fba3d514 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Fri, 5 Aug 2022 10:45:01 -0700 Subject: [PATCH] Fix FlexBuffers Verifier tracking vectors reuse at wrong offset See test for an example. Found in: https://github.com/aardappel/lobster/pull/193 --- include/flatbuffers/flexbuffers.h | 4 ++-- tests/test.cpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/flatbuffers/flexbuffers.h b/include/flatbuffers/flexbuffers.h index e841368ff..025d6625d 100644 --- a/include/flatbuffers/flexbuffers.h +++ b/include/flatbuffers/flexbuffers.h @@ -1740,9 +1740,9 @@ class Verifier FLATBUFFERS_FINAL_CLASS { if (!Check(depth_ <= max_depth_ && num_vectors_ <= max_vectors_)) return false; 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; + FLEX_CHECK_VERIFIED(p - size_byte_width, + PackedType(Builder::WidthB(size_byte_width), r.type_)); auto sized = Sized(p, size_byte_width); auto num_elems = sized.size(); auto elem_byte_width = r.type_ == FBT_STRING || r.type_ == FBT_BLOB diff --git a/tests/test.cpp b/tests/test.cpp index 186c219a4..4d1a9deb3 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -3304,6 +3304,24 @@ void FlexBuffersTest() { TEST_EQ(slb.GetSize(), 664); } +void FlexBuffersReuseBugTest() { + flexbuffers::Builder slb; + slb.Map([&]() { + slb.Vector("vec", [&]() {}); + slb.Bool("bool", true); + }); + slb.Finish(); + std::vector 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() { #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) flexbuffers::Builder slb(512, @@ -4568,6 +4586,7 @@ int FlatBufferTests() { JsonDefaultTest(); JsonEnumsTest(); FlexBuffersTest(); + FlexBuffersReuseBugTest(); FlexBuffersDeprecatedTest(); UninitializedVectorTest(); EqualOperatorTest();