From 91c46a99b0b9464d01b5aca2116bbe073b878725 Mon Sep 17 00:00:00 2001 From: cHengstler <69518287+cHengstler@users.noreply.github.com> Date: Fri, 5 May 2023 19:30:13 +0200 Subject: [PATCH] fix: UriTemplate reserved expansion does not escape reserved chars (#1844) When using UriTemplate.expand with a reserved expansion "{+var}", a set of allowed characters must not be encoded. According to section of [3.2.3 Reserved Expansion: {+var}](https://www.rfc-editor.org/rfc/rfc6570#section-3.2.3), unreserved and reserved character should not be escaped. This fix adds the missing characters `#[]` that must not be percent encoded when using reserved expansion. - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [x] Appropriate docs were updated (if necessary) Fixes #1838 --- .../client/util/escape/PercentEscaper.java | 11 +++++--- .../api/client/http/UriTemplateTest.java | 26 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/google-http-client/src/main/java/com/google/api/client/util/escape/PercentEscaper.java b/google-http-client/src/main/java/com/google/api/client/util/escape/PercentEscaper.java index 3866265a3..601b52c14 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/escape/PercentEscaper.java +++ b/google-http-client/src/main/java/com/google/api/client/util/escape/PercentEscaper.java @@ -64,10 +64,15 @@ public class PercentEscaper extends UnicodeEscaper { public static final String SAFEPATHCHARS_URLENCODER = "-_.!~*'()@:$&,;=+"; /** - * Contains the safe characters plus all reserved characters. This happens to be the safe path - * characters plus those characters which are reserved for URI segments, namely '/' and '?'. + * A string of characters that do not need to be encoded when used in URI Templates reserved + * expansion, as specified in RFC 6570. This includes the safe characters plus all reserved + * characters. + * + * <p>For details on escaping URI Templates using the reserved expansion, see <a + * href="https://www.rfc-editor.org/rfc/rfc6570#section-3.2.3">RFC 6570 - section 3.2.3</a>. */ - public static final String SAFE_PLUS_RESERVED_CHARS_URLENCODER = SAFEPATHCHARS_URLENCODER + "/?"; + public static final String SAFE_PLUS_RESERVED_CHARS_URLENCODER = + SAFEPATHCHARS_URLENCODER + "/?#[]"; /** * A string of characters that do not need to be encoded when used in URI user info part, as diff --git a/google-http-client/src/test/java/com/google/api/client/http/UriTemplateTest.java b/google-http-client/src/test/java/com/google/api/client/http/UriTemplateTest.java index 1a38eeafa..14ebc61b6 100644 --- a/google-http-client/src/test/java/com/google/api/client/http/UriTemplateTest.java +++ b/google-http-client/src/test/java/com/google/api/client/http/UriTemplateTest.java @@ -322,4 +322,30 @@ public void testExpandSeveralTemplatesNoParametersUsed() { SortedMap<String, Object> map = Maps.newTreeMap(); assertEquals("", UriTemplate.expand("{?id,uid}", map, false)); } + + public void testExpandTemplates_reservedExpansion_mustNotEscapeReservedCharSet() { + + String reservedSet = ":/?#[]@!$&'()*+,;="; + + SortedMap<String, Object> requestMap = Maps.newTreeMap(); + requestMap.put("var", reservedSet); + + assertEquals( + "Reserved expansion must not escape chars from reserved set according to rfc6570#section-3.2.3", + reservedSet, + UriTemplate.expand("{+var}", requestMap, false)); + } + + public void testExpandTemplates_reservedExpansion_mustNotEscapeUnreservedCharSet() { + + String unReservedSet = "-._~"; + + SortedMap<String, Object> requestMap = Maps.newTreeMap(); + requestMap.put("var", unReservedSet); + + assertEquals( + "Reserved expansion must not escape chars from unreserved set according to rfc6570#section-3.2.3", + unReservedSet, + UriTemplate.expand("{+var}", requestMap, false)); + } }