From c80f8d18c15c1bbe85b47bb3943bd772f0e5841e Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Fri, 27 Jul 2018 12:40:44 -0700 Subject: [PATCH] Fixed FlatBufferBuilder::Required not checking vtable size. As reported in: https://github.com/google/flatbuffers/issues/4846 Tested: on Linux. Change-Id: Id5e82dc5a46a681119cfe5a15415d522aac0e1f2 --- include/flatbuffers/flatbuffers.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index cb5feaa4f..7eb3c5791 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -1038,14 +1038,7 @@ class FlatBufferBuilder { // This checks a required field has been set in a given table that has // just been constructed. - template void Required(Offset table, voffset_t field) { - auto table_ptr = buf_.data_at(table.o); - auto vtable_ptr = table_ptr - ReadScalar(table_ptr); - bool ok = ReadScalar(vtable_ptr + field) != 0; - // If this fails, the caller will show what field needs to be set. - FLATBUFFERS_ASSERT(ok); - (void)ok; - } + template void Required(Offset table, voffset_t field); uoffset_t StartStruct(size_t alignment) { Align(alignment); @@ -1206,7 +1199,7 @@ class FlatBufferBuilder { void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) { PreAlign(len * elemsize, alignment); } - + // Similar to ForceVectorAlignment but for String fields. void ForceStringAlignment(size_t len, size_t alignment) { PreAlign((len + 1) * sizeof(char), alignment); @@ -2117,6 +2110,15 @@ class Table { uint8_t data_[1]; }; +template void FlatBufferBuilder::Required(Offset table, + voffset_t field) { + auto table_ptr = reinterpret_cast(buf_.data_at(table.o)); + bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; + // If this fails, the caller will show what field needs to be set. + FLATBUFFERS_ASSERT(ok); + (void)ok; +} + /// @brief This can compute the start of a FlatBuffer from a root pointer, i.e. /// it is the opposite transformation of GetRoot(). /// This may be useful if you want to pass on a root and have the recipient