diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 55f79c4bc3..b984031a42 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -19,6 +19,10 @@ a pure JSON library. #1391: Fix issue where the parser can read back old number state when parsing later numbers (fix contributed by @pjfanning) +#1397: Jackson changes additional values to infinite in case of special + JSON structures and existing infinite values + (reported by @Rodenstock) + (fix contributed by @pjfanning) 2.18.2 (27-Nov-2024) diff --git a/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java b/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java index 9d037d3daf..4ab0fcb9b5 100644 --- a/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java +++ b/src/main/java/com/fasterxml/jackson/core/base/ParserBase.java @@ -592,6 +592,7 @@ protected final JsonToken resetInt(boolean negative, int intLen) _fractLength = 0; _expLength = 0; _numTypesValid = NR_UNKNOWN; // to force decoding + _numberString = null; return JsonToken.VALUE_NUMBER_INT; } @@ -606,6 +607,7 @@ protected final JsonToken resetFloat(boolean negative, int intLen, int fractLen, _fractLength = fractLen; _expLength = expLen; _numTypesValid = NR_UNKNOWN; // to force decoding + _numberString = null; return JsonToken.VALUE_NUMBER_FLOAT; } @@ -616,6 +618,7 @@ protected final JsonToken resetAsNaN(String valueStr, double value) _numberDouble = value; _numTypesValid = NR_DOUBLE; _numberIsNaN = true; + _numberString = null; return JsonToken.VALUE_NUMBER_FLOAT; } diff --git a/src/test/java/com/fasterxml/jackson/core/read/NumberParsing1397Test.java b/src/test/java/com/fasterxml/jackson/core/read/NumberParsing1397Test.java new file mode 100644 index 0000000000..27a445f0f4 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/core/read/NumberParsing1397Test.java @@ -0,0 +1,77 @@ +package com.fasterxml.jackson.core.read; + +import com.fasterxml.jackson.core.JUnit5TestBase; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.TokenStreamFactory; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class NumberParsing1397Test extends JUnit5TestBase +{ + private TokenStreamFactory JSON_F = newStreamFactory(); + + final String radiusValue = "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + final String INPUT_JSON = a2q("{ 'results': [ { " + + "'radius': " + radiusValue + ", " + + "'type': 'center', " + + "'center': { " + + "'x': -11.0, " + + "'y': -2.0 } } ] }"); + + // [jackson-core#1397] + @Test + public void issue1397() throws Exception + { + for (int mode : ALL_MODES) { + testIssue(JSON_F, mode, INPUT_JSON, true); + testIssue(JSON_F, mode, INPUT_JSON, false); + } + } + + private void testIssue(final TokenStreamFactory jsonF, + final int mode, + final String json, + final boolean checkFirstNumValues) throws Exception + { + // checkFirstNumValues=false reproduces the issue in https://github.com/FasterXML/jackson-core/issues/1397 + try (JsonParser p = createParser(jsonF, mode, json)) { + assertToken(JsonToken.START_OBJECT, p.nextToken()); + assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("results", p.currentName()); + assertToken(JsonToken.START_ARRAY, p.nextToken()); + assertToken(JsonToken.START_OBJECT, p.nextToken()); + assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("radius", p.currentName()); + assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); + assertEquals(JsonParser.NumberType.BIG_INTEGER, p.getNumberType()); + assertEquals(radiusValue, p.getNumberValueDeferred()); + assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("type", p.currentName()); + assertToken(JsonToken.VALUE_STRING, p.nextToken()); + assertEquals("center", p.getText()); + assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("center", p.currentName()); + assertToken(JsonToken.START_OBJECT, p.nextToken()); + assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("x", p.currentName()); + assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); + if (checkFirstNumValues) { + assertEquals(JsonParser.NumberType.DOUBLE, p.getNumberType()); + assertEquals(Double.valueOf(-11.0d), p.getNumberValueDeferred()); + } + assertEquals(Double.valueOf(-11.0d), p.getDoubleValue()); + assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("y", p.currentName()); + assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); + assertEquals(JsonParser.NumberType.DOUBLE, p.getNumberType()); + assertEquals(Double.valueOf(-2.0d), p.getNumberValueDeferred()); + assertEquals(Double.valueOf(-2.0d), p.getDoubleValue()); + assertToken(JsonToken.END_OBJECT, p.nextToken()); + assertToken(JsonToken.END_OBJECT, p.nextToken()); + assertToken(JsonToken.END_ARRAY, p.nextToken()); + assertToken(JsonToken.END_OBJECT, p.nextToken()); + } + } +}