Fixed reflection.h not modifying certain table configurations.

It would write 64bits offsets instead of 32bit ones, and update
the vtable pointer before the fields were processed.

Change-Id: I0c0fa942bbd3b42839294f5653ba8fa048612624
Tested: on Linux.
This commit is contained in:
Wouter van Oortmerssen
2016-07-25 14:43:41 -07:00
parent f98870715a
commit 1bba4fd9ea
2 changed files with 67 additions and 61 deletions

View File

@@ -356,7 +356,8 @@ public:
void MutateOffset(uoffset_t i, const uint8_t *val) { void MutateOffset(uoffset_t i, const uint8_t *val) {
assert(i < size()); assert(i < size());
assert(sizeof(T) == sizeof(uoffset_t)); assert(sizeof(T) == sizeof(uoffset_t));
WriteScalar(data() + i, val - (Data() + i * sizeof(uoffset_t))); WriteScalar(data() + i,
static_cast<uoffset_t>(val - (Data() + i * sizeof(uoffset_t))));
} }
// Get a mutable pointer to tables/strings inside this vector. // Get a mutable pointer to tables/strings inside this vector.
@@ -1495,7 +1496,8 @@ class Table {
bool SetPointer(voffset_t field, const uint8_t *val) { bool SetPointer(voffset_t field, const uint8_t *val) {
auto field_offset = GetOptionalFieldOffset(field); auto field_offset = GetOptionalFieldOffset(field);
if (!field_offset) return false; if (!field_offset) return false;
WriteScalar(data_ + field_offset, val - (data_ + field_offset)); WriteScalar(data_ + field_offset,
static_cast<uoffset_t>(val - (data_ + field_offset)));
return true; return true;
} }

View File

@@ -204,16 +204,15 @@ class ResizeContext {
if (DagCheck(table)) if (DagCheck(table))
return; // Table already visited. return; // Table already visited.
auto vtable = table->GetVTable(); auto vtable = table->GetVTable();
// Check if the vtable offset points beyond the insertion point.
Straddle<soffset_t, -1>(table, vtable, table);
// This direction shouldn't happen because vtables that sit before tables
// are always directly adjacent, but check just in case we ever change the
// way flatbuffers are built.
Straddle<soffset_t, -1>(vtable, table, table);
// Early out: since all fields inside the table must point forwards in // Early out: since all fields inside the table must point forwards in
// memory, if the insertion point is before the table we can stop here. // memory, if the insertion point is before the table we can stop here.
auto tableloc = reinterpret_cast<uint8_t *>(table); auto tableloc = reinterpret_cast<uint8_t *>(table);
if (startptr_ <= tableloc) return; if (startptr_ <= tableloc) {
// Check if insertion point is between the table and a vtable that
// precedes it. This can't happen in current construction code, but check
// just in case we ever change the way flatbuffers are built.
Straddle<soffset_t, -1>(vtable, table, table);
} else {
// Check each field. // Check each field.
auto fielddefs = objectdef.fields(); auto fielddefs = objectdef.fields();
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
@@ -271,6 +270,11 @@ class ResizeContext {
assert(false); assert(false);
} }
} }
// Check if the vtable offset points beyond the insertion point.
// Must do this last, since GetOptionalFieldOffset above still reads
// this value.
Straddle<soffset_t, -1>(table, vtable, table);
}
} }
void operator=(const ResizeContext &rc); void operator=(const ResizeContext &rc);