Skip to content

Commit 8d57c4b

Browse files
committed
jooby-apt: Java strings not escaped properly in mvc source code generation.
- fix #3455 - shade commons-text + use automatic-module-name
1 parent b015958 commit 8d57c4b

File tree

7 files changed

+101
-31
lines changed

7 files changed

+101
-31
lines changed

modules/jooby-apt/pom.xml

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
<scope>test</scope>
2727
</dependency>
2828

29+
<dependency>
30+
<groupId>org.apache.commons</groupId>
31+
<artifactId>commons-text</artifactId>
32+
<version>1.12.0</version>
33+
</dependency>
34+
2935
<!-- Test dependencies -->
3036
<dependency>
3137
<groupId>com.google.testing.compile</groupId>
@@ -110,33 +116,47 @@
110116
</plugin>
111117

112118
<plugin>
113-
<groupId>org.moditect</groupId>
114-
<artifactId>moditect-maven-plugin</artifactId>
115-
<version>${moditec.version}</version>
119+
<groupId>org.apache.maven.plugins</groupId>
120+
<artifactId>maven-shade-plugin</artifactId>
116121
<executions>
117122
<execution>
118-
<id>generate-module-info</id>
123+
<id>fat-jar</id>
119124
<phase>package</phase>
120125
<goals>
121-
<goal>add-module-info</goal>
126+
<goal>shade</goal>
122127
</goals>
123128
<configuration>
124-
<overwriteExistingFiles>true</overwriteExistingFiles>
125-
<failOnWarning>false</failOnWarning>
126-
<module>
127-
<moduleInfo>
128-
<name>io.jooby.apt</name>
129-
<exports>
130-
!io.jooby.internal.*;
131-
*;
132-
</exports>
133-
</moduleInfo>
134-
</module>
129+
<minimizeJar>true</minimizeJar>
130+
<artifactSet>
131+
<includes>
132+
<include>org.apache.commons:commons-text</include>
133+
</includes>
134+
</artifactSet>
135+
<filters>
136+
<filter>
137+
<artifact>org.apache.commons:commons-text</artifact>
138+
<includes>
139+
<include>org/apache/commons/text/**</include>
140+
</includes>
141+
</filter>
142+
</filters>
143+
<relocations>
144+
<relocation>
145+
<pattern>org.apache.commons.text</pattern>
146+
<shadedPattern>${shaded.package}.commonstext</shadedPattern>
147+
</relocation>
148+
</relocations>
149+
<transformers>
150+
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
151+
<manifestEntries>
152+
<Automatic-Module-Name>io.jooby.apt</Automatic-Module-Name>
153+
</manifestEntries>
154+
</transformer>
155+
</transformers>
135156
</configuration>
136157
</execution>
137158
</executions>
138159
</plugin>
139-
140160
</plugins>
141161
</build>
142162
</project>

modules/jooby-apt/src/main/java/io/jooby/internal/apt/CodeBlock.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
package io.jooby.internal.apt;
77

8+
import static org.apache.commons.text.StringEscapeUtils.ESCAPE_JAVA;
9+
810
import java.util.List;
911
import java.util.stream.Stream;
1012

@@ -22,7 +24,7 @@ public static String of(CharSequence... sequence) {
2224
}
2325

2426
public static CharSequence string(CharSequence value) {
25-
return "\"" + value + "\"";
27+
return "\"" + ESCAPE_JAVA.translate(value) + "\"";
2628
}
2729

2830
public static CharSequence clazz(boolean kt) {

modules/jooby-apt/src/main/java/io/jooby/internal/apt/MvcRoute.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public List<String> generateMapping(boolean kt) {
133133
block.add(statement(indent(2), ".setExecutorKey(", string(dispatch), ")")));
134134
/* attributes */
135135
attributeGenerator
136-
.toSourceCode(this, indent(2))
136+
.toSourceCode(this, 2)
137137
.ifPresent(
138138
attributes -> block.add(statement(indent(2), ".setAttributes(", attributes, ")")));
139139
/* returnType */

modules/jooby-apt/src/main/java/io/jooby/internal/apt/RouteAttributesGenerator.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.jooby.internal.apt;
77

88
import static io.jooby.apt.JoobyProcessor.Options.SKIP_ATTRIBUTE_ANNOTATIONS;
9+
import static io.jooby.internal.apt.CodeBlock.indent;
910

1011
import java.lang.annotation.Retention;
1112
import java.lang.annotation.RetentionPolicy;
@@ -53,16 +54,16 @@ public RouteAttributesGenerator(MvcContext context) {
5354
this.skip = Options.stringListOpt(environment, SKIP_ATTRIBUTE_ANNOTATIONS);
5455
}
5556

56-
public Optional<String> toSourceCode(MvcRoute route, String indent) {
57+
public Optional<String> toSourceCode(MvcRoute route, int indent) {
5758
var attributes = annotationMap(route.getMethod());
5859
if (attributes.isEmpty()) {
5960
return Optional.empty();
6061
} else {
61-
return Optional.of(toSourceCode(annotationMap(route.getMethod()), indent));
62+
return Optional.of(toSourceCode(annotationMap(route.getMethod()), indent + 6));
6263
}
6364
}
6465

65-
private String toSourceCode(Map<String, Object> attributes, String indent) {
66+
private String toSourceCode(Map<String, Object> attributes, int indent) {
6667
var buffer = new StringBuilder();
6768
var separator = ",\n";
6869
var pairPrefix = "";
@@ -75,26 +76,25 @@ private String toSourceCode(Map<String, Object> attributes, String indent) {
7576
factoryMethod = "ofEntries";
7677
}
7778
buffer.append("java.util.Map.").append(factoryMethod).append("(\n");
78-
var lineIndent = indent + " ";
7979
for (var e : attributes.entrySet()) {
80-
buffer.append(lineIndent);
80+
buffer.append(indent(indent + 4));
8181
buffer.append(pairPrefix);
82-
buffer.append("\"").append(e.getKey()).append("\"").append(", ");
83-
buffer.append(valueToSourceCode(e.getValue(), lineIndent));
82+
buffer.append(CodeBlock.string(e.getKey())).append(", ");
83+
buffer.append(valueToSourceCode(e.getValue(), indent + 4));
8484
buffer.append(pairSuffix).append(separator);
8585
}
8686
buffer.setLength(buffer.length() - separator.length());
8787
buffer.append(")");
8888
return buffer.toString();
8989
}
9090

91-
private Object valueToSourceCode(Object value, String indent) {
91+
private Object valueToSourceCode(Object value, int indent) {
9292
if (value instanceof String) {
93-
return "\"" + value + "\"";
93+
return CodeBlock.string((String) value);
9494
} else if (value instanceof Character) {
9595
return "'" + value + "'";
9696
} else if (value instanceof Map attributeMap) {
97-
return "\n " + indent + toSourceCode(attributeMap, indent + " ");
97+
return "\n " + indent(indent) + toSourceCode(attributeMap, indent + 1);
9898
} else if (value instanceof List list) {
9999
return valueToSourceCode(list, indent);
100100
} else if (value instanceof EnumValue enumValue) {
@@ -116,7 +116,7 @@ private Object valueToSourceCode(Object value, String indent) {
116116
}
117117
}
118118

119-
private String valueToSourceCode(List values, String indent) {
119+
private String valueToSourceCode(List values, int indent) {
120120
var buffer = new StringBuilder();
121121
buffer.append("java.util.List.of(");
122122
var separator = ", ";

modules/jooby-apt/src/test/java/tests/i2417/Issue2417.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public class Issue2417 {
1818
public void shouldNotIgnoreAnnotationOnParam() throws Exception {
1919
new ProcessorRunner(new C2417())
2020
.withRouter(
21-
app -> {
21+
(app, source) -> {
22+
System.out.println(source);
2223
MockRouter router = new MockRouter(app);
2324
assertEquals(
2425
"2417",
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3455;
7+
8+
import edu.umd.cs.findbugs.annotations.NonNull;
9+
import io.jooby.annotation.GET;
10+
import io.jooby.annotation.Path;
11+
import io.jooby.annotation.QueryParam;
12+
import io.swagger.v3.oas.annotations.media.Schema;
13+
14+
@Path("/\"path")
15+
public class C3455 {
16+
@GET("/required\"-string-param")
17+
@Schema(description = "test\"ttttt")
18+
public String requiredStringParam(@QueryParam("value\"") @NonNull String value) {
19+
return value;
20+
}
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3455;
7+
8+
import static org.junit.jupiter.api.Assertions.assertTrue;
9+
10+
import org.junit.jupiter.api.Test;
11+
12+
import io.jooby.apt.ProcessorRunner;
13+
14+
public class Issue3455 {
15+
16+
@Test
17+
public void shouldEscapeJavaSpecialCharacters() throws Exception {
18+
new ProcessorRunner(new C3455())
19+
.withRouter(
20+
(app, source) -> {
21+
assertTrue(source.toString().contains("\"/\\\"path/required\\\"-string-param\""));
22+
assertTrue(source.toString().contains("\"test\\\"ttttt\""));
23+
assertTrue(source.toString().contains("\"value\\\"\""));
24+
});
25+
}
26+
}

0 commit comments

Comments
 (0)