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

Commit

Permalink
fix(oas2): prevent treating overlapping paths as a circular reference
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
kylef committed Jul 15, 2021
1 parent a6ec9eb commit 3e95d89
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 4 deletions.
12 changes: 9 additions & 3 deletions packages/openapi2-parser/lib/json-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ const pathHasCircularReference = (paths, path, reference) => {
const currentPath = (path || []).join('/');

// Check for direct circular reference
if (currentPath.startsWith(reference)) {
if (currentPath === reference || currentPath.startsWith(`${reference}/`)) {
return true;
}

// Check for indirect circular Reference
if ((paths || []).find(p => p.startsWith(reference))) {
if ((paths || []).find(p => p === reference || p.startsWith(`${reference}/`))) {
return true;
}

Expand Down Expand Up @@ -393,5 +393,11 @@ const convertSchemaDefinitions = (definitions) => {
};

module.exports = {
isExtension, parseReference, lookupReference, dereference, convertSchema, convertSchemaDefinitions,
isExtension,
parseReference,
lookupReference,
dereference,
convertSchema,
convertSchemaDefinitions,
pathHasCircularReference,
};
51 changes: 50 additions & 1 deletion packages/openapi2-parser/test/json-schema-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const { expect } = require('chai');
const { convertSchema, convertSchemaDefinitions, dereference } = require('../lib/json-schema');
const {
convertSchema, convertSchemaDefinitions, dereference, pathHasCircularReference,
} = require('../lib/json-schema');

describe('Swagger Schema to JSON Schema', () => {
it('returns compatible schema when given valid JSON Schema', () => {
Expand Down Expand Up @@ -853,3 +855,50 @@ describe('Dereferencing', () => {
});
});
});


describe('#pathHasCircularReference', () => {
it('does not detect circular reference when reference is not circular', () => {
const reference = '#/definitions/User';
const currentPath = ['#', 'definitions', 'ListUsers'];

expect(pathHasCircularReference([], currentPath, reference)).to.be.false;
});

it('detects circular reference when current path is reference path', () => {
const reference = '#/definitions/User';
const currentPath = ['#', 'definitions', 'User'];

expect(pathHasCircularReference([], currentPath, reference)).to.be.true;
});

it('detects circular reference when current path contains reference path', () => {
const reference = '#/definitions/User';
const currentPath = ['#', 'definitions', 'User', 'properties', 'parent'];

expect(pathHasCircularReference([], currentPath, reference)).to.be.true;
});

it('detects incircular reference when current path is in the prior referenced tree', () => {
const reference = '#/definitions/User';
const currentPath = ['#', 'definitions', 'ListUsers'];
const currentTree = ['#/definitions/User/properties/children'];

expect(pathHasCircularReference(currentTree, currentPath, reference)).to.be.true;
});

it('does not detect circular reference when reference last component prefixes current path', () => {
const reference = '#/definitions/User';
const currentPath = ['#', 'definitions', 'UserList'];

expect(pathHasCircularReference([], currentPath, reference)).to.be.false;
});

it('does not detect incircular reference when reference last component prefixes path in prior reference tree', () => {
const reference = '#/definitions/User';
const currentPath = ['#', 'definitions', 'UserDetail'];
const currentTree = ['#/definitions/UserList/items'];

expect(pathHasCircularReference(currentTree, currentPath, reference)).to.be.false;
});
});

0 comments on commit 3e95d89

Please sign in to comment.