flatbuffers
flatbuffers copied to clipboard
[dart] Struct serialization broken
While adding tests to #6682, I've found out struct (fixed size) writing doesn't produce the right buffer. Can be reproduced by adding a check to an existing test case - read the value of a just created buffer:
Index: dart/test/flat_buffers_test.dart
<+>UTF-8
===================================================================
diff --git a/dart/test/flat_buffers_test.dart b/dart/test/flat_buffers_test.dart
--- a/dart/test/flat_buffers_test.dart (revision e73fab27d432e58fb68b68c0562ca49111bf9950)
+++ b/dart/test/flat_buffers_test.dart (date 1626077399457)
@@ -199,6 +199,10 @@
..addTestarrayofstringOffset(testArrayOfString);
final mon = monBuilder.finish();
fbBuilder.finish(mon);
+
+ final mon3 = example.Monster(fbBuilder.buffer);
+ expect(mon3.name, 'MyMonster');
+ expect(mon3.pos!.test1, 3.0);
}
void test_error_addInt32_withoutStartTable([Builder? builder]) {
which fails with:
Expected: <3.0>
Actual: <5.325712093e-315>
I tried to figure out the exact cause of the issue by comparing what other languages do (e.g. Go), but am not sure - looks like an issue with alignment/padding, e.g. generated Go code starts with builder.Prep(8, 32) for Vec3 while Dart doesn't. Just adding the code (requires exposing Builder.prepare() in dart) doesn't fix the issue because there are other differences, e.g. prepare() in Dart doesn't pad while Go does... My attempts to fix the issue were unsuccessful so far.
cc: @dnfield @aardappel
The Prep call shouldn't cause data issues by itself though, as that just pre-aligns the data, so if its missing will cause the data to be missaligned, but most languages and CPUs read misaligned data just fine.
Can you check that you can read mon3.name correctly, i.e. the problem is just in the struct?
How do the existing tests pass?
Isn't data an offset? How does that work being passed to Monster ?
Can you check that you can read mon3.name correctly, i.e. the problem is just in the struct?
yes, mon3.name is read correctly
How do the existing tests pass?
Easily, they don't try to read the created buffer :)
Isn't data an offset? How does that work being passed to Monster ?
it's a Uint8List, or rather it was, now after a recent PR it's accessible in fbBuilder.buffer. I've updated the issue description with the updated patch file
This issue is stale because it has been open 6 months with no activity. Please comment or this will be closed in 14 days.
This is still an issue...
This issue is stale because it has been open 6 months with no activity. Please comment or label not-stale, or this will be closed in 14 days.
I don't currently have the capacity to address this but I think it's still an issue.
@vaind I think this is the origin of the issue: https://github.com/google/flatbuffers/issues/8070
This issue is stale because it has been open 6 months with no activity. Please comment or label not-stale, or this will be closed in 14 days.
not-stale