mirror of
https://github.com/Redocly/redoc.git
synced 2025-02-07 13:30:33 +03:00
fix: false-positive recursive detection with oneOf
fixes #723, fixes #585
This commit is contained in:
parent
e2d0cd5b18
commit
59eaa8d633
|
@ -291,6 +291,12 @@ export class OpenAPIParser {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exitParents(shema: MergedOpenAPISchema) {
|
||||||
|
for (const parent$ref of shema.parentRefs || []) {
|
||||||
|
this.exitRef({ $ref: parent$ref });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private hoistOneOfs(schema: OpenAPISchema) {
|
private hoistOneOfs(schema: OpenAPISchema) {
|
||||||
if (schema.allOf === undefined) {
|
if (schema.allOf === undefined) {
|
||||||
return schema;
|
return schema;
|
||||||
|
@ -304,9 +310,14 @@ export class OpenAPIParser {
|
||||||
const afterAllOf = allOf.slice(i + 1);
|
const afterAllOf = allOf.slice(i + 1);
|
||||||
return {
|
return {
|
||||||
oneOf: sub.oneOf.map(part => {
|
oneOf: sub.oneOf.map(part => {
|
||||||
return this.mergeAllOf({
|
const merged = this.mergeAllOf({
|
||||||
allOf: [...beforeAllOf, part, ...afterAllOf],
|
allOf: [...beforeAllOf, part, ...afterAllOf],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// each oneOf should be independent so exiting all the parent refs
|
||||||
|
// otherwise it will cause false-positive recursive detection
|
||||||
|
this.exitParents(merged);
|
||||||
|
return merged;
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,11 +75,7 @@ export class SchemaModel {
|
||||||
this.init(parser, isChild);
|
this.init(parser, isChild);
|
||||||
|
|
||||||
parser.exitRef(schemaOrRef);
|
parser.exitRef(schemaOrRef);
|
||||||
|
parser.exitParents(this.schema);
|
||||||
for (const parent$ref of this.schema.parentRefs || []) {
|
|
||||||
// exit all the refs visited during allOf traverse
|
|
||||||
parser.exitRef({ $ref: parent$ref });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.showExtensions) {
|
if (options.showExtensions) {
|
||||||
this.extensions = extractExtensions(this.schema, options.showExtensions);
|
this.extensions = extractExtensions(this.schema, options.showExtensions);
|
||||||
|
@ -164,20 +160,28 @@ export class SchemaModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private initOneOf(oneOf: OpenAPISchema[], parser: OpenAPIParser) {
|
private initOneOf(oneOf: OpenAPISchema[], parser: OpenAPIParser) {
|
||||||
this.oneOf = oneOf!.map(
|
this.oneOf = oneOf!.map((variant, idx) => {
|
||||||
(variant, idx) =>
|
const merged = parser.mergeAllOf(variant, this.pointer + '/oneOf/' + idx);
|
||||||
new SchemaModel(
|
|
||||||
parser,
|
const schema = new SchemaModel(
|
||||||
// merge base schema into each of oneOf's subschemas
|
parser,
|
||||||
{
|
// merge base schema into each of oneOf's subschemas
|
||||||
// variant may already have allOf so merge it to not get overwritten
|
{
|
||||||
...parser.mergeAllOf(variant, this.pointer + '/oneOf/' + idx),
|
// variant may already have allOf so merge it to not get overwritten
|
||||||
allOf: [{ ...this.schema, oneOf: undefined, anyOf: undefined }],
|
...merged,
|
||||||
} as OpenAPISchema,
|
allOf: [{ ...this.schema, oneOf: undefined, anyOf: undefined }],
|
||||||
this.pointer + '/oneOf/' + idx,
|
} as OpenAPISchema,
|
||||||
this.options,
|
this.pointer + '/oneOf/' + idx,
|
||||||
),
|
this.options,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// each oneOf should be independent so exiting all the parent refs
|
||||||
|
// otherwise it will cause false-positive recursive detection
|
||||||
|
parser.exitParents(merged);
|
||||||
|
|
||||||
|
return schema;
|
||||||
|
});
|
||||||
|
|
||||||
this.displayType = this.oneOf
|
this.displayType = this.oneOf
|
||||||
.map(schema => {
|
.map(schema => {
|
||||||
let name =
|
let name =
|
||||||
|
|
Loading…
Reference in New Issue
Block a user