mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-05 04:58:57 +00:00
[C++] Rare bad buffer content alignment if sizeof(T) != alignof(T) (#7520)
* [C++] Add a failing unit test for #7516 (Rare bad buffer content alignment if sizeof(T) != alignof(T)) * [C++] Fix final buffer alignment when using an array of structs * A struct can have an arbitrary size and therefore sizeof(struct) == alignof(struct) does not hold anymore as for value primitives. * This patch fixes this by introducing alignment parameters to various CreateVector*/StartVector calls. * Closes #7516
This commit is contained in:
@@ -1614,6 +1614,7 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
|
||||
});
|
||||
ECHECK(err);
|
||||
|
||||
const size_t alignment = InlineAlignment(type);
|
||||
const size_t len = count * InlineSize(type) / InlineAlignment(type);
|
||||
const size_t elemsize = InlineAlignment(type);
|
||||
const auto force_align = field->attributes.Lookup("force_align");
|
||||
@@ -1623,7 +1624,8 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
|
||||
if (align > 1) { builder_.ForceVectorAlignment(len, elemsize, align); }
|
||||
}
|
||||
|
||||
builder_.StartVector(len, elemsize);
|
||||
// TODO Fix using element alignment as size (`elemsize`)!
|
||||
builder_.StartVector(len, elemsize, alignment);
|
||||
for (uoffset_t i = 0; i < count; i++) {
|
||||
// start at the back, since we're building the data backwards.
|
||||
auto &val = field_stack_.back().first;
|
||||
|
||||
@@ -689,9 +689,10 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
||||
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||
default: { // Scalars and structs.
|
||||
auto element_size = GetTypeSize(element_base_type);
|
||||
auto element_alignment = element_size; // For primitive elements
|
||||
if (elemobjectdef && elemobjectdef->is_struct())
|
||||
element_size = elemobjectdef->bytesize();
|
||||
fbb.StartVector(vec->size(), element_size);
|
||||
fbb.StartVector(vec->size(), element_size, element_alignment);
|
||||
fbb.PushBytes(vec->Data(), element_size * vec->size());
|
||||
offset = fbb.EndVector(vec->size());
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user