Skip to content

Commit 0606291

Browse files
authored
Merge branch 'networknt:master' into master
2 parents 669e4ee + 53fa5de commit 0606291

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+5469
-3022
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
4949
}
5050

5151
if (format != null) {
52+
if(format.getName().equals("ipv6")) {
53+
if(!node.textValue().trim().equals(node.textValue())) {
54+
// leading and trailing spaces
55+
errors.add(buildValidationMessage(at, format.getName(), format.getErrorMessageDescription()));
56+
} else if(node.textValue().contains("%")) {
57+
// zone id is not part of the ipv6
58+
errors.add(buildValidationMessage(at, format.getName(), format.getErrorMessageDescription()));
59+
}
60+
}
5261
try {
5362
if (!format.matches(node.textValue())) {
5463
errors.add(buildValidationMessage(at, format.getName(), format.getErrorMessageDescription()));

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ static PatternFormat pattern(String name, String regex) {
4343
COMMON_BUILTIN_FORMATS.add(pattern("time", "^\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?$"));
4444
COMMON_BUILTIN_FORMATS.add(pattern("ip-address",
4545
"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"));
46-
COMMON_BUILTIN_FORMATS.add(pattern("ipv4",
47-
"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"));
46+
COMMON_BUILTIN_FORMATS.add(pattern("ipv4", "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"));
4847
COMMON_BUILTIN_FORMATS.add(pattern("ipv6",
4948
"^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$"));
5049

src/main/java/com/networknt/schema/utils/JsonNodeUtil.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,11 @@ public static boolean equalsToSchemaType(JsonNode node, JsonType schemaType, Jso
8484
}
8585

8686
ValidatorState state = (ValidatorState) CollectorContext.getInstance().get(ValidatorState.VALIDATOR_STATE_KEY);
87-
if(JsonType.NULL.equals(nodeType) ){
88-
if(state.isComplexValidator() && JsonNodeUtil.isNodeNullable(parentSchema.getParentSchema().getSchemaNode(), config) || JsonNodeUtil.isNodeNullable(parentSchema.getSchemaNode()) ){
89-
return true;
87+
if(JsonType.NULL.equals(nodeType)) {
88+
if(state.isComplexValidator() && parentSchema != null) {
89+
if( parentSchema.getParentSchema() != null && JsonNodeUtil.isNodeNullable(parentSchema.getParentSchema().getSchemaNode(), config) || JsonNodeUtil.isNodeNullable(parentSchema.getSchemaNode()) ) {
90+
return true;
91+
}
9092
}
9193
}
9294

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.networknt.schema;
2+
import com.fasterxml.jackson.databind.JsonNode;
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.networknt.schema.JsonSchema;
5+
import com.networknt.schema.JsonSchemaFactory;
6+
import com.networknt.schema.SpecVersion;
7+
import com.networknt.schema.ValidationMessage;
8+
import com.networknt.schema.uri.URIFactory;
9+
import com.networknt.schema.uri.URIFetcher;
10+
import org.junit.jupiter.api.Test;
11+
12+
import java.io.ByteArrayInputStream;
13+
import java.io.IOException;
14+
import java.io.InputStream;
15+
import java.net.URI;
16+
import java.nio.charset.StandardCharsets;
17+
import java.util.Set;
18+
19+
import static org.hamcrest.CoreMatchers.is;
20+
import static org.hamcrest.MatcherAssert.assertThat;
21+
22+
public class CustomUriTest {
23+
@Test
24+
public void customUri() throws Exception {
25+
/* Given */
26+
final JsonSchemaFactory factory = buildJsonSchemaFactory();
27+
final JsonSchema schema = factory.getSchema(
28+
"{\"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\"type\": \"object\",\"additionalProperties\": false,\"properties\": {\"customAnyOf\": {\"anyOf\": [{\"type\": \"null\"},{\"$ref\": \"custom:date\"}]},\"customOneOf\": {\"oneOf\": [{\"type\": \"null\"},{\"$ref\": \"custom:date\"}]}}}");
29+
final ObjectMapper mapper = new ObjectMapper();
30+
final JsonNode value = mapper.readTree("{\"customAnyOf\": null,\"customOneOf\": null}");
31+
32+
/* When */
33+
final Set<ValidationMessage> errors = schema.validate(value);
34+
35+
/* Then */
36+
assertThat(errors.isEmpty(), is(true));
37+
}
38+
39+
private JsonSchemaFactory buildJsonSchemaFactory() {
40+
return JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909))
41+
.uriFetcher(new CustomUriFetcher(), "custom").uriFactory(new CustomUriFactory(), "custom").build();
42+
}
43+
44+
private static class CustomUriFetcher implements URIFetcher {
45+
private static final String SCHEMA = "{\"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\"$id\":\"custom:date\",\"type\":\"string\",\"format\":\"date\"}";
46+
47+
@Override
48+
public InputStream fetch(final URI uri) throws IOException {
49+
return new ByteArrayInputStream(SCHEMA.getBytes(StandardCharsets.UTF_8));
50+
}
51+
}
52+
53+
private static class CustomUriFactory implements URIFactory {
54+
@Override
55+
public URI create(final String uri) {
56+
return URI.create(uri);
57+
}
58+
59+
@Override
60+
public URI create(final URI baseURI, final String segment) {
61+
return baseURI.resolve(segment);
62+
}
63+
}
64+
}

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,15 @@ public class UriMappingTest {
4949
@Test
5050
public void testBuilderUriMappingUri() throws IOException {
5151
URL mappings = ClasspathURLFactory.convert(
52-
this.classpathURLFactory.create("resource:draft4/uri_mapping/uri-mapping.json"));
52+
this.classpathURLFactory.create("resource:draft4/extra/uri_mapping/uri-mapping.json"));
5353
JsonMetaSchema draftV4 = JsonMetaSchema.getV4();
5454
Builder builder = JsonSchemaFactory.builder()
5555
.defaultMetaSchemaURI(draftV4.getUri())
5656
.addMetaSchema(draftV4)
5757
.addUriMappings(getUriMappingsFromUrl(mappings));
5858
JsonSchemaFactory instance = builder.build();
5959
JsonSchema schema = instance.getSchema(this.urlFactory.create(
60-
"https://raw.githubusercontent.com/networknt/json-schema-validator/master/src/test/resources/draft4/uri_mapping/uri-mapping.schema.json"));
60+
"https://raw.githubusercontent.com/networknt/json-schema-validator/master/src/test/resources/draft4/extra/uri_mapping/uri-mapping.schema.json"));
6161
assertEquals(0, schema.validate(mapper.readTree(mappings)).size());
6262
}
6363

@@ -88,7 +88,7 @@ public void testBuilderExampleMappings() throws IOException {
8888
fail("Unexpected exception thrown");
8989
}
9090
URL mappings = ClasspathURLFactory.convert(
91-
this.classpathURLFactory.create("resource:draft4/uri_mapping/invalid-schema-uri.json"));
91+
this.classpathURLFactory.create("resource:draft4/extra/uri_mapping/invalid-schema-uri.json"));
9292
JsonMetaSchema draftV4 = JsonMetaSchema.getV4();
9393
Builder builder = JsonSchemaFactory.builder()
9494
.defaultMetaSchemaURI(draftV4.getUri())
@@ -109,11 +109,11 @@ public void testBuilderExampleMappings() throws IOException {
109109
public void testValidatorConfigUriMappingUri() throws IOException {
110110
JsonSchemaFactory instance = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4);
111111
URL mappings = ClasspathURLFactory.convert(
112-
this.classpathURLFactory.create("resource:draft4/uri_mapping/uri-mapping.json"));
112+
this.classpathURLFactory.create("resource:draft4/extra/uri_mapping/uri-mapping.json"));
113113
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
114114
config.setUriMappings(getUriMappingsFromUrl(mappings));
115115
JsonSchema schema = instance.getSchema(this.urlFactory.create(
116-
"https://raw.githubusercontent.com/networknt/json-schema-validator/master/src/test/resources/draft4/uri_mapping/uri-mapping.schema.json"),
116+
"https://raw.githubusercontent.com/networknt/json-schema-validator/master/src/test/resources/draft4/extra/uri_mapping/uri-mapping.schema.json"),
117117
config);
118118
assertEquals(0, schema.validate(mapper.readTree(mappings)).size());
119119
}
@@ -146,7 +146,7 @@ public void testValidatorConfigExampleMappings() throws IOException {
146146
fail("Unexpected exception thrown");
147147
}
148148
URL mappings = ClasspathURLFactory.convert(
149-
this.classpathURLFactory.create("resource:draft4/uri_mapping/invalid-schema-uri.json"));
149+
this.classpathURLFactory.create("resource:draft4/extra/uri_mapping/invalid-schema-uri.json"));
150150
config.setUriMappings(getUriMappingsFromUrl(mappings));
151151
JsonSchema schema = instance.getSchema(example, config);
152152
assertEquals(0, schema.validate(mapper.createObjectNode()).size());
@@ -156,10 +156,10 @@ public void testValidatorConfigExampleMappings() throws IOException {
156156
public void testMappingsForRef() throws IOException {
157157
JsonSchemaFactory instance = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4);
158158
URL mappings = ClasspathURLFactory.convert(
159-
this.classpathURLFactory.create("resource:draft4/uri_mapping/schema-with-ref-mapping.json"));
159+
this.classpathURLFactory.create("resource:draft4/extra/uri_mapping/schema-with-ref-mapping.json"));
160160
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
161161
config.setUriMappings(getUriMappingsFromUrl(mappings));
162-
JsonSchema schema = instance.getSchema(this.classpathURLFactory.create("resource:draft4/uri_mapping/schema-with-ref.json"),
162+
JsonSchema schema = instance.getSchema(this.classpathURLFactory.create("resource:draft4/extra/uri_mapping/schema-with-ref.json"),
163163
config);
164164
assertEquals(0, schema.validate(mapper.readTree("[]")).size());
165165
}

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

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.fasterxml.jackson.databind.JsonNode;
2020
import com.fasterxml.jackson.databind.ObjectMapper;
21+
import org.junit.jupiter.api.Disabled;
2122
import org.junit.jupiter.api.Test;
2223

2324
import java.io.IOException;
@@ -40,13 +41,49 @@ public void testLoadingWithId() throws Exception {
4041
JsonSchema schema = factory.getSchema(schemaJson);
4142
}
4243

44+
@Test
45+
@Disabled
46+
public void testFormatDateTimeValidator() throws Exception {
47+
runTestFile("draft4/optional/format/date-time.json");
48+
}
49+
50+
@Test
51+
public void testFormatEmailValidator() throws Exception {
52+
runTestFile("draft4/optional/format/email.json");
53+
}
54+
55+
@Test
56+
public void testFormatHostnameValidator() throws Exception {
57+
runTestFile("draft4/optional/format/hostname.json");
58+
}
59+
60+
@Test
61+
public void testFormatIpv4Validator() throws Exception {
62+
runTestFile("draft4/optional/format/ipv4.json");
63+
}
64+
65+
@Test
66+
public void testFormatIpv6Validator() throws Exception {
67+
runTestFile("draft4/optional/format/ipv6.json");
68+
}
69+
70+
@Test
71+
public void testFormatUnknownValidator() throws Exception {
72+
runTestFile("draft4/optional/format/unknown.json");
73+
}
74+
75+
@Test
76+
public void testFormatUriValidator() throws Exception {
77+
runTestFile("draft4/optional/format/uri.json");
78+
}
79+
4380
@Test
4481
public void testBignumValidator() throws Exception {
4582
runTestFile("draft4/optional/bignum.json");
4683
}
4784

4885
@Test
49-
public void testFormatValidator() throws Exception {
86+
public void testOptionalFormatValidator() throws Exception {
5087
runTestFile("draft4/optional/format.json");
5188
}
5289

@@ -55,6 +92,16 @@ public void testComplexSchema() throws Exception {
5592
runTestFile("draft4/optional/complex.json");
5693
}
5794

95+
@Test
96+
public void testFloatOverflowValidator() throws Exception {
97+
runTestFile("draft4/optional/float-overflow.json");
98+
}
99+
100+
@Test
101+
public void testNonBmpRegexValidator() throws Exception {
102+
runTestFile("draft4/optional/non-bmp-regex.json");
103+
}
104+
58105
@Test
59106
public void testZeroTerminatedFloatsValidator() throws Exception {
60107
runTestFile("draft4/optional/zeroTerminatedFloats.json");
@@ -100,6 +147,22 @@ public void testEnumValidator() throws Exception {
100147
runTestFile("draft4/enum.json");
101148
}
102149

150+
@Test
151+
public void testFormatValidator() throws Exception {
152+
runTestFile("draft4/format.json");
153+
}
154+
155+
@Test
156+
@Disabled
157+
public void testIdValidator() throws Exception {
158+
runTestFile("draft4/id.json");
159+
}
160+
161+
@Test
162+
public void testInfiniteLoopDetectionValidator() throws Exception {
163+
runTestFile("draft4/infinite-loop-detection.json");
164+
}
165+
103166
@Test
104167
public void testItemsValidator() throws Exception {
105168
runTestFile("draft4/items.json");
@@ -207,7 +270,7 @@ public void testTypeValidator() throws Exception {
207270

208271
@Test
209272
public void testUnionTypeValidator() throws Exception {
210-
runTestFile("draft4/union_type.json");
273+
runTestFile("draft4/extra/union_type.json");
211274
}
212275

213276
@Test
@@ -222,17 +285,17 @@ public void testEnumObject() throws Exception {
222285

223286
@Test
224287
public void testIdSchemaWithUrl() throws Exception {
225-
runTestFile("draft4/property.json");
288+
runTestFile("draft4/extra/property.json");
226289
}
227290

228291
@Test
229292
public void testSchemaFromClasspath() throws Exception {
230-
runTestFile("draft4/classpath/schema.json");
293+
runTestFile("draft4/extra/classpath/schema.json");
231294
}
232295

233296
@Test
234297
public void testUUIDValidator() throws Exception {
235-
runTestFile("draft4/uuid.json");
298+
runTestFile("draft4/extra/uuid.json");
236299
}
237300

238301
/**
@@ -241,7 +304,7 @@ public void testUUIDValidator() throws Exception {
241304
@Test
242305
public void testFailFast_AllErrors() throws IOException {
243306
try {
244-
validateFailingFastSchemaFor("product.schema.json", "product-all-errors-data.json");
307+
validateFailingFastSchemaFor("extra/product/product.schema.json", "extra/product/product-all-errors-data.json");
245308
fail("Exception must be thrown");
246309
} catch (JsonSchemaException e) {
247310
final Set<ValidationMessage> messages = e.getValidationMessages();
@@ -255,7 +318,7 @@ public void testFailFast_AllErrors() throws IOException {
255318
@Test
256319
public void testFailFast_OneErrors() throws IOException {
257320
try {
258-
validateFailingFastSchemaFor("product.schema.json", "product-one-error-data.json");
321+
validateFailingFastSchemaFor("extra/product/product.schema.json", "extra/product/product-one-error-data.json");
259322
fail("Exception must be thrown");
260323
} catch (JsonSchemaException e) {
261324
final Set<ValidationMessage> messages = e.getValidationMessages();
@@ -269,7 +332,7 @@ public void testFailFast_OneErrors() throws IOException {
269332
@Test
270333
public void testFailFast_TwoErrors() throws IOException {
271334
try {
272-
validateFailingFastSchemaFor("product.schema.json", "product-two-errors-data.json");
335+
validateFailingFastSchemaFor("extra/product/product.schema.json", "extra/product/product-two-errors-data.json");
273336
fail("Exception must be thrown");
274337
} catch (JsonSchemaException e) {
275338
final Set<ValidationMessage> messages = e.getValidationMessages();
@@ -283,7 +346,7 @@ public void testFailFast_TwoErrors() throws IOException {
283346
@Test
284347
public void testFailFast_NoErrors() throws IOException {
285348
try {
286-
final Set<ValidationMessage> messages = validateFailingFastSchemaFor("product.schema.json", "product-no-errors-data.json");
349+
final Set<ValidationMessage> messages = validateFailingFastSchemaFor("extra/product/product.schema.json", "extra/product/product-no-errors-data.json");
287350
assertTrue(messages.isEmpty());
288351
} catch (JsonSchemaException e) {
289352
fail("Must not get an errors");

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public V6JsonSchemaTest() {
2323
super(SpecVersion.VersionFlag.V6);
2424
}
2525

26+
@Test
27+
public void testFormatIpv4Validator() throws Exception {
28+
runTestFile("draft4/optional/format/ipv4.json");
29+
}
30+
2631
@Test
2732
public void testOptionalBignumValidator() throws Exception {
2833
runTestFile("draft6/optional/bignum.json");

0 commit comments

Comments
 (0)