Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Since 1.3.0: $id seems to accept anything #936

Closed
itineric opened this issue Jan 29, 2024 · 5 comments · Fixed by #942
Closed

Since 1.3.0: $id seems to accept anything #936

itineric opened this issue Jan 29, 2024 · 5 comments · Fixed by #942

Comments

@itineric
Copy link

When passing a schema with an invalid $id, the parsing works since 1.3.0. Previously we were getting a JsonSchemaException.

The following schema does not contain a valid $id

{
  "$id": "0",
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}

according to: https://json-schema.org/draft/2019-09/json-schema-core#rfc.section.8.2.2

But since 1.3.0 no error is reported.

@justin-tay
Copy link
Contributor

I will look into this. But by itself, "0" may be a valid iri reference if it can resolve to an absolute iri given a base iri.

I was hoping to avoid strictly validating $id because in particular the older drafts were more lax with what it could contain.

@itineric
Copy link
Author

We just tried migration from 1.2.0 to 1.3.0 and tests were broken.
Maybe you can keep previous behaviour for ascending compatibility and run your new code on a configuration basis?

@justin-tay
Copy link
Contributor

The specification uses the term SHOULD NOT instead of MUST NOT and attempting to perform the validation by ensuring that the $id can resolve to an absolute IRI causes one of the tests in the JSON Schema Test Suite to fail. This particular test seems to have been introduced fairly recently.

What I will likely do is introduce a configurable JsonSchemaIdValidator into the SchemaValidatorsConfig and retain the current lax validation as default. I will likely also write a strict implementation of the validator that can be used.

@justin-tay
Copy link
Contributor

I have looked at the previous behavior and it looks like it is a semi strict about the $id value. If you loaded your schema from a classpath resource using a URI it doesn't throw in the previous version either. Loading it without a base URI causes it to throw in the previous version. I will try to replicate this previous behavior and set it as the default validator.

@justin-tay
Copy link
Contributor

This will be fixed in the next version in the following manner

  • Adding a JsonSchemaIdValidator interface
  • Adding a DefaultJsonSchemaIdValidator implementation that implements the previous logic
  • The DefaultJsonSchemaIdValidator will be configured as default

This will make the behavior the same as 1.2.0.

That said if you really need the $id to be valid according to the spec, you would need to write your own implementation.

According to the spec

"$id" MUST NOT contain a non-empty fragment, and SHOULD NOT contain an empty fragment

The previous logic since 1.0.33 accepts non-empty fragment ids with the isUriFragmentWithNoContext check.

private URI combineCurrentUriWithIds(URI currentUri, JsonNode schemaNode) {
final String id = validationContext.resolveSchemaId(schemaNode);
if (id == null) {
return currentUri;
} else if (isUriFragmentWithNoContext(currentUri, id)) {
return null;
} else {
try {
return this.validationContext.getURIFactory().create(currentUri, id);
} catch (IllegalArgumentException e) {
throw new JsonSchemaException(ValidationMessage.of(ValidatorTypeCode.ID.getValue(), ValidatorTypeCode.ID, id, currentUri.toString()));
}
}
}

The following schema does not throw in 1.2.0 and before.

{
  "$id": "#0",
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants