Skip to content

Commit 83fcdfb

Browse files
tafjwrbclozel
authored andcommitted
Fix AntPathMatcher URI template variable extractor
See gh-33085
1 parent 9b58e1f commit 83fcdfb

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

spring-core/src/main/java/org/springframework/util/AntPathMatcher.java

+7-9
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ protected AntPathStringMatcher getStringMatcher(String pattern) {
462462
matcher = this.stringMatcherCache.get(pattern);
463463
}
464464
if (matcher == null) {
465-
matcher = new AntPathStringMatcher(pattern, this.caseSensitive);
465+
matcher = new AntPathStringMatcher(pattern, this.pathSeparator, this.caseSensitive);
466466
if (cachePatterns == null && this.stringMatcherCache.size() >= CACHE_TURNOFF_THRESHOLD) {
467467
// Try to adapt to the runtime situation that we're encountering:
468468
// There are obviously too many different patterns coming in here...
@@ -646,8 +646,6 @@ public Comparator<String> getPatternComparator(String path) {
646646
*/
647647
protected static class AntPathStringMatcher {
648648

649-
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
650-
651649
private static final String DEFAULT_VARIABLE_PATTERN = "((?s).*)";
652650

653651
private final String rawPattern;
@@ -661,15 +659,11 @@ protected static class AntPathStringMatcher {
661659

662660
private final List<String> variableNames = new ArrayList<>();
663661

664-
public AntPathStringMatcher(String pattern) {
665-
this(pattern, true);
666-
}
667-
668-
public AntPathStringMatcher(String pattern, boolean caseSensitive) {
662+
public AntPathStringMatcher(String pattern, String pathSeparator, boolean caseSensitive) {
669663
this.rawPattern = pattern;
670664
this.caseSensitive = caseSensitive;
671665
StringBuilder patternBuilder = new StringBuilder();
672-
Matcher matcher = GLOB_PATTERN.matcher(pattern);
666+
Matcher matcher = getGlobPattern(pathSeparator).matcher(pattern);
673667
int end = 0;
674668
while (matcher.find()) {
675669
patternBuilder.append(quote(pattern, end, matcher.start()));
@@ -710,6 +704,10 @@ else if (match.startsWith("{") && match.endsWith("}")) {
710704
}
711705
}
712706

707+
private static Pattern getGlobPattern(String pathSeparator) {
708+
return Pattern.compile(String.format("\\?|\\*|\\{((?:\\{[^%s]+?\\}|[^%s{}]|\\\\[{}])+?)\\}", pathSeparator, pathSeparator));
709+
}
710+
713711
private String quote(String s, int start, int end) {
714712
if (start == end) {
715713
return "";

spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java

+19
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
class AntPathMatcherTests {
4242

4343
private final AntPathMatcher pathMatcher = new AntPathMatcher();
44+
private final AntPathMatcher dotSeparatedPathMatcher = new AntPathMatcher(".");
4445

4546

4647
@Test
@@ -357,6 +358,24 @@ void extractUriTemplateVariables() {
357358
assertThat(result).isEqualTo(expected);
358359
}
359360

361+
@Test // gh-26264
362+
void extractUriTemplateVariablesFromDotSeparatedPath() {
363+
Map<String, String> result = dotSeparatedPathMatcher.extractUriTemplateVariables("price.stock.{tickerSymbol}", "price.stock.aaa");
364+
assertThat(result).isEqualTo(Collections.singletonMap("tickerSymbol", "aaa"));
365+
366+
result = dotSeparatedPathMatcher.extractUriTemplateVariables("price.stock.{ticker/symbol}", "price.stock.aaa");
367+
assertThat(result).isEqualTo(Collections.singletonMap("ticker/symbol", "aaa"));
368+
369+
result = dotSeparatedPathMatcher.extractUriTemplateVariables("notification.**.{operation}", "notification.foo.update");
370+
assertThat(result).isEqualTo(Collections.singletonMap("operation", "update"));
371+
372+
result = dotSeparatedPathMatcher.extractUriTemplateVariables("news.sports.feed/{type}", "news.sports.feed/xml");
373+
assertThat(result).isEqualTo(Collections.singletonMap("type", "xml"));
374+
375+
result = dotSeparatedPathMatcher.extractUriTemplateVariables("news.sports.{operation}/*", "news.sports.feed/xml");
376+
assertThat(result).isEqualTo(Collections.singletonMap("operation", "feed"));
377+
}
378+
360379
@Test
361380
void extractUriTemplateVariablesRegex() {
362381
Map<String, String> result = pathMatcher

0 commit comments

Comments
 (0)