Reject "/path/**/other" patterns in PathPatternParser

Prior to this commit, patterns like `"/path/**/other"` would be treated
as `"/path/*/other"` (single wildcard, i.e. matching zero to many chars
within a path segment). This will not match multiple segments, as
expected by `AntPathMatcher` users or by `PathPatternParser` users when
in patterns like `"/resource/**"`.

This commit now rejects patterns like `"/path/**/other"` as invalid.
This behavior was previously warned against since gh-24958.

Closes gh-24952
This commit is contained in:
Brian Clozel
2020-05-11 19:08:21 +02:00
parent 7bcda3a29b
commit e4cb25f365
5 changed files with 35 additions and 40 deletions

View File

@@ -236,7 +236,7 @@ class InternalPathPatternParser {
/**
* After processing a separator, a quick peek whether it is followed by
* (and only before the end of the pattern or the next separator).
* a double wildcard (and only as the last path element).
*/
private boolean peekDoubleWildcard() {
if ((this.pos + 2) >= this.pathPatternLength) {
@@ -245,6 +245,11 @@ class InternalPathPatternParser {
if (this.pathPatternData[this.pos + 1] != '*' || this.pathPatternData[this.pos + 2] != '*') {
return false;
}
char separator = this.parser.getPathOptions().separator();
if ((this.pos + 3) < this.pathPatternLength && this.pathPatternData[this.pos + 3] == separator) {
throw new PatternParseException(this.pos, this.pathPatternData,
PatternMessage.NO_MORE_DATA_EXPECTED_AFTER_CAPTURE_THE_REST);
}
return (this.pos + 3 == this.pathPatternLength);
}

View File

@@ -16,9 +16,6 @@
package org.springframework.web.util.pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.server.PathContainer;
/**
@@ -37,8 +34,6 @@ import org.springframework.http.server.PathContainer;
*/
public class PathPatternParser {
private static final Log logger = LogFactory.getLog(PathPatternParser.class);
private boolean matchOptionalTrailingSeparator = true;
private boolean caseSensitive = true;
@@ -114,11 +109,6 @@ public class PathPatternParser {
* @throws PatternParseException in case of parse errors
*/
public PathPattern parse(String pathPattern) throws PatternParseException {
int wildcardIndex = pathPattern.indexOf("**" + this.pathOptions.separator());
if (wildcardIndex != -1 && wildcardIndex != pathPattern.length() - 3) {
logger.warn("'**' patterns are not supported in the middle of patterns and will be rejected in the future. " +
"Consider using '*' instead for matching a single path segment.");
}
return new InternalPathPatternParser(this).parse(pathPattern);
}

View File

@@ -100,7 +100,7 @@ public class PatternParseException extends IllegalArgumentException {
CANNOT_HAVE_ADJACENT_CAPTURES("Adjacent captures are not allowed"),
ILLEGAL_CHARACTER_AT_START_OF_CAPTURE_DESCRIPTOR("Char ''{0}'' not allowed at start of captured variable name"),
ILLEGAL_CHARACTER_IN_CAPTURE_DESCRIPTOR("Char ''{0}'' is not allowed in a captured variable name"),
NO_MORE_DATA_EXPECTED_AFTER_CAPTURE_THE_REST("No more pattern data allowed after '{*...}' pattern element"),
NO_MORE_DATA_EXPECTED_AFTER_CAPTURE_THE_REST("No more pattern data allowed after '{*...}' or '**' pattern element"),
BADLY_FORMED_CAPTURE_THE_REST("Expected form when capturing the rest of the path is simply '{*...}'"),
MISSING_REGEX_CONSTRAINT("Missing regex constraint on capture"),
ILLEGAL_DOUBLE_CAPTURE("Not allowed to capture ''{0}'' twice in the same pattern"),