davishmcclurg / json_schemer

JSON Schema validator. Supports drafts 4, 6, 7, 2019-09, 2020-12, OpenAPI 3.0, and OpenAPI 3.1.
MIT License
408 stars 64 forks source link

Uncaught parse errors during schema validation #167

Closed eapache-opslevel closed 9 months ago

eapache-opslevel commented 11 months ago

json_schemer version 2.1.1

Trying to validate the following malformed schema:

JSONSchemer.validate_schema({"$schema"=>"https://json-schema.org/draft/2020-12/schema", "type"=>"object", "properties"=>""})

Results in an exception:

/Users/eapache/.rvm/gems/ruby-3.2.2@opslevel/gems/json_schemer-2.1.1/lib/json_schemer/draft202012/vocab/applicator.rb:224:in `parse': undefined method `each_with_object' for "":String (NoMethodError)

            value.each_with_object({}) do |(property, subschema), out|
                 ^^^^^^^^^^^^^^^^^
davishmcclurg commented 10 months ago

Hi @eapache-opslevel! Thanks for opening this. You're right—it's broken when schema parsing fails. I think the solution is to not parse the schema fully (should only need $schema) when validation schemas. I need to think about it some more, though. I'm not sure about custom meta schemas.

davishmcclurg commented 9 months ago

Another example from https://github.com/davishmcclurg/json_schemer/issues/174:

>> schemer = JSONSchemer.schema({ "$id" => 1 })
>> schemer.valid_schema?
/Users/dharsha/.asdf/installs/ruby/3.3.0/lib/ruby/3.3.0/uri/rfc3986_parser.rb:177:in `convert_to_uri': bad argument (expected URI object or URI string) (ArgumentError)
    from /Users/dharsha/.asdf/installs/ruby/3.3.0/lib/ruby/3.3.0/uri/generic.rb:1110:in `merge'
    from /Users/dharsha/.asdf/installs/ruby/3.3.0/lib/ruby/3.3.0/uri/rfc3986_parser.rb:141:in `inject'
    from /Users/dharsha/.asdf/installs/ruby/3.3.0/lib/ruby/3.3.0/uri/rfc3986_parser.rb:141:in `join'
    from /Users/dharsha/.asdf/installs/ruby/3.3.0/lib/ruby/3.3.0/uri/common.rb:212:in `join'
    from /Users/dharsha/repos/json_schemer/lib/json_schemer/draft202012/vocab/core.rb:38:in `parse'
davishmcclurg commented 9 months ago

I merged a fix—it'll be released shortly in 2.2.0. Original example now returns an error:

>> JSONSchemer.validate_schema({"$schema"=>"https://json-schema.org/draft/2020-12/schema", "type"=>"object", "properties"=>""}).map { _1.fetch('error') }
=> ["value at `/properties` is not an object"]

JSONSchemer.schema still doesn't support invalid schemas (and likely won't). I don't want every schema object to have to take the hit of validating the provided schema before parsing. When working with schemas that are potentially invalid, it's best to check them with JSONSchemer.valid_schema? first.

Now that I think of it, JSONSchemer::Schema#valid_schema? and JSONSchemer::Schema#validate_schema were probably mistakes to begin with—may want to deprecate in the future.