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 63eea1e9eab..bf4eb349e07 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -275,6 +275,10 @@ public class AntPathMatcher implements PathMatcher { if (!matchStrings(pattDir, pathDirs[pathIdxEnd], uriTemplateVariables)) { return false; } + if (pattIdxEnd == (pattDirs.length - 1) + && pattern.endsWith(this.pathSeparator) != path.endsWith(this.pathSeparator)) { + return false; + } pattIdxEnd--; pathIdxEnd--; } 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 8bebf5920ff..b018e99caf7 100644 --- a/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java +++ b/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java @@ -704,4 +704,11 @@ class AntPathMatcherTests { assertThat(pathMatcher.isPattern(null)).isFalse(); } + @Test // gh-27506 + void consistentMatchWithWildcardsAndTrailingSlash() { + assertThat(pathMatcher.match("/*/foo", "/en/foo")).isTrue(); + assertThat(pathMatcher.match("/*/foo", "/en/foo/")).isFalse(); + assertThat(pathMatcher.match("/**/foo", "/en/foo")).isTrue(); + assertThat(pathMatcher.match("/**/foo", "/en/foo/")).isFalse(); + } }