google / flatbuffers

FlatBuffers: Memory Efficient Serialization Library
https://flatbuffers.dev/
Apache License 2.0
23.28k stars 3.25k forks source link

Nested vector of structs parsed incorrectly (C++, gcc5.4, Ubuntu16.04, 1.8.0) #4596

Closed lubkoll closed 6 years ago

lubkoll commented 6 years ago

flatc generates incorrect code if a table contains a member that is a repeated struct, as here:

// foo.fbs namespace test;

struct Foo { value:uint; }

table Boo { foos:[test.Foo]; }

This example works if foos would be a single Foo (without square brackets) or if Foo would be made a table. For the above example flatc generates, a.o., this function:

inline flatbuffers::Offset CreateBooDirect( flatbuffers::FlatBufferBuilder &_fbb, const std::vector<const Foo > foos = nullptr) { return test::CreateBoo( _fbb, foos ? _fbb.CreateVector<const Foo >(foos) : 0); }

where instead this would be correct:

inline flatbuffers::Offset CreateBooDirect( flatbuffers::FlatBufferBuilder &_fbb, const std::vector foos = nullptr) { return test::CreateBoo( _fbb, foos ? _fbb.CreateVectorOfStructs(foos) : 0); }

As a consequence when reading from Foo::value, we don't retrieve our data but instead get random output. This can be easily replicated using // main.cpp

include

include "foo_generated.h"

using namespace std; using namespace test;

int main() { cout << boolalpha; flatbuffers::FlatBufferBuilder builder;

const Foo foo(2);
const std::vector<const Foo*> foo_vec(1, &foo);
const auto vertex_data = CreateBooDirect(builder, &foo_vec);
builder.Finish(vertex_data);
const auto data = builder.Release();

const auto root = flatbuffers::GetRoot<Boo>(data.data());
flatbuffers::Verifier verifier(data.data(), data.size());
cout << "verification: " << root->Verify(verifier) << endl;

const auto foos = root->foos();
cout << "value: " << foos->begin()->value() << endl;

}

aardappel commented 6 years ago

I think this fixes it: https://github.com/google/flatbuffers/commit/fee9afd80b6358a63b92b6991d858604da524e2b

lubkoll commented 6 years ago

Thx a lot for the fast feedback! Your fix looks good. I will try it out tomorrow and then let you know about the result. Thx again, also in the name of my colleagues!

lubkoll commented 6 years ago

Works, thank you!