Browse Source

Fix PathPattern comparator result for wildcard suffix usage

Without this change the comparator thinks "/{foo}"
is more specific than "/{foo}.*". The minimal fix here
to address it is to copy what the AntPathMatcher
comparator does which is to consider '.*' as *not*
a usage of a wildcard. See PatternInfo#initCounters()
for the AntPathMatcher handling of this.

This change ensures the PathPattern comparator now produces
the expected result but suffix usage in general needs more
thought at some point.

Issue: SPR-15597
pull/1444/head
Andy Clement 8 years ago
parent
commit
77576ed6fe
  1. 7
      spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java
  2. 20
      spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternMatcherTests.java

7
spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java

@ -72,7 +72,12 @@ class RegexPathElement extends PathElement { @@ -72,7 +72,12 @@ class RegexPathElement extends PathElement {
}
else if ("*".equals(match)) {
patternBuilder.append(".*");
this.wildcardCount++;
int pos = matcher.start();
if (pos < 1 || text.charAt(pos-1) != '.') {
// To be compatible with the AntPathMatcher comparator,
// '.*' is not considered a wildcard usage
this.wildcardCount++;
}
}
else if (match.startsWith("{") && match.endsWith("}")) {
int colonIdx = match.indexOf(':');

20
spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternMatcherTests.java

@ -23,6 +23,7 @@ import java.util.HashMap; @@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@ -1052,6 +1053,25 @@ public class PathPatternMatcherTests { @@ -1052,6 +1053,25 @@ public class PathPatternMatcherTests {
assertEquals(-1, comparator.compare(parse("*"), parse("*/**")));
assertEquals(1, comparator.compare(parse("*/**"), parse("*")));
}
@Test
public void compare_spr15597() {
PathPatternParser parser = new PathPatternParser();
PathPattern p1 = parser.parse("/{foo}");
PathPattern p2 = parser.parse("/{foo}.*");
Map<String, String> r1 = p1.matchAndExtract("/file.txt");
Map<String, String> r2 = p2.matchAndExtract("/file.txt");
// works fine
assertEquals(r1.get("foo"), "file.txt");
assertEquals(r2.get("foo"), "file");
// This produces 2 (see comments in https://jira.spring.io/browse/SPR-14544 )
// Comparator<String> patternComparator = new AntPathMatcher().getPatternComparator("");
// System.out.println(patternComparator.compare("/{foo}","/{foo}.*"));
assertThat(p1.compareTo(p2), Matchers.greaterThan(0));
}
@Test
public void patternCompareTo() {

Loading…
Cancel
Save