From eb11c6fa233092506d360fb46d40d489107efd5f Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 7 Oct 2020 11:31:52 +0100 Subject: [PATCH] Reinstate removal of jsessionid from lookup path Closes gh-25864 --- .../web/util/UrlPathHelper.java | 27 ++++++++++++++++-- .../web/util/UrlPathHelperTests.java | 2 +- ...questResponseBodyMethodProcessorTests.java | 1 + ...nnotationControllerHandlerMethodTests.java | 28 ++++++++++++++++++- 4 files changed, 54 insertions(+), 4 deletions(-) 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 8e6118c1a5..127bdbd047 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 @@ -556,7 +556,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) { @@ -570,6 +571,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 @@ -675,7 +692,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 0797120c32..b21855572a 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 { assertThat(helper.getRequestUri(request)).isEqualTo("/foo;a=b;c=d"); request.setRequestURI("/foo;jsessionid=c0o7fszeb1"); - assertThat(helper.getRequestUri(request)).isEqualTo("/foo;jsessionid=c0o7fszeb1"); + assertThat(helper.getRequestUri(request)).isEqualTo("/foo"); } @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 c952eb16a6..09e546ad56 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 @@ -389,6 +389,7 @@ public class RequestResponseBodyMethodProcessorTests { 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 ceaf509939..0aff4fbabf 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-2019 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. @@ -69,6 +69,28 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab assertThat(response.getContentAsString()).isEqualTo("test-42-7"); } + @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); + assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getContentAsString()).isEqualTo("test"); + + request = new MockHttpServletRequest("GET", "/data;foo=bar"); + response = new MockHttpServletResponse(); + getServlet().service(request, response); + assertThat(response.getStatus()).isEqualTo(404); + + request = new MockHttpServletRequest("GET", "/data;jsessionid=123"); + response = new MockHttpServletResponse(); + getServlet().service(request, response); + assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getContentAsString()).isEqualTo("test"); + } + @Test public void multiple() throws Exception { initServletWithControllers(MultipleUriTemplateController.class); @@ -388,6 +410,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