mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 02:23:43 +03:00
fix: crashes on some dereferencing/allOf merging cases
This commit is contained in:
parent
ce543cf793
commit
335deb983e
|
@ -109,8 +109,12 @@ export class OpenAPIParser {
|
||||||
* resets visited enpoints. should be run after
|
* resets visited enpoints. should be run after
|
||||||
*/
|
*/
|
||||||
resetVisited() {
|
resetVisited() {
|
||||||
for (let k in this._refCounter._counter) {
|
if (__DEV__) {
|
||||||
if (this._refCounter._counter[k] > 0) {
|
// check in dev mode
|
||||||
|
for (let k in this._refCounter._counter) {
|
||||||
|
if (this._refCounter._counter[k] > 0) {
|
||||||
|
console.warn('Not exited reference: ' + k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._refCounter = new RefCounter();
|
this._refCounter = new RefCounter();
|
||||||
|
@ -129,11 +133,12 @@ export class OpenAPIParser {
|
||||||
deref<T extends object>(obj: OpenAPIRef | T, forceCircular: boolean = false): T {
|
deref<T extends object>(obj: OpenAPIRef | T, forceCircular: boolean = false): T {
|
||||||
if (this.isRef(obj)) {
|
if (this.isRef(obj)) {
|
||||||
const resolved = this.byRef<T>(obj.$ref)!;
|
const resolved = this.byRef<T>(obj.$ref)!;
|
||||||
if (this._refCounter.visited(obj.$ref) && !forceCircular) {
|
const visited = this._refCounter.visited(obj.$ref);
|
||||||
|
this._refCounter.visit(obj.$ref);
|
||||||
|
if (visited && !forceCircular) {
|
||||||
// circular reference detected
|
// circular reference detected
|
||||||
return Object.assign({}, resolved, { 'x-circular-ref': true });
|
return Object.assign({}, resolved, { 'x-circular-ref': true });
|
||||||
}
|
}
|
||||||
this._refCounter.visit(obj.$ref);
|
|
||||||
// deref again in case one more $ref is here
|
// deref again in case one more $ref is here
|
||||||
if (this.isRef(resolved)) {
|
if (this.isRef(resolved)) {
|
||||||
const res = this.deref(resolved);
|
const res = this.deref(resolved);
|
||||||
|
@ -169,9 +174,11 @@ export class OpenAPIParser {
|
||||||
const allOfSchemas = schema.allOf.map((subSchema, idx) => {
|
const allOfSchemas = schema.allOf.map((subSchema, idx) => {
|
||||||
const resolved = this.deref(subSchema, forceCircular);
|
const resolved = this.deref(subSchema, forceCircular);
|
||||||
const subRef = subSchema.$ref || $ref + '/allOf/' + idx;
|
const subRef = subSchema.$ref || $ref + '/allOf/' + idx;
|
||||||
|
const subMerged = this.mergeAllOf(resolved, subRef, forceCircular);
|
||||||
|
receiver.namedParents!.push(...(subMerged.namedParents || []));
|
||||||
return {
|
return {
|
||||||
$ref: subRef,
|
$ref: subRef,
|
||||||
schema: this.mergeAllOf(resolved, subRef, forceCircular),
|
schema: subMerged,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -188,7 +195,10 @@ export class OpenAPIParser {
|
||||||
throw new Error(`Uncopatible types in allOf at "${$ref}"`);
|
throw new Error(`Uncopatible types in allOf at "${$ref}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
receiver.type = subSchema.type;
|
if (subSchema.type !== undefined) {
|
||||||
|
receiver.type = subSchema.type;
|
||||||
|
}
|
||||||
|
|
||||||
if (subSchema.properties !== undefined) {
|
if (subSchema.properties !== undefined) {
|
||||||
// TODO: merge properties contents
|
// TODO: merge properties contents
|
||||||
receiver.properties = {
|
receiver.properties = {
|
||||||
|
|
|
@ -68,6 +68,7 @@ export class SchemaModel {
|
||||||
this.init(parser, isChild);
|
this.init(parser, isChild);
|
||||||
|
|
||||||
parser.exitRef(schemaOrRef);
|
parser.exitRef(schemaOrRef);
|
||||||
|
|
||||||
for (let $ref of this.schema.namedParents || []) {
|
for (let $ref of this.schema.namedParents || []) {
|
||||||
// exit all the refs visited during allOf traverse
|
// exit all the refs visited during allOf traverse
|
||||||
parser.exitRef({ $ref });
|
parser.exitRef({ $ref });
|
||||||
|
|
Loading…
Reference in New Issue
Block a user