diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java index fd1a384577..1629c8fd02 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java @@ -18,8 +18,8 @@ package org.springframework.web.servlet.resource; import java.io.IOException; import java.net.URLDecoder; +import java.util.Arrays; import java.util.List; - import javax.servlet.http.HttpServletRequest; import org.springframework.core.io.ClassPathResource; @@ -122,24 +122,21 @@ public class PathResourceResolver extends AbstractResourceResolver { if (checkResource(resource, location)) { return resource; } - else { - if (logger.isTraceEnabled()) { - logger.trace("resourcePath=\"" + resourcePath + "\" was successfully resolved " + - "but resource=\"" + resource.getURL() + "\" is neither under the " + - "current location=\"" + location.getURL() + "\" nor under any of the " + - "allowed locations=" + getAllowedLocations()); - } + else if (logger.isTraceEnabled()) { + logger.trace("Resource path=\"" + resourcePath + "\" was successfully resolved " + + "but resource=\"" + resource.getURL() + "\" is neither under the " + + "current location=\"" + location.getURL() + "\" nor under any of the " + + "allowed locations=" + Arrays.asList(getAllowedLocations())); } } return null; } /** - * Perform additional checks on a resolved resource beyond checking whether - * the resources exists and is readable. The default implementation also - * verifies the resource is either under the location relative to which it - * was found or is under one of the {@link #setAllowedLocations allowed - * locations}. + * Perform additional checks on a resolved resource beyond checking whether the + * resources exists and is readable. The default implementation also verifies + * the resource is either under the location relative to which it was found or + * is under one of the {@link #setAllowedLocations allowed locations}. * @param resource the resource to check * @param location the location relative to which the resource was found * @return "true" if resource is in a valid location, "false" otherwise. @@ -165,15 +162,15 @@ public class PathResourceResolver extends AbstractResourceResolver { } String resourcePath; String locationPath; - if (resource instanceof ClassPathResource) { - resourcePath = ((ClassPathResource) resource).getPath(); - locationPath = ((ClassPathResource) location).getPath(); - } - else if (resource instanceof UrlResource) { + if (resource instanceof UrlResource) { resourcePath = resource.getURL().toExternalForm(); locationPath = location.getURL().toExternalForm(); } - else if(resource instanceof ServletContextResource) { + else if (resource instanceof ClassPathResource) { + resourcePath = ((ClassPathResource) resource).getPath(); + locationPath = ((ClassPathResource) location).getPath(); + } + else if (resource instanceof ServletContextResource) { resourcePath = ((ServletContextResource) resource).getPath(); locationPath = ((ServletContextResource) location).getPath(); } @@ -186,7 +183,7 @@ public class PathResourceResolver extends AbstractResourceResolver { return false; } if (resourcePath.contains("%")) { - // Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars + // Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8 chars... if (URLDecoder.decode(resourcePath, "UTF-8").contains("../")) { if (logger.isTraceEnabled()) { logger.trace("Resolved resource path contains \"../\" after decoding: " + resourcePath); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java index e93ec91203..9a722e24dd 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java @@ -15,19 +15,19 @@ */ package org.springframework.web.servlet.resource; -import static org.junit.Assert.*; - import java.io.IOException; import java.util.Arrays; -import org.junit.Before; import org.junit.Test; + import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.mock.web.test.MockServletContext; import org.springframework.web.context.support.ServletContextResource; +import static org.junit.Assert.*; + /** * Unit tests for * {@link org.springframework.web.servlet.resource.PathResourceResolver}. @@ -37,14 +37,9 @@ import org.springframework.web.context.support.ServletContextResource; */ public class PathResourceResolverTests { - private PathResourceResolver resolver; + private final PathResourceResolver resolver = new PathResourceResolver(); - @Before - public void setup() { - this.resolver = new PathResourceResolver(); - } - @Test public void resolveFromClasspath() throws IOException { Resource location = new ClassPathResource("test/", PathResourceResolver.class); @@ -80,6 +75,14 @@ public class PathResourceResolverTests { testCheckResource(location, "url:" + secretPath); } + private void testCheckResource(Resource location, String requestPath) throws IOException { + Resource actual = this.resolver.resolveResource(null, requestPath, Arrays.asList(location), null); + if (!location.createRelative(requestPath).exists() && !requestPath.contains(":")) { + fail(requestPath + " doesn't actually exist as a relative path"); + } + assertNull(actual); + } + @Test public void checkResourceWithAllowedLocations() { this.resolver.setAllowedLocations( @@ -105,10 +108,4 @@ public class PathResourceResolverTests { assertTrue(this.resolver.checkResource(resource, servletContextLocation)); } - private void testCheckResource(Resource location, String requestPath) throws IOException { - Resource actual = this.resolver.resolveResource(null, requestPath, Arrays.asList(location), null); - assertTrue(location.createRelative(requestPath).exists()); - assertNull(actual); - } - } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index 1fb896af87..6c103782b1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -16,19 +16,15 @@ package org.springframework.web.servlet.resource; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; - import javax.servlet.http.HttpServletResponse; import org.junit.Before; import org.junit.Test; + import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; @@ -38,6 +34,8 @@ import org.springframework.mock.web.test.MockServletContext; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.servlet.HandlerMapping; +import static org.junit.Assert.*; + /** * Unit tests for ResourceHttpRequestHandler. * @@ -154,6 +152,16 @@ public class ResourceHttpRequestHandlerTests { testInvalidPath(location, "url:" + secretPath); } + private void testInvalidPath(Resource location, String requestPath) throws Exception { + this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, requestPath); + this.response = new MockHttpServletResponse(); + this.handler.handleRequest(this.request, this.response); + if (!location.createRelative(requestPath).exists() && !requestPath.contains(":")) { + fail(requestPath + " doesn't actually exist as a relative path"); + } + assertEquals(404, this.response.getStatus()); + } + @Test public void ignoreInvalidEscapeSequence() throws Exception { this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/%foo%/bar.txt"); @@ -250,12 +258,12 @@ public class ResourceHttpRequestHandlerTests { assertEquals(404, this.response.getStatus()); } - @Test(expected=IllegalStateException.class) + @Test(expected = IllegalStateException.class) public void noPathWithinHandlerMappingAttribute() throws Exception { this.handler.handleRequest(this.request, this.response); } - @Test(expected=HttpRequestMethodNotSupportedException.class) + @Test(expected = HttpRequestMethodNotSupportedException.class) public void unsupportedHttpMethod() throws Exception { this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css"); this.request.setMethod("POST"); @@ -269,6 +277,7 @@ public class ResourceHttpRequestHandlerTests { assertEquals(404, this.response.getStatus()); } + private long headerAsLong(String responseHeaderName) { return Long.valueOf(this.response.getHeader(responseHeaderName)); } @@ -277,14 +286,6 @@ public class ResourceHttpRequestHandlerTests { return new ClassPathResource(resourceName, getClass()).getFile().lastModified(); } - private void testInvalidPath(Resource location, String requestPath) throws Exception { - this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, requestPath); - this.response = new MockHttpServletResponse(); - this.handler.handleRequest(this.request, this.response); - assertTrue(location.createRelative(requestPath).exists()); - assertEquals(404, this.response.getStatus()); - } - private static class TestServletContext extends MockServletContext { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/MessageTagTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/MessageTagTests.java index a9520aad28..c992d67f39 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/MessageTagTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/tags/MessageTagTests.java @@ -271,7 +271,7 @@ public class MessageTagTests extends AbstractTagTests { tag.setHtmlEscape(true); assertTrue("Correct doStartTag return value", tag.doStartTag() == Tag.EVAL_BODY_INCLUDE); assertEquals("Correct doEndTag return value", Tag.EVAL_PAGE, tag.doEndTag()); - assertEquals("Correct message", "test & text é", message.toString()); + assertTrue("Correct message", message.toString().startsWith("test & text &")); } @SuppressWarnings("serial")