Skip to content

Commit 4172360

Browse files
Improve type validation of integrals (#496)
* Improve type validation of integrals Instead of doing string comparison, use new jackson method to determine if a number is an integral. The `javaSemantics` config option was added in PR #343 which partially addressed issue #334. In the notes for this PR: > Once jackson-databind 2.12.0 is out, I'll replace my solution with a call to canConvertToExactIntegral jackson-databind has been updated to 2.12.1 so this is available but the change has not yet been made. PR #450 which addressed #446 missed this location which is used when calling `JsonSchemaFactory.getSchema`. Issue #344 requested coercion of various types but the only type implemented in PR #379 was lossless narrowing, set with configuration option `losslessNarrowing`. I believe that setting is unnecessary now as this implementation of `javaSemantics` addresses the original issue, but left it for backwards compatibility. It also allows you to set `javaSemantics=false` and `losslessNarrowing=true` to achieve only this specific case rather than anything that `javaSemantics` is used for in the future. At this time, these properties do exactly the same thing. - Change from string comparison to `canConvertToExactIntegral` for `javaSemantics` and `losslessNarrowing` - Add missing documentation around `losslessNarrowing` - Add more test cases around integrals * Update changelog
1 parent 7f96315 commit 4172360

File tree

4 files changed

+30
-6
lines changed

4 files changed

+30
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1010

1111
### Changed
1212

13+
- fixes #446 maxLength and minLength do not work when a number with a zero decimal is used
14+
1315
## 1.0.65 - 2022-01-07
1416

1517
### Changed

doc/config.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,11 @@ When set to true, use Java-specific semantics rather than native JavaScript sema
5555
For example, if the node type is `number` per JS semantics where the value can be losslesly interpreted as `java.lang.Long`, the validator would use `integer` as the node type instead of `number`. This is useful when schema type is `integer`, since validation would fail otherwise.
5656

5757
For more details, please refer to this [issue](https://github.com/networknt/json-schema-validator/issues/334).
58+
59+
* losslessNarrowing
60+
61+
When set to true, can interpret round doubles as integers.
62+
63+
Note that setting `javaSemantics = true` will achieve the same functionality at this time.
64+
65+
For more details, please refer to this [issue](https://github.com/networknt/json-schema-validator/issues/344).

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ public static JsonType getValueNodeType(JsonNode node, SchemaValidatorsConfig co
7272
if (node.isIntegralNumber())
7373
return JsonType.INTEGER;
7474
if (node.isNumber())
75-
if (config != null && config.isJavaSemantics() && node.canConvertToLong() && (node.asText().indexOf('.') == -1))
75+
if (config != null && config.isJavaSemantics() && node.canConvertToExactIntegral())
7676
return JsonType.INTEGER;
77-
else if (config!= null && config.isLosslessNarrowing() && node.asText().endsWith(".0"))
77+
else if (config != null && config.isLosslessNarrowing() && node.canConvertToExactIntegral())
7878
return JsonType.INTEGER;
7979
else
8080
return JsonType.NUMBER;

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,43 @@ public class TypeFactoryTest {
2828

2929
private static final String[] validIntegralValues = {
3030
"1", "-1", "0E+1", "0E1", "-0E+1", "-0E1", "10.1E+1", "10.1E1", "-10.1E+1", "-10.1E1", "1E+0", "1E-0",
31-
"1E0", "1E18", "9223372036854775807", "-9223372036854775808"
31+
"1E0", "1E18", "9223372036854775807", "-9223372036854775808", "1.0", "1.00", "-1.0", "-1.00"
32+
};
33+
34+
private static final String[] validNonIntegralNumberValues = {
35+
"1.1", "-1.1", "1.10"
3236
};
3337

3438
private final SchemaValidatorsConfig schemaValidatorsConfig = new SchemaValidatorsConfig();
3539

3640
@Test
37-
public void testValidIntegralValuesWithJavaSemantics() {
41+
public void testIntegralValuesWithJavaSemantics() {
3842
schemaValidatorsConfig.setJavaSemantics(true);
3943
for (String validValue : validIntegralValues) {
4044
assertSame(JsonType.INTEGER,
4145
getValueNodeType(DecimalNode.valueOf(new BigDecimal(validValue)), schemaValidatorsConfig),
4246
validValue);
4347
}
48+
for (String validValue : validNonIntegralNumberValues) {
49+
assertSame(JsonType.NUMBER,
50+
getValueNodeType(DecimalNode.valueOf(new BigDecimal(validValue)), schemaValidatorsConfig),
51+
validValue);
52+
}
4453
}
4554

4655
@Test
47-
public void testValidIntegralValuesWithoutJavaSemantics() {
56+
public void testIntegralValuesWithoutJavaSemantics() {
4857
schemaValidatorsConfig.setJavaSemantics(false);
4958
for (String validValue : validIntegralValues) {
5059
assertSame(JsonType.NUMBER,
5160
getValueNodeType(DecimalNode.valueOf(new BigDecimal(validValue)), schemaValidatorsConfig),
5261
validValue);
5362
}
63+
for (String validValue : validNonIntegralNumberValues) {
64+
assertSame(JsonType.NUMBER,
65+
getValueNodeType(DecimalNode.valueOf(new BigDecimal(validValue)), schemaValidatorsConfig),
66+
validValue);
67+
}
5468
}
5569

5670

@@ -82,4 +96,4 @@ public void testWithoutLosslessNarrowing() {
8296
}
8397

8498
}
85-
}
99+
}

0 commit comments

Comments
 (0)