Skip to content

Commit 029101c

Browse files
committed
Merge pull request #2025 from neVERberleRfellerER/SPR-17535
2 parents 82eb82a + 3eee118 commit 029101c

File tree

2 files changed

+50
-51
lines changed

2 files changed

+50
-51
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public String resolveUrlPath(String url) {
115115
return null;
116116
}
117117
if (this.indexLookupPath != null && url.startsWith(this.prefixLookupPath)) {
118-
int suffixIndex = getQueryParamsIndex(url);
118+
int suffixIndex = getEndPathIndex(url);
119119
String suffix = url.substring(suffixIndex);
120120
String lookupPath = url.substring(this.indexLookupPath, suffixIndex);
121121
lookupPath = this.resourceUrlProvider.getForLookupPath(lookupPath);
@@ -126,9 +126,16 @@ public String resolveUrlPath(String url) {
126126
return null;
127127
}
128128

129-
private int getQueryParamsIndex(String url) {
130-
int index = url.indexOf('?');
131-
return (index > 0 ? index : url.length());
129+
private int getEndPathIndex(String path) {
130+
int end = path.indexOf('?');
131+
int fragmentIndex = path.indexOf('#');
132+
if (fragmentIndex != -1 && (end == -1 || fragmentIndex < end)) {
133+
end = fragmentIndex;
134+
}
135+
if (end == -1) {
136+
end = path.length();
137+
}
138+
return end;
132139
}
133140
}
134141

spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
*/
1616
package org.springframework.web.servlet.resource;
1717

18+
import java.io.IOException;
1819
import java.util.ArrayList;
1920
import java.util.Collections;
2021
import java.util.List;
22+
import javax.servlet.ServletException;
2123
import javax.servlet.http.HttpServletResponse;
2224

2325
import org.junit.Before;
@@ -68,37 +70,26 @@ private ResourceUrlProvider createResourceUrlProvider(List<ResourceResolver> res
6870

6971
@Test
7072
public void encodeURL() throws Exception {
71-
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
72-
MockHttpServletResponse response = new MockHttpServletResponse();
73-
74-
this.filter.doFilter(request, response, (req, res) -> {
75-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
76-
String result = ((HttpServletResponse) res).encodeURL("/resources/bar.css");
77-
assertEquals("/resources/bar-11e16cf79faee7ac698c805cf28248d2.css", result);
78-
});
73+
testEncodeUrl(new MockHttpServletRequest("GET", "/"),
74+
"/resources/bar.css", "/resources/bar-11e16cf79faee7ac698c805cf28248d2.css");
7975
}
8076

8177
@Test
82-
public void encodeURLWithContext() throws Exception {
78+
public void encodeUrlWithContext() throws Exception {
8379
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/foo");
8480
request.setContextPath("/context");
85-
MockHttpServletResponse response = new MockHttpServletResponse();
8681

87-
this.filter.doFilter(request, response, (req, res) -> {
88-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
89-
String result = ((HttpServletResponse) res).encodeURL("/context/resources/bar.css");
90-
assertEquals("/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css", result);
91-
});
82+
testEncodeUrl(request, "/context/resources/bar.css",
83+
"/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css");
9284
}
9385

9486

9587
@Test
9688
public void encodeUrlWithContextAndForwardedRequest() throws Exception {
9789
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/foo");
9890
request.setContextPath("/context");
99-
MockHttpServletResponse response = new MockHttpServletResponse();
10091

101-
this.filter.doFilter(request, response, (req, res) -> {
92+
this.filter.doFilter(request, new MockHttpServletResponse(), (req, res) -> {
10293
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
10394
request.setRequestURI("/forwarded");
10495
request.setContextPath("/");
@@ -111,65 +102,66 @@ public void encodeUrlWithContextAndForwardedRequest() throws Exception {
111102
public void encodeContextPathUrlWithoutSuffix() throws Exception {
112103
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context");
113104
request.setContextPath("/context");
114-
MockHttpServletResponse response = new MockHttpServletResponse();
115105

116-
this.filter.doFilter(request, response, (req, res) -> {
117-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
118-
String result = ((HttpServletResponse) res).encodeURL("/context/resources/bar.css");
119-
assertEquals("/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css", result);
120-
});
106+
testEncodeUrl(request, "/context/resources/bar.css",
107+
"/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css");
121108
}
122109

123110
@Test
124111
public void encodeContextPathUrlWithSuffix() throws Exception {
125112
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/");
126113
request.setContextPath("/context");
127-
MockHttpServletResponse response = new MockHttpServletResponse();
128114

129-
this.filter.doFilter(request, response, (req, res) -> {
130-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
131-
String result = ((HttpServletResponse) res).encodeURL("/context/resources/bar.css");
132-
assertEquals("/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css", result);
133-
});
115+
testEncodeUrl(request, "/context/resources/bar.css",
116+
"/context/resources/bar-11e16cf79faee7ac698c805cf28248d2.css");
134117
}
135118

136119
@Test // SPR-13018
137-
public void encodeEmptyURLWithContext() throws Exception {
120+
public void encodeEmptyUrlWithContext() throws Exception {
138121
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/foo");
139122
request.setContextPath("/context");
140-
MockHttpServletResponse response = new MockHttpServletResponse();
141123

142-
this.filter.doFilter(request, response, (req, res) -> {
143-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
144-
String result = ((HttpServletResponse) res).encodeURL("?foo=1");
145-
assertEquals("?foo=1", result);
146-
});
124+
testEncodeUrl(request, "?foo=1", "?foo=1");
147125
}
148126

149127
@Test // SPR-13374
150-
public void encodeURLWithRequestParams() throws Exception {
128+
public void encodeUrlWithRequestParams() throws Exception {
151129
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
152130
request.setContextPath("/");
153-
MockHttpServletResponse response = new MockHttpServletResponse();
154131

155-
this.filter.doFilter(request, response, (req, res) -> {
156-
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
157-
String result = ((HttpServletResponse) res).encodeURL("/resources/bar.css?foo=bar&url=http://example.org");
158-
assertEquals("/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org", result);
159-
});
132+
testEncodeUrl(request, "/resources/bar.css?foo=bar&url=http://example.org",
133+
"/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org");
160134
}
161135

162136
@Test // SPR-13847
163137
public void encodeUrlPreventStringOutOfBounds() throws Exception {
164138
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context-path/index");
165139
request.setContextPath("/context-path");
166140
request.setServletPath("");
167-
MockHttpServletResponse response = new MockHttpServletResponse();
168141

169-
this.filter.doFilter(request, response, (req, res) -> {
142+
testEncodeUrl(request, "index?key=value", "index?key=value");
143+
}
144+
145+
@Test // SPR-17535
146+
public void encodeUrlWithFragment() throws Exception {
147+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
148+
request.setContextPath("/");
149+
150+
testEncodeUrl(request, "/resources/bar.css#something",
151+
"/resources/bar-11e16cf79faee7ac698c805cf28248d2.css#something");
152+
153+
testEncodeUrl(request,
154+
"/resources/bar.css?foo=bar&url=http://example.org#something",
155+
"/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org#something");
156+
}
157+
158+
private void testEncodeUrl(MockHttpServletRequest request, String url, String expected)
159+
throws ServletException, IOException {
160+
161+
this.filter.doFilter(request, new MockHttpServletResponse(), (req, res) -> {
170162
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
171-
String result = ((HttpServletResponse) res).encodeURL("index?key=value");
172-
assertEquals("index?key=value", result);
163+
String result = ((HttpServletResponse) res).encodeURL(url);
164+
assertEquals(expected, result);
173165
});
174166
}
175167

0 commit comments

Comments
 (0)