Skip to content

Commit 6a7b516

Browse files
authored
check number lengths (#3687)
1 parent 1016dc5 commit 6a7b516

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ protected final Double _parseDouble(JsonParser p, DeserializationContext ctxt) t
751751
if (_checkTextualNull(ctxt, text)) {
752752
return (Double) getNullValue(ctxt);
753753
}
754+
p.streamReadConstraints().validateFPLength(text.length());
754755
try {
755756
return _parseDouble(text, p.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER));
756757
} catch (IllegalArgumentException iae) { }
@@ -843,13 +844,15 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
843844
}
844845
try {
845846
if (!_isIntNumber(text)) {
847+
p.streamReadConstraints().validateFPLength(text.length());
846848
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
847849
return NumberInput.parseBigDecimal(
848850
text, p.isEnabled(StreamReadFeature.USE_FAST_BIG_NUMBER_PARSER));
849851
}
850852
return Double.valueOf(
851853
NumberInput.parseDouble(text, p.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER)));
852854
}
855+
p.streamReadConstraints().validateIntegerLength(text.length());
853856
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
854857
return NumberInput.parseBigInteger(text, p.isEnabled(StreamReadFeature.USE_FAST_BIG_NUMBER_PARSER));
855858
}
@@ -961,6 +964,7 @@ public BigInteger deserialize(JsonParser p, DeserializationContext ctxt) throws
961964
// note: no need to call `coerce` as this is never primitive
962965
return getNullValue(ctxt);
963966
}
967+
p.streamReadConstraints().validateIntegerLength(text.length());
964968
try {
965969
return NumberInput.parseBigInteger(text, p.isEnabled(StreamReadFeature.USE_FAST_BIG_NUMBER_PARSER));
966970
} catch (IllegalArgumentException iae) { }
@@ -1030,6 +1034,7 @@ public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt)
10301034
// note: no need to call `coerce` as this is never primitive
10311035
return getNullValue(ctxt);
10321036
}
1037+
p.streamReadConstraints().validateFPLength(text.length());
10331038
try {
10341039
return NumberInput.parseBigDecimal(text, p.isEnabled(StreamReadFeature.USE_FAST_BIG_NUMBER_PARSER));
10351040
} catch (IllegalArgumentException iae) { }
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package com.fasterxml.jackson.databind.deser;
2+
3+
import com.fasterxml.jackson.core.JsonFactory;
4+
import com.fasterxml.jackson.core.StreamReadConstraints;
5+
import com.fasterxml.jackson.databind.BaseMapTest;
6+
import com.fasterxml.jackson.databind.JsonMappingException;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.databind.json.JsonMapper;
9+
10+
import java.math.BigDecimal;
11+
import java.math.BigInteger;
12+
13+
public class TestBigNumbers extends BaseMapTest
14+
{
15+
static class BigDecimalWrapper {
16+
BigDecimal number;
17+
18+
public BigDecimalWrapper() {}
19+
20+
public BigDecimalWrapper(BigDecimal number) {
21+
this.number = number;
22+
}
23+
24+
public void setNumber(BigDecimal number) {
25+
this.number = number;
26+
}
27+
}
28+
29+
static class BigIntegerWrapper {
30+
BigInteger number;
31+
32+
public BigIntegerWrapper() {}
33+
34+
public BigIntegerWrapper(BigInteger number) {
35+
this.number = number;
36+
}
37+
38+
public void setNumber(BigInteger number) {
39+
this.number = number;
40+
}
41+
}
42+
43+
/*
44+
/**********************************************************
45+
/* Tests
46+
/**********************************************************
47+
*/
48+
49+
private final ObjectMapper MAPPER = newJsonMapper();
50+
51+
private final ObjectMapper newJsonMapperWithUnlimitedNumberSizeSupport() {
52+
JsonFactory jsonFactory = JsonFactory.builder()
53+
.streamReadConstraints(StreamReadConstraints.builder().maxNumberLength(Integer.MAX_VALUE).build())
54+
.build();
55+
return JsonMapper.builder(jsonFactory).build();
56+
}
57+
58+
public void testDouble() throws Exception
59+
{
60+
try {
61+
MAPPER.readValue(generateJson("d"), DoubleWrapper.class);
62+
} catch (JsonMappingException jsonMappingException) {
63+
assertTrue("unexpected exception message: " + jsonMappingException.getMessage(),
64+
jsonMappingException.getMessage().startsWith("Malformed numeric value ([number with 1200 characters])"));
65+
}
66+
}
67+
68+
public void testDoubleUnlimited() throws Exception
69+
{
70+
DoubleWrapper dw =
71+
newJsonMapperWithUnlimitedNumberSizeSupport().readValue(generateJson("d"), DoubleWrapper.class);
72+
assertNotNull(dw);
73+
}
74+
75+
public void testBigDecimal() throws Exception
76+
{
77+
try {
78+
MAPPER.readValue(generateJson("number"), BigDecimalWrapper.class);
79+
} catch (JsonMappingException jsonMappingException) {
80+
assertTrue("unexpected exception message: " + jsonMappingException.getMessage(),
81+
jsonMappingException.getMessage().startsWith("Malformed numeric value ([number with 1200 characters])"));
82+
}
83+
}
84+
85+
public void testBigDecimalUnlimited() throws Exception
86+
{
87+
BigDecimalWrapper bdw =
88+
newJsonMapperWithUnlimitedNumberSizeSupport()
89+
.readValue(generateJson("number"), BigDecimalWrapper.class);
90+
assertNotNull(bdw);
91+
}
92+
93+
public void testBigInteger() throws Exception
94+
{
95+
try {
96+
MAPPER.readValue(generateJson("number"), BigIntegerWrapper.class);
97+
} catch (JsonMappingException jsonMappingException) {
98+
assertTrue("unexpected exception message: " + jsonMappingException.getMessage(),
99+
jsonMappingException.getMessage().startsWith("Malformed numeric value ([number with 1200 characters])"));
100+
}
101+
}
102+
103+
public void testBigIntegerUnlimited() throws Exception
104+
{
105+
BigIntegerWrapper bdw =
106+
newJsonMapperWithUnlimitedNumberSizeSupport()
107+
.readValue(generateJson("number"), BigIntegerWrapper.class);
108+
assertNotNull(bdw);
109+
}
110+
111+
private String generateJson(final String fieldName) {
112+
final int len = 1200;
113+
final StringBuilder sb = new StringBuilder();
114+
sb.append("{\"")
115+
.append(fieldName)
116+
.append("\": ");
117+
for (int i = 0; i < len; i++) {
118+
sb.append(1);
119+
}
120+
sb.append("}");
121+
return sb.toString();
122+
}
123+
}

0 commit comments

Comments
 (0)