Skip to content

Jackson: BigDecimal fails to be parsed properly if the number is a long #231

Description

@fdinoff

The following fails because of a MessageIntegerOverflowException

ArrayList<BigDecimal> list = new ArrayList<>();
list.add(new BigDecimal(Long.MAX_VALUE));
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
byte[] bytes = objectMapper.writeValueAsBytes(list);

ArrayList<BigDecimal> result = objectMapper.readValue(
        bytes, new TypeReference<ArrayList<BigDecimal>>() {});
com.fasterxml.jackson.databind.JsonMappingException: 9223372036854775807 (through reference chain: java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:210)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:189)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:249)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:206)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:25)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2247)
    ...
Caused by: org.msgpack.core.MessageIntegerOverflowException: 9223372036854775807
    at org.msgpack.value.holder.IntegerHolder.asInt(IntegerHolder.java:224)
    at org.msgpack.jackson.dataformat.MessagePackParser.getDecimalValue(MessagePackParser.java:278)
    at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$BigDecimalDeserializer.deserialize(NumberDeserializers.java:577)
    at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$BigDecimalDeserializer.deserialize(NumberDeserializers.java:562)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:232)
    ... 31 more

A possible fix would be

diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java
index 321f10e..37ebaca 100644
--- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java
+++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java
@@ -292,7 +292,7 @@ public class MessagePackParser extends ParserMinimalBase {
             NumberValue number = ref.asNumber();
             //optimization to not convert the value to BigInteger unnecessarily
             if (number.isValidByte() || number.isValidShort() || number.isValidInt() || number.isValidLong()) {
-                return BigDecimal.valueOf(number.asInt());
+                return BigDecimal.valueOf(number.asLong());
             }
             else {
                 return new BigDecimal(number.asBigInteger());

Which is just grab the value as a long instead of an int which can't hold the full range of the long.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions