Skip to content

Commit 0d62a62

Browse files
committed
Fix issue #15298
1 parent 04b34e7 commit 0d62a62

File tree

3 files changed

+117
-5
lines changed

3 files changed

+117
-5
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,8 +3147,12 @@ protected void setAddProps(Schema schema, IJsonSchemaValidationProperties proper
31473147
* @param sc The Schema that may contain the discriminator
31483148
* @param discPropName The String that is the discriminator propertyName in the schema
31493149
*/
3150-
private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc, String discPropName, OpenAPI openAPI) {
3150+
private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc, String discPropName, OpenAPI openAPI, Set<Schema> visitedSchemas) {
31513151
Schema refSchema = ModelUtils.getReferencedSchema(openAPI, sc);
3152+
if (visitedSchemas.contains(refSchema)) {
3153+
return null;
3154+
}
3155+
visitedSchemas.add(refSchema);
31523156
if (refSchema.getProperties() != null && refSchema.getProperties().get(discPropName) != null) {
31533157
Schema discSchema = (Schema) refSchema.getProperties().get(discPropName);
31543158
CodegenProperty cp = new CodegenProperty();
@@ -3166,7 +3170,7 @@ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc,
31663170
if (composedSchema.getAllOf() != null) {
31673171
// If our discriminator is in one of the allOf schemas break when we find it
31683172
for (Schema allOf : composedSchema.getAllOf()) {
3169-
CodegenProperty cp = discriminatorFound(composedSchemaName, allOf, discPropName, openAPI);
3173+
CodegenProperty cp = discriminatorFound(composedSchemaName, allOf, discPropName, openAPI, visitedSchemas);
31703174
if (cp != null) {
31713175
return cp;
31723176
}
@@ -3177,7 +3181,7 @@ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc,
31773181
CodegenProperty cp = new CodegenProperty();
31783182
for (Schema oneOf : composedSchema.getOneOf()) {
31793183
String modelName = ModelUtils.getSimpleRef(oneOf.get$ref());
3180-
CodegenProperty thisCp = discriminatorFound(composedSchemaName, oneOf, discPropName, openAPI);
3184+
CodegenProperty thisCp = discriminatorFound(composedSchemaName, oneOf, discPropName, openAPI, visitedSchemas);
31813185
if (thisCp == null) {
31823186
LOGGER.warn(
31833187
"'{}' defines discriminator '{}', but the referenced OneOf schema '{}' is missing {}",
@@ -3200,7 +3204,7 @@ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc,
32003204
CodegenProperty cp = new CodegenProperty();
32013205
for (Schema anyOf : composedSchema.getAnyOf()) {
32023206
String modelName = ModelUtils.getSimpleRef(anyOf.get$ref());
3203-
CodegenProperty thisCp = discriminatorFound(composedSchemaName, anyOf, discPropName, openAPI);
3207+
CodegenProperty thisCp = discriminatorFound(composedSchemaName, anyOf, discPropName, openAPI, visitedSchemas);
32043208
if (thisCp == null) {
32053209
LOGGER.warn(
32063210
"'{}' defines discriminator '{}', but the referenced AnyOf schema '{}' is missing {}",
@@ -3355,7 +3359,8 @@ protected List<MappedModel> getOneOfAnyOfDescendants(String composedSchemaName,
33553359
"Invalid inline schema defined in oneOf/anyOf in '{}'. Per the OpenApi spec, for this case when a composed schema defines a discriminator, the oneOf/anyOf schemas must use $ref. Change this inline definition to a $ref definition",
33563360
composedSchemaName);
33573361
}
3358-
CodegenProperty df = discriminatorFound(composedSchemaName, sc, discPropName, openAPI);
3362+
HashSet<Schema> visitedSchemas = new HashSet<>();
3363+
CodegenProperty df = discriminatorFound(composedSchemaName, sc, discPropName, openAPI, visitedSchemas);
33593364
String modelName = ModelUtils.getSimpleRef(ref);
33603365
if (df == null || !df.isString || df.required != true) {
33613366
String msgSuffix = "";

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,4 +2670,37 @@ public void testEnumCaseSensitive_issue8084() throws IOException {
26702670
.bodyContainsLines("if (b.value.equals(value)) {");
26712671
}
26722672

2673+
@Test
2674+
public void shouldNotFallWithNPEOrStackOverflow() throws IOException {
2675+
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
2676+
output.deleteOnExit();
2677+
2678+
OpenAPI openAPI = new OpenAPIParser()
2679+
.readLocation("src/test/resources/3_0/issue_spring_codegen_polymorphism.yaml", null, new ParseOptions()).getOpenAPI();
2680+
2681+
SpringCodegen codegen = new SpringCodegen();
2682+
codegen.setOutputDir(output.getAbsolutePath());
2683+
codegen.additionalProperties().put(SpringCodegen.DATE_LIBRARY, "java8-localdatetime");
2684+
codegen.additionalProperties().put(INTERFACE_ONLY, "true");
2685+
codegen.additionalProperties().put(USE_ONE_OF_INTERFACES, "false");
2686+
codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, "true");
2687+
codegen.additionalProperties().put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true");
2688+
codegen.additionalProperties().put(USE_TAGS, "true");
2689+
2690+
ClientOptInput input = new ClientOptInput();
2691+
input.openAPI(openAPI);
2692+
input.config(codegen);
2693+
2694+
DefaultGenerator generator = new DefaultGenerator();
2695+
generator.setGeneratorPropertyDefault(CodegenConstants.LIBRARY, "spring-cloud");
2696+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
2697+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
2698+
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
2699+
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
2700+
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
2701+
2702+
List<File> generate = generator.opts(input).generate();
2703+
System.out.println(generate);
2704+
}
2705+
26732706
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
openapi: 3.0.2
2+
info:
3+
title: Polymorphism Java Example
4+
version: 1.0.0
5+
contact:
6+
name: polydectes
7+
email: 12345@sharklasers.com
8+
servers:
9+
- url: 'https://localhost'
10+
tags:
11+
- name: Example
12+
paths:
13+
'/animal':
14+
post:
15+
tags:
16+
- Example
17+
operationId: createAnAnimal
18+
requestBody:
19+
required: true
20+
content:
21+
application/json:
22+
schema:
23+
$ref: '#/components/schemas/Animal'
24+
responses:
25+
'200':
26+
$ref: '#/components/responses/200-OK'
27+
'400':
28+
$ref: '#/components/responses/400-BadRequest'
29+
components:
30+
responses:
31+
200-OK:
32+
description: OK
33+
content:
34+
application/json:
35+
schema:
36+
$ref: '#/components/schemas/Animal'
37+
400-BadRequest:
38+
description: Error
39+
content:
40+
application/json:
41+
schema:
42+
$ref: '#/components/schemas/ErrorResponse'
43+
schemas:
44+
Animal:
45+
type: object
46+
oneOf:
47+
- $ref: '#/components/schemas/Cat'
48+
- $ref: '#/components/schemas/Dog'
49+
discriminator:
50+
propertyName: animalType
51+
Cat:
52+
type: object
53+
allOf:
54+
- $ref: '#/components/schemas/Animal'
55+
properties:
56+
acceptableAsHousepet:
57+
type: boolean
58+
Dog:
59+
type: object
60+
allOf:
61+
- $ref: '#/components/schemas/Animal'
62+
properties:
63+
canBeTrained:
64+
type: string
65+
OkResponse:
66+
type: object
67+
properties:
68+
id:
69+
type: string
70+
ErrorResponse:
71+
type: object
72+
properties:
73+
message:
74+
type: string

0 commit comments

Comments
 (0)