Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Escape JSON pointer tokens #122

Merged
merged 1 commit into from
Dec 8, 2022
Merged

Conversation

davishmcclurg
Copy link
Owner

When building data_pointer and schema_pointer in error objects.

JSON Pointer RFC:

Because the characters '~' (%x7E) and '/' (%x2F) have special
meanings in JSON Pointer, '~' needs to be encoded as '~0' and '/'
needs to be encoded as '~1' when these characters appear in a
reference token.

Fixes: #121

When building `data_pointer` and `schema_pointer` in error objects.

[JSON Pointer RFC][0]:

```
Because the characters '~' (%x7E) and '/' (%x2F) have special
meanings in JSON Pointer, '~' needs to be encoded as '~0' and '/'
needs to be encoded as '~1' when these characters appear in a
reference token.
```

Fixes: #121

[0]: https://www.rfc-editor.org/rfc/rfc6901#section-3
@davishmcclurg davishmcclurg merged commit 0541704 into master Dec 8, 2022
@davishmcclurg davishmcclurg deleted the escape-json-pointer-tokens branch December 8, 2022 00:51
@eraffel-MDSol
Copy link

@davishmcclurg This breaks when the token is not a string, for example a boolean

@davishmcclurg
Copy link
Owner Author

@eraffel-MDSol do you mind providing an example that I can test with?

@eraffel-MDSol
Copy link

Ok, correction, the issue is when the key is a boolean.
example: { true => 'asdf' }

I guess my question is this, since the library is accepting a hash, should it do the conversion from true to 'true', or should the caller be responsible for that.

Regardless, I would assume you don't want to throw an exception, so there should be a check that the key is a string, right?

@eraffel-MDSol
Copy link

@davishmcclurg Any thoughts on the above?

@davishmcclurg
Copy link
Owner Author

For reference:

>> schema = { 'type' => 'object' }
=> {"type"=>"object"}
>> data = { true => 'value' }
=> {true=>"value"}
>> JSONSchemer.schema(schema).valid?(data)
/Users/dharsha/repos/json_schemer/lib/json_schemer/schema/base.rb:625:in `escape_json_pointer_token': undefined method `gsub' for true:TrueClass (NoMethodError)

        token.gsub(JSON_POINTER_TOKEN_ESCAPE_REGEXP, JSON_POINTER_TOKEN_ESCAPE_CHARS)
             ^^^^^
        from /Users/dharsha/repos/json_schemer/lib/json_schemer/schema/base.rb:552:in `block in validate_object'

I guess my question is this, since the library is accepting a hash, should it do the conversion from true to 'true', or should the caller be responsible for that.

Hmm, good question. I think ideally the caller should be responsible for that since this library assumes data is valid JSON (ie, string keys). For example, versions prior to this change have a similar problem with patternProperties:

>> schema = { 'patternProperties' => { '.+' => { 'type' => 'string' } } }
=> {"patternProperties"=>{".+"=>{"type"=>"string"}}}
>> data = { true => 'value' }
=> {true=>"value"}
>> JSONSchemer.schema(schema).valid?(data)
/Users/dharsha/repos/json_schemer/lib/json_schemer/schema/base.rb:583:in `match?': no implicit conversion of true into String (TypeError)
	from /Users/dharsha/repos/json_schemer/lib/json_schemer/schema/base.rb:583:in `block (2 levels) in validate_object'

There's also the issue of referencing non-string keys in schemas. JSON schemas don't allow non-string properties (because JSON itself doesn't), so if we implicitly to_s keys they can't be referenced or validated. For example, how would these keys be differentiated?

data = {
  true => 'value',
  'true' => 'value'
}

A valid JSON schema can only target the string version.

That said, this is a change in behavior and calling to_s in escape_json_pointer_token would be more like the previous behavior. I opened an issue for more discussion, but for now I think I'm going to leave this as it is. Let me know in that issue if you have additional thoughts/concerns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JSON pointers: "/" and "~" are not escaped
2 participants