santhosh-tekuri/jsonschema

Panic on nil pointer dereference when compiling schema in v6

Closed this issue · 3 comments

This currently works with v5, but tries to dereference a nil pointer in v6, panicking on the call to compiler.Compile:

package main

import (
	_ "embed"
	"log"
	"strings"

	"github.com/santhosh-tekuri/jsonschema/v6"
)

const schemaID = "schema.json"

//go:embed schema.json
var schema string

func main() {
	compiler := jsonschema.NewCompiler()
	if err := compiler.AddResource(schemaID, strings.NewReader(schema)); err != nil {
		panic(err)
	}
	if _, err := compiler.Compile(schemaID); err != nil {
		log.Fatal(err)
	}
}
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "http://example.com/schema.json",
  "type": "object",
  "additionalProperties": false,
  "required": ["id"],
  "properties": {
    "name": {
      "type": "string"
    }
  }
}

This schema is just a basic example of what triggers the segfault, but it's still valid according to:

$ jv schema.json && echo $?
0
$ check-jsonschema --check-metaschema schema.json
ok -- validation done

The segfault panic looks like:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x20 pc=0x102cfc058]

goroutine 1 [running]:
github.com/santhosh-tekuri/jsonschema/v6.(*roots).validate(0x140002ea2c0, 0x140002d5f20, {0x102d84d60, 0x14000257be0}, {0x0, 0x0})
        /home/davidjb/.go/pkg/mod/github.com/santhosh-tekuri/jsonschema/v6@v6.0.1/roots.go:241 +0x98
github.com/santhosh-tekuri/jsonschema/v6.(*roots).addRoot(0x140002ea2c0, {0x140002e2980, 0x37}, {0x102d84d60?, 0x14000257be0})
        /home/davidjb/.go/pkg/mod/github.com/santhosh-tekuri/jsonschema/v6@v6.0.1/roots.go:53 +0x1b0
github.com/santhosh-tekuri/jsonschema/v6.(*roots).orLoad(0x140002ea2c0, {0x140002e2980, 0x37})
        /home/davidjb/.go/pkg/mod/github.com/santhosh-tekuri/jsonschema/v6@v6.0.1/roots.go:38 +0x8c
github.com/santhosh-tekuri/jsonschema/v6.(*roots).resolveFragment(0x102d1115a?, {{0x140002e2980?, 0x140002e2900?}, {0x0?, 0x140002ea2c0?}})
        /home/davidjb/.go/pkg/mod/github.com/santhosh-tekuri/jsonschema/v6@v6.0.1/roots.go:63 +0x2c
github.com/santhosh-tekuri/jsonschema/v6.(*Compiler).Compile(0x140002d5e30, {0x102d1115a?, 0x14000022120?})
        /home/davidjb/.go/pkg/mod/github.com/santhosh-tekuri/jsonschema/v6@v6.0.1/compiler.go:183 +0x50
main.main()
        /home/davidjb/schemas/main.go:21 +0x2a4
exit status 2

In the inner-most call to https://github.com/santhosh-tekuri/jsonschema/blob/boon/roots.go#L241, the call to r.resource(ptr).dialect is being called with a ptr value of "" (empty string) which results in a nil being returned from https://github.com/santhosh-tekuri/jsonschema/blob/boon/root.go#L20. In this function, the r.resources map is empty, resulting in that code falling through to r.rootResource() which returns nil, which is eventually returned and attempted to be dereferenced with .dialect.

In the example above, if I swap /v6 to back to /v5 it works fine.

Also, may I ask what breaking changes are present within v6? I've looked over the notes at https://github.com/santhosh-tekuri/jsonschema/releases but these aren't very specific.

second argument to compiler.addResource api is changed fromv5 to v6

in v5 it is r io.CloseReader where as in v6 it is doc any

in v6, you have to add parsed json as resource.

so you have to change:

	if err := compiler.AddResource(schemaID, strings.NewReader(schema)); err != nil {
		panic(err)
	}

to

        doc, err := jsonschema.UnmarshalJSON(strings.NewReader(schema))
        if err != nil {
            panic(err)
        }
	if err := compiler.AddResource(schemaID, doc); err != nil {
		panic(err)
	}

BTW it should not panic instead it should return an error; this is fixed with 86cca28

recording breaking changes, you can look at #172
but this may not be complete list