mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-06 05:27:24 +00:00
Define minimum buffer size (#7440)
* add check for zero sized buffers * Define minimum flatbuffer size
This commit is contained in:
@@ -331,6 +331,13 @@ typedef uintmax_t largest_scalar_t;
|
||||
// In 32bits, this evaluates to 2GB - 1
|
||||
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1)
|
||||
|
||||
// The minimum size buffer that can be a valid flatbuffer.
|
||||
// Includes the offset to the root table (uoffset_t), the offset to the vtable
|
||||
// of the root table (soffset_t), the size of the vtable (uint16_t), and the
|
||||
// size of the referring table (uint16_t).
|
||||
#define FLATBUFFERS_MIN_BUFFER_SIZE sizeof(uoffset_t) + sizeof(soffset_t) + \
|
||||
sizeof(uint16_t) + sizeof(uint16_t)
|
||||
|
||||
// We support aligning the contents of buffers up to this size.
|
||||
#ifndef FLATBUFFERS_MAX_ALIGNMENT
|
||||
#define FLATBUFFERS_MAX_ALIGNMENT 32
|
||||
|
||||
@@ -178,6 +178,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
|
||||
template<typename T>
|
||||
bool VerifyBufferFromStart(const char *const identifier, const size_t start) {
|
||||
// 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 an identifier is provided, check that we have a buffer
|
||||
if (identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) &&
|
||||
BufferHasIdentifier(buf_ + start, identifier)))) {
|
||||
return false;
|
||||
@@ -198,7 +204,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
template<typename T>
|
||||
bool VerifyNestedFlatBuffer(const Vector<uint8_t> *const buf,
|
||||
const char *const identifier) {
|
||||
// An empty buffer is OK as it indicates not present.
|
||||
if (!buf) return true;
|
||||
|
||||
// If there is a nested buffer, it must be greater than the min size.
|
||||
if(!Check(buf->size() >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false;
|
||||
|
||||
Verifier nested_verifier(buf->data(), buf->size());
|
||||
return nested_verifier.VerifyBuffer<T>(identifier);
|
||||
}
|
||||
|
||||
@@ -4340,6 +4340,28 @@ void NestedVerifierTest() {
|
||||
builder.GetSize());
|
||||
TEST_EQ(false, VerifyMonsterBuffer(verifier));
|
||||
}
|
||||
|
||||
{
|
||||
// Create the outer monster.
|
||||
flatbuffers::FlatBufferBuilder builder;
|
||||
|
||||
// Purposely invalidate the nested flatbuffer setting its length to 0, an
|
||||
// invalid length.
|
||||
uint8_t *invalid_nested_buffer = nullptr;
|
||||
auto nested_monster_bytes = builder.CreateVector(invalid_nested_buffer, 0);
|
||||
|
||||
auto name = builder.CreateString("OuterMonster");
|
||||
|
||||
MonsterBuilder mon_builder(builder);
|
||||
mon_builder.add_name(name);
|
||||
mon_builder.add_testnestedflatbuffer(nested_monster_bytes);
|
||||
FinishMonsterBuffer(builder, mon_builder.Finish());
|
||||
|
||||
// Verify the root monster fails, since the included nested monster fails.
|
||||
flatbuffers::Verifier verifier(builder.GetBufferPointer(),
|
||||
builder.GetSize());
|
||||
TEST_EQ(false, VerifyMonsterBuffer(verifier));
|
||||
}
|
||||
}
|
||||
|
||||
void ParseIncorrectMonsterJsonTest() {
|
||||
|
||||
Reference in New Issue
Block a user