Skip to content

Commit 777f01d

Browse files
committed
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
1 parent f8fea01 commit 777f01d

File tree

5 files changed

+19
-1
lines changed

5 files changed

+19
-1
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ public char[] getChars() {
118118
return this.text;
119119
}
120120

121+
@Override
122+
public boolean isLiteral() {
123+
return true;
124+
}
121125

122126
@Override
123127
public String toString() {

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* Common supertype for the Ast nodes created to represent a path pattern.
2626
*
2727
* @author Andy Clement
28+
* @author Brian Clozel
2829
* @since 5.0
2930
*/
3031
abstract class PathElement {
@@ -99,6 +100,14 @@ public int getScore() {
99100
return 0;
100101
}
101102

103+
/**
104+
* Return whether this PathElement can be strictly {@link String#compareTo(String) compared}
105+
* against another element for matching.
106+
*/
107+
public boolean isLiteral() {
108+
return false;
109+
}
110+
102111
/**
103112
* Return if the there are no more PathElements in the pattern.
104113
* @return {@code true} if the there are no more elements

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public PathContainer extractPathWithinPattern(PathContainer path) {
303303
// Find first path element that is not a separator or a literal (i.e. the first pattern based element)
304304
PathElement elem = this.head;
305305
while (elem != null) {
306-
if (elem.getWildcardCount() != 0 || elem.getCaptureCount() != 0) {
306+
if (!elem.isLiteral()) {
307307
break;
308308
}
309309
elem = elem.next;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ public char[] getChars() {
6767
return new char[] {this.separator};
6868
}
6969

70+
@Override
71+
public boolean isLiteral() {
72+
return true;
73+
}
7074

7175
@Override
7276
public String toString() {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,7 @@ public void extractPathWithinPattern() throws Exception {
684684
checkExtractPathWithinPattern("/docs/commit.html", "/docs/commit.html", "");
685685
checkExtractPathWithinPattern("/docs/*", "/docs/cvs/commit", "cvs/commit");
686686
checkExtractPathWithinPattern("/docs/cvs/*.html", "/docs/cvs/commit.html", "commit.html");
687+
checkExtractPathWithinPattern("/docs/cvs/file.*.html", "/docs/cvs/file.sha.html", "file.sha.html");
687688
checkExtractPathWithinPattern("/docs/**", "/docs/cvs/commit", "cvs/commit");
688689
checkExtractPathWithinPattern("/doo/{*foobar}", "/doo/customer.html", "customer.html");
689690
checkExtractPathWithinPattern("/doo/{*foobar}", "/doo/daa/customer.html", "daa/customer.html");

0 commit comments

Comments
 (0)