Update variable detection in UriComponentsBuilder#encode
This commit better aligns how URI variable placeholders are detected
in UriComponentsBuilder#encode (i.e. the pre-encoding of the literal
parts of a URI template) and how they are expanded later on.
The latter relies on a pattern that stops at the first closing '}'
which excludes the possibility for well-formed, nested placeholders
other than variables with regex syntax, e.g. "{year:\d{1,4}}".
UriComponentsBuilder#encode now also stops at the first closing '}' and
further ensures the placeholder is not empty and that it has '{' before
deciding to treat it as a URI variable.
Closes gh-26466
This commit is contained in:
@@ -25,6 +25,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -1037,6 +1038,35 @@ class UriComponentsBuilderTests {
|
||||
assertThat(result1.getSchemeSpecificPart()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test // gh-26466
|
||||
void encodeTemplateWithInvalidPlaceholderSyntax() {
|
||||
|
||||
BiConsumer<String, String> tester = (in, out) ->
|
||||
assertThat(UriComponentsBuilder.fromUriString(in).encode().toUriString()).isEqualTo(out);
|
||||
|
||||
// empty
|
||||
tester.accept("{}", "%7B%7D");
|
||||
tester.accept("{ \t}", "%7B%20%09%7D");
|
||||
tester.accept("/a{}b", "/a%7B%7Db");
|
||||
tester.accept("/a{ \t}b", "/a%7B%20%09%7Db");
|
||||
|
||||
// nested, matching
|
||||
tester.accept("{foo{}}", "%7Bfoo%7B%7D%7D");
|
||||
tester.accept("{foo{bar}baz}", "%7Bfoo%7Bbar%7Dbaz%7D");
|
||||
tester.accept("/a{foo{}}b", "/a%7Bfoo%7B%7D%7Db");
|
||||
tester.accept("/a{foo{bar}baz}b", "/a%7Bfoo%7Bbar%7Dbaz%7Db");
|
||||
|
||||
// mismatched
|
||||
tester.accept("{foo{{}", "%7Bfoo%7B%7B%7D");
|
||||
tester.accept("{foo}}", "{foo}%7D");
|
||||
tester.accept("/a{foo{{}bar", "/a%7Bfoo%7B%7B%7Dbar");
|
||||
tester.accept("/a{foo}}b", "/a{foo}%7Db");
|
||||
|
||||
// variable with regex
|
||||
tester.accept("{year:\\d{1,4}}", "{year:\\d{1,4}}");
|
||||
tester.accept("/a{year:\\d{1,4}}b", "/a{year:\\d{1,4}}b");
|
||||
}
|
||||
|
||||
@Test // SPR-11856
|
||||
void fromHttpRequestForwardedHeader() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
Reference in New Issue
Block a user