diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index e6a3c2f022..6c8fdaad5a 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -62,7 +62,7 @@ public class UriComponentsBuilder { private static final String HTTP_PATTERN = "(?i)(http|https):"; - private static final String USERINFO_PATTERN = "([^@/]*)"; + private static final String USERINFO_PATTERN = "([^@\\[/?#]*)"; private static final String HOST_IPV4_PATTERN = "[^\\[/?#:]*"; diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index 1e1c2ffa78..e116ddb21f 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -26,6 +26,7 @@ import org.junit.Test; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; @@ -216,6 +217,17 @@ public class UriComponentsBuilderTests { assertEquals("[::192.168.1.1]", resultIPv4compatible.getHost()); } + // SPR-11970 + + @Test + public void fromUriStringNoPathWithReservedCharInQuery() { + UriComponents result = UriComponentsBuilder.fromUriString("http://example.com?foo=bar@baz").build(); + assertTrue(StringUtils.isEmpty(result.getUserInfo())); + assertEquals("example.com", result.getHost()); + assertTrue(result.getQueryParams().containsKey("foo")); + assertEquals("bar@baz", result.getQueryParams().getFirst("foo")); + } + @Test public void path() throws URISyntaxException { UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/foo/bar");