From 2221b7f6d4ca703f613349ce044a24fd64391675 Mon Sep 17 00:00:00 2001 From: Roger Peppe Date: Tue, 24 Sep 2024 11:10:27 +0100 Subject: [PATCH] encoding/jsonschema: ignore empty fragment when comparing schema versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a very common error for the presence or absence of an empty fragment in schema version URI not to match the presence or absence of the empty fragment in the canonical version URI, particularly as earlier versions included that empty fragment but later versions do not. From a technical point of view, a URI with an empty fragment _should_ be considered identical to a URI with no fragment (as witness Go's `net/url` package which always omits an empty fragment). The specification says [1] of `$schema`: > The value of this keyword MUST be a URI (containing a scheme) and this > URI MUST be normalized. The current schema MUST be valid against the > meta-schema identified by this URI. I think it can reasonably be argued that a URI with a mismatching empty fragment "identifies" the same URL its counterpart. So compare versions while ignoring a trailing empty fragment. [1]: https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-00#rfc.section.8.1.1 Signed-off-by: Roger Peppe Change-Id: I28c6e767f7be7a2832b42124ffe5f0ec37f83635 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1201677 Reviewed-by: Daniel Martí TryBot-Result: CUEcueckoo Unity-Result: CUE porcuepine --- .../jsonschema/testdata/txtar/extrafragment_version.txtar | 6 +++--- .../testdata/txtar/missingfragment_version.txtar | 6 +++--- encoding/jsonschema/version.go | 8 +++++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/encoding/jsonschema/testdata/txtar/extrafragment_version.txtar b/encoding/jsonschema/testdata/txtar/extrafragment_version.txtar index 56ac298a7d9..c7b3ee267e9 100644 --- a/encoding/jsonschema/testdata/txtar/extrafragment_version.txtar +++ b/encoding/jsonschema/testdata/txtar/extrafragment_version.txtar @@ -7,6 +7,6 @@ "type": "string" } -- out/decode/extract -- -ERROR: -invalid $schema URL "https://json-schema.org/draft/2019-09/schema#": $schema URI not recognized: - schema.json:2:3 +@jsonschema(schema="https://json-schema.org/draft/2019-09/schema") +@jsonschema(id="http://example.test") +string diff --git a/encoding/jsonschema/testdata/txtar/missingfragment_version.txtar b/encoding/jsonschema/testdata/txtar/missingfragment_version.txtar index ade280e5b54..6dac793559c 100644 --- a/encoding/jsonschema/testdata/txtar/missingfragment_version.txtar +++ b/encoding/jsonschema/testdata/txtar/missingfragment_version.txtar @@ -7,6 +7,6 @@ "type": "string" } -- out/decode/extract -- -ERROR: -invalid $schema URL "http://json-schema.org/draft-04/schema": $schema URI not recognized: - schema.json:2:3 +@jsonschema(schema="http://json-schema.org/draft-04/schema#") +@jsonschema(id="http://example.test") +string diff --git a/encoding/jsonschema/version.go b/encoding/jsonschema/version.go index 94e9fb2fda2..d6dc7672087 100644 --- a/encoding/jsonschema/version.go +++ b/encoding/jsonschema/version.go @@ -16,6 +16,7 @@ package jsonschema import ( "fmt" + "strings" ) //go:generate go run golang.org/x/tools/cmd/stringer -type=Version -linecomment @@ -74,10 +75,15 @@ func vto(v Version) versionSet { // ParseVersion parses a version URI that defines a JSON Schema version. func ParseVersion(sv string) (Version, error) { + // Ignore a trailing empty fragment: it's a common error + // to omit or supply such a fragment and it's not entirely + // clear whether comparison should or should not + // be sensitive to its presence or absence. + sv = strings.TrimSuffix(sv, "#") // If this linear search is ever a performance issue, we could // build a map, but it doesn't seem worthwhile for now. for i := Version(1); i < numJSONSchemaVersions; i++ { - if sv == i.String() { + if sv == strings.TrimSuffix(i.String(), "#") { return i, nil } }