Skip to content

Commit fceceb4

Browse files
committed
Validate Resource type in ResourceHttpRequestHandler
1 parent e5ab67b commit fceceb4

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.springframework.web.HttpRequestHandler;
5858
import org.springframework.web.accept.ContentNegotiationManager;
5959
import org.springframework.web.context.request.ServletWebRequest;
60+
import org.springframework.web.context.support.ServletContextResource;
6061
import org.springframework.web.cors.CorsConfiguration;
6162
import org.springframework.web.cors.CorsConfigurationSource;
6263
import org.springframework.web.servlet.HandlerMapping;
@@ -445,6 +446,12 @@ private void resolveResourceLocations() {
445446
location = location.substring(endIndex + 1);
446447
}
447448
Resource resource = applicationContext.getResource(location);
449+
if (location.equals("/") && !(resource instanceof ServletContextResource)) {
450+
throw new IllegalStateException(
451+
"The String-based location \"/\" should be relative to the web application root " +
452+
"but resolved to a Resource of type: " + resource.getClass() + ". " +
453+
"If this is intentional, please pass it as a pre-configured Resource via setLocations.");
454+
}
448455
this.locationsToUse.add(resource);
449456
if (charset != null) {
450457
if (!(resource instanceof UrlResource)) {

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.junit.jupiter.api.extension.ExtendWith;
3030

3131
import org.springframework.core.io.ClassPathResource;
32+
import org.springframework.core.io.FileSystemResource;
3233
import org.springframework.core.io.Resource;
3334
import org.springframework.core.io.UrlResource;
3435
import org.springframework.http.HttpMethod;
@@ -38,6 +39,7 @@
3839
import org.springframework.web.HttpRequestMethodNotSupportedException;
3940
import org.springframework.web.accept.ContentNegotiationManager;
4041
import org.springframework.web.accept.ContentNegotiationManagerFactoryBean;
42+
import org.springframework.web.context.support.StaticWebApplicationContext;
4143
import org.springframework.web.servlet.HandlerMapping;
4244
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
4345
import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
@@ -723,6 +725,25 @@ public void ignoreLastModified() throws Exception {
723725
assertThat(this.response.getContentAsString()).isEqualTo("h1 { color:red; }");
724726
}
725727

728+
@Test
729+
public void servletContextRootValidation() {
730+
StaticWebApplicationContext context = new StaticWebApplicationContext() {
731+
@Override
732+
public Resource getResource(String location) {
733+
return new FileSystemResource("/");
734+
}
735+
};
736+
737+
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
738+
handler.setLocationValues(Collections.singletonList("/"));
739+
handler.setApplicationContext(context);
740+
741+
assertThatIllegalStateException().isThrownBy(handler::afterPropertiesSet)
742+
.withMessage("The String-based location \"/\" should be relative to the web application root but " +
743+
"resolved to a Resource of type: class org.springframework.core.io.FileSystemResource. " +
744+
"If this is intentional, please pass it as a pre-configured Resource via setLocations.");
745+
}
746+
726747

727748
private long resourceLastModified(String resourceName) throws IOException {
728749
return new ClassPathResource(resourceName, getClass()).getFile().lastModified();

0 commit comments

Comments
 (0)