xeipuuv / gojsonschema

An implementation of JSON Schema, draft v4 v6 & v7 - Go language
2.57k stars 358 forks source link

When using RawLoader, int with exclusiveMinimum 0 validates with 0 value #341

Open Helyk opened 3 years ago

Helyk commented 3 years ago

Hello. Here is an example code to confirm the issue:

package main

import (
    "fmt"

    "github.com/xeipuuv/gojsonschema"
)

var schema = `{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "a": {"type": "integer", "exclusiveMinimum": 0}
    }
}`

var doc = struct {
    A int
}{
    A: 0,
}

func main() {
    schemaLoader := gojsonschema.NewBytesLoader([]byte(schema))
    documentLoader := gojsonschema.NewRawLoader(doc) // <- note RawLoader here

    result, err := gojsonschema.Validate(schemaLoader, documentLoader)
    if err != nil {
        panic(err.Error())
    }

    if result.Valid() {
        fmt.Printf("The document is valid\n")
    } else {
        fmt.Printf("The document is not valid. see errors :\n")
        for _, desc := range result.Errors() {
            fmt.Printf("- %s\n", desc)
        }
    }
}

I saved in on playground so that you can run it and see that it results in The document is valid, while value of A is zero, which is prohibited by "exclusiveMinimum": 0 so it shouldn't validate.

To compare with, ByteLoader with same data gives appropriate error.

Helyk commented 3 years ago

Uh I thought it might be due to 0 being int's zero-value and some omitempty behavior or because of A being capital but now I tried to alter those factors and it still validates no matter what.

See example:

package main

import (
    "fmt"

    "github.com/xeipuuv/gojsonschema"
)

var schema = `{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "A": {"type": "integer", "exclusiveMinimum": 1}
    },
    "required": ["A"]
}`

var doc = struct {
    B int
}{
    B: 1,
}

func main() {
    schemaLoader := gojsonschema.NewBytesLoader([]byte(schema))
    documentLoader := gojsonschema.NewRawLoader(doc)

    result, err := gojsonschema.Validate(schemaLoader, documentLoader)
    if err != nil {
        panic(err.Error())
    }

    if result.Valid() {
        fmt.Printf("The document is valid\n")
    } else {
        fmt.Printf("The document is not valid. see errors :\n")
        for _, desc := range result.Errors() {
            fmt.Printf("- %s\n", desc)
        }
    }
}

// The document is valid

I'm confused now. Why it validates? Am I doing something wrong?