Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ a pure JSON library.
=== Releases ===
------------------------------------------------------------------------

2.17.4 (not yet released)

#1391: Fix issue where the parser can read back old number state when
parsing later numbers
(fix contributed by @pjfanning)

2.17.3 (01-Nov-2024)

#1331: Update to FastDoubleParser v1.0.1 to fix `BigDecimal` decoding problem
Expand All @@ -23,7 +29,6 @@ a pure JSON library.
#1352: Fix infinite loop due to integer overflow when reading large strings
(reported by Adam J.S)
(fix contributed by @pjfanning)


2.17.2 (05-Jul-2024)

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/fasterxml/jackson/core/base/ParserBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,7 @@ public BigInteger getBigIntegerValue() throws IOException
}
if ((_numTypesValid & NR_BIGINT) == 0) {
convertNumberToBigInteger();
return _numberBigInt;
}
}
return _getBigInteger();
Expand All @@ -840,6 +841,7 @@ public float getFloatValue() throws IOException
}
if ((_numTypesValid & NR_FLOAT) == 0) {
convertNumberToFloat();
return _numberFloat;
}
}
return _getNumberFloat();
Expand All @@ -854,6 +856,7 @@ public double getDoubleValue() throws IOException
}
if ((_numTypesValid & NR_DOUBLE) == 0) {
convertNumberToDouble();
return _numberDouble;
}
}
return _getNumberDouble();
Expand All @@ -868,6 +871,7 @@ public BigDecimal getDecimalValue() throws IOException
}
if ((_numTypesValid & NR_BIGDECIMAL) == 0) {
convertNumberToBigDecimal();
return _numberBigDecimal;
}
}
return _getBigDecimal();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.fasterxml.jackson.core.read;

import java.math.BigDecimal;
import java.math.BigInteger;

import org.junit.jupiter.api.Test;

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 static org.junit.jupiter.api.Assertions.assertEquals;

class NumberParsingDb4917Test extends JUnit5TestBase
{
private TokenStreamFactory JSON_F = newStreamFactory();

final String INPUT_JSON = a2q("{'decimalHolder':100.00,'number':50}");

// [jackson-databind#4917]
@Test
public void bigDecimal4917Integers() throws Exception
{
for (int mode : ALL_MODES) {
testBigDecimal4917(JSON_F, mode, INPUT_JSON, true, JsonParser.NumberType.BIG_INTEGER);
testBigDecimal4917(JSON_F, mode, INPUT_JSON, true, JsonParser.NumberType.INT);
testBigDecimal4917(JSON_F, mode, INPUT_JSON, true, JsonParser.NumberType.LONG);
}
}

@Test
public void bigDecimal4917Floats() throws Exception
{
for (int mode : ALL_MODES) {
testBigDecimal4917(JSON_F, mode, INPUT_JSON, false, JsonParser.NumberType.DOUBLE);
testBigDecimal4917(JSON_F, mode, INPUT_JSON, true, JsonParser.NumberType.DOUBLE);
testBigDecimal4917(JSON_F, mode, INPUT_JSON, true, JsonParser.NumberType.FLOAT);
testBigDecimal4917(JSON_F, mode, INPUT_JSON, true, JsonParser.NumberType.BIG_DECIMAL);
}
}

private void testBigDecimal4917(final TokenStreamFactory jsonF,
final int mode,
final String json,
final boolean checkFirstNumValues,
final JsonParser.NumberType secondNumTypeCheck) throws Exception
{
// checkFirstNumValues=false reproduces the issue in https://github.com/FasterXML/jackson-databind/issues/4917
// it is useful to check the second number value while requesting different number types
// but the call adjusts state of the parser, so it is better to redo the test and then test w
try (JsonParser p = createParser(jsonF, mode, json)) {
assertToken(JsonToken.START_OBJECT, p.nextToken());
assertToken(JsonToken.FIELD_NAME, p.nextToken());
assertEquals("decimalHolder", p.currentName());
assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
assertEquals(JsonParser.NumberType.DOUBLE, p.getNumberType());
if (checkFirstNumValues) {
assertEquals(Double.valueOf(100.0), p.getNumberValueDeferred());
assertEquals(new BigDecimal("100.00"), p.getDecimalValue());
}
assertEquals("100.00", p.getText());
assertToken(JsonToken.FIELD_NAME, p.nextToken());
assertEquals("number", p.currentName());
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(JsonParser.NumberType.INT, p.getNumberType());
assertEquals(Integer.valueOf(50), p.getNumberValueDeferred());
if (secondNumTypeCheck == JsonParser.NumberType.BIG_DECIMAL) {
assertEquals(new BigDecimal("50"), p.getDecimalValue());
} else if (secondNumTypeCheck == JsonParser.NumberType.BIG_INTEGER) {
assertEquals(new BigInteger("50"), p.getBigIntegerValue());
} else if (secondNumTypeCheck == JsonParser.NumberType.FLOAT) {
assertEquals(50.0f, p.getFloatValue());
} else if (secondNumTypeCheck == JsonParser.NumberType.LONG) {
assertEquals(50L, p.getLongValue());
} else if (secondNumTypeCheck == JsonParser.NumberType.INT) {
assertEquals(50, p.getIntValue());
} else {
assertEquals(50.0d, p.getDoubleValue());
}
assertEquals(50, p.getIntValue());
assertToken(JsonToken.END_OBJECT, p.nextToken());
}
}
}
Loading