From 9f43ee3304ba9fe88b17bc54d8229ec088233c74 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 30 Oct 2019 16:19:40 +0100 Subject: [PATCH] Treat InvalidPathException like an IOException in MockServletContext Prior to this commit, if MockServletContext was configured with a FileSystemResourceLoader, invocations of the following methods on a Microsoft Windows operating system resulted in an InvalidPathException if the supplied path contained a colon (such as "C:\\temp"). This is inconsistent with the behavior on non-Windows operating systems. In addition, for comparable errors resulting in an IOException, those methods (except getRealPath()) return null instead of throwing the exception. - getResourcePaths() - getResource() - getResourceAsStream() - getRealPath() This commit makes handling of InvalidPathException and IOException consistent for these methods: both exceptions now result in null be returned by these methods. Closes gh-23717 --- .../mock/web/MockServletContext.java | 51 +++++++++------ .../mock/web/MockServletContextTests.java | 62 +++++++++++++++++-- .../mock/web/test/MockServletContext.java | 51 +++++++++------ 3 files changed, 121 insertions(+), 43 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java b/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java index 97fed0c5d1..7dab1c8c21 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.InvalidPathException; import java.util.Collections; import java.util.Enumeration; import java.util.EventListener; @@ -294,8 +295,10 @@ public class MockServletContext implements ServletContext { @Nullable public Set getResourcePaths(String path) { String actualPath = (path.endsWith("/") ? path : path + "/"); - Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath)); + String resourceLocation = getResourceLocation(actualPath); + Resource resource = null; try { + resource = this.resourceLoader.getResource(resourceLocation); File file = resource.getFile(); String[] fileList = file.list(); if (ObjectUtils.isEmpty(fileList)) { @@ -311,9 +314,10 @@ public class MockServletContext implements ServletContext { } return resourcePaths; } - catch (IOException ex) { + catch (InvalidPathException | IOException ex ) { if (logger.isWarnEnabled()) { - logger.warn("Could not get resource paths for " + resource, ex); + logger.warn("Could not get resource paths for " + + (resource != null ? resource : resourceLocation), ex); } return null; } @@ -322,19 +326,22 @@ public class MockServletContext implements ServletContext { @Override @Nullable public URL getResource(String path) throws MalformedURLException { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - if (!resource.exists()) { - return null; - } + String resourceLocation = getResourceLocation(path); + Resource resource = null; try { + resource = this.resourceLoader.getResource(resourceLocation); + if (!resource.exists()) { + return null; + } return resource.getURL(); } catch (MalformedURLException ex) { throw ex; } - catch (IOException ex) { + catch (InvalidPathException | IOException ex) { if (logger.isWarnEnabled()) { - logger.warn("Could not get URL for " + resource, ex); + logger.warn("Could not get URL for resource " + + (resource != null ? resource : resourceLocation), ex); } return null; } @@ -343,16 +350,19 @@ public class MockServletContext implements ServletContext { @Override @Nullable public InputStream getResourceAsStream(String path) { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - if (!resource.exists()) { - return null; - } + String resourceLocation = getResourceLocation(path); + Resource resource = null; try { + resource = this.resourceLoader.getResource(resourceLocation); + if (!resource.exists()) { + return null; + } return resource.getInputStream(); } - catch (IOException ex) { + catch (InvalidPathException | IOException ex) { if (logger.isWarnEnabled()) { - logger.warn("Could not open InputStream for " + resource, ex); + logger.warn("Could not open InputStream for resource " + + (resource != null ? resource : resourceLocation), ex); } return null; } @@ -459,13 +469,16 @@ public class MockServletContext implements ServletContext { @Override @Nullable public String getRealPath(String path) { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + String resourceLocation = getResourceLocation(path); + Resource resource = null; try { + resource = this.resourceLoader.getResource(resourceLocation); return resource.getFile().getAbsolutePath(); } - catch (IOException ex) { + catch (InvalidPathException | IOException ex) { if (logger.isWarnEnabled()) { - logger.warn("Could not determine real path of resource " + resource, ex); + logger.warn("Could not determine real path of resource " + + (resource != null ? resource : resourceLocation), ex); } return null; } diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java index b1669dbea5..66b61e94a7 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.mock.web; +import java.io.InputStream; +import java.net.URL; import java.util.Map; import java.util.Set; @@ -24,7 +26,9 @@ import javax.servlet.RequestDispatcher; import javax.servlet.ServletRegistration; import org.junit.Test; +import org.junit.jupiter.api.condition.OS; +import org.springframework.core.io.FileSystemResourceLoader; import org.springframework.http.MediaType; import static org.junit.Assert.assertEquals; @@ -34,6 +38,8 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; /** + * Unit tests for {@link MockServletContext}. + * * @author Juergen Hoeller * @author Chris Beams * @author Sam Brannen @@ -45,27 +51,27 @@ public class MockServletContextTests { @Test - public void listFiles() { + public void getResourcePaths() { Set paths = sc.getResourcePaths("/web"); assertNotNull(paths); assertTrue(paths.contains("/web/MockServletContextTests.class")); } @Test - public void listSubdirectories() { + public void getResourcePathsWithSubdirectories() { Set paths = sc.getResourcePaths("/"); assertNotNull(paths); assertTrue(paths.contains("/web/")); } @Test - public void listNonDirectory() { + public void getResourcePathsWithNonDirectory() { Set paths = sc.getResourcePaths("/web/MockServletContextTests.class"); assertNull(paths); } @Test - public void listInvalidPath() { + public void getResourcePathsWithInvalidPath() { Set paths = sc.getResourcePaths("/web/invalid"); assertNull(paths); } @@ -194,4 +200,50 @@ public class MockServletContextTests { assertEquals(0, filterRegistrations.size()); } + /** + * @since 5.1.11 + */ + @Test + public void getResourcePathsWithRelativePathToWindowsCDrive() { + MockServletContext servletContext = new MockServletContext( "org/springframework/mock", new FileSystemResourceLoader()); + Set paths = servletContext.getResourcePaths("C:\\temp"); + assertNull(paths); + } + + /** + * @since 5.1.11 + */ + @Test + public void getResourceWithRelativePathToWindowsCDrive() throws Exception { + MockServletContext servletContext = new MockServletContext( "org/springframework/mock", new FileSystemResourceLoader()); + URL resource = servletContext.getResource("C:\\temp"); + assertNull(resource); + } + + /** + * @since 5.1.11 + */ + @Test + public void getResourceAsStreamWithRelativePathToWindowsCDrive() { + MockServletContext servletContext = new MockServletContext( "org/springframework/mock", new FileSystemResourceLoader()); + InputStream inputStream = servletContext.getResourceAsStream("C:\\temp"); + assertNull(inputStream); + } + + /** + * @since 5.1.11 + */ + @Test + public void getRealPathWithRelativePathToWindowsCDrive() { + MockServletContext servletContext = new MockServletContext( "org/springframework/mock", new FileSystemResourceLoader()); + String realPath = servletContext.getRealPath("C:\\temp"); + + if (OS.WINDOWS.isCurrentOs()) { + assertNull(realPath); + } + else { + assertNotNull(realPath); + } + } + } diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java index 3b78ed50ee..32fa355b86 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.InvalidPathException; import java.util.Collections; import java.util.Enumeration; import java.util.EventListener; @@ -294,8 +295,10 @@ public class MockServletContext implements ServletContext { @Nullable public Set getResourcePaths(String path) { String actualPath = (path.endsWith("/") ? path : path + "/"); - Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath)); + String resourceLocation = getResourceLocation(actualPath); + Resource resource = null; try { + resource = this.resourceLoader.getResource(resourceLocation); File file = resource.getFile(); String[] fileList = file.list(); if (ObjectUtils.isEmpty(fileList)) { @@ -311,9 +314,10 @@ public class MockServletContext implements ServletContext { } return resourcePaths; } - catch (IOException ex) { + catch (InvalidPathException | IOException ex ) { if (logger.isWarnEnabled()) { - logger.warn("Could not get resource paths for " + resource, ex); + logger.warn("Could not get resource paths for " + + (resource != null ? resource : resourceLocation), ex); } return null; } @@ -322,19 +326,22 @@ public class MockServletContext implements ServletContext { @Override @Nullable public URL getResource(String path) throws MalformedURLException { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - if (!resource.exists()) { - return null; - } + String resourceLocation = getResourceLocation(path); + Resource resource = null; try { + resource = this.resourceLoader.getResource(resourceLocation); + if (!resource.exists()) { + return null; + } return resource.getURL(); } catch (MalformedURLException ex) { throw ex; } - catch (IOException ex) { + catch (InvalidPathException | IOException ex) { if (logger.isWarnEnabled()) { - logger.warn("Could not get URL for " + resource, ex); + logger.warn("Could not get URL for resource " + + (resource != null ? resource : resourceLocation), ex); } return null; } @@ -343,16 +350,19 @@ public class MockServletContext implements ServletContext { @Override @Nullable public InputStream getResourceAsStream(String path) { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - if (!resource.exists()) { - return null; - } + String resourceLocation = getResourceLocation(path); + Resource resource = null; try { + resource = this.resourceLoader.getResource(resourceLocation); + if (!resource.exists()) { + return null; + } return resource.getInputStream(); } - catch (IOException ex) { + catch (InvalidPathException | IOException ex) { if (logger.isWarnEnabled()) { - logger.warn("Could not open InputStream for " + resource, ex); + logger.warn("Could not open InputStream for resource " + + (resource != null ? resource : resourceLocation), ex); } return null; } @@ -459,13 +469,16 @@ public class MockServletContext implements ServletContext { @Override @Nullable public String getRealPath(String path) { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + String resourceLocation = getResourceLocation(path); + Resource resource = null; try { + resource = this.resourceLoader.getResource(resourceLocation); return resource.getFile().getAbsolutePath(); } - catch (IOException ex) { + catch (InvalidPathException | IOException ex) { if (logger.isWarnEnabled()) { - logger.warn("Could not determine real path of resource " + resource, ex); + logger.warn("Could not determine real path of resource " + + (resource != null ? resource : resourceLocation), ex); } return null; }