flatbuffers icon indicating copy to clipboard operation
flatbuffers copied to clipboard

[dart] Struct serialization broken

Open vaind opened this issue 4 years ago • 9 comments

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

vaind avatar Jun 09 '21 14:06 vaind

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 ?

aardappel avatar Jun 10 '21 19:06 aardappel

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

vaind avatar Jul 12 '21 08:07 vaind

This issue is stale because it has been open 6 months with no activity. Please comment or this will be closed in 14 days.

github-actions[bot] avatar Jan 10 '22 20:01 github-actions[bot]

This is still an issue...

vaind avatar Jan 25 '22 20:01 vaind

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.

github-actions[bot] avatar Mar 04 '23 01:03 github-actions[bot]

I don't currently have the capacity to address this but I think it's still an issue.

vaind avatar Mar 04 '23 07:03 vaind

@vaind I think this is the origin of the issue: https://github.com/google/flatbuffers/issues/8070

Llamadmiral avatar Aug 17 '23 13:08 Llamadmiral

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.

github-actions[bot] avatar Feb 15 '24 20:02 github-actions[bot]

not-stale

Llamadmiral avatar Feb 15 '24 21:02 Llamadmiral