Very odd behaviour when generating flatbuffers from Dart for consumption from C++ (anywhere, really). Certain combinations of field sizes produce binary data which C++ can verify, but other combinations (e.g. just add or remove a few characters from a string, or omit/add an extra field), and then the buffer does not verify anymore. Binary-wise -- valid or not -- the binaries generated from dart never seem to match the output from flatc, just upon a visual inspection with xxd.
So for example, a user name field set to "Foo Bar1" will not verify, but a user name of "Foo Bar" will. ("Foo Bar123" might be good again, who knows?!)
I made a reproducible test case (on my dev machine, but I originally ran into it on an embedded platform on the C++ side and cloud platform on the Dart side, but that is difficult to repro).
tree .
.
├── pubspec.yaml
├── repro.cpp
├── repro.dart
└── repro.fbs
cat pubspec.yaml:
name: repro
environment:
sdk: '>=2.0.0-dev.55.0 <2.0.0'
dependencies:
flat_buffers: ^1.9.0
cat repro.cpp:
#include <flatbuffers/flatbuffers.h>
#include <fstream>
#include "repro_generated.h"
auto main()
-> int
{
std::ifstream stream("repro.fb", std::ios::in | std::ios::binary);
std::vector<uint8_t> repro_fb(
(std::istreambuf_iterator<char>(stream)),
std::istreambuf_iterator<char>()
);
flatbuffers::Verifier verifier(repro_fb.data(), repro_fb.size());
if (verifier.VerifyBuffer<Repro::User>("repr"))
{
printf("valid user = true\n");
}
return 0;
}
cat repro.dart:
import "dart:io";
import "repro_repro_generated.dart" as Repro;
const String REPRO_FILE_IDENTIFIER = "repr";
void main() {
final userBuilder = new Repro.UserObjectBuilder(
name: "Foo Bar1",
id: "123",
);
final userBytes = userBuilder.toBytes(REPRO_FILE_IDENTIFIER);
if (userBytes == null) {
throw ("Invalid (empty) User flatbuffer");
}
final filename = "repro.fb";
new File(filename).writeAsBytes(userBytes).then((File file) {
final user = new Repro.User(userBytes);
print("got User: ${user}");
});
}
cat repro.fbs:
namespace Repro;
table User
{
name:string;
id:string;
}
root_type User;
file_identifier "repr";
file_extension "fb";
To run it, do this:
pub get
flatc --cpp --dart -o . repro.fbs
c++ -std=c++14 repro.cpp -o repro
dart repro.dart && ./repro
The behaviour is erratic but if you add some characters on the end of the name field in the repro.dart file, the test will pass or fail based on the length (maybe it has to do with alignment but I didn't expect that for a string?)
Very odd behaviour when generating flatbuffers from Dart for consumption from C++ (anywhere, really). Certain combinations of field sizes produce binary data which C++ can verify, but other combinations (e.g. just add or remove a few characters from a string, or omit/add an extra field), and then the buffer does not verify anymore. Binary-wise -- valid or not -- the binaries generated from dart never seem to match the output from
flatc, just upon a visual inspection withxxd.So for example, a user name field set to "Foo Bar1" will not verify, but a user name of "Foo Bar" will. ("Foo Bar123" might be good again, who knows?!)
I made a reproducible test case (on my dev machine, but I originally ran into it on an embedded platform on the C++ side and cloud platform on the Dart side, but that is difficult to repro).
cat pubspec.yaml:cat repro.cpp:cat repro.dart:cat repro.fbs:To run it, do this:
The behaviour is erratic but if you add some characters on the end of the
namefield in therepro.dartfile, the test will pass or fail based on the length (maybe it has to do with alignment but I didn't expect that for astring?)