This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push: new 7617b9c247 Expand checks for webAppMount 7617b9c247 is described below commit 7617b9c247bc77ed0444dd69adcd8aa48777886c Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Jun 4 11:28:24 2025 +0100 Expand checks for webAppMount --- .../webresources/AbstractArchiveResourceSet.java | 7 ++++--- .../catalina/webresources/AbstractResourceSet.java | 12 ++++++++++++ .../org/apache/catalina/webresources/DirResourceSet.java | 10 +++++----- .../catalina/webresources/AbstractTestResourceSet.java | 16 ++++++++++++++-- webapps/docs/changelog.xml | 4 ++++ 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java b/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java index e9379c01e2..d73deee956 100644 --- a/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java +++ b/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java @@ -68,7 +68,7 @@ public abstract class AbstractArchiveResourceSet extends AbstractResourceSet { String webAppMount = getWebAppMount(); ArrayList<String> result = new ArrayList<>(); - if (path.startsWith(webAppMount)) { + if (isPathMounted(path, webAppMount)) { String pathInJar = getInternalPath() + path.substring(webAppMount.length()); // Always strip off the leading '/' to get the JAR path if (!pathInJar.isEmpty() && pathInJar.charAt(0) == '/') { @@ -108,13 +108,14 @@ public abstract class AbstractArchiveResourceSet extends AbstractResourceSet { return result.toArray(new String[0]); } + @Override public final Set<String> listWebAppPaths(String path) { checkPath(path); String webAppMount = getWebAppMount(); ResourceSet<String> result = new ResourceSet<>(); - if (path.startsWith(webAppMount)) { + if (isPathMounted(path, webAppMount)) { String pathInJar = getInternalPath() + path.substring(webAppMount.length()); // Always strip off the leading '/' to get the JAR path and make // sure it ends in '/' @@ -225,7 +226,7 @@ public abstract class AbstractArchiveResourceSet extends AbstractResourceSet { // If the JAR has been mounted below the web application root, return // an empty resource for requests outside of the mount point. - if (path.startsWith(webAppMount)) { + if (isPathMounted(path, webAppMount)) { String pathInJar = getInternalPath() + path.substring(webAppMount.length()); // Always strip off the leading '/' to get the JAR path if (!pathInJar.isEmpty() && pathInJar.charAt(0) == '/') { diff --git a/java/org/apache/catalina/webresources/AbstractResourceSet.java b/java/org/apache/catalina/webresources/AbstractResourceSet.java index bd7d0c55e7..80961d738a 100644 --- a/java/org/apache/catalina/webresources/AbstractResourceSet.java +++ b/java/org/apache/catalina/webresources/AbstractResourceSet.java @@ -83,6 +83,18 @@ public abstract class AbstractResourceSet extends LifecycleBase implements WebRe return webAppMount; } + protected boolean isPathMounted(String path, String webAppMount) { + // Doesn't call getWebAppMount() as value might have changed + if (path.startsWith(webAppMount)) { + if (path.length() != webAppMount.length() && path.charAt(webAppMount.length()) != '/') { + return false; + } + return true; + } + return false; + } + + public final void setBase(String base) { this.base = base; } diff --git a/java/org/apache/catalina/webresources/DirResourceSet.java b/java/org/apache/catalina/webresources/DirResourceSet.java index 4ed93e5eee..89afbf5cfc 100644 --- a/java/org/apache/catalina/webresources/DirResourceSet.java +++ b/java/org/apache/catalina/webresources/DirResourceSet.java @@ -103,7 +103,7 @@ public class DirResourceSet extends AbstractFileResourceSet implements WebResour String webAppMount = getWebAppMount(); WebResourceRoot root = getRoot(); boolean readOnly = isReadOnly(); - if (path.startsWith(webAppMount)) { + if (isPathMounted(path, webAppMount)) { /* * Lock the path for reading until the WebResource has been constructed. The lock prevents concurrent reads * and writes (e.g. HTTP GET and PUT / DELETE) for the same path causing corruption of the FileResource @@ -137,7 +137,7 @@ public class DirResourceSet extends AbstractFileResourceSet implements WebResour public String[] list(String path) { checkPath(path); String webAppMount = getWebAppMount(); - if (path.startsWith(webAppMount)) { + if (isPathMounted(path, webAppMount)) { File f = file(path.substring(webAppMount.length()), true); if (f == null) { return EMPTY_STRING_ARRAY; @@ -165,7 +165,7 @@ public class DirResourceSet extends AbstractFileResourceSet implements WebResour checkPath(path); String webAppMount = getWebAppMount(); ResourceSet<String> result = new ResourceSet<>(); - if (path.startsWith(webAppMount)) { + if (isPathMounted(path, webAppMount)) { File f = file(path.substring(webAppMount.length()), true); if (f != null) { File[] list = f.listFiles(); @@ -242,7 +242,7 @@ public class DirResourceSet extends AbstractFileResourceSet implements WebResour return false; } String webAppMount = getWebAppMount(); - if (path.startsWith(webAppMount)) { + if (isPathMounted(path, webAppMount)) { File f = file(path.substring(webAppMount.length()), false); if (f == null) { return false; @@ -272,7 +272,7 @@ public class DirResourceSet extends AbstractFileResourceSet implements WebResour } String webAppMount = getWebAppMount(); - if (!path.startsWith(webAppMount)) { + if (!isPathMounted(path, webAppMount)) { return false; } diff --git a/test/org/apache/catalina/webresources/AbstractTestResourceSet.java b/test/org/apache/catalina/webresources/AbstractTestResourceSet.java index ce4c31b28c..7e07ef1e26 100644 --- a/test/org/apache/catalina/webresources/AbstractTestResourceSet.java +++ b/test/org/apache/catalina/webresources/AbstractTestResourceSet.java @@ -97,7 +97,7 @@ public abstract class AbstractTestResourceSet { } @Test - public final void testGetResourceDirA() { + public final void testGetResourceDirWithoutTrailingFileSeperator() { WebResource webResource = resourceRoot.getResource(getMount() + "/d1"); Assert.assertTrue(webResource.isDirectory()); Assert.assertEquals("d1", webResource.getName()); @@ -108,7 +108,7 @@ public abstract class AbstractTestResourceSet { } @Test - public final void testGetResourceDirB() { + public final void testGetResourceDirWithTrailingFileSeperator() { WebResource webResource = resourceRoot.getResource(getMount() + "/d1/"); Assert.assertTrue(webResource.isDirectory()); Assert.assertEquals("d1", webResource.getName()); @@ -118,6 +118,18 @@ public abstract class AbstractTestResourceSet { Assert.assertNull(webResource.getInputStream()); } + @Test + public final void testGetResourceDirWithoutLeadingFileSeperator() { + String mount = getMount(); + if (mount.isEmpty()) { + // Test is only meaningful when resource is mounted below web application root. + return; + } + WebResource webResource = resourceRoot.getResource(mount + "d1"); + Assert.assertFalse(webResource.exists()); + Assert.assertEquals(mount + "d1", webResource.getWebappPath()); + } + @Test public final void testGetResourceFile() { WebResource webResource = diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index f4402d9e64..adcaf889b0 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -135,6 +135,10 @@ <bug>69706</bug>: Fix saved request serialization issue in FORM introduced when allowing infinite session timeouts. (remm) </fix> + <fix> + Expand the path checks for Pre-Resources and Post-Resources mounted at a + path within the web application. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org