Skip to content

Commit

Permalink
Fix refs with relative paths pointing outside current dir
Browse files Browse the repository at this point in the history
This fixes resolving refs like '../a/b.json'.
The main issue here was that `URI.join(base_uri, other)` (called inside json_schemer) needs a path ending with a slash otherwise it does not treat the dirname as a path fragment.
  • Loading branch information
ahx committed Jan 16, 2025
1 parent b67c72f commit b23206e
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Fix issue with $ref resolving paths poiting outside directories `$ref: '../a/b.yaml'`

## 2.2.0

- Fix support for discriminator in response bodies if no mapping is defined (https://github.com/ahx/openapi_first/issues/285)
Expand Down
9 changes: 5 additions & 4 deletions lib/openapi_first/ref_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ module Resolvable
def initialize(value, context: value, dir: nil)
@value = value
@context = context
@dir = dir
@dir = (dir && File.absolute_path(dir)) || Dir.pwd
end

# The value of this node
Expand Down Expand Up @@ -108,10 +108,11 @@ def each

def schema(options = {})
ref_resolver = JSONSchemer::CachedResolver.new do |uri|
FileLoader.load(File.join(dir, uri.path))
FileLoader.load(uri.path)
end
root = JSONSchemer::Schema.new(context, ref_resolver:, **options)
JSONSchemer::Schema.new(value, nil, root, **options)
base_uri = URI::File.build({ path: "#{dir}/" })
root = JSONSchemer::Schema.new(context, base_uri:, ref_resolver:, **options)
JSONSchemer::Schema.new(value, nil, root, base_uri:, **options)
end
end

Expand Down
7 changes: 7 additions & 0 deletions spec/ref_resolver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@
expect(schema.valid?([{ id: 2, name: 'Spet' }])).to eq(true)
expect(schema.valid?([{ id: 'two', name: 'Spet' }])).to eq(false)
end

it 'works with relative paths in the schema' do
node = described_class.load('./spec/data/splitted-train-travel-api/openapi.yaml')
schema = node.dig('paths', '/bookings', 'get', 'responses', '200', 'content', 'application/json', 'schema').schema
expect(schema.valid?({ data: [{ has_bicycle: true }] })).to eq(true)
expect(schema.valid?({ data: [{ has_bicycle: 'red' }] })).to eq(false)
end
end

describe '#[]' do
Expand Down

0 comments on commit b23206e

Please sign in to comment.