Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Issues
  • #8671
Closed
Open
Issue created Feb 10, 2021 by Administrator@rootContributor5 of 6 checklist items completed5/6 checklist items

[BUG] StackOverflow Error Swift5 CodeGeneration

Created by: Donkov76

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue? The following valid yaml creates StackOverflow Errors:
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output? Expected: no Stackoverflow
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

Generating a Swift5 Client from the yaml file below produces StackOverflow Errors.

org.openapitools.codegen.CodegenModel.hashCode(CodegenModel.java:804) at java.base/java.util.Arrays.hashCode(Arrays.java:4498) at java.base/java.util.Objects.hash(Objects.java:133) at org.openapitools.codegen.CodegenModel.hashCode(CodegenModel.java:804) at java.base/java.util.ArrayList.hashCodeRange(ArrayList.java:595) at java.base/java.util.ArrayList.hashCode(ArrayList.java:582) at java.base/java.util.Arrays.hashCode(Arrays.java:4498) at java.base/java.util.Objects.hash(Objects.java:133) at org.openapitools.codegen.CodegenModel.hashCode(CodegenModel.java:804) at java.base/java.util.Arrays.hashCode(Arrays.java:4498) at java.base/java.util.Objects.hash(Objects.java:133) at org.openapitools.codegen.CodegenModel.hashCode(CodegenModel.java:804) at java.base/java.util.ArrayList.hashCodeRange(ArrayList.java:595) at java.base/java.util.ArrayList.hashCode(ArrayList.java:582) at java.base/java.util.Arrays.hashCode(Arrays.java:4498) at java.base/java.util.Objects.hash(Objects.java:133) at org.openapitools.codegen.CodegenModel.hashCode(CodegenModel.java:804)

After I fixed this the following Error occurred:

at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1105)
at org.openapitools.codegen.languages.Swift5ClientCodegen.constructExampleCode(Swift5ClientCodegen.java:1091)
openapi-generator version

openapi-generator-cli 5.0.1 I also tested it with the current master branch

OpenAPI declaration file content or url
openapi: 3.0.1
info:
  title: XXX
  description: Das ist jetzt der erste OpenAPI 3.0 Endpoint
  contact:
    email: XXX.XXX@XXX.de
  version: "1.0"
paths:
  /api/v1/petresource/pet:
    post:
      tags:
        - v1/petresource
      summary: Save a Pet.
      description: Save a Pet.
      operationId: savePet
      requestBody:
        content:
          '*/*':
            schema:
              $ref: '#/components/schemas/Pet'
      responses:
        default:
          description: PetResponse
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'
  /api/v1/petresource/petstore:
    post:
      tags:
        - v1/petresource
      summary: Save a Petstore.
      description: Save a Petstore.
      operationId: savePetStore
      requestBody:
        content:
          '*/*':
            schema:
              $ref: '#/components/schemas/PetStore'
      responses:
        default:
          description: PetStore
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PetStore'
components:
  schemas:
    Cat:
      required:
        - type
      type: object
      description: Cat
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            catFood:
              type: string
    Dog:
      required:
        - type
      type: object
      description: Dog
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            dogFood:
              type: string
    Pet:
      required:
        - type
      type: object
      properties:
        name:
          type: string
          description: Name
        store:
          $ref: '#/components/schemas/PetStore'
        mother:
          $ref: '#/components/schemas/Pet'
        father:
          $ref: '#/components/schemas/Pet'
        type:
          type: string
          description: Type Diskriminator
      description: Base Pet
      discriminator:
        propertyName: type
        mapping:
          Dog: '#/components/schemas/Dog'
          Cat: '#/components/schemas/Cat'
    PetStore:
      type: object
      properties:
        pets:
          type: array
          items:
            $ref: '#/components/schemas/Pet'
      description: PetStore
Generation Details
Steps to reproduce

openapi-generator generate -i "Swift5CodeGenarationBug2.yaml" -g swift5

Related issues/PRs
Suggest a fix

In my opinion there are 2 different bugs

  1. The hashCode implementation in org.openapitools.codegen.CodegenModel causes a overflow, because parent and children Models are both in the hash. My workaround for this issue was to add just the type and not the model to the visitedModel Set. (In Swift5ClientCodegen constructExampleCode)

I replaced all occurrences of visitedModels.contains(modelMaps.get(codegenProperty.dataType)) with visitedModels.contains(codegenProperty.dataType)

  1. constructExampleCode in org.openapitools.codegen.languagesSwift5ClientCodegen updates the visitedModel Map only in "constructExampleCode(CodegenParameter codegenParameter" and not in "constructExampleCode(CodegenProperty codegenProperty".

I suggest to add visitedModels.add(codegenProperty.dataType); in constructExampleCode(CodegenProperty codegenProperty,

public String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps, Set<String> visitedModels) {
        if (codegenProperty.isArray) { // array
            return "[" + constructExampleCode(codegenProperty.items, modelMaps, visitedModels) + "]";
        } else if (codegenProperty.isMap) { // TODO: map, file type
            return "\"TODO\"";
        } else if (languageSpecificPrimitives.contains(codegenProperty.dataType)) { // primitive type
            if ("String".equals(codegenProperty.dataType) || "Character".equals(codegenProperty.dataType)) {
                if (StringUtils.isEmpty(codegenProperty.example)) {
                    return "\"" + codegenProperty.example + "\"";
                } else {
                    return "\"" + codegenProperty.name + "_example\"";
                }
            } else if ("Bool".equals(codegenProperty.dataType)) { // boolean
                if (Boolean.parseBoolean(codegenProperty.example)) {
                    return "true";
                } else {
                    return "false";
                }
            } else if ("URL".equals(codegenProperty.dataType)) { // URL
                return "URL(string: \"https://example.com\")!";
            } else if ("Date".equals(codegenProperty.dataType)) { // date
                return "Date()";
            } else { // numeric
                if (StringUtils.isEmpty(codegenProperty.example)) {
                    return codegenProperty.example;
                } else {
                    return "123";
                }
            }
        } else {
            // look up the model
            if (modelMaps.containsKey(codegenProperty.dataType)) {
                if (visitedModels.contains(codegenProperty.dataType)) {
                    // recursive/self-referencing model, simply return nil to avoid stackoverflow
                    return "nil";
                } else {
                    visitedModels.add(codegenProperty.dataType); // <--- Add this Line
                    return constructExampleCode(modelMaps.get(codegenProperty.dataType), modelMaps, visitedModels);
                }
            } else {
                //LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenProperty.dataType);
                return "\"TODO\"";
            }
        }
    }

The best solution may be to fix the hashCode Implementation in CodegenModel, but this could be a risky change. Maybe it is a good idea to add an option to disable the sample code generation.

Assignee
Assign to
Time tracking