Skip to content

Commit 3502f6f

Browse files
committed
Validate contextPath in RedirectView
Issue: SPR-16752
1 parent 8d67a98 commit 3502f6f

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/view/RedirectView.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ protected final String createTargetUrl(Map<String, Object> model, HttpServletReq
332332
StringBuilder targetUrl = new StringBuilder();
333333
if (this.contextRelative && getUrl().startsWith("/")) {
334334
// Do not apply context path to relative URLs.
335-
targetUrl.append(request.getContextPath());
335+
targetUrl.append(getContextPath(request));
336336
}
337337
targetUrl.append(getUrl());
338338

@@ -358,6 +358,14 @@ protected final String createTargetUrl(Map<String, Object> model, HttpServletReq
358358
return targetUrl.toString();
359359
}
360360

361+
private String getContextPath(HttpServletRequest request) {
362+
String contextPath = request.getContextPath();
363+
while (contextPath.startsWith("//")) {
364+
contextPath = contextPath.substring(1);
365+
}
366+
return contextPath;
367+
}
368+
361369
/**
362370
* Replace URI template variables in the target URL with encoded model
363371
* attributes or URI variables from the current request. Model attributes

spring-webmvc/src/test/java/org/springframework/web/servlet/view/RedirectViewTests.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -172,9 +172,7 @@ public void updateTargetUrl() throws Exception {
172172
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
173173

174174
given(mockProcessor.processUrl(request, "/path")).willReturn("/path?key=123");
175-
176175
rv.render(new ModelMap(), request, response);
177-
178176
verify(mockProcessor).processUrl(request, "/path");
179177
}
180178

@@ -196,19 +194,15 @@ public void updateTargetUrlWithContextLoader() throws Exception {
196194
rv.setUrl("/path");
197195

198196
given(mockProcessor.processUrl(request, "/path")).willReturn("/path?key=123");
199-
200197
rv.render(new ModelMap(), request, response);
201-
202198
verify(mockProcessor).processUrl(request, "/path");
203199
}
204200
finally {
205201
contextLoader.closeWebApplicationContext(servletContext);
206202
}
207203
}
208204

209-
// SPR-13693
210-
211-
@Test
205+
@Test // SPR-13693
212206
public void remoteHost() throws Exception {
213207
RedirectView rv = new RedirectView();
214208

@@ -224,6 +218,19 @@ public void remoteHost() throws Exception {
224218

225219
}
226220

221+
@Test // SPR-16752
222+
public void contextRelativeWithValidatedContextPath() throws Exception {
223+
String url = "/myUrl";
224+
225+
this.request.setContextPath("//context");
226+
this.response = new MockHttpServletResponse();
227+
doTest(new HashMap<>(), url, true, "/context" + url);
228+
229+
this.request.setContextPath("///context");
230+
this.response = new MockHttpServletResponse();
231+
doTest(new HashMap<>(), url, true, "/context" + url);
232+
}
233+
227234
@Test
228235
public void emptyMap() throws Exception {
229236
String url = "/myUrl";

0 commit comments

Comments
 (0)