-
-
Notifications
You must be signed in to change notification settings - Fork 280
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
$schema introduces specification-level circular dependency #1521
Comments
This isn't a concern. Meta-schema validation isn't required when processing a schema, so most of the time it's skipped. This also means that when validating a schema against its meta-schema, you're not also validating the meta-schema against itself. |
i see, so an implementation should just assume that the meta-schema is a valid json schema? |
Generally, yes. When validating a schema, the schema takes the role of the instance, and the meta-schema takes the role of the schema. But that doesn't mean that the implementation has to then validate the meta-schema's meta-schema. Typcially it won't. |
I totally get that part, but that priced in, how can you validate a schema that is its own meta-schema ($schema === $id), e.g. https://json-schema.org/draft/2020-12/schema it does not make sense! |
Okay, so let's take an example. Suppose you (the user) have this instance: {
"foo": "bar"
} And you want to validate it against the schema: {
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.json-schema.org/foobar-object",
"type": "object",
"properties": {
"foo": { "const": "bar" }
}
} To validate that instance using that schema, I (the implementation) check the IMPORTANTLY, I don't need to actually validate that the schema is a Draft 7 schema. I just interpret it that way. An error may occur if a keyword has an incompatible value. If you tell me that I definitely should validate the schema, then I temporarily change modes and validate your schema as an instance against the meta-schema as a schema. When I do this, I see that the draft 7 meta-schema ( If that passes, then I continue as before, evaluating your original instance against your original schema. The meta-schema evaluation never goes into a loop because being configured to validate a schema against its meta-schema doesn't mean that I also need to validate the meta-schema against its meta-schema. Now, let's assume that I don't know what Draft 7 is, which means I don't recognize |
this use-case! the problem i insist on here: the specification doesn't require you "to know" the SCHEMA's META-SCHEMA, i can, on the fly, grab the META-SCHEMA uri, fetch it, and interpret it dynamically (i.e. interpreting $vocabulary etc), so i can proceed with interpreting the keywords in the SCHEMA. my worry, is that there is an implicit requirement for the meta-schema to be a VALID json schema, and this requirement cannot be verified, and can only based on trusting the meta-schema author! |
No, the spec explicitly warns implementations not fetch any reference. However, many implementations still do, and ideally such functionality is disabled by default. Even if you were to use a custom meta-schema, eventually that meta-schema's For example, if you have {
"$schema": "https://some-cust.om/meta-schema",
"$id": "https://example.json-schema.org/foobar-object",
"type": "object",
"properties": {
"foo": { "const": "bar" }
}
} and {
"$schema": "https://some-cust.om/meta-schema",
"$id": "https://some-cust.om/meta-schema",
// ...
} The implementation should error saying it can't process the schema. Ideally it would catch the circular meta-schema reference (implementations MUST catch circular references through What you need to do in your custom meta-schema is eventually point back to one of the known meta-schemas: {
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://some-cust.om/meta-schema",
// ...
} This way, the implementation knows how to ultimately process your schema. |
i understand that uri doesn't need to be fetchable, but you gotta get the referenced schemas from somewhere (let's say a cache that maps URIs to schemas :) )
that would be how i'd go about it currently too, i.e. marking [TRUSTINGLY] known schemas as inherently valid, so that we can halt the validation. but this trused valid schemas concept is very implicit, adding to that, in the broader applicability of the specification, a custom meta-schema DOESN'T NECESSARILY point back to one of the known meta-schemas, and there is no concept of a "known meta-schema". the closest concept to this is the core vocabulary, anything else can be different.
|
Walk me through how a custom meta-schema pointing to itself would work? How do I know how to process, for example, The meta-schemas must eventually point back to the version of JSON Schema you're using so that the tooling knows how to process the schema.
There is. Validation Section 5 identifies the top-level meta-schema. (I'd expect it to be in Core, but it doesn't appear to be.) This meta-schema identifies that draft 2020-12 rules are to be used, especially for tools that don't support If I don't personally recommend this, though, since vocabs aren't universally supported (their support is quite rare actually). In fact, we're extracting vocabularies as a concept to a proposal because they're not fully defined. |
i can just reuse the core vocabulary with the same $ref keyword specification (ignoring/processing sibling keywords).
that is just a provided schema for convenience, as the specification states:
this is good, but there is no such thing as "supporting a dialect", please bear with me, a "dialect" is just another json schema, and the specification applies to it just like any other schema.
|
A dialect is not a schema - it typically corresponds to a meta-schema, but a dialect is more a definition of how a schema (including a meta-schema) behaves. You quote "this meta-schema describes a dialect..." - in my opinion a clearer wording would be "this meta-schema describes schemas defined by a dialect..." In 2020-12 a dialect is, roughly, the sum of a number of vocabularies (which are also definitions of behaviors, with corresponding schemas), and there may be many dialects. Up to draft 7 (though the word 'dialect' wasn't used, applying the same concept) the dialect was what the specification defined, with one dialect per draft. So "supporting a dialect" is a thing, and if an implementation doesn't support the dialect that corresponds to a given meta-schema, it doesn't make sense for it to process schemas described by that meta-schema, defined by that dialect - it should error on encountering a Given that an implementation must support a dialect, it should be able to use the rules of that dialect to validate schemas defined by that dialect, including the meta-schema that describes those schemas and itself.
You can dynamically construct a dialect from a meta-schema's |
@mathematikoi I think Core 9.1.3 might hold the answers you're looking for: meta-schema evaluation is a special operation and not standard validation. |
case: a schema where $id equals $schema
the fact that a schema MUST be valid according to its meta-schema, goes on forever! especially if a "validation session" considers a schema and its meta-schema with no further context.
should this be a legitimate concern for implementations looking to be FULLY compliant with the spec?
The text was updated successfully, but these errors were encountered: