Skip to content

Commit fae4d7a

Browse files
Donkov76wing328
andauthored
Fix for StackOverflow in Swift5 CodeGeneration Issue #8671 (#8672)
* StackOverflowFix for Issue 8671 * update samples Co-authored-by: William Cheng <[email protected]>
1 parent bf859c6 commit fae4d7a

File tree

13 files changed

+152
-17
lines changed

13 files changed

+152
-17
lines changed

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -999,13 +999,13 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
999999
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
10001000
for (CodegenOperation operation : operations) {
10011001
for (CodegenParameter cp : operation.allParams) {
1002-
cp.vendorExtensions.put("x-swift-example", constructExampleCode(cp, modelMaps, new HashSet()));
1002+
cp.vendorExtensions.put("x-swift-example", constructExampleCode(cp, modelMaps, new HashSet<String>()));
10031003
}
10041004
}
10051005
return objs;
10061006
}
10071007

1008-
public String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps, Set visitedModels) {
1008+
public String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps, Set<String> visitedModels) {
10091009
if (codegenParameter.isArray) { // array
10101010
return "[" + constructExampleCode(codegenParameter.items, modelMaps, visitedModels) + "]";
10111011
} else if (codegenParameter.isMap) { // TODO: map, file type
@@ -1037,11 +1037,11 @@ public String constructExampleCode(CodegenParameter codegenParameter, HashMap<St
10371037
} else { // model
10381038
// look up the model
10391039
if (modelMaps.containsKey(codegenParameter.dataType)) {
1040-
if (visitedModels.contains(modelMaps.get(codegenParameter.dataType))) {
1040+
if (visitedModels.contains(codegenParameter.dataType)) {
10411041
// recursive/self-referencing model, simply return nil to avoid stackoverflow
10421042
return "nil";
10431043
} else {
1044-
visitedModels.add(modelMaps.get(codegenParameter.dataType));
1044+
visitedModels.add(codegenParameter.dataType);
10451045
return constructExampleCode(modelMaps.get(codegenParameter.dataType), modelMaps, visitedModels);
10461046
}
10471047
} else {
@@ -1051,7 +1051,7 @@ public String constructExampleCode(CodegenParameter codegenParameter, HashMap<St
10511051
}
10521052
}
10531053

1054-
public String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps, Set visitedModels) {
1054+
public String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps, Set<String> visitedModels) {
10551055
if (codegenProperty.isArray) { // array
10561056
return "[" + constructExampleCode(codegenProperty.items, modelMaps, visitedModels) + "]";
10571057
} else if (codegenProperty.isMap) { // TODO: map, file type
@@ -1083,10 +1083,11 @@ public String constructExampleCode(CodegenProperty codegenProperty, HashMap<Stri
10831083
} else {
10841084
// look up the model
10851085
if (modelMaps.containsKey(codegenProperty.dataType)) {
1086-
if (visitedModels.contains(modelMaps.get(codegenProperty.dataType))) {
1086+
if (visitedModels.contains(codegenProperty.dataType)) {
10871087
// recursive/self-referencing model, simply return nil to avoid stackoverflow
10881088
return "nil";
10891089
} else {
1090+
visitedModels.add(codegenProperty.dataType);
10901091
return constructExampleCode(modelMaps.get(codegenProperty.dataType), modelMaps, visitedModels);
10911092
}
10921093
} else {
@@ -1096,7 +1097,7 @@ public String constructExampleCode(CodegenProperty codegenProperty, HashMap<Stri
10961097
}
10971098
}
10981099

1099-
public String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps, Set visitedModels) {
1100+
public String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps, Set<String> visitedModels) {
11001101
String example;
11011102
example = codegenModel.name + "(";
11021103
List<String> propertyExamples = new ArrayList<>();

modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,37 @@ public void crashSwift5ExampleCodeGenerationStackOverflowTest() throws IOExcepti
185185
}
186186
}
187187

188+
@Test(description = "Bug example code generation 2", enabled = true)
189+
public void crashSwift5ExampleCodeGenerationStackOverflowBug_2Test() throws IOException {
190+
//final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/bugs/Swift5CodeGenerationStackOverflow#2966.yaml");
191+
Path target = Files.createTempDirectory("test");
192+
File output = target.toFile();
193+
try {
194+
final CodegenConfigurator configurator = new CodegenConfigurator()
195+
.setGeneratorName("swift5")
196+
.setValidateSpec(false)
197+
// .setInputSpec("http://localhost:8080/api/openapi.yaml")
198+
.setInputSpec("src/test/resources/bugs/Swift5CodeGenarationBug2.yaml")
199+
//.setInputSpec("http://localhost:8080/api/openapi.yaml")
200+
.setEnablePostProcessFile(true)
201+
.setOutputDir(target.toAbsolutePath().toString());
202+
203+
final ClientOptInput clientOptInput = configurator.toClientOptInput();
204+
DefaultGenerator generator = new DefaultGenerator(false);
205+
206+
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
207+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "true");
208+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "true");
209+
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
210+
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "true");
211+
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "true");
212+
generator.setGeneratorPropertyDefault(CodegenConstants.ENABLE_POST_PROCESS_FILE, "true");
213+
214+
List<File> files = generator.opts(clientOptInput).generate();
215+
Assert.assertTrue(files.size() > 0, "No files generated");
216+
} finally {
217+
output.delete();
218+
}
219+
}
220+
188221
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
openapi: 3.0.1
2+
info:
3+
title: XXX
4+
description: Das ist jetzt der erste OpenAPI 3.0 Endpoint
5+
contact:
6+
7+
version: "1.0"
8+
paths:
9+
/api/v1/petresource/pet:
10+
post:
11+
tags:
12+
- v1/petresource
13+
summary: Save a Pet.
14+
description: Save a Pet.
15+
operationId: savePet
16+
requestBody:
17+
content:
18+
'*/*':
19+
schema:
20+
$ref: '#/components/schemas/Pet'
21+
responses:
22+
default:
23+
description: PetResponse
24+
content:
25+
application/json:
26+
schema:
27+
$ref: '#/components/schemas/Pet'
28+
/api/v1/petresource/petstore:
29+
post:
30+
tags:
31+
- v1/petresource
32+
summary: Save a Petstore.
33+
description: Save a Petstore.
34+
operationId: savePetStore
35+
requestBody:
36+
content:
37+
'*/*':
38+
schema:
39+
$ref: '#/components/schemas/PetStore'
40+
responses:
41+
default:
42+
description: PetStore
43+
content:
44+
application/json:
45+
schema:
46+
$ref: '#/components/schemas/PetStore'
47+
components:
48+
schemas:
49+
Cat:
50+
required:
51+
- type
52+
type: object
53+
description: Cat
54+
allOf:
55+
- $ref: '#/components/schemas/Pet'
56+
- type: object
57+
properties:
58+
catFood:
59+
type: string
60+
Dog:
61+
required:
62+
- type
63+
type: object
64+
description: Dog
65+
allOf:
66+
- $ref: '#/components/schemas/Pet'
67+
- type: object
68+
properties:
69+
dogFood:
70+
type: string
71+
Pet:
72+
required:
73+
- type
74+
type: object
75+
properties:
76+
name:
77+
type: string
78+
description: Name
79+
store:
80+
$ref: '#/components/schemas/PetStore'
81+
mother:
82+
$ref: '#/components/schemas/Pet'
83+
father:
84+
$ref: '#/components/schemas/Pet'
85+
type:
86+
type: string
87+
description: Type Diskriminator
88+
description: Base Pet
89+
discriminator:
90+
propertyName: type
91+
mapping:
92+
Dog: '#/components/schemas/Dog'
93+
Cat: '#/components/schemas/Cat'
94+
PetStore:
95+
type: object
96+
properties:
97+
pets:
98+
type: array
99+
items:
100+
$ref: '#/components/schemas/Pet'
101+
description: PetStore

samples/client/petstore/swift5/alamofireLibrary/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
228228
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
229229
import PetstoreClient
230230

231-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
231+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
232232

233233
FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
234234
guard error == nil else {

samples/client/petstore/swift5/combineLibrary/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
228228
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
229229
import PetstoreClient
230230

231-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
231+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
232232

233233
FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
234234
guard error == nil else {

samples/client/petstore/swift5/default/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
228228
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
229229
import PetstoreClient
230230

231-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
231+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
232232

233233
FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
234234
guard error == nil else {

samples/client/petstore/swift5/nonPublicApi/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
228228
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
229229
import PetstoreClient
230230

231-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
231+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
232232

233233
FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
234234
guard error == nil else {

samples/client/petstore/swift5/objcCompatible/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
228228
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
229229
import PetstoreClient
230230

231-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
231+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
232232

233233
FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
234234
guard error == nil else {

samples/client/petstore/swift5/promisekitLibrary/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ For this test, the body for this request much reference a schema named `File`.
216216
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
217217
import PetstoreClient
218218

219-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
219+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
220220

221221
FakeAPI.testBodyWithFileSchema(body: body).then {
222222
// when the promise is fulfilled

samples/client/petstore/swift5/readonlyProperties/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
228228
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
229229
import PetstoreClient
230230

231-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
231+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
232232

233233
FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
234234
guard error == nil else {

samples/client/petstore/swift5/resultLibrary/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
228228
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
229229
import PetstoreClient
230230

231-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
231+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
232232

233233
FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
234234
guard error == nil else {

samples/client/petstore/swift5/rxswiftLibrary/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ For this test, the body for this request much reference a schema named `File`.
192192
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
193193
import PetstoreClient
194194

195-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
195+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
196196

197197
// TODO RxSwift sample code not yet implemented. To contribute, please open a ticket via http://github.com/OpenAPITools/openapi-generator/issues/new
198198
```

samples/client/petstore/swift5/urlsessionLibrary/docs/FakeAPI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ For this test, the body for this request much reference a schema named `File`.
228228
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
229229
import PetstoreClient
230230

231-
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [File(sourceURI: "sourceURI_example")]) // FileSchemaTestClass |
231+
let body = FileSchemaTestClass(file: File(sourceURI: "sourceURI_example"), files: [nil]) // FileSchemaTestClass |
232232

233233
FakeAPI.testBodyWithFileSchema(body: body) { (response, error) in
234234
guard error == nil else {

0 commit comments

Comments
 (0)