pboettch / json-schema-validator

JSON schema validator for JSON for Modern C++
Other
466 stars 134 forks source link

unknown_keywords not synchronized with schema structure #143

Closed DanFulger closed 3 years ago

DanFulger commented 3 years ago

The unknown_keywords variable in json-validator.cpp is created gradually, by using operator[] with JSON pointers. This fails for some schemas when:

The validator fails to load a valid schema because of this. Example:

{
    "properties": {
        "123": { 
            "examples": [ "something" ]
        },
        "abc": {
            "examples": [ "something" ]
        }
    }
}
pboettch commented 3 years ago

You can inline JSON here with ```JSON ... ```(three dots are lines actually)

pboettch commented 3 years ago

I reduced your schema to

{
    "1": {
    },
    "a": {
    }
}    
pboettch commented 3 years ago

OK, I understood what you mean with operator[] with JSON-pointers.

Basically this pure nlohmann::json-code will fail:

#include <nlohmann/json.hpp>

int main(void)
{
    nlohmann::json j;
    j["/obj/1"_json_pointer] = 1;
    j["/obj/a"_json_pointer] = 2;
    return 0;
}

Because the first json-pointer "/obj/1" makes it create obj as an array.

What does the standard say? 👀 It does not detail this ambiguity.

That means, it has to be handled manually, probably in nlohmann::json. If instance is an object, 0 is actually "0", otherwise if array, it's zero.

pboettch commented 3 years ago

I fixed it inside this library: as unknown-keywords are always objects, we can easily force it.

pboettch commented 3 years ago

And there is no issue with nlohmann::json:

#include <nlohmann/json.hpp>

#include <iostream>

int main(void)
{
    nlohmann::json j;
    j["obj"] = {10, 20, 30};

    std::cout << j << ": " << j["/obj/1"_json_pointer] << "\n";

    j["obj"] = {{"1", 20}, {"2", 30}};
    std::cout << j << ": " << j["/obj/1"_json_pointer] << "\n";

    return 0;
}
DanFulger commented 3 years ago

The original schema still fails, it's the multiple levels that require doing this parent by parent:

> ./json-install/bin/json-schema-validate issue_143.json
setting root schema failed
[json.exception.parse_error.109] parse error: array index 'abc' is not a number
pboettch commented 3 years ago

Could you try the https://github.com/pboettch/json-schema-validator/tree/fix-143 -branch whether this works for your real-world-schema?

Sorry for the inconvenience with the first incomplete fix.

DanFulger commented 3 years ago

Thank you very much, it's working now!

DanFulger commented 3 years ago

You forgot #include <deque>; gcc compiled ok, but Visual C++ needs the include.

pboettch commented 3 years ago

Thanks, I added it. Now missing only the tests.

pboettch commented 3 years ago

I forgot the merge this to master! Done now.