for-GET / jesse

jesse (JSon Schema Erlang) is an implementation of a JSON Schema validator for Erlang.
https://github.com/for-get/jesse
Apache License 2.0
126 stars 64 forks source link

Crashes when "id" is used as a key for a member of "definitions" #134

Open alexo-spb opened 1 year ago

alexo-spb commented 1 year ago

I've noticed an issue with jesse:validate/2 tag 1.7.11. It doesn't function as expected when the "definitions": {...} section contains a subschema referenced using the "id" key. Actually, I'm aware the "id" is a keyword, but there are no specifications stating that it cannot be used as part of a reference, please correct me if I'm wrong. Also, I've played with some alternative implementations, and they worked as expected using the "id" as a key.

For example, there are two schemas request.json and types.json:

{
    "$id": "http://example.net/schema/request.json",
    "$schema": "http://json-schema.org/draft-06/schema#",
    "type": "object",
    "properties": {
        "id": {
            "$ref": "types.json#/definitions/id"
        }
    }
}
{
    "$id": "http://example.net/schema/types.json",
    "$schema": "http://json-schema.org/draft-06/schema#",
    "definitions": {
        "id": {
            "type": "string"
        }
    }
}

The thing is that jesse takes the definitions object as a schema not expecting the nested "id" as a subschema key. Finally it crashes trying to build a combined schema ID out of an object, please see the stacktrace:

=== Ended at 2023-10-13 21:34:12
=== Location: [{unicode,characters_to_list,895},
              {jesse_state,parse_ref,426},
              {jesse_state,combine_id,319},
              {jesse_state,set_current_schema,193},
              {jesse_state,load_local_schema,286},
              {jesse_state,resolve_ref,248},
              {jesse_validator_draft6,resolve_ref,1230},
              {jesse_validator_draft6,validate_ref,1215}]
=== === Reason: bad argument
  in function  unicode:characters_to_list/1
     called as unicode:characters_to_list(#{<<"type">> => <<"string">>})
     *** argument 1: not valid character data (an iodata term)
  in call from jesse_state:parse_ref/1 (/Project/_build/default/lib/jesse/src/jesse_state.erl, line 426)
  in call from jesse_state:combine_id/2 (/Project/_build/default/lib/jesse/src/jesse_state.erl, line 319)
  in call from jesse_state:set_current_schema/2 (/Project/_build/default/lib/jesse/src/jesse_state.erl, line 193)
  in call from jesse_state:load_local_schema/2 (/Project/_build/default/lib/jesse/src/jesse_state.erl, line 286)
  in call from jesse_state:resolve_ref/2 (/Projects/_build/default/lib/jesse/src/jesse_state.erl, line 248)
  in call from jesse_validator_draft6:resolve_ref/2 (/Project/_build/default/lib/jesse/src/jesse_validator_draft6.erl, line 1230)
  in call from jesse_validator_draft6:validate_ref/3 (/Project/_build/default/lib/jesse/src/jesse_validator_draft6.erl, line 1215)