From afc2ea80a3c76ee9da6e570d93d5da92a54ed0ce Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Thu, 7 Dec 2023 13:48:12 +0100 Subject: [PATCH] Adapt SortHandlerMethodArgumentResolver after changes to sort parameter. Since the introduction of 6e22ffd, the sort parameter has been rendered as composite parameter which will cause the comma used to delimit property from direction potentially be encoded by clients following the URI template RFC. Thus, we need to defensively decode the source parameter value before parsing. Related ticket: GH-2531. --- .../web/SortHandlerMethodArgumentResolver.java | 9 +++++++-- ...SortHandlerMethodArgumentResolverUnitTests.java | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java b/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java index fd590e7c7..f97037872 100644 --- a/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java @@ -15,6 +15,7 @@ */ package org.springframework.data.web; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import org.springframework.core.MethodParameter; @@ -23,8 +24,8 @@ import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; +import org.springframework.web.util.UriUtils; /** * {@link HandlerMethodArgumentResolver} to automatically create {@link Sort} instances from request parameters or @@ -61,6 +62,10 @@ public class SortHandlerMethodArgumentResolver extends SortHandlerMethodArgument return getDefaultFromAnnotationOrFallback(parameter); } - return parseParameterIntoSort(Arrays.asList(directionParameter), getPropertyDelimiter()); + var decoded = Arrays.stream(directionParameter) + .map(it -> UriUtils.decode(it, StandardCharsets.UTF_8)) + .toList(); + + return parseParameterIntoSort(decoded, getPropertyDelimiter()); } } diff --git a/src/test/java/org/springframework/data/web/SortHandlerMethodArgumentResolverUnitTests.java b/src/test/java/org/springframework/data/web/SortHandlerMethodArgumentResolverUnitTests.java index 3b7ef0766..e94b3b47a 100755 --- a/src/test/java/org/springframework/data/web/SortHandlerMethodArgumentResolverUnitTests.java +++ b/src/test/java/org/springframework/data/web/SortHandlerMethodArgumentResolverUnitTests.java @@ -20,6 +20,7 @@ import static org.springframework.data.domain.Sort.Direction.*; import jakarta.servlet.http.HttpServletRequest; +import java.nio.charset.StandardCharsets; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeAll; @@ -35,6 +36,7 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.util.StringUtils; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.util.UriUtils; /** * Unit tests for {@link SortHandlerMethodArgumentResolver}. @@ -259,6 +261,18 @@ class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitTests { assertSupportedAndResolvedTo(getRequestWithSort(reference, "merged"), parameter, reference); } + @Test + void readsEncodedSort() { + + var request = new MockHttpServletRequest(); + request.addParameter("sort", UriUtils.encode("foo,desc", StandardCharsets.UTF_8)); + + var parameter = getParameterOfMethod("supportedMethod"); + var encoded = UriUtils.encode("foo,desc", StandardCharsets.UTF_8); + + assertSupportedAndResolvedTo(new ServletWebRequest(request), parameter, Sort.by("foo").descending()); + } + private static Sort resolveSort(HttpServletRequest request, MethodParameter parameter) throws Exception { var resolver = new SortHandlerMethodArgumentResolver();