forked from loafle/openapi-generator-original
[Slim] Encode path to support non-latin characters (#1687)
* [Slim] Add encodePath method * [Slim] Add tests for encodePath method * [Slim] Use unescaped path in router Both variables basePathWithoutHost and path are already urlEncoded in codegen itself. Builtin html encoding in mustache is redundant. We can use these raw codegen values with no fear. * [Slim] Refresh samples
This commit is contained in:
parent
a0e5b74b2b
commit
e8ac630ca5
@ -81,6 +81,8 @@ public interface CodegenConfig {
|
||||
|
||||
String escapeTextWhileAllowingNewLines(String text);
|
||||
|
||||
String encodePath(String text);
|
||||
|
||||
String escapeUnsafeCharacters(String input);
|
||||
|
||||
String escapeReservedWord(String name);
|
||||
|
@ -557,6 +557,12 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
.replace("\"", "\\\""));
|
||||
}
|
||||
|
||||
// override with any special encoding and escaping logic
|
||||
@SuppressWarnings("static-method")
|
||||
public String encodePath(String input) {
|
||||
return escapeText(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* override with any special text escaping logic to handle unsafe
|
||||
* characters so as to avoid code injection
|
||||
|
@ -537,9 +537,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
}
|
||||
});
|
||||
Map<String, Object> operation = processOperations(config, tag, ops, allModels);
|
||||
|
||||
URL url = URLPathUtils.getServerURL(openAPI);
|
||||
operation.put("basePath", basePath);
|
||||
operation.put("basePathWithoutHost", basePathWithoutHost);
|
||||
operation.put("basePathWithoutHost", config.encodePath(url.getPath()).replaceAll("/$", ""));
|
||||
operation.put("contextPath", contextPath);
|
||||
operation.put("baseName", tag);
|
||||
operation.put("apiPackage", config.apiPackage());
|
||||
|
@ -31,6 +31,13 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.net.URLEncoder;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
|
||||
public class PhpSlimServerCodegen extends AbstractPhpCodegen {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PhpSlimServerCodegen.class);
|
||||
@ -179,4 +186,57 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
|
||||
operations.put(USER_CLASSNAME_KEY, classname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodePath(String input) {
|
||||
if (input == null) {
|
||||
return input;
|
||||
}
|
||||
|
||||
// from DefaultCodegen.java
|
||||
// remove \t, \n, \r
|
||||
// replace \ with \\
|
||||
// replace " with \"
|
||||
// outter unescape to retain the original multi-byte characters
|
||||
// finally escalate characters avoiding code injection
|
||||
input = super.escapeUnsafeCharacters(
|
||||
StringEscapeUtils.unescapeJava(
|
||||
StringEscapeUtils.escapeJava(input)
|
||||
.replace("\\/", "/"))
|
||||
.replaceAll("[\\t\\n\\r]", " ")
|
||||
.replace("\\", "\\\\"));
|
||||
// .replace("\"", "\\\""));
|
||||
|
||||
// from AbstractPhpCodegen.java
|
||||
// Trim the string to avoid leading and trailing spaces.
|
||||
input = input.trim();
|
||||
try {
|
||||
|
||||
input = URLEncoder.encode(input, "UTF-8")
|
||||
.replaceAll("\\+", "%20")
|
||||
.replaceAll("\\%2F", "/")
|
||||
.replaceAll("\\%7B", "{") // keep { part of complex placeholders
|
||||
.replaceAll("\\%7D", "}") // } part
|
||||
.replaceAll("\\%5B", "[") // [ part
|
||||
.replaceAll("\\%5D", "]") // ] part
|
||||
.replaceAll("\\%3A", ":") // : part
|
||||
.replaceAll("\\%2B", "+") // + part
|
||||
.replaceAll("\\%5C\\%5Cd", "\\\\d"); // \d part
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// continue
|
||||
LOGGER.error(e.getMessage(), e);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenOperation fromOperation(String path,
|
||||
String httpMethod,
|
||||
Operation operation,
|
||||
Map<String, Schema> schemas,
|
||||
OpenAPI openAPI) {
|
||||
CodegenOperation op = super.fromOperation(path, httpMethod, operation, schemas, openAPI);
|
||||
op.path = encodePath(path);
|
||||
return op;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class SlimRouter
|
||||
[
|
||||
'httpMethod' => '{{httpMethod}}',
|
||||
'basePathWithoutHost' => '{{{basePathWithoutHost}}}',
|
||||
'path' => '{{path}}',
|
||||
'path' => '{{{path}}}',
|
||||
'apiPackage' => '{{apiPackage}}',
|
||||
'classname' => '{{classname}}',
|
||||
'userClassname' => '{{userClassname}}',
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.slim;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import org.openapitools.codegen.languages.PhpSlimServerCodegen;
|
||||
|
||||
public class PhpSlimServerCodegenTest {
|
||||
|
||||
@Test
|
||||
public void testEncodePath() {
|
||||
final PhpSlimServerCodegen codegen = new PhpSlimServerCodegen();
|
||||
|
||||
Assert.assertEquals(codegen.encodePath("/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r/fake"), "/%20%27%20%22%20%3Dend%20--%20%5C%5Cr%5C%5Cn%20%5C%5Cn%20%5C%5Cr/v2%20*_/%20%27%20%22%20%3Dend%20--%20%5C%5Cr%5C%5Cn%20%5C%5Cn%20%5C%5Cr/fake");
|
||||
Assert.assertEquals(codegen.encodePath("/o\'\"briens/v2/o\'\"henry/fake"), "/o%27%22briens/v2/o%27%22henry/fake");
|
||||
Assert.assertEquals(codegen.encodePath("/comedians/Chris D\'Elia"), "/comedians/Chris%20D%27Elia");
|
||||
Assert.assertEquals(codegen.encodePath("/разработчики/Юрий Беленко"), "/%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%87%D0%B8%D0%BA%D0%B8/%D0%AE%D1%80%D0%B8%D0%B9%20%D0%91%D0%B5%D0%BB%D0%B5%D0%BD%D0%BA%D0%BE");
|
||||
Assert.assertEquals(codegen.encodePath("/text with multilines \\\n\\\t\\\r"), "/text%20with%20multilines%20%5C%5C%20%5C%5C%20%5C%5C");
|
||||
Assert.assertEquals(codegen.encodePath("/path with argument {value}"), "/path%20with%20argument%20{value}");
|
||||
|
||||
// few examples from Slim documentation
|
||||
Assert.assertEquals(codegen.encodePath("/users[/{id}]"), "/users[/{id}]");
|
||||
Assert.assertEquals(codegen.encodePath("/news[/{year}[/{month}]]"), "/news[/{year}[/{month}]]");
|
||||
Assert.assertEquals(codegen.encodePath("/news[/{params:.*}]"), "/news[/{params:.*}]");
|
||||
Assert.assertEquals(codegen.encodePath("/users/{id:[0-9]+}"), "/users/{id:[0-9]+}");
|
||||
|
||||
// from FastRoute\RouteParser\Std.php
|
||||
Assert.assertEquals(codegen.encodePath("/user/{name}[/{id:[0-9]+}]"), "/user/{name}[/{id:[0-9]+}]");
|
||||
Assert.assertEquals(codegen.encodePath("/fixedRoutePart/{varName}[/moreFixed/{varName2:\\d+}]"), "/fixedRoutePart/{varName}[/moreFixed/{varName2:\\d+}]");
|
||||
}
|
||||
}
|
@ -53,7 +53,7 @@ class SlimRouter
|
||||
private $operations = [
|
||||
[
|
||||
'httpMethod' => 'PUT',
|
||||
'basePathWithoutHost' => '/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r',
|
||||
'basePathWithoutHost' => '/%20%27%20%22%20%3Dend%20--%20%5C%5Cr%5C%5Cn%20%5C%5Cn%20%5C%5Cr/v2%20*_/%20%27%20%22%20%3Dend%20--%20%5C%5Cr%5C%5Cn%20%5C%5Cn%20%5C%5Cr',
|
||||
'path' => '/fake',
|
||||
'apiPackage' => 'OpenAPIServer\Api',
|
||||
'classname' => 'AbstractFakeApi',
|
||||
|
Loading…
x
Reference in New Issue
Block a user