Skip to content

Commit b45c0ad

Browse files
authored
Merge pull request #150 from networknt/fix/min-max-validator-big-integer
fixed for PR #148
2 parents dd9970b + ab49e2c commit b45c0ad

File tree

4 files changed

+330
-2
lines changed

4 files changed

+330
-2
lines changed

src/main/java/com/networknt/schema/MaximumValidator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ public boolean crossesThreshold(JsonNode node) {
7373
long val = node.asLong();
7474
if(node.isBigInteger()) {
7575
//node.isBigInteger is not trustable, the type BigInteger doesn't mean it is a big number.
76-
return node.bigIntegerValue().compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) > 0;
76+
if(node.bigIntegerValue().compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) > 0) {
77+
return true;
78+
}
7779
}
7880
return lm < val || (excludeEqual && lm <= val);
7981
}

src/main/java/com/networknt/schema/MinimumValidator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ public boolean crossesThreshold(JsonNode node) {
7676
long val = node.asLong();
7777
if(node.isBigInteger()) {
7878
//node.isBigInteger is not trustable, the type BigInteger doesn't mean it is a big number.
79-
return node.bigIntegerValue().compareTo(new BigInteger(String.valueOf(Long.MIN_VALUE))) < 0;
79+
if(node.bigIntegerValue().compareTo(new BigInteger(String.valueOf(Long.MIN_VALUE))) < 0) {
80+
return true;
81+
}
8082
}
8183
return lmin > val || (excluded && lmin >= val);
8284
}

src/test/java/com/networknt/schema/MaximumValidatorTest.java

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ public class MaximumValidatorTest {
3535

3636
private static ObjectMapper mapper;
3737
private static ObjectMapper bigDecimalMapper;
38+
private static ObjectMapper bigIntegerMapper;
3839

3940
@Before
4041
public void setUp() {
4142
mapper = new ObjectMapper();
4243
bigDecimalMapper = new ObjectMapper().enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
44+
bigIntegerMapper = new ObjectMapper().enable(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS);
4345
}
4446

4547
@Test
@@ -219,6 +221,166 @@ public void longValueOverflowWithInverseEffect() throws IOException {
219221
assertTrue(format("Expecing no validation errors as maximum %s is greater than value %s", maximum, value), messages.isEmpty());
220222
}
221223
}
224+
225+
@Test
226+
public void BigIntegerBothWithinLongRangePositive() throws IOException {
227+
String[][] values = {
228+
// maximum, value
229+
{"20", "10"}
230+
};
231+
232+
for(String[] aTestCycle : values) {
233+
String maximum = aTestCycle[0];
234+
String value = aTestCycle[1];
235+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": true}", maximum);
236+
237+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
238+
JsonNode doc = bigIntegerMapper.readTree(value);
239+
240+
Set<ValidationMessage> messages = v.validate(doc);
241+
assertTrue(format("Expecing no validation errors as maximum %s is greater than value %s", maximum, value), messages.isEmpty());
242+
}
243+
}
244+
245+
@Test
246+
public void BigIntegerBothWithinLongRangeNegative() throws IOException {
247+
String[][] values = {
248+
// maximum, value
249+
{"10", "20"}
250+
};
251+
252+
for(String[] aTestCycle : values) {
253+
String maximum = aTestCycle[0];
254+
String value = aTestCycle[1];
255+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": true}", maximum);
256+
257+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
258+
JsonNode doc = bigIntegerMapper.readTree(value);
259+
260+
Set<ValidationMessage> messages = v.validate(doc);
261+
assertFalse(format("Expecting validation error with maximum %s and value %s", maximum, value), messages.isEmpty());
262+
}
263+
}
264+
265+
@Test
266+
public void BigIntegerOverflow() throws IOException {
267+
String[][] values = {
268+
// maximum, value
269+
{"9223372036854775806", "9223372036854775808"}
270+
};
271+
272+
for(String[] aTestCycle : values) {
273+
String maximum = aTestCycle[0];
274+
String value = aTestCycle[1];
275+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": true}", maximum);
276+
277+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
278+
JsonNode doc = bigIntegerMapper.readTree(value);
279+
280+
Set<ValidationMessage> messages = v.validate(doc);
281+
assertFalse(format("Expecting validation error with maximum %s and value %s", maximum, value), messages.isEmpty());
282+
}
283+
}
284+
285+
@Test
286+
public void BigIntegerNotOverflow() throws IOException {
287+
String[][] values = {
288+
// maximum, value
289+
{"9223372036854775809", "9223372036854775806"}
290+
};
291+
292+
for(String[] aTestCycle : values) {
293+
String maximum = aTestCycle[0];
294+
String value = aTestCycle[1];
295+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": true}", maximum);
296+
297+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
298+
JsonNode doc = bigIntegerMapper.readTree(value);
299+
300+
Set<ValidationMessage> messages = v.validate(doc);
301+
assertTrue(format("Expecing no validation errors as maximum %s is greater than value %s", maximum, value), messages.isEmpty());
302+
}
303+
}
304+
305+
@Test
306+
public void BigIntegerBothAboveLongRangePositive() throws IOException {
307+
String[][] values = {
308+
// maximum, value
309+
{"9223372036854775809", "9223372036854775808"}
310+
};
311+
312+
for(String[] aTestCycle : values) {
313+
String maximum = aTestCycle[0];
314+
String value = aTestCycle[1];
315+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": true}", maximum);
316+
317+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
318+
JsonNode doc = bigIntegerMapper.readTree(value);
319+
320+
Set<ValidationMessage> messages = v.validate(doc);
321+
assertTrue(format("Expecing no validation errors as maximum %s is greater than value %s", maximum, value), messages.isEmpty());
322+
}
323+
}
324+
325+
@Test
326+
public void BigIntegerBothAboveLongRangeNegative() throws IOException {
327+
String[][] values = {
328+
// maximum, value
329+
{"9223372036854775808", "9223372036854775809"}
330+
};
331+
332+
for(String[] aTestCycle : values) {
333+
String maximum = aTestCycle[0];
334+
String value = aTestCycle[1];
335+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": true}", maximum);
336+
337+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
338+
JsonNode doc = bigIntegerMapper.readTree(value);
339+
340+
Set<ValidationMessage> messages = v.validate(doc);
341+
assertFalse(format("Expecting validation error with maximum %s and value %s", maximum, value), messages.isEmpty());
342+
}
343+
}
344+
345+
@Test
346+
public void BigIntegerNotOverflowOnLongRangeEdge() throws IOException {
347+
String[][] values = {
348+
// maximum, value
349+
{"9223372036854775807", "9223372036854775807"}
350+
};
351+
352+
for(String[] aTestCycle : values) {
353+
String maximum = aTestCycle[0];
354+
String value = aTestCycle[1];
355+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": false}", maximum);
356+
357+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
358+
JsonNode doc = bigIntegerMapper.readTree(value);
359+
360+
Set<ValidationMessage> messages = v.validate(doc);
361+
assertTrue(format("Expecing no validation errors as maximum %s is greater than value %s", maximum, value), messages.isEmpty());
362+
}
363+
}
364+
365+
@Test
366+
public void BigIntegerOverflowOnLongRangeEdge() throws IOException {
367+
String[][] values = {
368+
// maximum, value
369+
{"9223372036854775808", "9223372036854775808"}
370+
};
371+
372+
for(String[] aTestCycle : values) {
373+
String maximum = aTestCycle[0];
374+
String value = aTestCycle[1];
375+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": false}", maximum);
376+
377+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
378+
JsonNode doc = bigIntegerMapper.readTree(value);
379+
380+
Set<ValidationMessage> messages = v.validate(doc);
381+
assertTrue(format("Expecing no validation errors as maximum %s is greater than value %s", maximum, value), messages.isEmpty());
382+
}
383+
}
222384
}
223385

224386

src/test/java/com/networknt/schema/MinimumValidatorTest.java

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ public class MinimumValidatorTest {
3535

3636
private static ObjectMapper mapper;
3737
private static ObjectMapper bigDecimalMapper;
38+
private static ObjectMapper bigIntegerMapper;
3839

3940
@Before
4041
public void setUp() {
4142
mapper = new ObjectMapper();
4243
bigDecimalMapper = new ObjectMapper().enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
44+
bigIntegerMapper = new ObjectMapper().enable(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS);
45+
4346
}
4447

4548
@Test
@@ -219,6 +222,165 @@ public void longValueOverflowWithInverseEffect() throws IOException {
219222
assertTrue(format("Expecing no validation errors as minimum %s is lesser than value %s", minimum, value), messages.isEmpty());
220223
}
221224
}
225+
@Test
226+
public void BigIntegerBothWithinLongRangePositive() throws IOException {
227+
String[][] values = {
228+
// minimum, value
229+
{"10", "20"}
230+
};
231+
232+
for(String[] aTestCycle : values) {
233+
String minimum = aTestCycle[0];
234+
String value = aTestCycle[1];
235+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"minimum\": %s, \"exclusiveMinimum\": true}", minimum);
236+
237+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
238+
JsonNode doc = bigIntegerMapper.readTree(value);
239+
240+
Set<ValidationMessage> messages = v.validate(doc);
241+
assertTrue(format("Expecting no validation errors as minimum %s is lesser than value %s", minimum, value), messages.isEmpty());
242+
}
243+
}
244+
245+
@Test
246+
public void BigIntegerBothWithinLongRangeNegative() throws IOException {
247+
String[][] values = {
248+
// minimum, value
249+
{"20", "10"}
250+
};
251+
252+
for(String[] aTestCycle : values) {
253+
String minimum = aTestCycle[0];
254+
String value = aTestCycle[1];
255+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"minimum\": %s, \"exclusiveMinimum\": true}", minimum);
256+
257+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
258+
JsonNode doc = bigIntegerMapper.readTree(value);
259+
260+
Set<ValidationMessage> messages = v.validate(doc);
261+
assertFalse(format("Expecting validation error with minimum %s and value %s", minimum, value), messages.isEmpty());
262+
}
263+
}
264+
265+
@Test
266+
public void BigIntegerOverflow() throws IOException {
267+
String[][] values = {
268+
// minimum, value
269+
{"-9223372036854775807", "-9223372036854775809"}
270+
};
271+
272+
for(String[] aTestCycle : values) {
273+
String minimum = aTestCycle[0];
274+
String value = aTestCycle[1];
275+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"minimum\": %s, \"exclusiveMinimum\": true}", minimum);
276+
277+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
278+
JsonNode doc = bigIntegerMapper.readTree(value);
279+
280+
Set<ValidationMessage> messages = v.validate(doc);
281+
assertFalse(format("Expecing validation error with minimum %s and value %s", minimum, value), messages.isEmpty());
282+
}
283+
}
284+
285+
@Test
286+
public void BigIntegerNotOverflow() throws IOException {
287+
String[][] values = {
288+
// minimum, value
289+
{"-9223372036854775809", "-9223372036854775807"}
290+
};
291+
292+
for(String[] aTestCycle : values) {
293+
String minimum = aTestCycle[0];
294+
String value = aTestCycle[1];
295+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"minimum\": %s, \"exclusiveMinimum\": true}", minimum);
296+
297+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
298+
JsonNode doc = bigIntegerMapper.readTree(value);
299+
300+
Set<ValidationMessage> messages = v.validate(doc);
301+
assertTrue(format("Expecting no validation errors as minimum %s is lesser than value %s", minimum, value), messages.isEmpty());
302+
}
303+
}
304+
305+
@Test
306+
public void BigIntegerBothAboveLongRangePositive() throws IOException {
307+
String[][] values = {
308+
// minimum, value
309+
{"-9223372036854775810", "-9223372036854775809"}
310+
};
311+
312+
for(String[] aTestCycle : values) {
313+
String minimum = aTestCycle[0];
314+
String value = aTestCycle[1];
315+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"minimum\": %s, \"exclusiveMinimum\": true}", minimum);
316+
317+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
318+
JsonNode doc = bigIntegerMapper.readTree(value);
319+
320+
Set<ValidationMessage> messages = v.validate(doc);
321+
assertTrue(format("Expecting no validation errors as minimum %s is lesser than value %s", minimum, value), messages.isEmpty());
322+
}
323+
}
324+
325+
@Test
326+
public void BigIntegerBothAboveLongRangeNegative() throws IOException {
327+
String[][] values = {
328+
// minimum, value
329+
{"-9223372036854775809", "-9223372036854775810"}
330+
};
331+
332+
for(String[] aTestCycle : values) {
333+
String minimum = aTestCycle[0];
334+
String value = aTestCycle[1];
335+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"minimum\": %s, \"exclusiveMinimum\": true}", minimum);
336+
337+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
338+
JsonNode doc = bigIntegerMapper.readTree(value);
339+
340+
Set<ValidationMessage> messages = v.validate(doc);
341+
assertFalse(format("Expecing validation error with minimum %s and value %s", minimum, value), messages.isEmpty());
342+
}
343+
}
344+
345+
@Test
346+
public void BigIntegerNotOverflowOnLongRangeEdge() throws IOException {
347+
String[][] values = {
348+
// minimum, value
349+
{"-9223372036854775808", "-9223372036854775808"}
350+
};
351+
352+
for(String[] aTestCycle : values) {
353+
String minimum = aTestCycle[0];
354+
String value = aTestCycle[1];
355+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"minimum\": %s, \"exclusiveMinimum\": false}", minimum);
356+
357+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
358+
JsonNode doc = bigIntegerMapper.readTree(value);
359+
360+
Set<ValidationMessage> messages = v.validate(doc);
361+
assertTrue(format("Expecing no validation errors as minimum %s is lesser than value %s", minimum, value), messages.isEmpty());
362+
}
363+
}
364+
365+
@Test
366+
public void BigIntegerOverflowOnLongRangeEdge() throws IOException {
367+
String[][] values = {
368+
// minimum, value
369+
{"-9223372036854775809", "-9223372036854775809"}
370+
};
371+
372+
for(String[] aTestCycle : values) {
373+
String maximum = aTestCycle[0];
374+
String value = aTestCycle[1];
375+
String schema = format("{ \"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\", \"maximum\": %s, \"exclusiveMaximum\": false}", maximum);
376+
377+
JsonSchema v = factory.getSchema(mapper.readTree(schema));
378+
JsonNode doc = bigIntegerMapper.readTree(value);
379+
380+
Set<ValidationMessage> messages = v.validate(doc);
381+
assertTrue(format("Expecing no validation errors as maximum %s is greater than value %s", maximum, value), messages.isEmpty());
382+
}
383+
}
222384
}
223385

224386

0 commit comments

Comments
 (0)