diff --git a/include/flatbuffers/verifier.h b/include/flatbuffers/verifier.h index a0b793597c..8ca5013f8c 100644 --- a/include/flatbuffers/verifier.h +++ b/include/flatbuffers/verifier.h @@ -254,11 +254,12 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS { template bool VerifySizePrefixedBuffer(const char* const identifier) { - return Verify(0U) && - // Ensure the prefixed size is within the bounds of the provided - // length. - Check(ReadScalar(buf_) + sizeof(SizeT) <= size_) && - VerifyBufferFromStart(identifier, sizeof(SizeT)); + if (!Verify(0U)) return false; + // Ensure the prefixed size is within the bounds of the provided length. + const auto prefixed_size = static_cast(ReadScalar(buf_)); + const auto max_payload_size = static_cast(size_ - sizeof(SizeT)); + if (!Check(prefixed_size <= max_payload_size)) return false; + return VerifyBufferFromStart(identifier, sizeof(SizeT)); } template diff --git a/tests/64bit/offset64_test.cpp b/tests/64bit/offset64_test.cpp index d185e38994..dee0b9f200 100644 --- a/tests/64bit/offset64_test.cpp +++ b/tests/64bit/offset64_test.cpp @@ -374,6 +374,17 @@ void Offset64SizePrefix() { // Verify the fields. TEST_EQ_STR(root_table->near_string()->c_str(), "some near string"); + + std::vector tampered(builder.GetBufferPointer(), + builder.GetBufferPointer() + builder.GetSize()); + WriteScalar(tampered.data(), + (std::numeric_limits::max)()); + + Verifier::Options tampered_options = options; + tampered_options.assert = false; + Verifier tampered_verifier(tampered.data(), tampered.size(), + tampered_options); + TEST_EQ(VerifySizePrefixedRootTableBuffer(tampered_verifier), false); } void Offset64ManyVectors() {