From b71e686cbd0689a3dbca55cc345de3e212ef7391 Mon Sep 17 00:00:00 2001 From: chenrl Date: Sun, 21 Mar 2021 16:46:15 +0800 Subject: [PATCH] Fix ServletContextResource isFile check Prior to this commit, `ServletContextResource` could rely on `ServletContext#getRealPath` to check whether a resource exists. This behavior is not enforced on some Servlet containers, as this method is only meant to translate virtual paths to real paths, but not necessarily check for the existence of the file. See https://bz.apache.org/bugzilla/show_bug.cgi?id=55837#c3 for a rationale of this behavior in Tomcat. This commit enforces an additional check, resolving the path as a `File` and checking that is exists and is a file. Closes gh-26707 --- .../web/context/support/ServletContextResource.java | 9 +++++++-- .../web/context/support/ResourceTests.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java index 9f19b76d997..ad236509d88 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextResource.java @@ -139,10 +139,15 @@ public class ServletContextResource extends AbstractFileResolvingResource implem return true; } else { - return (this.servletContext.getRealPath(this.path) != null); + String realPath = this.servletContext.getRealPath(this.path); + if (realPath == null) { + return false; + } + File file = new File(realPath); + return (file.exists() && file.isFile()); } } - catch (MalformedURLException ex) { + catch (IOException ex) { return false; } } diff --git a/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java b/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java index 34083887181..937885e107f 100644 --- a/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/support/ResourceTests.java @@ -36,6 +36,8 @@ public class ResourceTests { MockServletContext sc = new MockServletContext(); Resource resource = new ServletContextResource(sc, "org/springframework/core/io/Resource.class"); doTestResource(resource); + Resource resourceNotExists = new ServletContextResource(sc, "org/springframework/core/io/ResourceNotExists.class"); + doTestNotExistsResource(resourceNotExists); assertThat(new ServletContextResource(sc, "org/springframework/core/../core/io/./Resource.class")).isEqualTo(resource); } @@ -48,6 +50,9 @@ public class ResourceTests { } private void doTestResource(Resource resource) throws IOException { + assertThat(resource.getFile()).isNotNull(); + assertThat(resource.exists()).isTrue(); + assertThat(resource.isFile()).isTrue(); assertThat(resource.getFilename()).isEqualTo("Resource.class"); assertThat(resource.getURL().getFile().endsWith("Resource.class")).isTrue(); @@ -61,4 +66,9 @@ public class ResourceTests { assertThat(relative2.getURL().getFile().endsWith("ResourcePatternResolver.class")).isTrue(); assertThat(relative2.exists()).isTrue(); } + + private void doTestNotExistsResource(Resource resource) throws IOException { + assertThat(resource.exists()).isFalse(); + assertThat(resource.isFile()).isFalse(); + } }