Skip to content

Commit

Permalink
[UNDERTOW-1886] Add back non-null option to CanonicalPathUtils, while…
Browse files Browse the repository at this point in the history
… still keeping the system property out.

This partially reverts commit 66c6252.
  • Loading branch information
fl4via committed May 25, 2021
1 parent 0559617 commit d13a897
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 13 deletions.
16 changes: 10 additions & 6 deletions core/src/main/java/io/undertow/util/CanonicalPathUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,21 @@ public class CanonicalPathUtils {


public static String canonicalize(final String path) {
return canonicalize(path, false);
}

public static String canonicalize(final String path, final boolean nullAllowed) {
int state = START;
for (int i = path.length() - 1; i >= 0; --i) {
final char c = path.charAt(i);
switch (c) {
case '/':
if (state == FIRST_SLASH) {
return realCanonicalize(path, i + 1, FIRST_SLASH);
return realCanonicalize(path, i + 1, FIRST_SLASH, nullAllowed);
} else if (state == ONE_DOT) {
return realCanonicalize(path, i + 2, FIRST_SLASH);
return realCanonicalize(path, i + 2, FIRST_SLASH, nullAllowed);
} else if (state == TWO_DOT) {
return realCanonicalize(path, i + 3, FIRST_SLASH);
return realCanonicalize(path, i + 3, FIRST_SLASH, nullAllowed);
}
state = FIRST_SLASH;
break;
Expand Down Expand Up @@ -85,7 +89,7 @@ public static String canonicalize(final String path) {
static final int FIRST_BACKSLASH = 4;


private static String realCanonicalize(final String path, final int lastDot, final int initialState) {
private static String realCanonicalize(final String path, final int lastDot, final int initialState, final boolean nullAllowed) {
int state = initialState;
int eatCount = 0;
int tokenEnd = path.length();
Expand Down Expand Up @@ -170,8 +174,8 @@ private static String realCanonicalize(final String path, final int lastDot, fin
}
}
}
if (eatCount > 0) {
// the relative path is outside the context
if (eatCount > 0 && nullAllowed) {
// the relative path is outside the context and null allowed
return null;
}
final StringBuilder result = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ public void testCanonicalization() {
Assert.assertEquals("/b", CanonicalPathUtils.canonicalize("/a/c/../../b"));

// out of servlet context
Assert.assertNull(CanonicalPathUtils.canonicalize("/a/../.."));
Assert.assertNull(CanonicalPathUtils.canonicalize("/a/../../foo"));
Assert.assertNull(CanonicalPathUtils.canonicalize("/../../a/b/bar"));
Assert.assertNull(CanonicalPathUtils.canonicalize("/a/../..", true));
Assert.assertNull(CanonicalPathUtils.canonicalize("/a/../../foo", true));
Assert.assertNull(CanonicalPathUtils.canonicalize("/../../a/b/bar", true));
Assert.assertEquals("/", CanonicalPathUtils.canonicalize("/a/../.."));
Assert.assertEquals("/foo", CanonicalPathUtils.canonicalize("/a/../../foo"));

//preserve (single) trailing /
Assert.assertEquals("/a/", CanonicalPathUtils.canonicalize("/a/"));
Expand Down Expand Up @@ -106,9 +108,11 @@ public void testCanonicalizationBackslash() {
Assert.assertEquals("\\b", CanonicalPathUtils.canonicalize("\\a\\c\\..\\..\\b"));

// out of servlet context
Assert.assertNull(CanonicalPathUtils.canonicalize("\\a\\..\\.."));
Assert.assertNull(CanonicalPathUtils.canonicalize("\\a\\..\\..\\foo"));
Assert.assertNull(CanonicalPathUtils.canonicalize("\\..\\..\\a\\b\\bar"));
Assert.assertNull(CanonicalPathUtils.canonicalize("\\a\\..\\..", true));
Assert.assertNull(CanonicalPathUtils.canonicalize("\\a\\..\\..\\foo", true));
Assert.assertNull(CanonicalPathUtils.canonicalize("\\..\\..\\a\\b\\bar", true));
Assert.assertEquals("/", CanonicalPathUtils.canonicalize("\\a\\..\\.."));
Assert.assertEquals("\\foo", CanonicalPathUtils.canonicalize("\\a\\..\\..\\foo"));

//preserve (single) trailing \
Assert.assertEquals("\\a\\", CanonicalPathUtils.canonicalize("\\a\\"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ public RequestDispatcher getRequestDispatcher(final String path) {
if (!path.startsWith("/")) {
throw UndertowServletMessages.MESSAGES.pathMustStartWithSlashForRequestDispatcher(path);
}
final String realPath = CanonicalPathUtils.canonicalize(path);
final String realPath = CanonicalPathUtils.canonicalize(path, true);
if (realPath == null) {
// path is outside the servlet context, return null per spec
return null;
Expand Down

0 comments on commit d13a897

Please sign in to comment.