diff --git a/include/flatbuffers/flexbuffers.h b/include/flatbuffers/flexbuffers.h index 5c42a7ed47..9899f7273b 100644 --- a/include/flatbuffers/flexbuffers.h +++ b/include/flatbuffers/flexbuffers.h @@ -1860,7 +1860,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS { reuse_tracker_(reuse_tracker) { FLATBUFFERS_ASSERT(static_cast(size_) < FLATBUFFERS_MAX_BUFFER_SIZE); - if (reuse_tracker_) { + if (buf_ && reuse_tracker_) { reuse_tracker_->clear(); reuse_tracker_->resize(size_, PackedType(BIT_WIDTH_8, FBT_NULL)); } @@ -1879,10 +1879,11 @@ class Verifier FLATBUFFERS_FINAL_CLASS { // Verify any range within the buffer. bool VerifyFrom(size_t elem, size_t elem_len) const { - return Check(elem_len < size_ && elem <= size_ - elem_len); + return Check(buf_ != nullptr && elem_len < size_ && + elem <= size_ - elem_len); } bool VerifyBefore(size_t elem, size_t elem_len) const { - return Check(elem_len <= elem); + return Check(buf_ != nullptr && elem_len <= elem); } bool VerifyFromPointer(const uint8_t* p, size_t len) { @@ -2050,7 +2051,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS { public: bool VerifyBuffer() { - if (!Check(size_ >= 3)) return false; + if (!Check(buf_ != nullptr && size_ >= 3)) return false; auto end = buf_ + size_; auto byte_width = *--end; auto packed_type = *--end; @@ -2073,6 +2074,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS { // parameters. inline bool VerifyBuffer(const uint8_t* buf, size_t buf_len, std::vector* reuse_tracker = nullptr) { + if (!buf) return false; Verifier verifier(buf, buf_len, reuse_tracker); return verifier.VerifyBuffer(); } diff --git a/include/flatbuffers/verifier.h b/include/flatbuffers/verifier.h index a0b793597c..9bbe168b16 100644 --- a/include/flatbuffers/verifier.h +++ b/include/flatbuffers/verifier.h @@ -83,7 +83,8 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS { upper_bound_ = upper_bound; } } - return Check(elem_len < size_ && elem <= size_ - elem_len); + return Check(buf_ != nullptr && elem_len < size_ && + elem <= size_ - elem_len); } bool VerifyAlignment(const size_t elem, const size_t align) const { @@ -204,7 +205,9 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS { // Buffers have to be of some size to be valid. The reason it is a runtime // check instead of static_assert, is that nested flatbuffers go through // this call and their size is determined at runtime. - if (!Check(size_ >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false; + if (!Check(buf_ != nullptr && size_ >= FLATBUFFERS_MIN_BUFFER_SIZE)) { + return false; + } // If an identifier is provided, check that we have a buffer if (identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) && diff --git a/tests/flexbuffers_test.cpp b/tests/flexbuffers_test.cpp index 6087a0affb..97ac56f0c6 100644 --- a/tests/flexbuffers_test.cpp +++ b/tests/flexbuffers_test.cpp @@ -314,5 +314,14 @@ void ParseFlexbuffersFromJsonWithNullTest() { } } +void FlexBuffersVerifyNullBufferTest() { + TEST_EQ(flexbuffers::VerifyBuffer(nullptr, 0), false); + TEST_EQ(flexbuffers::VerifyBuffer(nullptr, 10), false); + std::vector reuse_tracker; + TEST_EQ(flexbuffers::VerifyBuffer(nullptr, 10, &reuse_tracker), false); + flexbuffers::Verifier verifier(nullptr, 10); + TEST_EQ(verifier.VerifyBuffer(), false); +} + } // namespace tests } // namespace flatbuffers diff --git a/tests/flexbuffers_test.h b/tests/flexbuffers_test.h index 132098fb37..40b1a1543a 100644 --- a/tests/flexbuffers_test.h +++ b/tests/flexbuffers_test.h @@ -9,6 +9,7 @@ void FlexBuffersReuseBugTest(); void FlexBuffersFloatingPointTest(); void FlexBuffersDeprecatedTest(); void ParseFlexbuffersFromJsonWithNullTest(); +void FlexBuffersVerifyNullBufferTest(); } // namespace tests } // namespace flatbuffers diff --git a/tests/test.cpp b/tests/test.cpp index 5a43546f53..789e3a5d8a 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1319,6 +1319,12 @@ void SizeVerifierTest() { TEST_EQ(length, size_verifier.GetComputedSize()); } +void VerifierNullBufferTest() { + flatbuffers::Verifier null_verifier(nullptr, 100); + TEST_EQ(false, null_verifier.VerifyBuffer()); + TEST_EQ(false, null_verifier.Verify(0, 10)); +} + template void TestIterators(const std::vector& expected, const Container& tested) { TEST_ASSERT(tested.rbegin().base() == tested.end()); @@ -1840,6 +1846,7 @@ int FlatBufferTests(const std::string& tests_data_path) { NativeTypeTest(); OptionalScalarsTest(); ParseFlexbuffersFromJsonWithNullTest(); + FlexBuffersVerifyNullBufferTest(); FlatbuffersSpanTest(); FixedLengthArrayConstructorTest(); FixedLengthArrayOperatorEqualTest(); @@ -1850,6 +1857,7 @@ int FlatBufferTests(const std::string& tests_data_path) { WarningsAsErrorsTest(); NestedVerifierTest(); SizeVerifierTest(); + VerifierNullBufferTest(); PrivateAnnotationsLeaks(); JsonUnsortedArrayTest(); VectorSpanTest();