Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/idl_gen_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,15 @@ struct JsonPrinter {
const uint8_t* prev_val, soffset_t vector_index) {
switch (type.base_type) {
case BASE_TYPE_UNION: {
// If this assert hits, you have an corrupt buffer, a union type field
// was not present or was out of range.
FLATBUFFERS_ASSERT(prev_val);
// Guard against corrupt buffer where union type field is missing or out of range.
if (!prev_val) return "corrupt buffer: missing union type field";
auto union_type_byte = *prev_val; // Always a uint8_t.
if (vector_index >= 0) {
auto type_vec = reinterpret_cast<const Vector<uint8_t>*>(
prev_val + ReadScalar<uoffset_t>(prev_val));
if (static_cast<uoffset_t>(vector_index) >= type_vec->size()) {
return "corrupt buffer: union type vector out of range";
}
union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index));
}
auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true);
Expand Down
17 changes: 17 additions & 0 deletions tests/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,23 @@ void UnionVectorTest(const std::string& tests_data_path) {
"root_type Root;"),
true);
TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true);
{
// Test corrupt buffer where union type field is missing in vtable (fixes #9033).
std::vector<uint8_t> corrupt_buf(
parser2.builder_.GetBufferPointer(),
parser2.builder_.GetBufferPointer() + parser2.builder_.GetSize());
auto root_pos =
flatbuffers::ReadScalar<flatbuffers::uoffset_t>(corrupt_buf.data());
auto vtable_soffset = flatbuffers::ReadScalar<flatbuffers::soffset_t>(
corrupt_buf.data() + root_pos);
auto vtable_pos = root_pos - vtable_soffset;
flatbuffers::WriteScalar<flatbuffers::voffset_t>(
corrupt_buf.data() + vtable_pos + 4, 0);
std::string corrupt_json;
auto corrupt_result = GenText(parser2, corrupt_buf.data(), &corrupt_json);
TEST_NOTNULL(corrupt_result);
TEST_EQ_STR(corrupt_result, "corrupt buffer: missing union type field");
}
}
#endif

Expand Down