Fix empty URLs handling in ResourceUrlEncodingFilter

Prior to this commit, the ResourceUrlEncodingFilter would fail with a
StringIndexOutOfBoundsException when:

* the current request has a servlet context
* the URL to encode is relative and is shorter than the context value

This change defensively checks for those lengths and delegates to the
parent implementation if necessary.

Issue: SPR-13018
This commit is contained in:
Brian Clozel 2015-05-13 14:30:09 +02:00
parent 02da2e85ee
commit 71c3e4e4ee
2 changed files with 26 additions and 4 deletions

View File

@ -73,10 +73,15 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter {
return super.encodeURL(url);
}
initIndexLookupPath(resourceUrlProvider);
String prefix = url.substring(0, this.indexLookupPath);
String lookupPath = url.substring(this.indexLookupPath);
lookupPath = resourceUrlProvider.getForLookupPath(lookupPath);
return (lookupPath != null ? super.encodeURL(prefix + lookupPath) : super.encodeURL(url));
if(url.length() >= this.indexLookupPath) {
String prefix = url.substring(0, this.indexLookupPath);
String lookupPath = url.substring(this.indexLookupPath);
lookupPath = resourceUrlProvider.getForLookupPath(lookupPath);
if (lookupPath != null) {
return super.encodeURL(prefix + lookupPath);
}
}
return super.encodeURL(url);
}
private ResourceUrlProvider getResourceUrlProvider() {

View File

@ -89,6 +89,23 @@ public class ResourceUrlEncodingFilterTests {
});
}
// SPR-13018
@Test
public void encodeEmptyURLWithContext() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/context/foo");
request.setContextPath("/context");
request.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider);
MockHttpServletResponse response = new MockHttpServletResponse();
this.filter.doFilterInternal(request, response, new FilterChain() {
@Override
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
String result = ((HttpServletResponse)response).encodeURL("?foo=1");
assertEquals("?foo=1", result);
}
});
}
protected ResourceUrlProvider createResourceUrlProvider(List<ResourceResolver> resolvers) {
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
handler.setLocations(Arrays.asList(new ClassPathResource("test/", getClass())));