Browse Source

Fix path within mapping when pattern contains ".*"

Prior to this commit, extracting the path within handler mapping would
result in "" if the matching path element would be a Regex and contain
".*". This could cause issues with resource handling if the handler
mapping pattern was similar to `"/folder/file.*.extension"`.

This commit introduces a new `isLiteral()` method in the `PathElement`
abstract class that expresses whether the path element can be compared
as a String for path matching or if it requires a more elaborate
matching process.

Using this method for extracting the path within handler mapping avoids
relying on wildcard count or other properties.

See gh-29712
Fixes gh-29716
pull/29935/head
Brian Clozel 3 years ago
parent
commit
777f01d786
  1. 4
      spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java
  2. 9
      spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java
  3. 2
      spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java
  4. 4
      spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java
  5. 1
      spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java

4
spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java

@ -118,6 +118,10 @@ class LiteralPathElement extends PathElement { @@ -118,6 +118,10 @@ class LiteralPathElement extends PathElement {
return this.text;
}
@Override
public boolean isLiteral() {
return true;
}
@Override
public String toString() {

9
spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java

@ -25,6 +25,7 @@ import org.springframework.web.util.pattern.PathPattern.MatchingContext; @@ -25,6 +25,7 @@ import org.springframework.web.util.pattern.PathPattern.MatchingContext;
* Common supertype for the Ast nodes created to represent a path pattern.
*
* @author Andy Clement
* @author Brian Clozel
* @since 5.0
*/
abstract class PathElement {
@ -99,6 +100,14 @@ abstract class PathElement { @@ -99,6 +100,14 @@ abstract class PathElement {
return 0;
}
/**
* Return whether this PathElement can be strictly {@link String#compareTo(String) compared}
* against another element for matching.
*/
public boolean isLiteral() {
return false;
}
/**
* Return if the there are no more PathElements in the pattern.
* @return {@code true} if the there are no more elements

2
spring-web/src/main/java/org/springframework/web/util/pattern/PathPattern.java

@ -303,7 +303,7 @@ public class PathPattern implements Comparable<PathPattern> { @@ -303,7 +303,7 @@ public class PathPattern implements Comparable<PathPattern> {
// Find first path element that is not a separator or a literal (i.e. the first pattern based element)
PathElement elem = this.head;
while (elem != null) {
if (elem.getWildcardCount() != 0 || elem.getCaptureCount() != 0) {
if (!elem.isLiteral()) {
break;
}
elem = elem.next;

4
spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java

@ -67,6 +67,10 @@ class SeparatorPathElement extends PathElement { @@ -67,6 +67,10 @@ class SeparatorPathElement extends PathElement {
return new char[] {this.separator};
}
@Override
public boolean isLiteral() {
return true;
}
@Override
public String toString() {

1
spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java

@ -684,6 +684,7 @@ public class PathPatternTests { @@ -684,6 +684,7 @@ public class PathPatternTests {
checkExtractPathWithinPattern("/docs/commit.html", "/docs/commit.html", "");
checkExtractPathWithinPattern("/docs/*", "/docs/cvs/commit", "cvs/commit");
checkExtractPathWithinPattern("/docs/cvs/*.html", "/docs/cvs/commit.html", "commit.html");
checkExtractPathWithinPattern("/docs/cvs/file.*.html", "/docs/cvs/file.sha.html", "file.sha.html");
checkExtractPathWithinPattern("/docs/**", "/docs/cvs/commit", "cvs/commit");
checkExtractPathWithinPattern("/doo/{*foobar}", "/doo/customer.html", "customer.html");
checkExtractPathWithinPattern("/doo/{*foobar}", "/doo/daa/customer.html", "daa/customer.html");

Loading…
Cancel
Save