fix: false-positive recursive detection with oneOf

fixes #723, fixes #585
This commit is contained in:
Roman Hotsiy 2018-11-27 12:21:28 +02:00
parent e2d0cd5b18
commit 59eaa8d633
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
2 changed files with 35 additions and 20 deletions

View File

@ -291,6 +291,12 @@ export class OpenAPIParser {
return res;
}
exitParents(shema: MergedOpenAPISchema) {
for (const parent$ref of shema.parentRefs || []) {
this.exitRef({ $ref: parent$ref });
}
}
private hoistOneOfs(schema: OpenAPISchema) {
if (schema.allOf === undefined) {
return schema;
@ -304,9 +310,14 @@ export class OpenAPIParser {
const afterAllOf = allOf.slice(i + 1);
return {
oneOf: sub.oneOf.map(part => {
return this.mergeAllOf({
const merged = this.mergeAllOf({
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;
}),
};
}

View File

@ -75,11 +75,7 @@ export class SchemaModel {
this.init(parser, isChild);
parser.exitRef(schemaOrRef);
for (const parent$ref of this.schema.parentRefs || []) {
// exit all the refs visited during allOf traverse
parser.exitRef({ $ref: parent$ref });
}
parser.exitParents(this.schema);
if (options.showExtensions) {
this.extensions = extractExtensions(this.schema, options.showExtensions);
@ -164,20 +160,28 @@ export class SchemaModel {
}
private initOneOf(oneOf: OpenAPISchema[], parser: OpenAPIParser) {
this.oneOf = oneOf!.map(
(variant, idx) =>
new SchemaModel(
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),
allOf: [{ ...this.schema, oneOf: undefined, anyOf: undefined }],
} as OpenAPISchema,
this.pointer + '/oneOf/' + idx,
this.options,
),
);
this.oneOf = oneOf!.map((variant, idx) => {
const merged = parser.mergeAllOf(variant, this.pointer + '/oneOf/' + idx);
const schema = new SchemaModel(
parser,
// merge base schema into each of oneOf's subschemas
{
// variant may already have allOf so merge it to not get overwritten
...merged,
allOf: [{ ...this.schema, oneOf: undefined, anyOf: undefined }],
} as OpenAPISchema,
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
.map(schema => {
let name =