From de18d96413465700ccc3c35fb85b65606bce3450 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 23 Apr 2018 15:20:12 -0400 Subject: [PATCH] Validate contextPath in RedirectView Issue: SPR-16752 --- .../web/servlet/view/RedirectView.java | 10 +++++++- .../web/servlet/view/RedirectViewTests.java | 23 ++++++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java index 277c341d37..e320a8cc26 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java @@ -329,7 +329,7 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView { if (this.contextRelative && getUrl().startsWith("/")) { // Do not apply context path to relative URLs. - targetUrl.append(request.getContextPath()); + targetUrl.append(getContextPath(request)); } targetUrl.append(getUrl()); @@ -355,6 +355,14 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView { return targetUrl.toString(); } + private String getContextPath(HttpServletRequest request) { + String contextPath = request.getContextPath(); + while (contextPath.startsWith("//")) { + contextPath = contextPath.substring(1); + } + return contextPath; + } + /** * Replace URI template variables in the target URL with encoded model * attributes or URI variables from the current request. Model attributes diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java index 0eeddc6ff5..8b045da106 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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. @@ -172,9 +172,7 @@ public class RedirectViewTests { request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); given(mockProcessor.processUrl(request, "/path")).willReturn("/path?key=123"); - rv.render(new ModelMap(), request, response); - verify(mockProcessor).processUrl(request, "/path"); } @@ -196,9 +194,7 @@ public class RedirectViewTests { rv.setUrl("/path"); given(mockProcessor.processUrl(request, "/path")).willReturn("/path?key=123"); - rv.render(new ModelMap(), request, response); - verify(mockProcessor).processUrl(request, "/path"); } finally { @@ -206,9 +202,7 @@ public class RedirectViewTests { } } - // SPR-13693 - - @Test + @Test // SPR-13693 public void remoteHost() throws Exception { RedirectView rv = new RedirectView(); @@ -224,6 +218,19 @@ public class RedirectViewTests { } + @Test // SPR-16752 + public void contextRelativeWithValidatedContextPath() throws Exception { + String url = "/myUrl"; + + this.request.setContextPath("//context"); + this.response = new MockHttpServletResponse(); + doTest(new HashMap<>(), url, true, "/context" + url); + + this.request.setContextPath("///context"); + this.response = new MockHttpServletResponse(); + doTest(new HashMap<>(), url, true, "/context" + url); + } + @Test public void emptyMap() throws Exception { String url = "/myUrl";