diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java index be1ba31d69..7a7e6095c2 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java @@ -755,12 +755,11 @@ protected final JsonNode _fromFloat(JsonParser p, DeserializationContext ctxt, return _fromBigDecimal(ctxt, nodeFactory, p.getDecimalValue()); } if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) { - // 20-May-2016, tatu: As per [databind#1028], need to be careful - // (note: JDK 1.8 would have `Double.isFinite()`) - if (p.isNaN()) { - return nodeFactory.numberNode(p.getDoubleValue()); + try { + return _fromBigDecimal(ctxt, nodeFactory, p.getDecimalValue()); + } catch (NumberFormatException nfe) { + // fall through - BigDecimal does not support values like NaN } - return _fromBigDecimal(ctxt, nodeFactory, p.getDecimalValue()); } if (nt == JsonParser.NumberType.FLOAT) { return nodeFactory.numberNode(p.getFloatValue()); diff --git a/src/test/java/com/fasterxml/jackson/databind/NumberNodes1770Test.java b/src/test/java/com/fasterxml/jackson/databind/NumberNodes1770Test.java new file mode 100644 index 0000000000..96ccf27999 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/NumberNodes1770Test.java @@ -0,0 +1,43 @@ +package com.fasterxml.jackson.databind; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.json.JsonReadFeature; +import com.fasterxml.jackson.databind.json.JsonMapper; + +import java.math.BigDecimal; + +/** + * Basic tests for {@link JsonNode} implementations that + * contain numeric values. + */ +public class NumberNodes1770Test extends BaseMapTest +{ + private final ObjectMapper MAPPER = newJsonMapper(); + + // For to [databind#1770] (broken due to fix for #1028): `JsonNodeDeserializer` + // would coerce ok but does `parser.isNaN()` check which ends up parsing + // as Double, gets `POSITIVE_INFINITY` and returns `true`: this results in + // `DoubleNode` being used even tho `BigDecimal` could fit the number. + public void testBigDecimalCoercion() throws Exception + { + final String value = "7976931348623157e309"; + final JsonNode jsonNode = MAPPER.reader() + .with(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) + .readTree(value); + assertTrue("Expected DecimalNode, got: "+jsonNode.getClass().getName()+": "+jsonNode, jsonNode.isBigDecimal()); + assertEquals(new BigDecimal(value), jsonNode.decimalValue()); + } + + public void testBigDecimalCoercionInf() throws Exception + { + final String value = "+INF"; + JsonFactory factory = JsonFactory.builder() + .enable(JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS) + .build(); + final JsonNode jsonNode = new JsonMapper(factory).reader() + .with(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) + .readTree(value); + assertTrue("Expected DoubleNode, got: "+jsonNode.getClass().getName()+": "+jsonNode, jsonNode.isDouble()); + assertEquals(Double.POSITIVE_INFINITY, jsonNode.doubleValue()); + } +} diff --git a/src/test/java/com/fasterxml/jackson/failing/NumberNodes1770Test.java b/src/test/java/com/fasterxml/jackson/failing/NumberNodes1770Test.java deleted file mode 100644 index a2e18f0ff4..0000000000 --- a/src/test/java/com/fasterxml/jackson/failing/NumberNodes1770Test.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.fasterxml.jackson.failing; - -import com.fasterxml.jackson.databind.*; - -/** - * Basic tests for {@link JsonNode} implementations that - * contain numeric values. - */ -public class NumberNodes1770Test extends BaseMapTest -{ - private final ObjectMapper MAPPER = newJsonMapper(); - - // For to [databind#1770] (broken due to fix for #1028): `JsonNodeDeserializer` - // would coerce ok but does `parser.isNaN()` check which ends up parsing - // as Double, gets `POSITIVE_INFINITY` and returns `true`: this results in - // `DoubleNode` being used even tho `BigDecimal` could fit the number. - public void testBigDecimalCoercion() throws Exception - { - final JsonNode jsonNode = MAPPER.reader() - .with(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) - .readTree("7976931348623157e309"); - assertTrue("Expected DecimalNode, got: "+jsonNode.getClass().getName()+": "+jsonNode, jsonNode.isBigDecimal()); - // the following fails with NumberFormatException, because jsonNode is a DoubleNode with a value of POSITIVE_INFINITY -// Assert.assertTrue(jsonNode.decimalValue().compareTo(new BigDecimal("7976931348623157e309")) == 0); - } -}