From 91cbfdb487ee39d46bf2daa5785b15b025f516cf Mon Sep 17 00:00:00 2001 From: Jeff Ching Date: Sun, 26 May 2019 07:27:50 -0700 Subject: [PATCH] Add Base64Test case for some base64 decoding edge cases (#644) * Add Base64Test case for some base64 decoding edge cases * Preserve decoding behavior for null decodeBase64(null) * Handle encoding with null inputs --- .../com/google/api/client/util/Base64.java | 11 +++- .../google/api/client/util/Base64Test.java | 65 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 google-http-client/src/test/java/com/google/api/client/util/Base64Test.java diff --git a/google-http-client/src/main/java/com/google/api/client/util/Base64.java b/google-http-client/src/main/java/com/google/api/client/util/Base64.java index 305ab688c..038156390 100644 --- a/google-http-client/src/main/java/com/google/api/client/util/Base64.java +++ b/google-http-client/src/main/java/com/google/api/client/util/Base64.java @@ -43,6 +43,9 @@ public static byte[] encodeBase64(byte[] binaryData) { * @return String containing Base64 characters or {@code null} for {@code null} input */ public static String encodeBase64String(byte[] binaryData) { + if (binaryData == null) { + return null; + } return BaseEncoding.base64().encode(binaryData); } @@ -66,6 +69,9 @@ public static byte[] encodeBase64URLSafe(byte[] binaryData) { * @return String containing Base64 characters or {@code null} for {@code null} input */ public static String encodeBase64URLSafeString(byte[] binaryData) { + if (binaryData == null) { + return null; + } return BaseEncoding.base64Url().omitPadding().encode(binaryData); } @@ -88,11 +94,14 @@ public static byte[] decodeBase64(byte[] base64Data) { * @return Array containing decoded data or {@code null} for {@code null} input */ public static byte[] decodeBase64(String base64String) { + if (base64String == null) { + return null; + } try { return BaseEncoding.base64().decode(base64String); } catch (IllegalArgumentException e) { if (e.getCause() instanceof DecodingException) { - return BaseEncoding.base64Url().decode(base64String); + return BaseEncoding.base64Url().decode(base64String.trim()); } throw e; } diff --git a/google-http-client/src/test/java/com/google/api/client/util/Base64Test.java b/google-http-client/src/test/java/com/google/api/client/util/Base64Test.java new file mode 100644 index 000000000..0ee174f9f --- /dev/null +++ b/google-http-client/src/test/java/com/google/api/client/util/Base64Test.java @@ -0,0 +1,65 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.api.client.util; + +import java.nio.charset.StandardCharsets; +import junit.framework.TestCase; + +/** + * Tests {@link Base64}. + * + * @author Jeff Ching + */ +public class Base64Test extends TestCase { + + public void test_decodeBase64_withPadding() { + String encoded = "Zm9vOmJhcg=="; + assertEquals("foo:bar", new String(Base64.decodeBase64(encoded), StandardCharsets.UTF_8)); + } + + public void test_decodeBase64_withoutPadding() { + String encoded = "Zm9vOmJhcg"; + assertEquals("foo:bar", new String(Base64.decodeBase64(encoded), StandardCharsets.UTF_8)); + } + + public void test_decodeBase64_withTrailingWhitespace() { + // Some internal use cases append extra space characters that apache-commons base64 decoding + // previously handled. + String encoded = "Zm9vOmJhcg==\r\n"; + assertEquals("foo:bar", new String(Base64.decodeBase64(encoded), StandardCharsets.UTF_8)); + } + + public void test_decodeBase64_withNullBytes_shouldReturnNull() { + byte[] encoded = null; + assertNull(Base64.decodeBase64(encoded)); + } + + public void test_decodeBase64_withNull_shouldReturnNull() { + String encoded = null; + assertNull(Base64.decodeBase64(encoded)); + } + + public void test_encodeBase64URLSafeString_withNull_shouldReturnNull() { + assertNull(Base64.encodeBase64URLSafeString(null)); + } + + public void test_encodeBase64URLSafe_withNull_shouldReturnNull() { + assertNull(Base64.encodeBase64URLSafe(null)); + } + + public void test_encodeBase64_withNull_shouldReturnNull() { + assertNull(Base64.encodeBase64(null)); + } +}