Skip to content

Commit 4e4ec26

Browse files
committed
Adjust error response in ResourceUrlEncodingFilter
Failure to find the lookup path now results in 400 instead of 500 reflecting the presence of some issue with the input path. Closes gh-23508
1 parent bd8f94a commit 4e4ec26

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
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
@@ -96,10 +96,7 @@ private void initLookupPath(ResourceUrlProvider urlProvider) {
9696
String lookupPath = pathHelper.getLookupPathForRequest(this);
9797
this.indexLookupPath = requestUri.lastIndexOf(lookupPath);
9898
if (this.indexLookupPath == -1) {
99-
throw new IllegalStateException(
100-
"Failed to find lookupPath '" + lookupPath + "' within requestUri '" + requestUri + "'. " +
101-
"Does the path have invalid encoded characters for characterEncoding '" +
102-
getRequest().getCharacterEncoding() + "'?");
99+
throw new LookupPathIndexException(lookupPath, requestUri);
103100
}
104101
this.prefixLookupPath = requestUri.substring(0, this.indexLookupPath);
105102
if ("/".equals(lookupPath) && !"/".equals(requestUri)) {
@@ -164,4 +161,14 @@ public String encodeURL(String url) {
164161
}
165162
}
166163

164+
165+
@SuppressWarnings("serial")
166+
static class LookupPathIndexException extends IllegalArgumentException {
167+
168+
LookupPathIndexException(String lookupPath, String requestUri) {
169+
super("Failed to find lookupPath '" + lookupPath + "' within requestUri '" + requestUri + "'. " +
170+
"This could be because the path has invalid encoded characters or isn't normalized.");
171+
}
172+
}
173+
167174
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -20,6 +20,7 @@
2020
import javax.servlet.http.HttpServletResponse;
2121

2222
import org.springframework.util.Assert;
23+
import org.springframework.web.bind.ServletRequestBindingException;
2324
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
2425

2526
/**
@@ -48,7 +49,12 @@ public ResourceUrlProviderExposingInterceptor(ResourceUrlProvider resourceUrlPro
4849
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
4950
throws Exception {
5051

51-
request.setAttribute(RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider);
52+
try {
53+
request.setAttribute(RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider);
54+
}
55+
catch (ResourceUrlEncodingFilter.LookupPathIndexException ex) {
56+
throw new ServletRequestBindingException(ex.getMessage(), ex);
57+
}
5258
return true;
5359
}
5460

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

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 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.
@@ -19,7 +19,9 @@
1919
import java.util.ArrayList;
2020
import java.util.Collections;
2121
import java.util.List;
22+
import javax.servlet.FilterChain;
2223
import javax.servlet.ServletException;
24+
import javax.servlet.http.HttpServletRequest;
2325
import javax.servlet.http.HttpServletResponse;
2426

2527
import org.junit.Before;
@@ -28,6 +30,7 @@
2830
import org.springframework.core.io.ClassPathResource;
2931
import org.springframework.mock.web.test.MockHttpServletRequest;
3032
import org.springframework.mock.web.test.MockHttpServletResponse;
33+
import org.springframework.web.bind.ServletRequestBindingException;
3134

3235
import static org.junit.Assert.*;
3336

@@ -155,14 +158,36 @@ public void encodeUrlWithFragment() throws Exception {
155158
"/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=https://example.org#something");
156159
}
157160

161+
@Test // gh-23508
162+
public void invalidLookupPath() throws Exception {
163+
MockHttpServletRequest request = new MockHttpServletRequest();
164+
request.setRequestURI("/a/b/../logo.png");
165+
request.setServletPath("/a/logo.png");
166+
167+
this.filter.doFilter(request, new MockHttpServletResponse(), (req, res) -> {
168+
try {
169+
ResourceUrlProviderExposingInterceptor interceptor =
170+
new ResourceUrlProviderExposingInterceptor(this.urlProvider);
171+
172+
interceptor.preHandle((HttpServletRequest) req, (HttpServletResponse) res, new Object());
173+
fail();
174+
}
175+
catch (Exception ex) {
176+
assertEquals(ServletRequestBindingException.class, ex.getClass());
177+
}
178+
});
179+
}
180+
158181
private void testEncodeUrl(MockHttpServletRequest request, String url, String expected)
159182
throws ServletException, IOException {
160183

161-
this.filter.doFilter(request, new MockHttpServletResponse(), (req, res) -> {
184+
FilterChain chain = (req, res) -> {
162185
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
163186
String result = ((HttpServletResponse) res).encodeURL(url);
164187
assertEquals(expected, result);
165-
});
188+
};
189+
190+
this.filter.doFilter(request, new MockHttpServletResponse(), chain);
166191
}
167192

168193
}

0 commit comments

Comments
 (0)