From 0721146b14e3df3bde3e6e8f2a871bb0b995ef4f Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 22 Oct 2012 10:37:40 -0400 Subject: [PATCH] Improve regex for parsing query params Previously UriComponentsBuilder used a regular expression for parsing query name-value pairs where both name and value were expected to not contain neither '&', not '='. The idea is that the presence of reserved characters makes it impossible to guess correctly how to parse the query string (e.g. a=b&c). This change relaxes the constraint on query param values, allowing them to contain '='. In effect '&' is the ultimate separator of name-value pairs, and any '=' in values is ignored. For example "q=1USD=?EUR" is interpreted as "q equals '1USD=?EUR'". Issue: SPR-9832 --- .../springframework/web/util/UriComponentsBuilder.java | 2 +- .../web/util/UriComponentsBuilderTests.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) 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 dc53ec6481..a52615d1ef 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 @@ -53,7 +53,7 @@ import org.springframework.util.StringUtils; */ public class UriComponentsBuilder { - private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("([^&=]+)=?([^&=]+)?"); + private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("([^&=]+)=?([^&]+)?"); private static final String SCHEME_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 e01436319b..057733e943 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 @@ -146,6 +146,16 @@ public class UriComponentsBuilderTests { assertEquals("28", result.getFragment()); } + // SPR-9832 + + @Test + public void fromUriStringQueryParamWithReservedCharInValue() throws URISyntaxException { + String uri = "http://www.google.com/ig/calculator?q=1USD=?EUR"; + UriComponents result = UriComponentsBuilder.fromUriString(uri).build(); + + assertEquals("q=1USD=?EUR", result.getQuery()); + assertEquals("1USD=?EUR", result.getQueryParams().getFirst("q")); + } @Test public void path() throws URISyntaxException {