[FlexBuffers][Java] Fix wrong access to a string using Reference::asString(). (#5532)
authorPaulo Pinheiro <paulovictor.pinheiro@gmail.com>
Wed, 25 Sep 2019 18:59:10 +0000 (20:59 +0200)
committerWouter van Oortmerssen <aardappel@gmail.com>
Wed, 25 Sep 2019 18:59:10 +0000 (11:59 -0700)
The real position of a string is  calculated by using the indirect() method,
which should be based on parentWidth and not byteWidth, as it was implemented.

We are also fixing the flag BUILDER_FLAG_SHARE_STRINGS on FlexBuffersBuilder
that was set as '1', same value as BUILDER_FLAG_SHARE_KEYS.

java/com/google/flatbuffers/FlexBuffers.java
java/com/google/flatbuffers/FlexBuffersBuilder.java
tests/JavaTest.java

index 6e7b086..3a5c655 100644 (file)
@@ -481,7 +481,7 @@ public class FlexBuffers {
          */
         public String asString() {
             if (isString()) {
-                int start = indirect(bb, end, byteWidth);
+                int start = indirect(bb, end, parentWidth);
                 int size = readInt(bb, start - byteWidth, byteWidth);
                 return Utf8.getDefault().decodeUtf8(bb, start, size);
             }
index a58c7a3..64db751 100644 (file)
@@ -64,7 +64,7 @@ public class FlexBuffersBuilder {
      * But serialization performance might be slower and consumes more memory. This is ideal if you expect many repeated
      * strings on the message.
      */
-    public static final int BUILDER_FLAG_SHARE_STRINGS = 1;
+    public static final int BUILDER_FLAG_SHARE_STRINGS = 2;
     /**
      * Strings and keys will be shared between elements.
      */
index 8e404ff..2a1e215 100644 (file)
@@ -20,6 +20,8 @@ import java.io.*;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.channels.FileChannel;
+import java.util.Map;
+import java.util.HashMap;
 import MyGame.Example.*;
 import NamespaceA.*;
 import NamespaceA.NamespaceB.*;
@@ -884,6 +886,43 @@ class JavaTest {
                 FlexBuffers.getRoot(b.getBuffer()).toString());
     }
 
+    public static void testHashMapToMap() {
+        int entriesCount = 12;
+
+        HashMap<String, String> source =  new HashMap<>();
+        for (int i = 0; i < entriesCount; i++) {
+            source.put("foo_param_" + i, "foo_value_" + i);
+        }
+
+        FlexBuffersBuilder builder = new FlexBuffersBuilder(1000);
+        int mapStart = builder.startMap();
+        for (Map.Entry<String, String> entry : source.entrySet()) {
+            builder.putString(entry.getKey(), entry.getValue());
+        }
+        builder.endMap(null, mapStart);
+        ByteBuffer bb = builder.finish();
+        bb.rewind();
+
+        FlexBuffers.Reference rootReference = FlexBuffers.getRoot(bb);
+
+        TestEq(rootReference.isMap(), true);
+
+        FlexBuffers.Map flexMap = rootReference.asMap();
+
+        FlexBuffers.KeyVector keys = flexMap.keys();
+        FlexBuffers.Vector values = flexMap.values();
+
+        TestEq(entriesCount, keys.size());
+        TestEq(entriesCount, values.size());
+
+        HashMap<String, String> result =  new HashMap<>();
+        for (int i = 0; i < keys.size(); i++) {
+            result.put(keys.get(i).toString(), values.get(i).asString());
+        }
+
+        TestEq(source, result);
+    }
+
     public static void TestFlexBuffers() {
         testSingleElementByte();
         testSingleElementShort();
@@ -899,7 +938,8 @@ class JavaTest {
         testSingleElementUInt();
         testSingleElementUByte();
         testSingleElementMap();
-       testFlexBuffersTest();
+        testFlexBuffersTest();
+        testHashMapToMap();
     }
 
     static <T> void TestEq(T a, T b) {