Added verifier alignment checking to table fields (#7018)

This commit is contained in:
Wouter van Oortmerssen
2022-01-14 14:39:15 -08:00
committed by GitHub
parent 96cc2f3ee3
commit a42e898979
18 changed files with 273 additions and 248 deletions

View File

@@ -1471,9 +1471,11 @@ class CppGenerator : public BaseGenerator {
" auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);";
if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
if (ev.union_type.struct_def->fixed) {
code_.SetValue("ALIGN",
NumToString(ev.union_type.struct_def->minalign));
code_ +=
" return verifier.Verify<{{TYPE}}>(static_cast<const "
"uint8_t *>(obj), 0);";
" return verifier.VerifyField<{{TYPE}}>("
"static_cast<const uint8_t *>(obj), 0, {{ALIGN}});";
} else {
code_ += getptr;
code_ += " return verifier.VerifyTable(ptr);";
@@ -1951,8 +1953,9 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("SIZE", GenTypeSize(field.value.type));
code_.SetValue("OFFSET", GenFieldOffsetName(field));
if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type)) {
code_ +=
"{{PRE}}VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, {{OFFSET}})\\";
code_.SetValue("ALIGN", NumToString(InlineAlignment(field.value.type)));
code_ += "{{PRE}}VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, "
"{{OFFSET}}, {{ALIGN}})\\";
} else {
code_ += "{{PRE}}VerifyOffset{{REQUIRED}}(verifier, {{OFFSET}})\\";
}

View File

@@ -505,8 +505,9 @@ bool VerifyStruct(flatbuffers::Verifier &v,
auto offset = parent_table.GetOptionalFieldOffset(field_offset);
if (required && !offset) { return false; }
return !offset || v.Verify(reinterpret_cast<const uint8_t *>(&parent_table),
offset, obj.bytesize());
return !offset ||
v.VerifyFieldStruct(reinterpret_cast<const uint8_t *>(&parent_table),
offset, obj.bytesize(), obj.minalign());
}
bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
@@ -553,7 +554,8 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
const flatbuffers::Table &table,
const reflection::Field &vec_field) {
FLATBUFFERS_ASSERT(vec_field.type()->base_type() == reflection::Vector);
if (!table.VerifyField<uoffset_t>(v, vec_field.offset())) return false;
if (!table.VerifyField<uoffset_t>(v, vec_field.offset(), sizeof(uoffset_t)))
return false;
switch (vec_field.type()->element()) {
case reflection::UType:
@@ -636,33 +638,48 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
switch (field_def->type()->base_type()) {
case reflection::None: FLATBUFFERS_ASSERT(false); break;
case reflection::UType:
if (!table->VerifyField<uint8_t>(v, field_def->offset())) return false;
if (!table->VerifyField<uint8_t>(v, field_def->offset(),
sizeof(uint8_t)))
return false;
break;
case reflection::Bool:
case reflection::Byte:
case reflection::UByte:
if (!table->VerifyField<int8_t>(v, field_def->offset())) return false;
if (!table->VerifyField<int8_t>(v, field_def->offset(),
sizeof(int8_t)))
return false;
break;
case reflection::Short:
case reflection::UShort:
if (!table->VerifyField<int16_t>(v, field_def->offset())) return false;
if (!table->VerifyField<int16_t>(v, field_def->offset(),
sizeof(int16_t)))
return false;
break;
case reflection::Int:
case reflection::UInt:
if (!table->VerifyField<int32_t>(v, field_def->offset())) return false;
if (!table->VerifyField<int32_t>(v, field_def->offset(),
sizeof(int32_t)))
return false;
break;
case reflection::Long:
case reflection::ULong:
if (!table->VerifyField<int64_t>(v, field_def->offset())) return false;
if (!table->VerifyField<int64_t>(v, field_def->offset(),
sizeof(int64_t)))
return false;
break;
case reflection::Float:
if (!table->VerifyField<float>(v, field_def->offset())) return false;
if (!table->VerifyField<float>(v, field_def->offset(),
sizeof(float)))
return false;
break;
case reflection::Double:
if (!table->VerifyField<double>(v, field_def->offset())) return false;
if (!table->VerifyField<double>(v, field_def->offset(),
sizeof(double)))
return false;
break;
case reflection::String:
if (!table->VerifyField<uoffset_t>(v, field_def->offset()) ||
if (!table->VerifyField<uoffset_t>(v, field_def->offset(),
sizeof(uoffset_t)) ||
!v.VerifyString(flatbuffers::GetFieldS(*table, *field_def))) {
return false;
}