mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-24 17:06:10 +00:00
Change SizedPrefixed verifier to be <= provided size (#7957)
* Change SizedPrefixed verifier to be <= provided size * add GetSizePrefixedBufferLength()
This commit is contained in:
@@ -81,6 +81,18 @@ inline SizeT GetPrefixedSize(const uint8_t *buf) {
|
|||||||
return ReadScalar<SizeT>(buf);
|
return ReadScalar<SizeT>(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the total length of the buffer given a sized prefixed FlatBuffer.
|
||||||
|
//
|
||||||
|
// This includes the size of the prefix as well as the buffer:
|
||||||
|
//
|
||||||
|
// [size prefix][flatbuffer]
|
||||||
|
// |---------length--------|
|
||||||
|
template<typename SizeT = uoffset_t>
|
||||||
|
inline SizeT GetSizePrefixedBufferLength(const uint8_t * const buf) {
|
||||||
|
return ReadScalar<SizeT>(buf) + sizeof(SizeT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Base class for native objects (FlatBuffer data de-serialized into native
|
// Base class for native objects (FlatBuffer data de-serialized into native
|
||||||
// C++ data structures).
|
// C++ data structures).
|
||||||
// Contains no functionality, purely documentative.
|
// Contains no functionality, purely documentative.
|
||||||
|
|||||||
@@ -177,8 +177,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow") bool VerifyTableStart(
|
FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow")
|
||||||
const uint8_t *const table) {
|
bool VerifyTableStart(const uint8_t *const table) {
|
||||||
// Check the vtable offset.
|
// Check the vtable offset.
|
||||||
const auto tableo = static_cast<size_t>(table - buf_);
|
const auto tableo = static_cast<size_t>(table - buf_);
|
||||||
if (!Verify<soffset_t>(tableo)) return false;
|
if (!Verify<soffset_t>(tableo)) return false;
|
||||||
@@ -246,7 +246,9 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
template<typename T, typename SizeT = uoffset_t>
|
template<typename T, typename SizeT = uoffset_t>
|
||||||
bool VerifySizePrefixedBuffer(const char *const identifier) {
|
bool VerifySizePrefixedBuffer(const char *const identifier) {
|
||||||
return Verify<SizeT>(0U) &&
|
return Verify<SizeT>(0U) &&
|
||||||
Check(ReadScalar<SizeT>(buf_) == size_ - sizeof(SizeT)) &&
|
// Ensure the prefixed size is within the bounds of the provided
|
||||||
|
// length.
|
||||||
|
Check(ReadScalar<SizeT>(buf_) + sizeof(SizeT) <= size_) &&
|
||||||
VerifyBufferFromStart<T>(identifier, sizeof(SizeT));
|
VerifyBufferFromStart<T>(identifier, sizeof(SizeT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "flatbuffers/base.h"
|
||||||
#include "flatbuffers/flatbuffer_builder.h"
|
#include "flatbuffers/flatbuffer_builder.h"
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/registry.h"
|
#include "flatbuffers/registry.h"
|
||||||
#include "flatbuffers/verifier.h"
|
#include "flatbuffers/verifier.h"
|
||||||
@@ -422,8 +424,8 @@ void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
|
|||||||
|
|
||||||
// Mutate structs.
|
// Mutate structs.
|
||||||
auto pos = monster->mutable_pos();
|
auto pos = monster->mutable_pos();
|
||||||
auto & test3 = pos->mutable_test3(); // Struct inside a struct.
|
auto &test3 = pos->mutable_test3(); // Struct inside a struct.
|
||||||
test3.mutate_a(50); // Struct fields never fail.
|
test3.mutate_a(50); // Struct fields never fail.
|
||||||
TEST_EQ(test3.a(), 50);
|
TEST_EQ(test3.a(), 50);
|
||||||
test3.mutate_a(10);
|
test3.mutate_a(10);
|
||||||
|
|
||||||
@@ -441,13 +443,12 @@ void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
|
|||||||
first->mutate_hp(1000);
|
first->mutate_hp(1000);
|
||||||
|
|
||||||
// Test for each loop over mutable entries
|
// Test for each loop over mutable entries
|
||||||
for (auto item: *tables)
|
for (auto item : *tables) {
|
||||||
{
|
|
||||||
TEST_EQ(item->hp(), 1000);
|
TEST_EQ(item->hp(), 1000);
|
||||||
item->mutate_hp(0);
|
item->mutate_hp(0);
|
||||||
TEST_EQ(item->hp(), 0);
|
TEST_EQ(item->hp(), 0);
|
||||||
item->mutate_hp(1000);
|
item->mutate_hp(1000);
|
||||||
break; // one iteration is enough, just testing compilation
|
break; // one iteration is enough, just testing compilation
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mutate via LookupByKey
|
// Mutate via LookupByKey
|
||||||
@@ -579,11 +580,31 @@ void SizePrefixedTest() {
|
|||||||
flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
|
flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
|
||||||
TEST_EQ(VerifySizePrefixedMonsterBuffer(verifier), true);
|
TEST_EQ(VerifySizePrefixedMonsterBuffer(verifier), true);
|
||||||
|
|
||||||
|
// The prefixed size doesn't include itself, so substract the size of the
|
||||||
|
// prefix
|
||||||
|
TEST_EQ(GetPrefixedSize(fbb.GetBufferPointer()),
|
||||||
|
fbb.GetSize() - sizeof(uoffset_t));
|
||||||
|
|
||||||
|
// Getting the buffer length does include the prefix size, so it should be the
|
||||||
|
// full lenght.
|
||||||
|
TEST_EQ(GetSizePrefixedBufferLength(fbb.GetBufferPointer()), fbb.GetSize());
|
||||||
|
|
||||||
// Access it.
|
// Access it.
|
||||||
auto m = GetSizePrefixedMonster(fbb.GetBufferPointer());
|
auto m = GetSizePrefixedMonster(fbb.GetBufferPointer());
|
||||||
TEST_EQ(m->mana(), 200);
|
TEST_EQ(m->mana(), 200);
|
||||||
TEST_EQ(m->hp(), 300);
|
TEST_EQ(m->hp(), 300);
|
||||||
TEST_EQ_STR(m->name()->c_str(), "bob");
|
TEST_EQ_STR(m->name()->c_str(), "bob");
|
||||||
|
|
||||||
|
{
|
||||||
|
// Verify that passing a larger size is OK, but not a smaller
|
||||||
|
flatbuffers::Verifier verifier_larger(fbb.GetBufferPointer(),
|
||||||
|
fbb.GetSize() + 10);
|
||||||
|
TEST_EQ(VerifySizePrefixedMonsterBuffer(verifier_larger), true);
|
||||||
|
|
||||||
|
flatbuffers::Verifier verifier_smaller(fbb.GetBufferPointer(),
|
||||||
|
fbb.GetSize() - 10);
|
||||||
|
TEST_EQ(VerifySizePrefixedMonsterBuffer(verifier_smaller), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestMonsterExtraFloats(const std::string &tests_data_path) {
|
void TestMonsterExtraFloats(const std::string &tests_data_path) {
|
||||||
|
|||||||
Reference in New Issue
Block a user