From 368f29d5bcd4e646ea03bae2b95715506fe22aaf Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 13 Apr 2016 18:20:15 +0200 Subject: [PATCH] Fix AntPathMatcher multiple segments matching Prior to this commit, the new match algorithm wouldn't work for multiple consecutive path separators. This commit separately matches path segments and path separators and allows for multiple, consecutive path separators. Issue: SPR-14141 --- .../springframework/util/AntPathMatcher.java | 36 +++++++++++-------- .../util/AntPathMatcherTests.java | 1 + 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java index c08f5e09939..633a932a27a 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -317,34 +317,42 @@ public class AntPathMatcher implements PathMatcher { char[] pathChars = path.toCharArray(); int pos = 0; for (String pattDir : pattDirs) { - int count = countStartsWith(pathChars, pos, this.pathSeparator, false); - pos += (count == this.pathSeparator.length() ? count : 0); - count = countStartsWith(pathChars, pos, pattDir, true); - if (count < pattDir.length()) { - if (count > 0) { + int skipped = skipSeparator(path, pos, this.pathSeparator); + pos += skipped; + skipped = skipSegment(pathChars, pos, pattDir); + if (skipped < pattDir.length()) { + if (skipped > 0) { return true; } return (pattDir.length() > 0) && isWildcardChar(pattDir.charAt(0)); } - pos += count; + pos += skipped; } return true; } - private int countStartsWith(char[] chars, int pos, String prefix, boolean stopOnWildcard) { - int count = 0; + private int skipSegment(char[] chars, int pos, String prefix) { + int skipped = 0; for (char c : prefix.toCharArray()) { - if (stopOnWildcard && isWildcardChar(c)) { - return count; + if (isWildcardChar(c)) { + return skipped; } - if (pos + count >= chars.length) { + else if (pos + skipped >= chars.length) { return 0; } - if (chars[pos + count] == c) { - count++; + else if (chars[pos + skipped] == c) { + skipped++; } } - return count; + return skipped; + } + + private int skipSeparator(String path, int pos, String separator) { + int skipped = 0; + while (path.startsWith(separator, pos + skipped)) { + skipped += separator.length(); + } + return skipped; } private boolean isWildcardChar(char c) { diff --git a/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java b/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java index 13e48927100..f75e637c502 100644 --- a/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java +++ b/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java @@ -53,6 +53,7 @@ public class AntPathMatcherTests { // test exact matching assertTrue(pathMatcher.match("test", "test")); assertTrue(pathMatcher.match("/test", "/test")); + assertTrue(pathMatcher.match("http://example.org", "http://example.org")); // SPR-14141 assertFalse(pathMatcher.match("/test.jpg", "test.jpg")); assertFalse(pathMatcher.match("test", "/test")); assertFalse(pathMatcher.match("/test", "test"));