voxpupuli / json-schema

Ruby JSON Schema Validator
MIT License
1.52k stars 242 forks source link

$ref paths relative to working directory don't work if containing schema was itself referenced #411

Open reitzig opened 6 years ago

reitzig commented 6 years ago

Consider the following folder structure with files as given in this Gist:

.
├── example.json
├── schemas
│   ├── more
│   │   ├── schemaB.json
│   │   └── schemaC.json
│   └── stuff
│       └── schemaA.json
└── validate.rb

Expected: Running validate.rb prints 0.

Actual:

Traceback (most recent call last):
    25: from ./validate.rb:8:in `<main>'
    <snip>
/home/user/.gem/ruby/2.5.0/gems/json-schema-2.8.0/lib/json-schema/schema/reader.rb:136:in `rescue in read_file': 
    Read of file at /<snip>/schematest/schemas/more/schemas/more/schemaC.json failed (JSON::Schema::ReadFailed)

Clearly, the path is assembled incorrectly:

This is inconsistent.

Is there a workaround? Changing the $ref paths is not an option if schemas are referenced at different depths.

reitzig commented 6 years ago

I traced the problem down to Addressable::URI.join being called on a UUID for references in the top-level schema, but on a real path (that of the top-level schema) for low levels. cf. JSON::Util::URI.absolutize_ref

Then, the dir-part absolute path of the top-level schema and the relative path to the schema are joined together without considering the overlap.

Not sure what the correct fix here is.

reitzig commented 6 years ago

Workaround: Call validate with the filename of the top-level schema instead of its content.

Then, all URIs are treated in the same way (Option 1).