diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
index 14a20c7e080..260986bfa36 100644
--- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
+++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
@@ -521,7 +521,8 @@ public class UrlPathHelper {
* @return the updated URI string
*/
public String removeSemicolonContent(String requestUri) {
- return (this.removeSemicolonContent ? removeSemicolonContentInternal(requestUri) : requestUri);
+ return (this.removeSemicolonContent ?
+ removeSemicolonContentInternal(requestUri) : removeJsessionid(requestUri));
}
private String removeSemicolonContentInternal(String requestUri) {
@@ -535,6 +536,22 @@ public class UrlPathHelper {
return requestUri;
}
+ private String removeJsessionid(String requestUri) {
+ String key = ";jsessionid=";
+ int index = requestUri.toLowerCase().indexOf(key);
+ if (index == -1) {
+ return requestUri;
+ }
+ String start = requestUri.substring(0, index);
+ for (int i = key.length(); i < requestUri.length(); i++) {
+ char c = requestUri.charAt(i);
+ if (c == ';' || c == '/') {
+ return start + requestUri.substring(i);
+ }
+ }
+ return start;
+ }
+
/**
* Decode the given URI path variables via {@link #decodeRequestString} unless
* {@link #setUrlDecode} is set to {@code true} in which case it is assumed
@@ -639,7 +656,13 @@ public class UrlPathHelper {
*
{@code defaultEncoding=}{@link WebUtils#DEFAULT_CHARACTER_ENCODING}
*
*/
- public static final UrlPathHelper rawPathInstance = new UrlPathHelper();
+ public static final UrlPathHelper rawPathInstance = new UrlPathHelper() {
+
+ @Override
+ public String removeSemicolonContent(String requestUri) {
+ return requestUri;
+ }
+ };
static {
rawPathInstance.setAlwaysUseFullPath(true);
diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
index 361972f56ab..35f6c93b199 100644
--- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
+++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
@@ -133,7 +133,7 @@ public class UrlPathHelperTests {
assertEquals("/foo;a=b;c=d", helper.getRequestUri(request));
request.setRequestURI("/foo;jsessionid=c0o7fszeb1");
- assertEquals("/foo;jsessionid=c0o7fszeb1", helper.getRequestUri(request));
+ assertEquals("/foo", helper.getRequestUri(request));
}
@Test
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java
index 9f220860dfa..0999b040eff 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java
@@ -380,15 +380,16 @@ public class RequestResponseBodyMethodProcessorTests {
Collections.singletonList(new StringHttpMessageConverter()),
factory.getObject());
- assertContentDisposition(processor, false, "/hello.json", "whitelisted extension");
+ assertContentDisposition(processor, false, "/hello.json", "safe extension");
assertContentDisposition(processor, false, "/hello.pdf", "registered extension");
assertContentDisposition(processor, true, "/hello.dataless", "uknown extension");
// path parameters
assertContentDisposition(processor, false, "/hello.json;a=b", "path param shouldn't cause issue");
- assertContentDisposition(processor, true, "/hello.json;a=b;setup.dataless", "uknown ext in path params");
- assertContentDisposition(processor, true, "/hello.dataless;a=b;setup.json", "uknown ext in filename");
- assertContentDisposition(processor, false, "/hello.json;a=b;setup.json", "whitelisted extensions");
+ assertContentDisposition(processor, true, "/hello.json;a=b;setup.dataless", "unknown ext in path params");
+ assertContentDisposition(processor, true, "/hello.dataless;a=b;setup.json", "unknown ext in filename");
+ assertContentDisposition(processor, false, "/hello.json;a=b;setup.json", "safe extensions");
+ assertContentDisposition(processor, true, "/hello.json;jsessionid=foo.bar", "jsessionid shouldn't cause issue");
// encoded dot
assertContentDisposition(processor, true, "/hello%2Edataless;a=b;setup.json", "encoded dot in filename");
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java
index 28e15ed3c8d..e3e4d674715 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -86,6 +86,28 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
assertEquals("test-42-7", response.getContentAsString());
}
+ @Test // gh-25864
+ public void literalMappingWithPathParams() throws Exception {
+ initServletWithControllers(MultipleUriTemplateController.class);
+
+ MockHttpServletRequest request = new MockHttpServletRequest("GET", "/data");
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ getServlet().service(request, response);
+ assertEquals(200, response.getStatus());
+ assertEquals("test", response.getContentAsString());
+
+ request = new MockHttpServletRequest("GET", "/data;foo=bar");
+ response = new MockHttpServletResponse();
+ getServlet().service(request, response);
+ assertEquals(404, response.getStatus());
+
+ request = new MockHttpServletRequest("GET", "/data;jsessionid=123");
+ response = new MockHttpServletResponse();
+ getServlet().service(request, response);
+ assertEquals(200, response.getStatus());
+ assertEquals("test", response.getContentAsString());
+ }
+
@Test
public void multiple() throws Exception {
initServletWithControllers(MultipleUriTemplateController.class);
@@ -405,6 +427,10 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
writer.write("test-" + hotel + "-q" + qHotel + "-" + booking + "-" + other + "-q" + qOther);
}
+ @RequestMapping("/data")
+ void handleWithLiteralMapping(Writer writer) throws IOException {
+ writer.write("test");
+ }
}
@Controller