From 9e227ca022efe89d700e22a455792940132f0090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ro=C5=BCek?= Date: Tue, 13 Dec 2022 13:26:32 +0100 Subject: [PATCH] fix: handle direct circular file $refs (#219) --- .../schemas/circular-file-reference.json | 10 ++++++ src/__tests__/resolver.spec.ts | 31 +++++++++++++++++++ src/runner.ts | 4 +++ 3 files changed, 45 insertions(+) create mode 100644 src/__tests__/fixtures/schemas/circular-file-reference.json diff --git a/src/__tests__/fixtures/schemas/circular-file-reference.json b/src/__tests__/fixtures/schemas/circular-file-reference.json new file mode 100644 index 0000000..701bf47 --- /dev/null +++ b/src/__tests__/fixtures/schemas/circular-file-reference.json @@ -0,0 +1,10 @@ +{ + "anyOf": [ + { + "$ref": "circular-file-reference.json" + }, + { + "$ref": "circular-file-reference.json#/anyOf" + } + ] +} diff --git a/src/__tests__/resolver.spec.ts b/src/__tests__/resolver.spec.ts index 3b6cc14..c4ee872 100644 --- a/src/__tests__/resolver.spec.ts +++ b/src/__tests__/resolver.spec.ts @@ -1208,6 +1208,37 @@ describe('resolver', () => { ], }); }); + + test('should handle circular direct file reference', async () => { + const resolver = new Resolver({ + resolvers: { + file: new FileReader(), + }, + }); + const docUri = join(__dirname, './fixtures/schemas/circular-file-reference.json'); + const resolved = await resolver.resolve(JSON.parse(fs.readFileSync(docUri, 'utf8')), { + baseUri: docUri, + }); + + expect(resolved.errors).toEqual([]); + expect(resolved.result).toStrictEqual({ + anyOf: [ + { + anyOf: [ + { + $ref: 'circular-file-reference.json', + }, + { + $ref: 'circular-file-reference.json#/anyOf', + }, + ], + }, + { + $ref: 'circular-file-reference.json#/anyOf', + }, + ], + }); + }); }); describe('cache', () => { diff --git a/src/runner.ts b/src/runner.ts index 7c30cfd..e333a0d 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -349,6 +349,10 @@ export class ResolveRunner implements Types.IResolveRunner { } } + if (String(ref).length > 0 && this.isFile(this.baseUri) && this.isFile(ref) && this.baseUri.path() === ref.path()) { + ref = new ExtendedURI(`#${ref.fragment()}`); + } + if (this.transformRef) { return this.transformRef( {