diff --git a/src/main/java/com/networknt/schema/keyword/RefValidator.java b/src/main/java/com/networknt/schema/keyword/RefValidator.java index 4ea86861..e691fd8b 100644 --- a/src/main/java/com/networknt/schema/keyword/RefValidator.java +++ b/src/main/java/com/networknt/schema/keyword/RefValidator.java @@ -23,6 +23,7 @@ import com.networknt.schema.Schema; import com.networknt.schema.SchemaException; import com.networknt.schema.SchemaRef; +import com.networknt.schema.SpecificationVersion; import com.networknt.schema.path.NodePath; import com.networknt.schema.utils.ThreadSafeCachingSupplier; import com.networknt.schema.SchemaLocation; @@ -146,7 +147,8 @@ private static void copySchemaResources(SchemaContext schemaContext, Schema sche private static String resolve(Schema parentSchema, String refValue) { // $ref prevents a sibling $id from changing the base uri Schema base = parentSchema; - if (parentSchema.getId() != null && parentSchema.getParentSchema() != null) { + if (parentSchema.getId() != null && parentSchema.getParentSchema() != null && parentSchema.getSchemaContext() + .getDialect().getSpecificationVersion().getOrder() <= SpecificationVersion.DRAFT_7.getOrder()) { base = parentSchema.getParentSchema(); } return SchemaLocation.resolve(base.getSchemaLocation(), refValue); diff --git a/src/test/java/com/networknt/schema/RefValidatorTest.java b/src/test/java/com/networknt/schema/RefValidatorTest.java index fff84afa..6f5430c0 100644 --- a/src/test/java/com/networknt/schema/RefValidatorTest.java +++ b/src/test/java/com/networknt/schema/RefValidatorTest.java @@ -17,6 +17,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Collections; import java.util.List; @@ -134,4 +135,95 @@ void classPathNoSlash() { + "}"; assertFalse(schema.validate(inputData, InputFormat.JSON, OutputFormat.BOOLEAN)); } + + @Test + void refSiblingId07AndBelow() { + String schemaData = "{\r\n" + + " \"$id\": \"http://localhost:1234/sibling_id/base/\",\r\n" + + " \"definitions\": {\r\n" + + " \"foo\": {\r\n" + + " \"$id\": \"http://localhost:1234/sibling_id/foo.json\",\r\n" + + " \"type\": \"string\"\r\n" + + " },\r\n" + + " \"base_foo\": {\r\n" + + " \"$comment\": \"this canonical uri is http://localhost:1234/sibling_id/base/foo.json\",\r\n" + + " \"$id\": \"foo.json\",\r\n" + + " \"type\": \"number\"\r\n" + + " }\r\n" + + " },\r\n" + + " \"allOf\": [\r\n" + + " {\r\n" + + " \"$comment\": \"$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json\",\r\n" + + " \"$id\": \"http://localhost:1234/sibling_id/\",\r\n" + + " \"$ref\": \"foo.json\"\r\n" + + " }\r\n" + + " ]\r\n" + + "}"; + SchemaRegistry factory = SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_7); + Schema schema = factory.getSchema(schemaData); + String inputData = "1"; + assertTrue(schema.validate(inputData, InputFormat.JSON, OutputFormat.BOOLEAN)); + } + + @Test + void refSiblingId201909AndAbove() { + String schemaData = "{\r\n" + + " \"$id\": \"http://localhost:1234/sibling_id/base/\",\r\n" + + " \"definitions\": {\r\n" + + " \"foo\": {\r\n" + + " \"$id\": \"http://localhost:1234/sibling_id/foo.json\",\r\n" + + " \"type\": \"string\"\r\n" + + " },\r\n" + + " \"base_foo\": {\r\n" + + " \"$comment\": \"this canonical uri is http://localhost:1234/sibling_id/base/foo.json\",\r\n" + + " \"$id\": \"foo.json\",\r\n" + + " \"type\": \"number\"\r\n" + + " }\r\n" + + " },\r\n" + + " \"allOf\": [\r\n" + + " {\r\n" + + " \"$comment\": \"$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json\",\r\n" + + " \"$id\": \"http://localhost:1234/sibling_id/\",\r\n" + + " \"$ref\": \"foo.json\"\r\n" + + " }\r\n" + + " ]\r\n" + + "}"; + SchemaRegistry factory = SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_2019_09); + Schema schema = factory.getSchema(schemaData); + String inputData = "\"a\""; + assertTrue(schema.validate(inputData, InputFormat.JSON, OutputFormat.BOOLEAN)); + } + + @Test + void refSiblingIdInner201909AndAbove() { + String schemaData = "{\r\n" + + " \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\r\n" + + " \"$id\": \"http://example.com/schema-relative-uri-defs1.json\",\r\n" + + " \"properties\": {\r\n" + + " \"foo\": {\r\n" + + " \"$id\": \"schema-relative-uri-defs2.json\",\r\n" + + " \"$defs\": {\r\n" + + " \"inner\": {\r\n" + + " \"properties\": {\r\n" + + " \"bar\": {\r\n" + + " \"type\": \"string\"\r\n" + + " }\r\n" + + " }\r\n" + + " }\r\n" + + " },\r\n" + + " \"$ref\": \"#/$defs/inner\"\r\n" + + " }\r\n" + + " },\r\n" + + " \"$ref\": \"schema-relative-uri-defs2.json\"\r\n" + + "}"; + SchemaRegistry factory = SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_2019_09); + Schema schema = factory.getSchema(schemaData); + String inputData = "{\r\n" + + " \"foo\": {\r\n" + + " \"bar\": \"a\"\r\n" + + " },\r\n" + + " \"bar\": \"a\"\r\n" + + "}"; + assertTrue(schema.validate(inputData, InputFormat.JSON, OutputFormat.BOOLEAN)); + } }