forked from loafle/openapi-generator-original
[Ruby] Fix incorrect escaping of Ruby forward slashes (#16474)
* [Ruby] Test correct escaping of pattern sequences Ruby is not correctly escaping pattern sequences containing forward slashes in their definition. This commit adds tests that verify the correct behaviour of the code generator. See issue #5582. * [Ruby] Correctly escape patterns containing forward slashes Ruby regexs are always generated as match patterns enclosed in slash characters (i.e. using the `/pattern/` syntax). Regular expressions defined in the OpenAPI declaration via the `pattern` attribute follow [ECMA 262](https://262.ecma-international.org/5.1/#sec-15.10.1) which means they already include the correct escaping of forward slashes as far as Ruby is concerned. The current Ruby codegen is incorrectly escaping all forward slashes, which ultimately causes the generated code to include additional incorrect escape sequences which cause the generated file to have an invalid syntax. This commit ports the same fix introduced in #1539 for the Python codegen, as both Ruby and Python use perl-flavored regular expressions so they behave in the same way when it comes to escaping forward slashes. Fixes #5582.
This commit is contained in:
parent
8608103c9f
commit
065b48177b
@ -204,6 +204,20 @@ abstract public class AbstractRubyCodegen extends DefaultCodegen implements Code
|
||||
return addRegularExpressionDelimiter(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addRegularExpressionDelimiter(String pattern) {
|
||||
if (StringUtils.isEmpty(pattern)) {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
if (!pattern.matches("^/.*")) {
|
||||
// Perform a negative lookbehind on each `/` to ensure that it is escaped.
|
||||
return "/" + pattern.replaceAll("(?<!\\\\)\\/", "\\\\/") + "/";
|
||||
}
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// obtain the name from parameterNameMapping directly if provided
|
||||
|
@ -712,4 +712,33 @@ public class RubyClientCodegenTest {
|
||||
Assert.assertFalse(cp2.required);
|
||||
Assert.assertEquals(cp2.dataType, "VerySpecialStringInRuby");
|
||||
}
|
||||
|
||||
@Test(description = "test regex patterns")
|
||||
public void testRegularExpressionOpenAPISchemaVersion3() {
|
||||
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_1517.yaml");
|
||||
final RubyClientCodegen codegen = new RubyClientCodegen();
|
||||
codegen.setOpenAPI(openAPI);
|
||||
final String path = "/ping";
|
||||
final Operation p = openAPI.getPaths().get(path).getGet();
|
||||
final CodegenOperation op = codegen.fromOperation(path, "get", p, null);
|
||||
// pattern_no_forward_slashes '^pattern$'
|
||||
Assert.assertEquals(op.allParams.get(0).pattern, "/^pattern$/");
|
||||
// pattern_two_slashes '/^pattern$/'
|
||||
Assert.assertEquals(op.allParams.get(1).pattern, "/^pattern$/");
|
||||
// pattern_dont_escape_backslash '/^pattern\d{3}$/'
|
||||
Assert.assertEquals(op.allParams.get(2).pattern, "/^pattern\\d{3}$/");
|
||||
// pattern_dont_escape_escaped_forward_slash '/^pattern\/\d{3}$/'
|
||||
Assert.assertEquals(op.allParams.get(3).pattern, "/^pattern\\/\\d{3}$/");
|
||||
// pattern_escape_unescaped_forward_slash '^pattern/\d{3}$'
|
||||
Assert.assertEquals(op.allParams.get(4).pattern, "/^pattern\\/\\d{3}$/");
|
||||
// pattern_with_modifiers '/^pattern\d{3}$/i
|
||||
Assert.assertEquals(op.allParams.get(5).pattern, "/^pattern\\d{3}$/i");
|
||||
// not testing pattern_with_backslash_after_bracket '/^[\pattern\d{3}$/i'
|
||||
// as "/^[\\pattern\\d{3}$/i" is invalid regex because [ is not escaped and there is no closing ]
|
||||
// Assert.assertEquals(op.allParams.get(6).pattern, "/^[\\pattern\\d{3}$/i");
|
||||
// alternation_with_forward_slash '/ax$|/bx$'
|
||||
Assert.assertEquals(op.allParams.get(7).pattern, "/ax$|/bx$");
|
||||
// patten_starts_ends_with_slash '/root/'
|
||||
Assert.assertEquals(op.allParams.get(8).pattern, "/root/");
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,17 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
pattern: '/^[\pattern\d{3}$/i'
|
||||
- name: alternation_with_forward_slash
|
||||
in: header
|
||||
schema:
|
||||
type: string
|
||||
pattern: '/ax$|/bx$'
|
||||
- name: patten_starts_ends_with_slash
|
||||
in: header
|
||||
schema:
|
||||
type: string
|
||||
pattern: '/root/'
|
||||
description: 'Should match only /root/ but not root'
|
||||
|
||||
responses:
|
||||
'200':
|
||||
|
Loading…
x
Reference in New Issue
Block a user