Fix URL decoding issue in reactive @RequestParam

%-encoded strings were injected undecoded into @RequestParam variables,
which does not coincide with spring-webmvc behaviour. This commit
fixes AbstractServerHttpRequest.getQueryParams() to correctly return
decoded name-value pairs.

Issue: SPR-15140
This commit is contained in:
Eiichi Sato 2017-01-14 20:43:31 +09:00 committed by Rossen Stoyanchev
parent 88c5f5981f
commit 613e65f043
2 changed files with 28 additions and 1 deletions

View File

@ -16,7 +16,10 @@
package org.springframework.http.server.reactive;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -76,6 +79,22 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
return this.queryParams;
}
/**
* A method for decoding name and value string in a name-value pair.
* <p>Note that the plus sign "+" is converted into a space character " ".</p>
* @param encodedString the string to be decoded
* @return the decoded string
* @see java.net.URLDecoder#decode(String, String)
*/
private static String decodeQueryParam(final String encodedString) {
try {
return URLDecoder.decode(encodedString, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
// StandardCharsets are guaranteed to be available on every implementation of the Java platform, so this should never happen.
throw new IllegalStateException(e);
}
}
/**
* A method for parsing of the query into name-value pairs. The return
* value is turned into an immutable map and cached.
@ -94,7 +113,8 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
String eq = matcher.group(2);
String value = matcher.group(3);
value = (value != null ? value : (StringUtils.hasLength(eq) ? "" : null));
queryParams.add(name, value);
queryParams.add(decodeQueryParam(name),
value != null ? decodeQueryParam(value) : null);
}
}
return queryParams;

View File

@ -64,6 +64,13 @@ public class ServerHttpRequestTests {
assertEquals(Arrays.asList("1", "2"), params.get("a"));
}
@Test
public void queryParamsWithUrlEncodedValue() throws Exception {
MultiValueMap<String, String> params = createHttpRequest("/path?a=%20%2B+%C3%A0").getQueryParams();
assertEquals(1, params.size());
assertEquals(Collections.singletonList(" + \u00e0"), params.get("a"));
}
@Test
public void queryParamsWithEmptyValue() throws Exception {
MultiValueMap<String, String> params = createHttpRequest("/path?a=").getQueryParams();