Skip to content

Commit 26f232a

Browse files
authored
Improve JsonNodeDeserializer handling of NaN wrt USE_BIG_DECIMAL_FOR_FLOATS (#4245)
1 parent 992c0fa commit 26f232a

File tree

2 files changed

+17
-16
lines changed

2 files changed

+17
-16
lines changed

src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -757,15 +757,14 @@ protected final JsonNode _fromFloat(JsonParser p, DeserializationContext ctxt,
757757
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
758758
// [databind#4194] Add an option to fail coercing NaN to BigDecimal
759759
// Currently, Jackson 2.x allows such coercion, but Jackson 3.x will not
760-
if (p.isNaN() && ctxt.isEnabled(JsonNodeFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION)) {
761-
ctxt.handleWeirdNumberValue(handledType(), p.getDoubleValue(),
762-
"Cannot convert NaN into BigDecimal");
763-
}
764-
try {
765-
return _fromBigDecimal(ctxt, nodeFactory, p.getDecimalValue());
766-
} catch (NumberFormatException nfe) {
767-
// fall through - BigDecimal does not support values like NaN
760+
if (p.isNaN()) {
761+
if (ctxt.isEnabled(JsonNodeFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION)) {
762+
return (JsonNode) ctxt.handleWeirdNumberValue(handledType(), p.getDoubleValue(),
763+
"Cannot convert NaN into BigDecimal");
764+
}
765+
return nodeFactory.numberNode(p.getDoubleValue());
768766
}
767+
return _fromBigDecimal(ctxt, nodeFactory, p.getDecimalValue());
769768
}
770769
if (nt == JsonParser.NumberType.FLOAT) {
771770
return nodeFactory.numberNode(p.getFloatValue());

src/test/java/com/fasterxml/jackson/databind/node/NumberNodes1770Test.java

+10-8
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,22 @@ public void testBigDecimalCoercionInf() throws Exception
4343
// [databind#4194]: should be able to, by configuration, fail coercing NaN to BigDecimal
4444
public void testBigDecimalCoercionNaN() throws Exception
4545
{
46-
_tryBigDecimalCoercionNaNWithOption(false);
46+
JsonNode n = _tryBigDecimalCoercionNaNWithOption(false);
47+
if (!n.isDouble()) {
48+
fail("Expected DoubleNode, got: "+n.getClass().getName());
49+
}
50+
assertEquals(Double.NaN, n.doubleValue());
4751

4852
try {
49-
_tryBigDecimalCoercionNaNWithOption(true);
50-
fail("Should not pass");
53+
n = _tryBigDecimalCoercionNaNWithOption(true);
54+
fail("Should not pass without allowing coercion: produced JsonNode of type "
55+
+n.getClass().getName());
5156
} catch (InvalidFormatException e) {
5257
verifyException(e, "Cannot convert NaN");
5358
}
5459
}
5560

56-
private void _tryBigDecimalCoercionNaNWithOption(boolean isEnabled) throws Exception
61+
private JsonNode _tryBigDecimalCoercionNaNWithOption(boolean isEnabled) throws Exception
5762
{
5863
JsonFactory factory = JsonFactory.builder()
5964
.enable(JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS)
@@ -64,11 +69,8 @@ private void _tryBigDecimalCoercionNaNWithOption(boolean isEnabled) throws Excep
6469

6570
final String value = "NaN";
6671
// depending on option
67-
final JsonNode jsonNode = isEnabled
72+
return isEnabled
6873
? reader.with(JsonNodeFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION).readTree(value)
6974
: reader.without(JsonNodeFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION).readTree(value);
70-
71-
assertTrue("Expected DoubleNode, got: "+jsonNode.getClass().getName()+": "+jsonNode, jsonNode.isDouble());
72-
assertEquals(Double.NaN, jsonNode.doubleValue());
7375
}
7476
}

0 commit comments

Comments
 (0)