Skip to content

Commit 2e6046a

Browse files
committed
Remove trailing slash matching in PathPatternParser
See gh-34036
1 parent 32db1a1 commit 2e6046a

File tree

8 files changed

+8
-302
lines changed

8 files changed

+8
-302
lines changed

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

-5
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,6 @@ public boolean matches(int pathIndex, PathPattern.MatchingContext matchingContex
100100
else {
101101
// Needs to be at least one character #SPR15264
102102
match = (pathIndex == matchingContext.pathLength);
103-
if (!match && matchingContext.isMatchOptionalTrailingSeparator()) {
104-
match = //(nextPos > candidateIndex) &&
105-
(pathIndex + 1) == matchingContext.pathLength &&
106-
matchingContext.isSeparator(pathIndex);
107-
}
108103
}
109104
}
110105
else {

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

+1-8
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,7 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
7878
return true;
7979
}
8080
else {
81-
if (pathIndex == matchingContext.pathLength) {
82-
return true;
83-
}
84-
else {
85-
return (matchingContext.isMatchOptionalTrailingSeparator() &&
86-
(pathIndex + 1) == matchingContext.pathLength &&
87-
matchingContext.isSeparator(pathIndex));
88-
}
81+
return (pathIndex == matchingContext.pathLength);
8982
}
9083
}
9184
else {

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

+3-15
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,6 @@ public class PathPattern implements Comparable<PathPattern> {
112112
/** The options to use to parse a pattern. */
113113
private final PathContainer.Options pathOptions;
114114

115-
/** If this pattern has no trailing slash, allow candidates to include one and still match successfully. */
116-
private final boolean matchOptionalTrailingSeparator;
117-
118115
/** Will this match candidates in a case-sensitive way? (case sensitivity at parse time). */
119116
private final boolean caseSensitive;
120117

@@ -152,12 +149,10 @@ public class PathPattern implements Comparable<PathPattern> {
152149
private boolean catchAll = false;
153150

154151

155-
@SuppressWarnings("deprecation")
156152
PathPattern(String patternText, PathPatternParser parser, @Nullable PathElement head) {
157153
this.patternString = patternText;
158154
this.parser = parser;
159155
this.pathOptions = parser.getPathOptions();
160-
this.matchOptionalTrailingSeparator = parser.isMatchOptionalTrailingSeparator();
161156
this.caseSensitive = parser.isCaseSensitive();
162157
this.head = head;
163158

@@ -202,8 +197,7 @@ public boolean hasPatternSyntax() {
202197
*/
203198
public boolean matches(PathContainer pathContainer) {
204199
if (this.head == null) {
205-
return !hasLength(pathContainer) ||
206-
(this.matchOptionalTrailingSeparator && pathContainerIsJustSeparator(pathContainer));
200+
return !hasLength(pathContainer);
207201
}
208202
else if (!hasLength(pathContainer)) {
209203
if (this.head instanceof WildcardTheRestPathElement || this.head instanceof CaptureTheRestPathElement) {
@@ -226,9 +220,7 @@ else if (!hasLength(pathContainer)) {
226220
@Nullable
227221
public PathMatchInfo matchAndExtract(PathContainer pathContainer) {
228222
if (this.head == null) {
229-
return (hasLength(pathContainer) &&
230-
!(this.matchOptionalTrailingSeparator && pathContainerIsJustSeparator(pathContainer)) ?
231-
null : PathMatchInfo.EMPTY);
223+
return (hasLength(pathContainer) && !pathContainerIsJustSeparator(pathContainer) ? null : PathMatchInfo.EMPTY);
232224
}
233225
else if (!hasLength(pathContainer)) {
234226
if (this.head instanceof WildcardTheRestPathElement || this.head instanceof CaptureTheRestPathElement) {
@@ -647,7 +639,7 @@ public Map<String, MultiValueMap<String, String>> getMatrixVariables() {
647639
* candidate currently being considered for a match but also some accumulators for
648640
* extracted variables.
649641
*/
650-
class MatchingContext {
642+
static class MatchingContext {
651643

652644
final PathContainer candidate;
653645

@@ -681,10 +673,6 @@ public void setMatchAllowExtraPath() {
681673
this.determineRemainingPath = true;
682674
}
683675

684-
public boolean isMatchOptionalTrailingSeparator() {
685-
return matchOptionalTrailingSeparator;
686-
}
687-
688676
public void set(String key, String value, MultiValueMap<String,String> parameters) {
689677
if (this.extractedUriVariables == null) {
690678
this.extractedUriVariables = new HashMap<>();

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

+1-36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,40 +35,11 @@
3535
*/
3636
public class PathPatternParser {
3737

38-
private boolean matchOptionalTrailingSeparator = false;
39-
4038
private boolean caseSensitive = true;
4139

4240
private PathContainer.Options pathOptions = PathContainer.Options.HTTP_PATH;
4341

4442

45-
/**
46-
* Configure whether a {@link PathPattern} produced by this parser should
47-
* automatically match request paths with a trailing slash.
48-
* <p>If set to {@code true} a {@code PathPattern} without a trailing slash
49-
* will also match request paths with a trailing slash. If set to
50-
* {@code false} a {@code PathPattern} will only match request paths with
51-
* a trailing slash.
52-
* <p>The default was changed in 6.0 from {@code true} to {@code false} in
53-
* order to support the deprecation of the property.
54-
* @deprecated transparent support for trailing slashes is deprecated as of
55-
* 6.0 in favor of configuring explicit redirects through a proxy,
56-
* Servlet/web filter, or a controller.
57-
*/
58-
@Deprecated(since = "6.0")
59-
public void setMatchOptionalTrailingSeparator(boolean matchOptionalTrailingSeparator) {
60-
this.matchOptionalTrailingSeparator = matchOptionalTrailingSeparator;
61-
}
62-
63-
/**
64-
* Whether optional trailing slashing match is enabled.
65-
* @deprecated as of 6.0 together with {@link #setMatchOptionalTrailingSeparator(boolean)}.
66-
*/
67-
@Deprecated(since = "6.0")
68-
public boolean isMatchOptionalTrailingSeparator() {
69-
return this.matchOptionalTrailingSeparator;
70-
}
71-
7243
/**
7344
* Configure whether path pattern matching should be case-sensitive.
7445
* <p>The default is {@code true}.
@@ -141,12 +112,6 @@ public PathPattern parse(String pathPattern) throws PatternParseException {
141112
*/
142113
public static final PathPatternParser defaultInstance = new PathPatternParser() {
143114

144-
@SuppressWarnings("deprecation")
145-
@Override
146-
public void setMatchOptionalTrailingSeparator(boolean matchOptionalTrailingSeparator) {
147-
raiseError();
148-
}
149-
150115
@Override
151116
public void setCaseSensitive(boolean caseSensitive) {
152117
raiseError();

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

-5
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,6 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
143143
// If pattern is capturing variables there must be some actual data to bind to them
144144
matches = (pathIndex + 1 >= matchingContext.pathLength) &&
145145
(this.variableNames.isEmpty() || !textToMatch.isEmpty());
146-
if (!matches && matchingContext.isMatchOptionalTrailingSeparator()) {
147-
matches = (this.variableNames.isEmpty() || !textToMatch.isEmpty()) &&
148-
(pathIndex + 2 >= matchingContext.pathLength) &&
149-
matchingContext.isSeparator(pathIndex + 1);
150-
}
151146
}
152147
}
153148
else {

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

+1-8
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,7 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
9999
return true;
100100
}
101101
else {
102-
if (pathIndex == matchingContext.pathLength) {
103-
return true;
104-
}
105-
else {
106-
return (matchingContext.isMatchOptionalTrailingSeparator() &&
107-
(pathIndex + 1) == matchingContext.pathLength &&
108-
matchingContext.isSeparator(pathIndex));
109-
}
102+
return (pathIndex == matchingContext.pathLength);
110103
}
111104
}
112105
else {

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

+2-10
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,8 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
6060
return true;
6161
}
6262
else {
63-
if (pathIndex == matchingContext.pathLength) {
64-
// and the path data has run out too
65-
return true;
66-
}
67-
else {
68-
return (matchingContext.isMatchOptionalTrailingSeparator() && // if optional slash is on...
69-
segmentData != null && !segmentData.isEmpty() && // and there is at least one character to match the *...
70-
(pathIndex + 1) == matchingContext.pathLength && // and the next path element is the end of the candidate...
71-
matchingContext.isSeparator(pathIndex)); // and the final element is a separator
72-
}
63+
// and the path data has run out too
64+
return (pathIndex == matchingContext.pathLength);
7365
}
7466
}
7567
else {

0 commit comments

Comments
 (0)