From c51a13f4c48a3e47c5c61058133e00222f5c0e7d Mon Sep 17 00:00:00 2001 From: Michael Zeng Date: Thu, 11 Aug 2016 18:23:06 -0700 Subject: [PATCH] Fixed long deserialization problem for longs of ~13digit length --- .../dataformat/protobuf/ProtobufParser.java | 3 +- .../dataformat/protobuf/BigNumPair.java | 12 ++++++++ .../dataformat/protobuf/SerDeserLongTest.java | 30 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/BigNumPair.java create mode 100644 protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/SerDeserLongTest.java diff --git a/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java b/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java index e1c086a0c..ec7a329a6 100644 --- a/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java +++ b/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java @@ -2326,7 +2326,8 @@ private long _decodeVLong() throws IOException v |= ((ch & 0x7F) << 14); ch = buf[_inputPtr++]; if (ch >= 0) { - return v | (ch << 21); + long l2 = (v | (ch << 21)); + return (l2 << 28) | l; } v |= ((ch & 0x7F) << 21); diff --git a/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/BigNumPair.java b/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/BigNumPair.java new file mode 100644 index 000000000..d73029bb2 --- /dev/null +++ b/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/BigNumPair.java @@ -0,0 +1,12 @@ +package com.fasterxml.jackson.dataformat.protobuf; + +public class BigNumPair { + public static final String protobuf_str = + "message BigNumPair {\n" + + " required int64 long1 = 1;\n" + + " required int64 long2 = 2;\n" + + "}\n"; + + public long long1; + public long long2; +} diff --git a/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/SerDeserLongTest.java b/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/SerDeserLongTest.java new file mode 100644 index 000000000..ca37d56e6 --- /dev/null +++ b/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/SerDeserLongTest.java @@ -0,0 +1,30 @@ +package com.fasterxml.jackson.dataformat.protobuf; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchema; +import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchemaLoader; +import org.junit.Test; + +import java.io.IOException; + +/** + * Created by miz on 8/10/16. + */ +public class SerDeserLongTest { + @Test + public void testWeirdLongSerDeser() throws IOException { + ObjectMapper mapper = new ObjectMapper(new ProtobufFactory()); + ProtobufSchema schema = ProtobufSchemaLoader.std.parse(BigNumPair.protobuf_str); + + BigNumPair bnp = new BigNumPair(); + bnp.long1 = 72057594037927935L; + bnp.long2 = 0; + + byte[] encoded = mapper.writer(schema).writeValueAsBytes(bnp); + + BigNumPair parsed = mapper.readerFor(BigNumPair.class).with(schema).readValue(encoded); + + assert parsed.long1 == bnp.long1; + assert parsed.long2 == bnp.long2; + } +}