Skip to content

Commit f9af5d4

Browse files
committed
Use custom path separator for pattern comparisons
As pointed out in gh-33085, the `AntPatternComparator` hardcodes the "/" separator when checking for "catch all" patterns like "/**". This commit ensures that the custom path separator is used for those checks, in order to guarantee consistent comparator results. See gh-33085
1 parent 6d1f117 commit f9af5d4

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

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

+13-6
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ else if (path1EndsWithSeparator || path2StartsWithSeparator) {
635635
*/
636636
@Override
637637
public Comparator<String> getPatternComparator(String path) {
638-
return new AntPatternComparator(path);
638+
return new AntPatternComparator(path, this.pathSeparator);
639639
}
640640

641641

@@ -770,8 +770,15 @@ protected static class AntPatternComparator implements Comparator<String> {
770770

771771
private final String path;
772772

773+
private final String pathSeparator;
774+
773775
public AntPatternComparator(String path) {
776+
this(path, DEFAULT_PATH_SEPARATOR);
777+
}
778+
779+
public AntPatternComparator(String path, String pathSeparator) {
774780
this.path = path;
781+
this.pathSeparator = pathSeparator;
775782
}
776783

777784
/**
@@ -782,8 +789,8 @@ public AntPatternComparator(String path) {
782789
*/
783790
@Override
784791
public int compare(String pattern1, String pattern2) {
785-
PatternInfo info1 = new PatternInfo(pattern1);
786-
PatternInfo info2 = new PatternInfo(pattern2);
792+
PatternInfo info1 = new PatternInfo(pattern1, this.pathSeparator);
793+
PatternInfo info2 = new PatternInfo(pattern2, this.pathSeparator);
787794

788795
if (info1.isLeastSpecific() && info2.isLeastSpecific()) {
789796
return 0;
@@ -865,12 +872,12 @@ private static class PatternInfo {
865872
@Nullable
866873
private Integer length;
867874

868-
public PatternInfo(@Nullable String pattern) {
875+
PatternInfo(@Nullable String pattern, String pathSeparator) {
869876
this.pattern = pattern;
870877
if (this.pattern != null) {
871878
initCounters();
872-
this.catchAllPattern = this.pattern.equals("/**");
873-
this.prefixPattern = !this.catchAllPattern && this.pattern.endsWith("/**");
879+
this.catchAllPattern = this.pattern.equals(pathSeparator + "**");
880+
this.prefixPattern = !this.catchAllPattern && this.pattern.endsWith(pathSeparator + "**");
874881
}
875882
if (this.uriVars == 0) {
876883
this.length = (this.pattern != null ? this.pattern.length() : 0);

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

+10
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,16 @@ void patternComparator() {
524524
assertThat(comparator.compare("*/**", "*")).isEqualTo(1);
525525
}
526526

527+
@Test
528+
void patternComparatorWithDotSeparator() {
529+
Comparator<String> comparator = dotSeparatedPathMatcher.getPatternComparator("price.stock.spring");
530+
531+
assertThat(comparator.compare(null, null)).isEqualTo(0);
532+
assertThat(comparator.compare("price.stock.ticker/symbol", "price.stock.ticker/symbol")).isEqualTo(0);
533+
assertThat(comparator.compare("price.stock.**", "price.stock.ticker")).isEqualTo(1);
534+
}
535+
536+
527537
@Test
528538
void patternComparatorSort() {
529539
Comparator<String> comparator = pathMatcher.getPatternComparator("/hotels/new");

0 commit comments

Comments
 (0)