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; + } +}