Skip to content

Commit acd6e4a

Browse files
committed
XWIKI-23898: Improve classpath resolution for Tomcat
(cherry picked from commit a979caf)
1 parent ba7d74e commit acd6e4a

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

xwiki-commons-core/xwiki-commons-classloader/xwiki-commons-classloader-api/src/main/java/org/xwiki/classloader/internal/ClassLoaderUtils.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,30 @@ private static String resolveResourceName(String prefixPath, String resourcePath
4747
fullPath = resourcePath;
4848

4949
// Prevent access to resources from other directories
50-
// TODO: find or implement something closed to Servlet ClassLoader behavior to be as accurate as possible
51-
// and be able to reuse the normalized result
52-
Path normalizedResource = Paths.get(fullPath).normalize();
50+
// TODO: find or implement something closer to Servlet ClassLoader behavior to be as accurate as possible
51+
// and be able to reuse the normalized result. Not so easy since the various applications servers can use
52+
// different logics.
53+
54+
// On Tomcat, all leading / have no effect, contrary to Paths#normalize()
55+
int index = 0;
56+
while (index < fullPath.length() && fullPath.charAt(index) == '/') {
57+
++index;
58+
}
59+
String normalizedPath = fullPath.substring(index);
60+
61+
Path normalizedResource = Paths.get(normalizedPath).normalize();
5362
if (normalizedResource.startsWith("../")) {
5463
throw new IllegalArgumentException(String.format(
5564
"The provided resource name [%s] is trying to navigate out of the mandatory root location",
56-
resourcePath));
65+
fullPath));
5766
}
5867
} else {
5968
fullPath = prefixPath + resourcePath;
6069

6170
// Prevent access to resources from other directories
6271
// TODO: find or implement something closed to Servlet ClassLoader behavior to be as accurate as possible
63-
// and be able to reuse the normalized result
72+
// and be able to reuse the normalized result. Not so easy since the various applications servers can use
73+
// different logics.
6474
Path normalizedResource = Paths.get(fullPath).normalize();
6575
if (!normalizedResource.startsWith(prefixPath)) {
6676
throw new IllegalArgumentException(String.format(

xwiki-commons-core/xwiki-commons-classloader/xwiki-commons-classloader-api/src/test/java/org/xwiki/classloader/internal/ClassLoaderUtilsTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ void getResource()
8585
assertSame(this.resouceURL, ClassLoaderUtils.getResource(this.classLoader, RESOURCE_NAME_BACK));
8686

8787
assertThrows(IllegalArgumentException.class, () -> ClassLoaderUtils.getResource(this.classLoader, ".."));
88+
assertThrows(IllegalArgumentException.class, () -> ClassLoaderUtils.getResource(this.classLoader, "/.."));
89+
assertThrows(IllegalArgumentException.class, () -> ClassLoaderUtils.getResource(this.classLoader, "////.."));
8890
assertThrows(IllegalArgumentException.class, () -> ClassLoaderUtils.getResource(this.classLoader, "./.."));
8991
assertThrows(IllegalArgumentException.class,
9092
() -> ClassLoaderUtils.getResource(this.classLoader, "resource/../.."));
@@ -106,6 +108,10 @@ void getResourceAsStream()
106108

107109
assertThrows(IllegalArgumentException.class,
108110
() -> ClassLoaderUtils.getResourceAsStream(this.classLoader, ".."));
111+
assertThrows(IllegalArgumentException.class,
112+
() -> ClassLoaderUtils.getResourceAsStream(this.classLoader, "/.."));
113+
assertThrows(IllegalArgumentException.class,
114+
() -> ClassLoaderUtils.getResourceAsStream(this.classLoader, "///.."));
109115
assertThrows(IllegalArgumentException.class,
110116
() -> ClassLoaderUtils.getResourceAsStream(this.classLoader, "./.."));
111117
assertThrows(IllegalArgumentException.class,

0 commit comments

Comments
 (0)