openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG] Swift : Invalid escape sequence in literal

Open kanduvisla opened this issue 2 years ago • 6 comments

Bug Report Checklist

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

If I want to create a Swift OpenAPI Client with an OpenAPI spec that contains a pattern that contains a slash, the generated code has an invalid pattern for the StringRule-object, resulting in code that won't compile because of the error: "Invalid escape sequence in literal":

Screenshot 2023-05-22 at 16 18 17 Screenshot 2023-05-22 at 16 17 34
openapi-generator version
openapi-generator-cli 6.6.0
  commit : 7f8b853
  built  : -999999999-01-01T00:00:00+18:00
OpenAPI declaration file content or url

This example spec will generate faulty code:

{
  "swagger" : "2.0",
  "info" : {
    "description" : "Example",
    "version" : "v1",
    "title" : "Example",
    "termsOfService" : "None",
    "contact" : {
      "name" : "Foo",
      "url" : "https://www.example.com"
    }
  },
  "host" : "www.example.com",
  "basePath" : "/Example",
  "schemes" : [ "https" ],
  "produces" : [ "application/json" ],
  "paths" : {
    "/api/example" : {
      "get" : {
        "responses" : {
          "200" : {
            "description" : "OK",
            "schema" : {
              "$ref" : "#/definitions/Output"
            }
          }
        }
      }
    }
  },
  "definitions" : {
    "Output" : {
      "type": "object",
      "properties":  {
        "street" : {
          "$ref" : "#/definitions/Street"
        }
      }
    },
    "Street" : {
      "description": "This is the address’ street name.",
      "type": "string",
      "minLength": 1,
      "maxLength": 45,
      "pattern": "[a-zA-Z0-9 ',./-]{1,35}",
      "example": "Down Best Street"
    }
  }
}

The Output.swift will have a Syntax error in the regex pattern. The slash is escaped with one backslash, but in Swift this need to be 2 (I believe, correct me if I'm wrong):

public struct Output: Codable, JSONEncodable, Hashable {

    static let streetRule = StringRule(minLength: 1, maxLength: 45, pattern: "/[a-zA-Z0-9 ',./-]{1,35}/")
    /** This is the address’ street name. */
    public var street: String?

    public init(street: String? = nil) {
        self.street = street
    }

    public enum CodingKeys: String, CodingKey, CaseIterable {
        case street
    }

    // Encodable protocol methods

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encodeIfPresent(street, forKey: .street)
    }
}
Generation Details

Run:

openapi-generator generate -i application.myline.api-swagger.json -g swift5

And check the generated output

kanduvisla avatar May 22 '23 14:05 kanduvisla

Small update: I did some testing and it appeared that this issue was introduced in v6.3.0

kanduvisla avatar May 22 '23 14:05 kanduvisla

Any update on this? I've just build an API with v7.0.0 (7.0.1 was not on docker hub yet), and the issue still exists, this time with the e-mail rule:

    static let emailRule = StringRule(minLength: 1, maxLength: nil, pattern: "/^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-||_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+([a-z]+|\\d|-|\\.{0,1}|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])?([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/")

kanduvisla avatar Aug 29 '23 11:08 kanduvisla

Any update on this? This issue is still present in 7.3.0

kanduvisla avatar Mar 05 '24 15:03 kanduvisla

In case anyone else is running into this issue, for now I have to manually "fix" my output, by removing all broken lines from my Swift code:

find ./path/to/generated/code -type f -exec sed -i '' '/= StringRule(minLength/d' {} +

kanduvisla avatar Mar 06 '24 08:03 kanduvisla

The issue is still here, @4brunu any idea? I manage to put a workaround with a replacing step:

find ${CURRENT_DIR}/../Generated/${PROJECT_NAME} -type f -name "*.swift" -exec python ${CURRENT_DIR}/replaceSlash.py {} \;

with the replaceSlash.py as

import sys
import re
import os
from tempfile import NamedTemporaryFile

def replace_slash(file_path):
    # Regex to find '/\' not preceded by '\'
    pattern = re.compile(r'(?<!\\)\\/')

    with NamedTemporaryFile(mode='w', delete=False) as temp_file:
        with open(file_path, 'r') as file:
            for line in file:
                temp_file.write(pattern.sub(r'\\\\/', line))
        temp_file_name = temp_file.name
    os.replace(temp_file_name, file_path)


if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python replaceSlash.py <file_path>")
        sys.exit(1)

    replace_slash(sys.argv[1])

gscalzo avatar May 03 '24 14:05 gscalzo

Hi, I'm not very familiar with this part, so I'm sure how can we fix this. Maybe around here? https://github.com/OpenAPITools/openapi-generator/blob/73f2d8289b2d4069675c79ea5375d9c58ea1853c/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift5ClientCodegen.java#L1219-L1222

4brunu avatar May 03 '24 14:05 4brunu