Skip to content

Commit

Permalink
Switch jsonschema validation libraries
Browse files Browse the repository at this point in the history
Signed-off-by: Brandon Mitchell <git@bmitch.net>
  • Loading branch information
sudo-bmitch committed May 26, 2024
1 parent dd33f72 commit 4bbdd7f
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 275 deletions.
10 changes: 1 addition & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,5 @@ go 1.18
require (
github.com/opencontainers/go-digest v1.0.0
github.com/russross/blackfriday v1.6.0
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415
github.com/xeipuuv/gojsonschema v1.2.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/stretchr/testify v1.7.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
)
21 changes: 2 additions & 19 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
2 changes: 1 addition & 1 deletion schema/defs-descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"mediaType": {
"id": "https://opencontainers.org/schema/image/descriptor/mediaType",
"type": "string",
"pattern": "^[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}$"
"pattern": "^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}$"
},
"digest": {
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",
Expand Down
4 changes: 4 additions & 0 deletions schema/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (

// A SyntaxError is a description of a JSON syntax error
// including line, column and offset in the JSON file.
//
// Deprecated: SyntaxError is no longer returned from Validator.
type SyntaxError struct {
msg string
Line, Col int
Expand All @@ -34,6 +36,8 @@ func (e *SyntaxError) Error() string { return e.msg }
// WrapSyntaxError checks whether the given error is a *json.SyntaxError
// and converts it into a *schema.SyntaxError containing line/col information using the given reader.
// If the given error is not a *json.SyntaxError it is returned unchanged.
//
// Deprecated: WrapSyntaxError is no longer returned by Validator.
func WrapSyntaxError(r io.Reader, err error) error {
var serr *json.SyntaxError
if errors.As(err, &serr) {
Expand Down
125 changes: 0 additions & 125 deletions schema/loader.go

This file was deleted.

84 changes: 45 additions & 39 deletions schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,56 +23,62 @@ import (

// Media types for the OCI image formats
const (
ValidatorMediaTypeDescriptor Validator = v1.MediaTypeDescriptor
ValidatorMediaTypeLayoutHeader Validator = v1.MediaTypeLayoutHeader
ValidatorMediaTypeManifest Validator = v1.MediaTypeImageManifest
ValidatorMediaTypeImageIndex Validator = v1.MediaTypeImageIndex
ValidatorMediaTypeImageConfig Validator = v1.MediaTypeImageConfig
ValidatorMediaTypeImageLayer unimplemented = v1.MediaTypeImageLayer
ValidatorMediaTypeDescriptor Validator = v1.MediaTypeDescriptor
ValidatorMediaTypeLayoutHeader Validator = v1.MediaTypeLayoutHeader
ValidatorMediaTypeManifest Validator = v1.MediaTypeImageManifest
ValidatorMediaTypeImageIndex Validator = v1.MediaTypeImageIndex
ValidatorMediaTypeImageConfig Validator = v1.MediaTypeImageConfig
ValidatorMediaTypeImageLayer Validator = v1.MediaTypeImageLayer
)

var (
// fs stores the embedded http.FileSystem
// having the OCI JSON schema files in root "/".
// specFS stores the embedded http.FileSystem having the OCI JSON schema files in root "/".
//go:embed *.json
fs embed.FS
specFS embed.FS

// schemaNamespaces is a set of URI prefixes which are treated as containing the schema files of fs.
// This is necessary because *.json schema files in this directory use "id" and "$ref" attributes which evaluate to such URIs, e.g.
// ./image-manifest-schema.json URI contains
// "id": "https://opencontainers.org/schema/image/manifest",
// and
// "$ref": "content-descriptor.json"
// which evaluates as a link to https://opencontainers.org/schema/image/content-descriptor.json .
//
// To support such links without accessing the network (and trying to load content which is not hosted at these URIs),
// fsLoaderFactory accepts any URI starting with one of the schemaNamespaces below,
// and uses _escFS to load them from the root of its in-memory filesystem tree.
//
// (Note that this must contain subdirectories before its parent directories for fsLoaderFactory.refContents to work.)
schemaNamespaces = []string{
"https://opencontainers.org/schema/image/descriptor/",
"https://opencontainers.org/schema/image/index/",
"https://opencontainers.org/schema/image/manifest/",
"https://opencontainers.org/schema/image/",
"https://opencontainers.org/schema/descriptor/",
"https://opencontainers.org/schema/",
// specsOrig maps OCI schema media types to schema files.
specs = map[Validator]string{
ValidatorMediaTypeDescriptor: "content-descriptor.json",
ValidatorMediaTypeLayoutHeader: "image-layout-schema.json",
ValidatorMediaTypeManifest: "image-manifest-schema.json",
ValidatorMediaTypeImageIndex: "image-index-schema.json",
ValidatorMediaTypeImageConfig: "config-schema.json",
}

// specs maps OCI schema media types to schema URIs.
// These URIs are expected to be used only by fsLoaderFactory (which trims schemaNamespaces defined above)
// and should never cause a network access.
specs = map[Validator]string{
ValidatorMediaTypeDescriptor: "https://opencontainers.org/schema/content-descriptor.json",
ValidatorMediaTypeLayoutHeader: "https://opencontainers.org/schema/image/image-layout-schema.json",
ValidatorMediaTypeManifest: "https://opencontainers.org/schema/image/image-manifest-schema.json",
ValidatorMediaTypeImageIndex: "https://opencontainers.org/schema/image/image-index-schema.json",
ValidatorMediaTypeImageConfig: "https://opencontainers.org/schema/image/config-schema.json",
// specURLs lists the various URLs a given spec may be known by.
// This is generated from the "id" value in each spec and relative ref values they contain.
specURLs = map[string][]string{
"config-schema.json": {
"https://opencontainers.org/schema/image/config",
},
"content-descriptor.json": {
"https://opencontainers.org/schema/descriptor",
"https://opencontainers.org/schema/image/content-descriptor.json",
},
"defs-descriptor.json": {
"https://opencontainers.org/schema/image/descriptor/mediaType",
"https://opencontainers.org/schema/defs-descriptor.json",
"https://opencontainers.org/schema/image/defs-descriptor.json",
},
"defs.json": {
"https://opencontainers.org/schema/defs.json",
"https://opencontainers.org/schema/image/defs.json",
"https://opencontainers.org/schema/image/descriptor/defs.json",
},
"image-index-schema.json": {
"https://opencontainers.org/schema/image/index",
},
"image-layout-schema.json": {
"https://opencontainers.org/schema/image/layout",
},
"image-manifest-schema.json": {
"https://opencontainers.org/schema/image/manifest",
},
}
)

// FileSystem returns an in-memory filesystem including the schema files.
// The schema files are located at the root directory.
func FileSystem() http.FileSystem {
return http.FS(fs)
return http.FS(specFS)
}
18 changes: 1 addition & 17 deletions schema/spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,27 +106,11 @@ func validate(t *testing.T, name string) {
err = schema.Validator(example.Mediatype).Validate(strings.NewReader(example.Body))
if err == nil {
printFields(t, "ok", example.Mediatype, example.Title)
t.Log(example.Body, "---")
continue
}

var errs []error
var verr schema.ValidationError
if errors.As(err, &verr) {
errs = verr.Errs
} else {
printFields(t, "error", example.Mediatype, example.Title, err)
t.Error(err)
t.Log(example.Body, "---")
continue
}

for _, err := range errs {
printFields(t, "invalid", example.Mediatype, example.Title)
t.Error(err)
fmt.Println(example.Body, "---")
continue
}
t.Log(example.Body, "---")
}
}

Expand Down
Loading

0 comments on commit 4bbdd7f

Please sign in to comment.