NumberLength1766Test.java
package tools.jackson.core.unittest.constraints;
import org.junit.jupiter.api.Test;
import tools.jackson.core.JsonParser;
import tools.jackson.core.JsonToken;
import tools.jackson.core.StreamReadConstraints;
import tools.jackson.core.exc.StreamConstraintsException;
import tools.jackson.core.json.JsonFactory;
import tools.jackson.core.json.JsonReadFeature;
import tools.jackson.core.unittest.JacksonCoreTestBase;
import static org.junit.jupiter.api.Assertions.*;
// [core#1766]: `ReaderBasedJsonParser` undercounted number length when
// fraction or exponent was absent (throttled Reader forces fallback path)
class NumberLength1766Test extends JacksonCoreTestBase
{
@Test
void exactLimitAccepted() throws Exception
{
JsonFactory f = factory(5);
for (String doc : new String[] { "123.45", "123e45", "12.3e45", "-123.45" }) {
assertParses(f, doc);
}
f = factory(1000);
assertParses(f, "1." + "7".repeat(999));
assertParses(f, "1e" + "7".repeat(999));
}
@Test
void oneOverLimitRejected() throws Exception
{
JsonFactory f = factory(5);
for (String doc : new String[] { "123.456", "12345e1", "12.34e56", "-12345e1" }) {
assertTooLong(f, doc);
}
// long enough to span TextBuffer segments
f = factory(1000);
assertTooLong(f, "1." + "7".repeat(1000));
assertTooLong(f, "1e" + "7".repeat(1000));
}
@Test
void nonStandardDecimalPoint() throws Exception
{
JsonFactory f = factory(5).rebuild()
.enable(JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS)
.enable(JsonReadFeature.ALLOW_TRAILING_DECIMAL_POINT_FOR_NUMBERS)
.build();
assertParses(f, ".12345");
assertTooLong(f, ".123456");
assertParses(f, "12345.");
assertTooLong(f, "123456.");
}
private void assertParses(JsonFactory f, String doc) throws Exception
{
try (JsonParser p = createParser(f, MODE_READER_THROTTLED, doc + " ")) {
assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
assertEquals(doc, p.getString());
assertNull(p.nextToken());
}
}
private void assertTooLong(JsonFactory f, String doc) throws Exception
{
try (JsonParser p = createParser(f, MODE_READER_THROTTLED, doc + " ")) {
StreamConstraintsException e = assertThrows(StreamConstraintsException.class,
p::nextToken, "Should exceed maxNumberLength: " + doc);
verifyException(e, "Number value length (");
}
}
private JsonFactory factory(int maxNumberLength) {
return JsonFactory.builder()
.streamReadConstraints(StreamReadConstraints.builder()
.maxNumberLength(maxNumberLength).build())
.build();
}
}