From 71c3e4e4ee2d0cf206fd733a424b6afb83254f13 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 13 May 2015 14:30:09 +0200 Subject: [PATCH] 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 --- .../resource/ResourceUrlEncodingFilter.java | 13 +++++++++---- .../ResourceUrlEncodingFilterTests.java | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java index 4a1b7a6aef7..49845296924 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java @@ -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() { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java index 2f44b4480de..e94a2a615ff 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java @@ -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 resolvers) { ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); handler.setLocations(Arrays.asList(new ClassPathResource("test/", getClass())));