mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-02 10:18:20 +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
|
// In 32bits, this evaluates to 2GB - 1
|
||||||
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 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.
|
// We support aligning the contents of buffers up to this size.
|
||||||
#ifndef FLATBUFFERS_MAX_ALIGNMENT
|
#ifndef FLATBUFFERS_MAX_ALIGNMENT
|
||||||
#define FLATBUFFERS_MAX_ALIGNMENT 32
|
#define FLATBUFFERS_MAX_ALIGNMENT 32
|
||||||
|
|||||||
@@ -178,6 +178,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool VerifyBufferFromStart(const char *const identifier, const size_t start) {
|
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) &&
|
if (identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) &&
|
||||||
BufferHasIdentifier(buf_ + start, identifier)))) {
|
BufferHasIdentifier(buf_ + start, identifier)))) {
|
||||||
return false;
|
return false;
|
||||||
@@ -198,7 +204,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
bool VerifyNestedFlatBuffer(const Vector<uint8_t> *const buf,
|
bool VerifyNestedFlatBuffer(const Vector<uint8_t> *const buf,
|
||||||
const char *const identifier) {
|
const char *const identifier) {
|
||||||
|
// An empty buffer is OK as it indicates not present.
|
||||||
if (!buf) return true;
|
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());
|
Verifier nested_verifier(buf->data(), buf->size());
|
||||||
return nested_verifier.VerifyBuffer<T>(identifier);
|
return nested_verifier.VerifyBuffer<T>(identifier);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4340,6 +4340,28 @@ void NestedVerifierTest() {
|
|||||||
builder.GetSize());
|
builder.GetSize());
|
||||||
TEST_EQ(false, VerifyMonsterBuffer(verifier));
|
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() {
|
void ParseIncorrectMonsterJsonTest() {
|
||||||
|
|||||||
Reference in New Issue
Block a user