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
124 stars 64 forks source link

inconsistent behavior with atoms as labels in schema and JSON #125

Closed RoadRunnr closed 3 months ago

RoadRunnr commented 1 year ago

jsx can parse labels to atoms and also serialize atoms in labels as strings. When using this for the schemas and/or the JSON, the validation results are inconsistent and in many cases plain wrong.

When using atom labels in the schema, validations seems be to totally broken. In this sample, schema validation should return invalid types for a, b, and c, but it doesn't. There is no difference in whether the labels in the JSON are atoms or binary.

2> Schema = jsx:decode(<<"{\"properties\": {\"a\": {\"type\": \"integer\"}, \"b\": {\"type\": \"string\"}, \"c\": {\"type\": \"boolean\"}}, \"additionalProperties\": false}">>, [{labels, atom}]). 
#{additionalProperties => false,
  properties =>
      #{a => #{type => <<"integer">>},
        b => #{type => <<"string">>},
        c => #{type => <<"boolean">>}}}
3> jesse:validate_with_schema(Schema, #{a => true, b => 2, c => 3}, [{allowed_errors, infinity}]).                                                                                                  
{ok,#{a => true,b => 2,c => 3}}
4> jesse:validate_with_schema(Schema, #{a => true, b => 2, <<"c">> => 3}, [{allowed_errors, infinity}]).
{ok,#{a => true,b => 2,<<"c">> => 3}}

When using binaries as labels in the schema and atom in the JSON, validation results are "strange":

1> Schema = jsx:decode(<<"{\"properties\": {\"a\": {\"type\": \"integer\"}, \"b\": {\"type\": \"string\"}, \"c\": {\"type\": \"boolean\"}}, \"additionalProperties\": false}">>). 
#{<<"additionalProperties">> => false,
  <<"properties">> =>
      #{<<"a">> => #{<<"type">> => <<"integer">>},
        <<"b">> => #{<<"type">> => <<"string">>},
        <<"c">> => #{<<"type">> => <<"boolean">>}}}
2> jesse:validate_with_schema(Schema, #{a => true, b => 2, c => 3}, [{allowed_errors, infinity}]).                                                                                
{error,[{data_invalid,#{<<"additionalProperties">> => false,
                        <<"properties">> =>
                            #{<<"a">> => #{<<"type">> => <<"integer">>},
                              <<"b">> => #{<<"type">> => <<"string">>},
                              <<"c">> => #{<<"type">> => <<"boolean">>}}},
                      no_extra_properties_allowed,
                      #{a => true,b => 2,c => 3},
                      [a]},
        {data_invalid,#{<<"additionalProperties">> => false,
                        <<"properties">> =>
                            #{<<"a">> => #{<<"type">> => <<"integer">>},
                              <<"b">> => #{<<"type">> => <<"string">>},
                              <<"c">> => #{<<"type">> => <<"boolean">>}}},
                      no_extra_properties_allowed,
                      #{a => true,b => 2,c => 3},
                      [b]},
        {data_invalid,#{<<"additionalProperties">> => false,
                        <<"properties">> =>
                            #{<<"a">> => #{<<"type">> => <<"integer">>},
                              <<"b">> => #{<<"type">> => <<"string">>},
                              <<"c">> => #{<<"type">> => <<"boolean">>}}},
                      no_extra_properties_allowed,
                      #{a => true,b => 2,c => 3},
                      [c]},
        {data_invalid,#{<<"type">> => <<"integer">>},
                      wrong_type,true,
                      [<<"a">>]},
        {data_invalid,#{<<"type">> => <<"string">>},
                      wrong_type,2,
                      [<<"b">>]},
        {data_invalid,#{<<"type">> => <<"boolean">>},
                      wrong_type,3,
                      [<<"c">>]}]}

It does pick up the wrong data types for a, b and c, but it also reports all the fields with an no_extra_properties_allowed error.

andreineculau commented 3 months ago

Thank you for reporting this @RoadRunnr . Fix/PR by @albertored merged.

Landed in 1.7.14