Skip to content

Test needed to differentiate between JSON Pointer or named schema in URI fragment #449

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

Closed
wheelerlaw opened this issue Nov 20, 2020 · 4 comments

Comments

@wheelerlaw
Copy link

I have been seeing this a lot recently:

"$ref": "common.json#properties/version"

However, according to the JSON pointer spec, JSON Pointers are supposed to start with /. According to the JSON Schema spec, if the fragment isn't a JSON Pointer, it is supposed to be treated as a named schema and therefore reference something with $id set, not a path.

The proper form for a JSON pointer would be:

"$ref": "common.json#/properties/version"

(note the / after the #).

The first example would point to a named schema, however according to the spec, schema identifiers are prohibited from container the / character:

Using JSON Pointer fragments requires knowledge of the structure of
the schema. When writing schema documents with the intention to
provide re-usable schemas, it may be preferable to use a plain name
fragment that is not tied to any particular structural location.
This allows a subschema to be relocated without requiring JSON
Pointer references to be updated.

To specify such a subschema identifier, the "$id" keyword is set to a
URI reference with a plain name fragment (not a JSON Pointer
fragment). This value MUST begin with the number sign that specifies
a fragment ("#"), then a letter ([A-Za-z]), followed by any number of
letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons
(":"), or periods (".").

The effect of using a fragment in "$id" that isn't blank or doesn't
follow the plain name syntax is undefined. [[CREF3: How should an
"$id" URI reference containing a fragment with other components be
interpreted? There are two cases: when the other components match
the current base URI and when they change the base URI. ]]

Although it would seem like the last paragraph leaves a little room for interpretation.

@Julian
Copy link
Member

Julian commented Nov 20, 2020

If I both remember right and follow reading your issue, yes, the former isn't a valid schema -- you're not saying there's a test in the suite that does so, right?

You're saying we should add what, a metaschema test to ensure {"$ref": "common.json#properties/version"} is considered by an implementation to be an invalid schema?

Happy to see that if so.

@wheelerlaw
Copy link
Author

Apologies for the confusion.

You're saying we should add what, a metaschema test...

That's correct, at least based on my best understanding of all of the relevant specs that I have only just read today. Although someone more knowledgeable of the specs might want to verify that.

@ssilverman
Copy link
Member

ssilverman commented Nov 21, 2020

There’s not yet a mechanism to test for invalid schemas, since some things aren’t expressible in a meta-schema. This is one example. Specifically, a meta-schema can’t really restrict the content of some things. (See the “$data” proposal stuff.)

@karenetheridge
Copy link
Member

karenetheridge commented Nov 21, 2020

Although it would seem like the last paragraph leaves a little room for interpretation.

FWIW, that paragraph no longer exists in the latest published specification draft (https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.8.2.3).

Strictly speaking, that's not an invalid schema. The value of the $ref keyword must be a uri-reference, and common.json#properties/version is a perfectly valid URI reference and, when resolved against the current base URI, will become a perfectly valid URI. It's just that this URI can't resolve to any actual json-schema location in existence, because (as you said) the fragment portion of the URI isn't a valid json pointer nor a valid anchor.

In order to (fail to) validate this against the metaschema, we'd need to be more specific about the expectations of $ref than "uri-reference". We could potentially do this by adding a mandatory regex check -- e.g. "pattern": "(#(/.*|[A-Za-z0-9_:.-]+)?)?$"

But that's out of scope of the test suite. It would need to be done in the specification metaschema.

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

No branches or pull requests

4 participants