Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.

Commit 3e95d89

Browse files
committed
fix(oas2): prevent treating overlapping paths as a circular reference
A check that a reference to `#/definitions/User` from within `#/definitions/UserList` would incorrectly been interpreted as a circular reference as a simplistic check that the current path starts with the current reference. We should ensure that the reference is either identical, or relative from another (such as with a trailing slash).
1 parent a6ec9eb commit 3e95d89

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

packages/openapi2-parser/lib/json-schema.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ const pathHasCircularReference = (paths, path, reference) => {
7676
const currentPath = (path || []).join('/');
7777

7878
// Check for direct circular reference
79-
if (currentPath.startsWith(reference)) {
79+
if (currentPath === reference || currentPath.startsWith(`${reference}/`)) {
8080
return true;
8181
}
8282

8383
// Check for indirect circular Reference
84-
if ((paths || []).find(p => p.startsWith(reference))) {
84+
if ((paths || []).find(p => p === reference || p.startsWith(`${reference}/`))) {
8585
return true;
8686
}
8787

@@ -393,5 +393,11 @@ const convertSchemaDefinitions = (definitions) => {
393393
};
394394

395395
module.exports = {
396-
isExtension, parseReference, lookupReference, dereference, convertSchema, convertSchemaDefinitions,
396+
isExtension,
397+
parseReference,
398+
lookupReference,
399+
dereference,
400+
convertSchema,
401+
convertSchemaDefinitions,
402+
pathHasCircularReference,
397403
};

packages/openapi2-parser/test/json-schema-test.js

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const { expect } = require('chai');
2-
const { convertSchema, convertSchemaDefinitions, dereference } = require('../lib/json-schema');
2+
const {
3+
convertSchema, convertSchemaDefinitions, dereference, pathHasCircularReference,
4+
} = require('../lib/json-schema');
35

46
describe('Swagger Schema to JSON Schema', () => {
57
it('returns compatible schema when given valid JSON Schema', () => {
@@ -853,3 +855,50 @@ describe('Dereferencing', () => {
853855
});
854856
});
855857
});
858+
859+
860+
describe('#pathHasCircularReference', () => {
861+
it('does not detect circular reference when reference is not circular', () => {
862+
const reference = '#/definitions/User';
863+
const currentPath = ['#', 'definitions', 'ListUsers'];
864+
865+
expect(pathHasCircularReference([], currentPath, reference)).to.be.false;
866+
});
867+
868+
it('detects circular reference when current path is reference path', () => {
869+
const reference = '#/definitions/User';
870+
const currentPath = ['#', 'definitions', 'User'];
871+
872+
expect(pathHasCircularReference([], currentPath, reference)).to.be.true;
873+
});
874+
875+
it('detects circular reference when current path contains reference path', () => {
876+
const reference = '#/definitions/User';
877+
const currentPath = ['#', 'definitions', 'User', 'properties', 'parent'];
878+
879+
expect(pathHasCircularReference([], currentPath, reference)).to.be.true;
880+
});
881+
882+
it('detects incircular reference when current path is in the prior referenced tree', () => {
883+
const reference = '#/definitions/User';
884+
const currentPath = ['#', 'definitions', 'ListUsers'];
885+
const currentTree = ['#/definitions/User/properties/children'];
886+
887+
expect(pathHasCircularReference(currentTree, currentPath, reference)).to.be.true;
888+
});
889+
890+
it('does not detect circular reference when reference last component prefixes current path', () => {
891+
const reference = '#/definitions/User';
892+
const currentPath = ['#', 'definitions', 'UserList'];
893+
894+
expect(pathHasCircularReference([], currentPath, reference)).to.be.false;
895+
});
896+
897+
it('does not detect incircular reference when reference last component prefixes path in prior reference tree', () => {
898+
const reference = '#/definitions/User';
899+
const currentPath = ['#', 'definitions', 'UserDetail'];
900+
const currentTree = ['#/definitions/UserList/items'];
901+
902+
expect(pathHasCircularReference(currentTree, currentPath, reference)).to.be.false;
903+
});
904+
});

0 commit comments

Comments
 (0)