Skip to content

Commit 80fd5e1

Browse files
committed
Fix ERRAI-904: Incorrect processing of nested braces in @PathParam regexes
1 parent 76dd616 commit 80fd5e1

8 files changed

Lines changed: 98 additions & 32 deletions

File tree

errai-jaxrs/errai-jaxrs-client/src/main/java/org/jboss/errai/enterprise/rebind/JaxrsProxyMethodGenerator.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,16 @@ private Statement generateUrl(final JaxrsResourceMethodParameters params) {
135135
String path = resourceMethod.getPath();
136136
ContextualStatementBuilder pathValue = Stmt.loadLiteral(path);
137137

138-
for (String pathParamName : JaxrsResourceMethodParameters.getPathParameterNames(path)) {
139-
String pathParamId = pathParamName;
140-
if (pathParamName.contains(":")) {
141-
pathParamId = pathParamName.split(":")[0];
138+
for (String pathParamExpr : JaxrsResourceMethodParameters.getPathParameterExpressions(path)) {
139+
String pathParamId = pathParamExpr;
140+
if (pathParamExpr.contains(":")) {
141+
pathParamId = pathParamExpr.split(":")[0];
142142
}
143143
Statement pathParam = marshal(params.getPathParameter(pathParamId));
144144
if (params.needsEncoding(pathParamId)) {
145145
pathParam = encodePath(pathParam);
146146
}
147-
pathValue = pathValue.invoke("replace", "{" + pathParamName + "}", pathParam);
147+
pathValue = pathValue.invoke("replace", "{" + pathParamExpr + "}", pathParam);
148148
}
149149

150150
if (params.getMatrixParameters() != null) {

errai-jaxrs/errai-jaxrs-client/src/main/java/org/jboss/errai/enterprise/rebind/JaxrsResourceMethodParameters.java

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ public class JaxrsResourceMethodParameters {
6262
private Map<Class<? extends Annotation>, MultivaluedMap<String, Statement>> parameters;
6363

6464
public static JaxrsResourceMethodParameters fromMethod(MetaMethod method) {
65-
List<Parameter> defParams = DefParameters.from(method).getParameters();
65+
final List<Parameter> defParams = DefParameters.from(method).getParameters();
6666
return fromMethod(method, defParams);
6767
}
6868

6969
public static JaxrsResourceMethodParameters fromMethod(MetaMethod method, String parameterArrayVarName) {
70-
List<Statement> params = new ArrayList<Statement>();
71-
Parameter[] defParms = DefParameters.from(method).getParameters().toArray(new Parameter[0]);
70+
final List<Statement> params = new ArrayList<Statement>();
71+
final Parameter[] defParms = DefParameters.from(method).getParameters().toArray(new Parameter[0]);
7272
for (int i = 0; i < defParms.length; i++) {
7373
final MetaClass type = defParms[i].getType().asBoxed();
7474
final Statement s = Cast.to(type, Stmt.loadVariable(parameterArrayVarName, i));
@@ -89,11 +89,11 @@ public MetaClass getType() {
8989
}
9090

9191
public static JaxrsResourceMethodParameters fromMethod(MetaMethod method, List<? extends Statement> parameterValues) {
92-
JaxrsResourceMethodParameters params = new JaxrsResourceMethodParameters();
92+
final JaxrsResourceMethodParameters params = new JaxrsResourceMethodParameters();
9393
int i = 0;
94-
for (MetaParameter param : method.getParameters()) {
94+
for (final MetaParameter param : method.getParameters()) {
9595

96-
Statement paramValue = parameterValues.get(i++);
96+
final Statement paramValue = parameterValues.get(i++);
9797
Annotation a = param.getAnnotation(PathParam.class);
9898
if (a != null) {
9999
params.add(PathParam.class, ((PathParam) a).value(), paramValue);
@@ -222,7 +222,7 @@ private Statement getParameterByName(Class<? extends Annotation> type, String na
222222
Statement param = null;
223223

224224
if (get(type) != null) {
225-
List<Statement> params = get(type).get(name);
225+
final List<Statement> params = get(type).get(name);
226226
if (params != null && !params.isEmpty()) {
227227
param = params.get(0);
228228
}
@@ -231,15 +231,18 @@ private Statement getParameterByName(Class<? extends Annotation> type, String na
231231
return param;
232232
}
233233

234-
public static List<String> getPathParameterNames(String path) {
235-
List<String> pathParamNames = new ArrayList<String>();
236-
Matcher matcher = PATH_PARAM_PATTERN.matcher(path);
237-
234+
public static List<String> getPathParameterExpressions(String path) {
235+
final String pathWithNestedBracesRemoved = replaceNestedCurlyBraces(path);
236+
final List<String> pathParamNames = new ArrayList<String>();
237+
final Matcher matcher = PATH_PARAM_PATTERN.matcher(pathWithNestedBracesRemoved);
238+
238239
while (matcher.find()) {
239-
String id = matcher.group(2);
240-
String regex = matcher.group(3);
241-
if (id != null)
242-
pathParamNames.add(id + ((regex != null) ? regex : ""));
240+
final String id = matcher.group(2);
241+
final String regex = matcher.group(3);
242+
if (id != null) {
243+
final String pathParamExpr = recoverNestedCurlyBraces(id + ((regex != null) ? regex : ""));
244+
pathParamNames.add(pathParamExpr);
245+
}
243246
}
244247

245248
return pathParamNames;
@@ -253,4 +256,31 @@ public boolean needsEncoding(String paramName) {
253256

254257
return true;
255258
}
259+
260+
private static final char openCurlyReplacement = 6;
261+
private static final char closeCurlyReplacement = 7;
262+
263+
private static String replaceNestedCurlyBraces(String str) {
264+
final char[] chars = str.toCharArray();
265+
int open = 0;
266+
for (int i = 0; i < chars.length; i++) {
267+
if (chars[i] == '{') {
268+
if (open != 0)
269+
chars[i] = openCurlyReplacement;
270+
open++;
271+
}
272+
else if (chars[i] == '}') {
273+
open--;
274+
if (open != 0) {
275+
chars[i] = closeCurlyReplacement;
276+
}
277+
}
278+
}
279+
return new String(chars);
280+
}
281+
282+
private static String recoverNestedCurlyBraces(String str) {
283+
return str.replace(openCurlyReplacement, '{').replace(closeCurlyReplacement, '}');
284+
}
285+
256286
}

errai-jaxrs/errai-jaxrs-client/src/test/java/org/jboss/errai/enterprise/jaxrs/client/shared/PathParamTestService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ public interface PathParamTestService {
4545
@GET
4646
@Path("/t1/{id:[0-9][0-9]*}")
4747
public long getWithPathParamRegex(@PathParam("id") long id);
48+
49+
@GET
50+
@Path("/t1/{id:[0-9]{1}[0-9]{0,}}")
51+
public long getWithPathParamRegexAndCurlyBracesQuantifier(@PathParam("id") long id);
4852

4953
@GET
5054
@Path("/t2/{id}")

errai-jaxrs/errai-jaxrs-client/src/test/java/org/jboss/errai/enterprise/jaxrs/client/test/AllJaxrsTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
JacksonIntegrationTest.class,
4040
JaxrsResponseObjectIntegrationTest.class,
4141
MatrixParamIntegrationTest.class,
42+
PathParamTest.class,
4243
PathParamIntegrationTest.class,
4344
PlainMethodIntegrationTest.class,
4445
QueryParamIntegrationTest.class })

errai-jaxrs/errai-jaxrs-client/src/test/java/org/jboss/errai/enterprise/jaxrs/client/test/PathParamIntegrationTest.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,23 @@ public void testGetWithPathParamRegex() {
5050
call(PathParamTestService.class,
5151
new AssertionCallback<Long>("@GET with @PathParam using regex failed", 2l)).getWithPathParamRegex(2l);
5252
}
53+
54+
@Test
55+
public void testGetWithPathParamRegexAndCurlyBracesQuantifier() {
56+
call(PathParamTestService.class,
57+
new AssertionCallback<Long>("@GET with @PathParam using regex failed", 2l)).getWithPathParamRegexAndCurlyBracesQuantifier(2l);
58+
}
5359

5460
@Test
5561
public void testGetWithEncodedPathParam() {
56-
String pathWithSpecialChars = "?<>!@#$%^\\&*()-+;:''\\/.,";
62+
final String pathWithSpecialChars = "?<>!@#$%^\\&*()-+;:''\\/.,";
5763
call(PathParamTestService.class, new AssertionCallback<String>("@GET w/ encoded @PathParam failed",
5864
pathWithSpecialChars)).getWithStringPathParam(pathWithSpecialChars);
5965
}
6066

6167
@Test
6268
public void testGetWithPathSegmentPathParam() {
63-
PathSegment ps = new PathSegmentImpl("path;name=nameValue;author=authorValue;empty=");
69+
final PathSegment ps = new PathSegmentImpl("path;name=nameValue;author=authorValue;empty=");
6470
assertEquals("path", ps.getPath());
6571
assertEquals("nameValue", ps.getMatrixParameters().getFirst("name"));
6672
assertEquals("authorValue", ps.getMatrixParameters().getFirst("author"));
@@ -73,8 +79,8 @@ public void testGetWithPathSegmentPathParam() {
7379
}
7480
@Test
7581
public void testGetWithDatePathParam() {
76-
Date d = new Date();
77-
String expected = d.toString();
82+
final Date d = new Date();
83+
final String expected = d.toString();
7884
call(PathParamTestService.class,
7985
new AssertionCallback<String>("@GET with @PathParams using java.util.Date failed",
8086
expected)).getWithDatePathParam(d);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.jboss.errai.enterprise.jaxrs.client.test;
2+
3+
import static org.jboss.errai.enterprise.rebind.JaxrsResourceMethodParameters.getPathParameterExpressions;
4+
import static org.junit.Assert.assertEquals;
5+
6+
import java.util.Arrays;
7+
import java.util.List;
8+
import java.util.stream.Collectors;
9+
10+
import org.junit.Test;
11+
12+
public class PathParamTest {
13+
14+
@Test
15+
public void testMatchPathParamExpressions() {
16+
final List<String> expected = Arrays.asList("isbn", "param", "name", "zip", "p", "many", "id", "nr");
17+
18+
final String path = "/{isbn}/aaa{param}bbb/{name}-{zip}/aaa{p:b+}/{many:.*}/{id:[0-9]{1}[0-9]{0,}}/{nr:[0-9]*}";
19+
final List<String> pathParamNames = getPathParameterExpressions(path)
20+
.stream()
21+
.map(s -> s.split(":")[0])
22+
.collect(Collectors.toList());
23+
24+
assertEquals(expected, pathParamNames);
25+
}
26+
27+
}

errai-jaxrs/errai-jaxrs-client/src/test/java/org/jboss/errai/enterprise/jaxrs/server/PathParamTestServiceImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public long getWithPathParamRegex(long id) {
3939
return id;
4040
}
4141

42+
@Override
43+
public long getWithPathParamRegexAndCurlyBracesQuantifier(long id) {
44+
return id;
45+
}
46+
4247
@Override
4348
public String getWithStringPathParam(String id) {
4449
return id;
@@ -82,4 +87,5 @@ public String getWithPathSegmentPathParam(PathSegment id) {
8287
public String getWithDatePathParam(Date date) {
8388
return date.toString();
8489
}
90+
8591
}

errai-jaxrs/pom.xml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,6 @@
6767
</configuration>
6868
</plugin>
6969

70-
<plugin>
71-
<artifactId>maven-compiler-plugin</artifactId>
72-
<configuration>
73-
<source>1.6</source>
74-
<target>1.6</target>
75-
</configuration>
76-
</plugin>
77-
7870
<plugin>
7971
<artifactId>maven-source-plugin</artifactId>
8072
<executions>

0 commit comments

Comments
 (0)