Skip to content

Commit 9f43ee3

Browse files
committed
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
1 parent 614c7b0 commit 9f43ee3

File tree

3 files changed

+121
-43
lines changed

3 files changed

+121
-43
lines changed

spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java

+32-19
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.
@@ -21,6 +21,7 @@
2121
import java.io.InputStream;
2222
import java.net.MalformedURLException;
2323
import java.net.URL;
24+
import java.nio.file.InvalidPathException;
2425
import java.util.Collections;
2526
import java.util.Enumeration;
2627
import java.util.EventListener;
@@ -294,8 +295,10 @@ public void addMimeType(String fileExtension, MediaType mimeType) {
294295
@Nullable
295296
public Set<String> getResourcePaths(String path) {
296297
String actualPath = (path.endsWith("/") ? path : path + "/");
297-
Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath));
298+
String resourceLocation = getResourceLocation(actualPath);
299+
Resource resource = null;
298300
try {
301+
resource = this.resourceLoader.getResource(resourceLocation);
299302
File file = resource.getFile();
300303
String[] fileList = file.list();
301304
if (ObjectUtils.isEmpty(fileList)) {
@@ -311,9 +314,10 @@ public Set<String> getResourcePaths(String path) {
311314
}
312315
return resourcePaths;
313316
}
314-
catch (IOException ex) {
317+
catch (InvalidPathException | IOException ex ) {
315318
if (logger.isWarnEnabled()) {
316-
logger.warn("Could not get resource paths for " + resource, ex);
319+
logger.warn("Could not get resource paths for " +
320+
(resource != null ? resource : resourceLocation), ex);
317321
}
318322
return null;
319323
}
@@ -322,19 +326,22 @@ public Set<String> getResourcePaths(String path) {
322326
@Override
323327
@Nullable
324328
public URL getResource(String path) throws MalformedURLException {
325-
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
326-
if (!resource.exists()) {
327-
return null;
328-
}
329+
String resourceLocation = getResourceLocation(path);
330+
Resource resource = null;
329331
try {
332+
resource = this.resourceLoader.getResource(resourceLocation);
333+
if (!resource.exists()) {
334+
return null;
335+
}
330336
return resource.getURL();
331337
}
332338
catch (MalformedURLException ex) {
333339
throw ex;
334340
}
335-
catch (IOException ex) {
341+
catch (InvalidPathException | IOException ex) {
336342
if (logger.isWarnEnabled()) {
337-
logger.warn("Could not get URL for " + resource, ex);
343+
logger.warn("Could not get URL for resource " +
344+
(resource != null ? resource : resourceLocation), ex);
338345
}
339346
return null;
340347
}
@@ -343,16 +350,19 @@ public URL getResource(String path) throws MalformedURLException {
343350
@Override
344351
@Nullable
345352
public InputStream getResourceAsStream(String path) {
346-
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
347-
if (!resource.exists()) {
348-
return null;
349-
}
353+
String resourceLocation = getResourceLocation(path);
354+
Resource resource = null;
350355
try {
356+
resource = this.resourceLoader.getResource(resourceLocation);
357+
if (!resource.exists()) {
358+
return null;
359+
}
351360
return resource.getInputStream();
352361
}
353-
catch (IOException ex) {
362+
catch (InvalidPathException | IOException ex) {
354363
if (logger.isWarnEnabled()) {
355-
logger.warn("Could not open InputStream for " + resource, ex);
364+
logger.warn("Could not open InputStream for resource " +
365+
(resource != null ? resource : resourceLocation), ex);
356366
}
357367
return null;
358368
}
@@ -459,13 +469,16 @@ public void log(String message, Throwable ex) {
459469
@Override
460470
@Nullable
461471
public String getRealPath(String path) {
462-
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
472+
String resourceLocation = getResourceLocation(path);
473+
Resource resource = null;
463474
try {
475+
resource = this.resourceLoader.getResource(resourceLocation);
464476
return resource.getFile().getAbsolutePath();
465477
}
466-
catch (IOException ex) {
478+
catch (InvalidPathException | IOException ex) {
467479
if (logger.isWarnEnabled()) {
468-
logger.warn("Could not determine real path of resource " + resource, ex);
480+
logger.warn("Could not determine real path of resource " +
481+
(resource != null ? resource : resourceLocation), ex);
469482
}
470483
return null;
471484
}

spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java

+57-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 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.
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.mock.web;
1818

19+
import java.io.InputStream;
20+
import java.net.URL;
1921
import java.util.Map;
2022
import java.util.Set;
2123

@@ -24,7 +26,9 @@
2426
import javax.servlet.ServletRegistration;
2527

2628
import org.junit.Test;
29+
import org.junit.jupiter.api.condition.OS;
2730

31+
import org.springframework.core.io.FileSystemResourceLoader;
2832
import org.springframework.http.MediaType;
2933

3034
import static org.junit.Assert.assertEquals;
@@ -34,6 +38,8 @@
3438
import static org.junit.Assert.assertTrue;
3539

3640
/**
41+
* Unit tests for {@link MockServletContext}.
42+
*
3743
* @author Juergen Hoeller
3844
* @author Chris Beams
3945
* @author Sam Brannen
@@ -45,27 +51,27 @@ public class MockServletContextTests {
4551

4652

4753
@Test
48-
public void listFiles() {
54+
public void getResourcePaths() {
4955
Set<String> paths = sc.getResourcePaths("/web");
5056
assertNotNull(paths);
5157
assertTrue(paths.contains("/web/MockServletContextTests.class"));
5258
}
5359

5460
@Test
55-
public void listSubdirectories() {
61+
public void getResourcePathsWithSubdirectories() {
5662
Set<String> paths = sc.getResourcePaths("/");
5763
assertNotNull(paths);
5864
assertTrue(paths.contains("/web/"));
5965
}
6066

6167
@Test
62-
public void listNonDirectory() {
68+
public void getResourcePathsWithNonDirectory() {
6369
Set<String> paths = sc.getResourcePaths("/web/MockServletContextTests.class");
6470
assertNull(paths);
6571
}
6672

6773
@Test
68-
public void listInvalidPath() {
74+
public void getResourcePathsWithInvalidPath() {
6975
Set<String> paths = sc.getResourcePaths("/web/invalid");
7076
assertNull(paths);
7177
}
@@ -194,4 +200,50 @@ public void getFilterRegistrations() {
194200
assertEquals(0, filterRegistrations.size());
195201
}
196202

203+
/**
204+
* @since 5.1.11
205+
*/
206+
@Test
207+
public void getResourcePathsWithRelativePathToWindowsCDrive() {
208+
MockServletContext servletContext = new MockServletContext( "org/springframework/mock", new FileSystemResourceLoader());
209+
Set<String> paths = servletContext.getResourcePaths("C:\\temp");
210+
assertNull(paths);
211+
}
212+
213+
/**
214+
* @since 5.1.11
215+
*/
216+
@Test
217+
public void getResourceWithRelativePathToWindowsCDrive() throws Exception {
218+
MockServletContext servletContext = new MockServletContext( "org/springframework/mock", new FileSystemResourceLoader());
219+
URL resource = servletContext.getResource("C:\\temp");
220+
assertNull(resource);
221+
}
222+
223+
/**
224+
* @since 5.1.11
225+
*/
226+
@Test
227+
public void getResourceAsStreamWithRelativePathToWindowsCDrive() {
228+
MockServletContext servletContext = new MockServletContext( "org/springframework/mock", new FileSystemResourceLoader());
229+
InputStream inputStream = servletContext.getResourceAsStream("C:\\temp");
230+
assertNull(inputStream);
231+
}
232+
233+
/**
234+
* @since 5.1.11
235+
*/
236+
@Test
237+
public void getRealPathWithRelativePathToWindowsCDrive() {
238+
MockServletContext servletContext = new MockServletContext( "org/springframework/mock", new FileSystemResourceLoader());
239+
String realPath = servletContext.getRealPath("C:\\temp");
240+
241+
if (OS.WINDOWS.isCurrentOs()) {
242+
assertNull(realPath);
243+
}
244+
else {
245+
assertNotNull(realPath);
246+
}
247+
}
248+
197249
}

spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java

+32-19
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.
@@ -21,6 +21,7 @@
2121
import java.io.InputStream;
2222
import java.net.MalformedURLException;
2323
import java.net.URL;
24+
import java.nio.file.InvalidPathException;
2425
import java.util.Collections;
2526
import java.util.Enumeration;
2627
import java.util.EventListener;
@@ -294,8 +295,10 @@ public void addMimeType(String fileExtension, MediaType mimeType) {
294295
@Nullable
295296
public Set<String> getResourcePaths(String path) {
296297
String actualPath = (path.endsWith("/") ? path : path + "/");
297-
Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath));
298+
String resourceLocation = getResourceLocation(actualPath);
299+
Resource resource = null;
298300
try {
301+
resource = this.resourceLoader.getResource(resourceLocation);
299302
File file = resource.getFile();
300303
String[] fileList = file.list();
301304
if (ObjectUtils.isEmpty(fileList)) {
@@ -311,9 +314,10 @@ public Set<String> getResourcePaths(String path) {
311314
}
312315
return resourcePaths;
313316
}
314-
catch (IOException ex) {
317+
catch (InvalidPathException | IOException ex ) {
315318
if (logger.isWarnEnabled()) {
316-
logger.warn("Could not get resource paths for " + resource, ex);
319+
logger.warn("Could not get resource paths for " +
320+
(resource != null ? resource : resourceLocation), ex);
317321
}
318322
return null;
319323
}
@@ -322,19 +326,22 @@ public Set<String> getResourcePaths(String path) {
322326
@Override
323327
@Nullable
324328
public URL getResource(String path) throws MalformedURLException {
325-
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
326-
if (!resource.exists()) {
327-
return null;
328-
}
329+
String resourceLocation = getResourceLocation(path);
330+
Resource resource = null;
329331
try {
332+
resource = this.resourceLoader.getResource(resourceLocation);
333+
if (!resource.exists()) {
334+
return null;
335+
}
330336
return resource.getURL();
331337
}
332338
catch (MalformedURLException ex) {
333339
throw ex;
334340
}
335-
catch (IOException ex) {
341+
catch (InvalidPathException | IOException ex) {
336342
if (logger.isWarnEnabled()) {
337-
logger.warn("Could not get URL for " + resource, ex);
343+
logger.warn("Could not get URL for resource " +
344+
(resource != null ? resource : resourceLocation), ex);
338345
}
339346
return null;
340347
}
@@ -343,16 +350,19 @@ public URL getResource(String path) throws MalformedURLException {
343350
@Override
344351
@Nullable
345352
public InputStream getResourceAsStream(String path) {
346-
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
347-
if (!resource.exists()) {
348-
return null;
349-
}
353+
String resourceLocation = getResourceLocation(path);
354+
Resource resource = null;
350355
try {
356+
resource = this.resourceLoader.getResource(resourceLocation);
357+
if (!resource.exists()) {
358+
return null;
359+
}
351360
return resource.getInputStream();
352361
}
353-
catch (IOException ex) {
362+
catch (InvalidPathException | IOException ex) {
354363
if (logger.isWarnEnabled()) {
355-
logger.warn("Could not open InputStream for " + resource, ex);
364+
logger.warn("Could not open InputStream for resource " +
365+
(resource != null ? resource : resourceLocation), ex);
356366
}
357367
return null;
358368
}
@@ -459,13 +469,16 @@ public void log(String message, Throwable ex) {
459469
@Override
460470
@Nullable
461471
public String getRealPath(String path) {
462-
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
472+
String resourceLocation = getResourceLocation(path);
473+
Resource resource = null;
463474
try {
475+
resource = this.resourceLoader.getResource(resourceLocation);
464476
return resource.getFile().getAbsolutePath();
465477
}
466-
catch (IOException ex) {
478+
catch (InvalidPathException | IOException ex) {
467479
if (logger.isWarnEnabled()) {
468-
logger.warn("Could not determine real path of resource " + resource, ex);
480+
logger.warn("Could not determine real path of resource " +
481+
(resource != null ? resource : resourceLocation), ex);
469482
}
470483
return null;
471484
}

0 commit comments

Comments
 (0)