From aad19cac6d6a67fdd65885899acd0c96675280d7 Mon Sep 17 00:00:00 2001 From: rmartinc Date: Mon, 4 Dec 2023 16:45:20 +0100 Subject: [PATCH] Save pathParamValues encoded and perform decoding when requested Fixes #35960 Signed-off-by: rmartinc --- .../core/ResteasyReactiveRequestContext.java | 41 ++++++++----------- .../LocatableResourcePathParamExtractor.java | 2 +- .../core/parameters/PathParamExtractor.java | 14 ++++--- .../reactive/server/jaxrs/UriInfoImpl.java | 2 +- .../server/mapping/RequestMapper.java | 4 +- .../vertx/test/matching/RegexMatchTest.java | 4 ++ 6 files changed, 33 insertions(+), 34 deletions(-) diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ResteasyReactiveRequestContext.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ResteasyReactiveRequestContext.java index dedaf7dd127cd..2248a8f7763ac 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ResteasyReactiveRequestContext.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ResteasyReactiveRequestContext.java @@ -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) { @@ -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 @@ -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() { @@ -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; } @@ -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++; @@ -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(); diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/parameters/LocatableResourcePathParamExtractor.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/parameters/LocatableResourcePathParamExtractor.java index 835be0b515340..e478141b7c45c 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/parameters/LocatableResourcePathParamExtractor.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/parameters/LocatableResourcePathParamExtractor.java @@ -12,7 +12,7 @@ public LocatableResourcePathParamExtractor(String name) { @Override public Object extractParameter(ResteasyReactiveRequestContext context) { - return context.getResourceLocatorPathParam(name); + return context.getResourceLocatorPathParam(name, false); } } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/parameters/PathParamExtractor.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/parameters/PathParamExtractor.java index ccfa99edca5c3..d56f72b856bf5 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/parameters/PathParamExtractor.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/parameters/PathParamExtractor.java @@ -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; @@ -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()); } } } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/UriInfoImpl.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/UriInfoImpl.java index 7cbd13cb272a6..987bbf2838113 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/UriInfoImpl.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/UriInfoImpl.java @@ -152,7 +152,7 @@ public MultivaluedMap 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 pathParam : target.getPathParameterIndexes().entrySet()) { - pathParams.add(pathParam.getKey(), currentRequest.getPathParam(pathParam.getValue())); + pathParams.add(pathParam.getKey(), currentRequest.getPathParam(pathParam.getValue(), false)); } } } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/RequestMapper.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/RequestMapper.java index 5d8d5fc931191..7fd7cb535f518 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/RequestMapper.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/RequestMapper.java @@ -8,8 +8,6 @@ import java.util.Map; import java.util.regex.Matcher; -import org.jboss.resteasy.reactive.common.util.URIDecoder; - public class RequestMapper { private static final String[] EMPTY_STRING_ARRAY = new String[0]; @@ -111,7 +109,7 @@ private RequestMatch mapFromPathMatcher(String path, PathMatcher.PathMatch