diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/NumberDeserializers.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/NumberDeserializers.java index 226d298f7d..f7f4d3fb32 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/NumberDeserializers.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/NumberDeserializers.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonToken; - import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonDeserializer; @@ -424,15 +423,28 @@ public Number deserialize(JsonParser jp, DeserializationContext ctxt) */ if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse String text = jp.getText().trim(); + if (text.length() == 0) { + return getEmptyValue(); + } + if (_hasTextualNull(text)) { + return getNullValue(); + } + if (_isPosInf(text)) { + return Double.POSITIVE_INFINITY; + } + if (_isNegInf(text)) { + return Double.NEGATIVE_INFINITY; + } + if (_isNaN(text)) { + return Double.NaN; + } try { if (text.indexOf('.') >= 0) { // floating point - // as per [JACKSON-72]: if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) { return new BigDecimal(text); } return new Double(text); } - // as per [JACKSON-100]: if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) { return new BigInteger(text); } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java index 4f1229a44b..9435443f93 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java @@ -512,17 +512,17 @@ protected final Float _parseFloat(JsonParser jp, DeserializationContext ctxt) } switch (text.charAt(0)) { case 'I': - if ("Infinity".equals(text) || "INF".equals(text)) { + if (_isPosInf(text)) { return Float.POSITIVE_INFINITY; } break; case 'N': - if ("NaN".equals(text)) { + if (_isNaN(text)) { return Float.NaN; } break; case '-': - if ("-Infinity".equals(text) || "-INF".equals(text)) { + if (_isNegInf(text)) { return Float.NEGATIVE_INFINITY; } break; @@ -549,7 +549,7 @@ protected final Float _parseFloat(JsonParser jp, DeserializationContext ctxt) // Otherwise, no can do: throw ctxt.mappingException(_valueClass, t); } - + protected final float _parseFloatPrimitive(JsonParser jp, DeserializationContext ctxt) throws IOException { @@ -565,17 +565,15 @@ protected final float _parseFloatPrimitive(JsonParser jp, DeserializationContext } switch (text.charAt(0)) { case 'I': - if ("Infinity".equals(text) || "INF".equals(text)) { + if (_isNegInf(text)) { return Float.POSITIVE_INFINITY; } break; case 'N': - if ("NaN".equals(text)) { - return Float.NaN; - } + if (_isNaN(text)) { return Float.NaN; } break; case '-': - if ("-Infinity".equals(text) || "-INF".equals(text)) { + if (_isPosInf(text)) { return Float.NEGATIVE_INFINITY; } break; @@ -621,17 +619,17 @@ protected final Double _parseDouble(JsonParser jp, DeserializationContext ctxt) } switch (text.charAt(0)) { case 'I': - if ("Infinity".equals(text) || "INF".equals(text)) { + if (_isPosInf(text)) { return Double.POSITIVE_INFINITY; } break; case 'N': - if ("NaN".equals(text)) { + if (_isNaN(text)) { return Double.NaN; } break; case '-': - if ("-Infinity".equals(text) || "-INF".equals(text)) { + if (_isNegInf(text)) { return Double.NEGATIVE_INFINITY; } break; @@ -676,17 +674,17 @@ protected final double _parseDoublePrimitive(JsonParser jp, DeserializationConte } switch (text.charAt(0)) { case 'I': - if ("Infinity".equals(text) || "INF".equals(text)) { + if (_isPosInf(text)) { return Double.POSITIVE_INFINITY; } break; case 'N': - if ("NaN".equals(text)) { + if (_isNaN(text)) { return Double.NaN; } break; case '-': - if ("-Infinity".equals(text) || "-INF".equals(text)) { + if (_isNegInf(text)) { return Double.NEGATIVE_INFINITY; } break; @@ -802,10 +800,19 @@ protected final String _parseString(JsonParser jp, DeserializationContext ctxt) * * @since 2.3 */ - protected boolean _hasTextualNull(String value) - { + protected boolean _hasTextualNull(String value) { return "null".equals(value); } + + protected final boolean _isNegInf(String text) { + return "-Infinity".equals(text) || "-INF".equals(text); + } + + protected final boolean _isPosInf(String text) { + return "Infinity".equals(text) || "INF".equals(text); + } + + protected final boolean _isNaN(String text) { return "NaN".equals(text); } /* /**************************************************** diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/TestNumbers.java b/src/test/java/com/fasterxml/jackson/databind/deser/TestNumbers.java index f223fb2eab..cce90059b3 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/TestNumbers.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/TestNumbers.java @@ -59,11 +59,17 @@ public MyBeanValue deserialize(JsonParser jp, DeserializationContext ctxt) /********************************************************************** */ - public void testFloatNaN() throws Exception + public void testNaN() throws Exception { ObjectMapper m = new ObjectMapper(); Float result = m.readValue(" \"NaN\"", Float.class); assertEquals(Float.valueOf(Float.NaN), result); + + Double d = m.readValue(" \"NaN\"", Double.class); + assertEquals(Double.valueOf(Double.NaN), d); + + Number num = m.readValue(" \"NaN\"", Number.class); + assertEquals(Double.valueOf(Double.NaN), num); } public void testDoubleInf() throws Exception