From 0798b7b69886a96a810ccb52e1aed79875eebf3a Mon Sep 17 00:00:00 2001 From: Paulo Pinheiro Date: Wed, 25 Sep 2019 20:59:10 +0200 Subject: [PATCH] [FlexBuffers][Java] Fix wrong access to a string using Reference::asString(). (#5532) 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 | 2 +- .../flatbuffers/FlexBuffersBuilder.java | 2 +- tests/JavaTest.java | 42 ++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/java/com/google/flatbuffers/FlexBuffers.java b/java/com/google/flatbuffers/FlexBuffers.java index 6e7b0868d..3a5c6558b 100644 --- a/java/com/google/flatbuffers/FlexBuffers.java +++ b/java/com/google/flatbuffers/FlexBuffers.java @@ -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); } diff --git a/java/com/google/flatbuffers/FlexBuffersBuilder.java b/java/com/google/flatbuffers/FlexBuffersBuilder.java index a58c7a30c..64db751f3 100644 --- a/java/com/google/flatbuffers/FlexBuffersBuilder.java +++ b/java/com/google/flatbuffers/FlexBuffersBuilder.java @@ -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. */ diff --git a/tests/JavaTest.java b/tests/JavaTest.java index 8e404ffa4..2a1e21574 100644 --- a/tests/JavaTest.java +++ b/tests/JavaTest.java @@ -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 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 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 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 void TestEq(T a, T b) {