Skip to content

Commit

Permalink
Save pathParamValues encoded and perform decoding when requested
Browse files Browse the repository at this point in the history
Fixes #35960

Signed-off-by: rmartinc <[email protected]>
  • Loading branch information
rmartinc committed Dec 4, 2023
1 parent 574e4f5 commit aad19ca
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,18 +226,20 @@ public void setMaxPathParams(int maxPathParams) {
}
}

public String getPathParam(int index) {
return doGetPathParam(index, pathParamValues);
public String getPathParam(int index, boolean encoded) {
return doGetPathParam(index, pathParamValues, encoded);
}

private String doGetPathParam(int index, Object pathParamValues) {
private String doGetPathParam(int index, Object pathParamValues, boolean encoded) {
if (pathParamValues instanceof String[]) {
return ((String[]) pathParamValues)[index];
String pathParam = ((String[]) pathParamValues)[index];
return encoded ? pathParam : Encode.decodePath(pathParam);
}
if (index > 1) {
throw new IndexOutOfBoundsException();
}
return (String) pathParamValues;
String pathParam = (String) pathParamValues;
return encoded ? pathParam : Encode.decodePath(pathParam);
}

public ResteasyReactiveRequestContext setPathParamValue(int index, String value) {
Expand Down Expand Up @@ -926,18 +928,11 @@ public String getPathParameter(String name, boolean encoded) {
Integer index = target.getPathParameterIndexes().get(name);
String value;
if (index != null) {
value = getPathParam(index);
} else {
// Check previous resources if the path is not defined in the current target
value = getResourceLocatorPathParam(name);
}

// It's possible to inject a path param that's not defined, return null in this case
if (encoded && value != null) {
return Encode.encodeQueryParam(value);
return getPathParam(index, encoded);
}

return value;
// Check previous resources if the path is not defined in the current target
return getResourceLocatorPathParam(name, encoded);
}

@Override
Expand Down Expand Up @@ -996,8 +991,8 @@ public ResteasyReactiveResourceInfo getResteasyReactiveResourceInfo() {

public abstract Runnable registerTimer(long millis, Runnable task);

public String getResourceLocatorPathParam(String name) {
return getResourceLocatorPathParam(name, (PreviousResource) getProperty(PreviousResource.PROPERTY_KEY));
public String getResourceLocatorPathParam(String name, boolean encoded) {
return getResourceLocatorPathParam(name, (PreviousResource) getProperty(PreviousResource.PROPERTY_KEY), encoded);
}

public FormData getFormData() {
Expand All @@ -1009,7 +1004,7 @@ public ResteasyReactiveRequestContext setFormData(FormData formData) {
return this;
}

private String getResourceLocatorPathParam(String name, PreviousResource previousResource) {
private String getResourceLocatorPathParam(String name, PreviousResource previousResource, boolean encoded) {
if (previousResource == null) {
return null;
}
Expand All @@ -1020,13 +1015,13 @@ private String getResourceLocatorPathParam(String name, PreviousResource previou
for (URITemplate.TemplateComponent component : classPath.components) {
if (component.name != null) {
if (component.name.equals(name)) {
return doGetPathParam(index, previousResource.locatorPathParamValues);
return doGetPathParam(index, previousResource.locatorPathParamValues, encoded);
}
index++;
} else if (component.names != null) {
for (String nm : component.names) {
if (nm.equals(name)) {
return doGetPathParam(index, previousResource.locatorPathParamValues);
return doGetPathParam(index, previousResource.locatorPathParamValues, encoded);
}
}
index++;
Expand All @@ -1036,19 +1031,19 @@ private String getResourceLocatorPathParam(String name, PreviousResource previou
for (URITemplate.TemplateComponent component : previousResource.locatorTarget.getPath().components) {
if (component.name != null) {
if (component.name.equals(name)) {
return doGetPathParam(index, previousResource.locatorPathParamValues);
return doGetPathParam(index, previousResource.locatorPathParamValues, encoded);
}
index++;
} else if (component.names != null) {
for (String nm : component.names) {
if (nm.equals(name)) {
return doGetPathParam(index, previousResource.locatorPathParamValues);
return doGetPathParam(index, previousResource.locatorPathParamValues, encoded);
}
}
index++;
}
}
return getResourceLocatorPathParam(name, previousResource.prev);
return getResourceLocatorPathParam(name, previousResource.prev, encoded);
}

public abstract boolean resumeExternalProcessing();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public LocatableResourcePathParamExtractor(String name) {

@Override
public Object extractParameter(ResteasyReactiveRequestContext context) {
return context.getResourceLocatorPathParam(name);
return context.getResourceLocatorPathParam(name, false);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.jboss.resteasy.reactive.server.core.parameters;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.jboss.resteasy.reactive.common.util.Encode;
import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext;
Expand All @@ -19,14 +21,14 @@ public PathParamExtractor(int index, boolean encoded, boolean single) {

@Override
public Object extractParameter(ResteasyReactiveRequestContext context) {
String pathParam = context.getPathParam(index);
if (encoded) {
pathParam = Encode.encodeQueryParam(pathParam);
}
String pathParam = context.getPathParam(index, true);
if (single) {
return pathParam;
return encoded ? pathParam : Encode.decodePath(pathParam);
} else {
return List.of(pathParam.split("/"));
return encoded
? List.of(pathParam.split("/"))
: Arrays.stream(pathParam.split("/")).map(Encode::decodePath)
.collect(Collectors.toList());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public MultivaluedMap<String, String> getPathParameters(boolean decode) {
RuntimeResource target = currentRequest.getTarget();
if (target != null) { // a target can be null if this happens in a filter that runs before the target is set
for (Entry<String, Integer> pathParam : target.getPathParameterIndexes().entrySet()) {
pathParams.add(pathParam.getKey(), currentRequest.getPathParam(pathParam.getValue()));
pathParams.add(pathParam.getKey(), currentRequest.getPathParam(pathParam.getValue(), false));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import java.util.Map;
import java.util.regex.Matcher;

import org.jboss.resteasy.reactive.common.util.URIDecoder;

public class RequestMapper<T> {

private static final String[] EMPTY_STRING_ARRAY = new String[0];
Expand Down Expand Up @@ -111,7 +109,7 @@ private RequestMatch<T> mapFromPathMatcher(String path, PathMatcher.PathMatch<Ar
while (matchPos < pathLength && path.charAt(matchPos) != '/') {
matchPos++;
}
params[paramCount++] = URIDecoder.decodeURIComponent(path.substring(start, matchPos), false);
params[paramCount++] = path.substring(start, matchPos);
}
}
if (!matched) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public void testLiteralInRegex() {
.then()
.statusCode(200)
.body(equalTo("plain:abb/foo/alongpathtotriggerbug"));
RestAssured.get("/regex/first space/foo/second space")
.then()
.statusCode(200)
.body(equalTo("plain:first space/foo/second space"));
RestAssured.get("/regex/abb/literal/ddc")
.then()
.statusCode(200)
Expand Down

0 comments on commit aad19ca

Please sign in to comment.