Skip to content

Commit

Permalink
Async JSON parser should handle large integer (literaly speaking) num…
Browse files Browse the repository at this point in the history
…ber representations.

Motivation:

Large number representations are not handled by the async JSON parser, leading to a decoder exception since the async parser tries to obtain a long number from the Jackson parser. The parser should be able to handle this case using a big integer.

Changes:

Obtain a java number from the Jackson parser instead of a Long.

Result:

When a large integer number is parsed, the async parser parses the value succesfully and the json event value will be a big integer.
  • Loading branch information
vietj committed Feb 6, 2025
1 parent 9f91d2b commit 9b27cbc
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,12 @@ private void checkTokens() {
}
case VALUE_NUMBER_INT: {
try {
event = new JsonEventImpl(token, JsonEventType.VALUE, field, parser.getLongValue());
Number number = parser.getNumberValue();
if (number instanceof Integer) {
// Backward compat
number = (long) (int) number;
}
event = new JsonEventImpl(token, JsonEventType.VALUE, field, number);
} catch (IOException e) {
handle(e);
continue;
Expand Down
32 changes: 30 additions & 2 deletions src/test/java/io/vertx/core/parsetools/JsonParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import io.vertx.test.core.TestUtils;
import org.junit.Test;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.*;
Expand Down Expand Up @@ -341,8 +343,8 @@ public void testLongValue() {
assertFalse(event.isString());
assertEquals(567, (long)event.integerValue());
assertEquals(567L, (long)event.longValue());
assertEquals(567f, (float)event.floatValue(), 0.01f);
assertEquals(567d, (double)event.doubleValue(), 0.01d);
assertEquals(567f, event.floatValue(), 0.01f);
assertEquals(567d, event.doubleValue(), 0.01d);
assertThrowCCE(event,
JsonEvent::stringValue,
JsonEvent::booleanValue,
Expand Down Expand Up @@ -377,6 +379,32 @@ public void testDoubleValue() {
});
}

@Test
public void testBigInteger() {
String expected = "18446744073709551615";
testValue(expected, event -> {
BigInteger big = new BigInteger(expected);
assertEquals(big, event.value());
assertFalse(event.isArray());
assertFalse(event.isObject());
assertTrue(event.isNumber());
assertFalse(event.isNull());
assertFalse(event.isBoolean());
assertFalse(event.isString());
assertEquals(big.intValue(), (int)event.integerValue());
assertEquals(big.longValue(), (long)event.longValue());
assertEquals(big.floatValue(), event.floatValue(), 0.01f);
assertEquals(big.doubleValue(), event.doubleValue(), 0.01d);
assertThrowCCE(event,
JsonEvent::stringValue,
JsonEvent::booleanValue,
JsonEvent::binaryValue,
JsonEvent::instantValue,
JsonEvent::objectValue,
JsonEvent::arrayValue);
});
}

@Test
public void testBooleanValue() {
testValue("true", event -> {
Expand Down

0 comments on commit 9b27cbc

Please sign in to comment.