pboettch / json-schema-validator

JSON schema validator for JSON for Modern C++
Other
470 stars 135 forks source link

Using "$ref" with "default" over files results in unresolved or freed schema-reference error #209

Closed DonKult closed 1 year ago

DonKult commented 1 year ago

Hi,

With the schema files:

{
        "$schema": "http://json-schema.org/draft-07/schema#",
        "$id": "https://example.invalid/entities.schema.json",
        "title": "Entities",
        "type": "array",
        "items": {
                "type": "object",
                "required": [ "name" ],
                "properties": {
                        "name": {
                                "type": "string"
                        },
                        "fg": { "$ref": "/types/color.schema.json", "default": "Black" }
                }
        }
}
{
        "$schema": "http://json-schema.org/draft-07/schema#",
        "$id": "https://example.invalid/types/color.schema.json",
        "title": "color",
        "description": "X11/HTML/CSS color name as a JSON string",
        "type": "string",
        "enum": [ "White", "Black", "Red" ]
}

and the document entities.json:

[
        {
                "name": "player",
                "fg": "White"
        },
        {
                "name": "enemy",
                "fg": "Red"
        }
]

The call json-schema-validate entities.schema.json < entities.json results in

ERROR: '"/0/fg"' - '"White"': unresolved or freed schema-reference https://example.invalid/types/color.schema.json #
ERROR: '"/1/fg"' - '"Red"': unresolved or freed schema-reference https://example.invalid/types/color.schema.json #
schema validation failed

while it used to be a valid document before. Yes, it technically wasn't as I was defining a default, but I was hoping json-schema-validate would eventually support it. Now it does claim to support it but the schema_ref codepath in schema::make seems bugged as I am back to a working and valid document if I comment out these two lines. I am not quite sure how this could be fixed for real though.

(The example files do not make a lot of sense, granted, I tried to strip my setup down as much as possible)

pboettch commented 1 year ago

What you are saying is that before, it worked but the default keyword was ignored (due to standard). Now the default-keyword is used and it fails?

pboettch commented 1 year ago

The problem is, when there is a default-value in a $ref-schema we copy the referenced-schema. Later all the reference are resolved, but not the ones which have been copied.

pboettch commented 1 year ago

I fixed this behavior as it was relatively easy to understand and fix. Please feel free to test more.