[BUG] Swift : Invalid escape sequence in literal
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":
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
Small update: I did some testing and it appeared that this issue was introduced in v6.3.0
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])))$/")
Any update on this? This issue is still present in 7.3.0
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' {} +
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])
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