From 3d8032fbdb402ddda9188403484494f6d0ca1d6d Mon Sep 17 00:00:00 2001 From: Ajay Date: Tue, 4 Dec 2018 15:31:18 -0500 Subject: [PATCH] fix #398 GenericUrl converts plus sign into space within URI path component --- .../google/api/client/http/GenericUrl.java | 2 +- .../api/client/util/escape/CharEscapers.java | 28 +++++++++++++++++++ .../api/client/http/GenericUrlTest.java | 2 ++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/google-http-client/src/main/java/com/google/api/client/http/GenericUrl.java b/google-http-client/src/main/java/com/google/api/client/http/GenericUrl.java index 9f70ac120..9d109eb6d 100644 --- a/google-http-client/src/main/java/com/google/api/client/http/GenericUrl.java +++ b/google-http-client/src/main/java/com/google/api/client/http/GenericUrl.java @@ -548,7 +548,7 @@ public static List toPathParts(String encodedPath) { } else { sub = encodedPath.substring(cur); } - result.add(CharEscapers.decodeUri(sub)); + result.add(CharEscapers.decode(sub)); cur = slash + 1; } return result; diff --git a/google-http-client/src/main/java/com/google/api/client/util/escape/CharEscapers.java b/google-http-client/src/main/java/com/google/api/client/util/escape/CharEscapers.java index 49470c81b..a5a74e22f 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/escape/CharEscapers.java +++ b/google-http-client/src/main/java/com/google/api/client/util/escape/CharEscapers.java @@ -15,6 +15,8 @@ package com.google.api.client.util.escape; import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URLDecoder; /** @@ -96,6 +98,32 @@ public static String decodeUri(String uri) { } } + /** + * Percent-decodes a US-ASCII string into a Unicode string. UTF-8 encoding is used to determine + * what characters are represented by any consecutive sequences of the form "%XX". + * + *

+ * This doesnt replaces each occurrence of '+' with a space, ' '. So this method should not be used for + * application/x-www-form-urlencoded strings such as query. + *

+ * + * @param uri a percent-encoded US-ASCII string + * @return a Unicode string + */ + public static String decode(String uri) { + if (uri.indexOf('%') > -1) { + if (uri.indexOf('+') > -1) { + try { + return new URI(uri).getPath(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + return decodeUri(uri); + } + return uri; + } + /** * Escapes the string value so it can be safely included in URI path segments. For details on * escaping URIs, see RFC 3986 - section diff --git a/google-http-client/src/test/java/com/google/api/client/http/GenericUrlTest.java b/google-http-client/src/test/java/com/google/api/client/http/GenericUrlTest.java index f4a8b22a2..105d6a886 100644 --- a/google-http-client/src/test/java/com/google/api/client/http/GenericUrlTest.java +++ b/google-http-client/src/test/java/com/google/api/client/http/GenericUrlTest.java @@ -475,6 +475,8 @@ public void testToPathParts() { subtestToPathParts("/path/to/resource", "", "path", "to", "resource"); subtestToPathParts("/path/to/resource/", "", "path", "to", "resource", ""); subtestToPathParts("/Go%3D%23%2F%25%26%20?%3Co%3Egle/2nd", "", "Go=#/%& ?gle", "2nd"); + subtestToPathParts("/path+with+plus/2nd", "", "path+with+plus", "2nd"); + subtestToPathParts("/path%2Bwith+plus/2nd", "", "path+with+plus", "2nd"); } private void subtestToPathParts(String encodedPath, String... expectedDecodedParts) {