1999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong/* 2999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * Copyright (C) 2017 The Android Open Source Project 3999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * 4999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * Licensed under the Apache License, Version 2.0 (the "License"); 5999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * you may not use this file except in compliance with the License. 6999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * You may obtain a copy of the License at 7999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * 8999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * http://www.apache.org/licenses/LICENSE-2.0 9999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * 10999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * Unless required by applicable law or agreed to in writing, software 11999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * distributed under the License is distributed on an "AS IS" BASIS, 12999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * See the License for the specific language governing permissions and 14999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong * limitations under the License. 15999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong */ 16999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong#include <utils/Log.h> 17999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 18999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong#include "gtest/gtest.h" 19999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 20999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong#include <media/stagefright/foundation/ABuffer.h> 21999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong#include <media/stagefright/foundation/AString.h> 22999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong#include <media/stagefright/foundation/AStringUtils.h> 23999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong#include <media/stagefright/foundation/base64.h> 24999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 25999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong#include <utils/RefBase.h> 26999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong#include <utils/String8.h> 27999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 28999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wongnamespace { 29999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wongconst android::String8 kBase64Padding("="); 30999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong}; 31999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 32999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wongnamespace android { 33999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 34999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wongclass Base64Test : public ::testing::Test { 35999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong}; 36999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 37999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wongvoid verifyDecode(const AString* expected, const AString* in) { 38999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong size_t numTests = 0; 39999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong while (!expected[numTests].empty()) 40999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong ++numTests; 41999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 42999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong for (size_t i = 0; i < numTests; ++i) { 43999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong // Since android::decodeBase64() requires padding characters, 44999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong // add them so length of encoded text is exactly a multiple of 4. 45999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong int remainder = in[i].size() % 4; 46999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong String8 paddedText(in[i].c_str()); 47999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong if (remainder > 0) { 48999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong for (int i = 0; i < 4 - remainder; ++i) { 49999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong paddedText.append(kBase64Padding); 50999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong } 51999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong } 52999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong sp<ABuffer> result = decodeBase64(AString(paddedText.string())); 53999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 54999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong ASSERT_EQ(AStringUtils::Compare(expected[i].c_str(), 55999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong reinterpret_cast<char*>(result->data()), 56999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong expected[i].size(), false), 0); 57999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong } 58999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong} 59999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 60999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wongvoid verifyEncode(const AString* expected, const AString* in) { 61999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong size_t numTests = 0; 62999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong while (!expected[numTests].empty()) 63999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong ++numTests; 64999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 65999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString out = AString(""); 66999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong for (size_t i = 0; i < numTests; ++i) { 67999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong encodeBase64Url(in[i].c_str(), in[i].size(), &out); 68999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 69999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong ASSERT_EQ(AStringUtils::Compare(expected[i].c_str(), out.c_str(), 70999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong expected[i].size(), false), 0); 71999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong } 72999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong} 73999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 74999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin WongTEST_F(Base64Test, TestDecodeBase64) { 75999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString base64[] = { 76999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("SGVsbG8gRnJpZW5kIQ"), 77999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("R29vZCBkYXkh"), 78999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("") // string to signal end of array 79999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 80999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 81999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString clearText[] = { 82999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Hello Friend!"), 83999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Good day!"), 84999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("") 85999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 86999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 87999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong verifyDecode(clearText, base64); 88999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong} 89999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 90999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin WongTEST_F(Base64Test, TestDecodeBase64Url) { 91999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString base64Url[] = { 92999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("SGVsbG8gRnJpZW5kICE-Pw"), 93999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("SGVsbG8gRnJpZW5kICE_"), 94999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("SGVsbG8gPz4-IEZyaWVuZCA_Pg"), 95999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("") 96999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 97999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 98999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString clearText[] = { 99999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Hello Friend !>?"), 100999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Hello Friend !?"), 101999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Hello ?>> Friend ?>"), 102999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("") 103999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 104999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 105999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong verifyDecode(clearText, base64Url); 106999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong} 107999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 108999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin WongTEST_F(Base64Test, TestDecodeMalformedBase64) { 109999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString base64Url[] = { 110999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("1?GawgguFyGrWKav7AX4VKUg"), // fail on parsing 111999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("GawgguFyGrWKav7AX4V???"), // fail on length not multiple of 4 112999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("GawgguFyGrWKav7AX4VKUg"), // ditto 113999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 114999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 115999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong for (size_t i = 0; i < 3; ++i) { 116999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong sp<ABuffer> result = decodeBase64(AString(base64Url[i])); 117999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong EXPECT_TRUE(result == nullptr); 118999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong } 119999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong} 120999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 121999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin WongTEST_F(Base64Test, TestEncodeBase64) { 122999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString clearText[] = { 123999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Hello Friend!"), 124999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Good day!"), 125999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("") 126999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 127999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 128999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString base64[] = { 129999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("SGVsbG8gRnJpZW5kIQ=="), 130999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("R29vZCBkYXkh"), 131999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("") 132999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 133999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 134999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong verifyEncode(base64, clearText); 135999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong} 136999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 137999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin WongTEST_F(Base64Test, TestEncodeBase64Url) { 138999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString clearText[] = { 139999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Hello Friend !>?"), 140999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Hello Friend !?"), 141999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("Hello ?>> Friend ?>"), 142999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("") 143999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 144999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 145999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong const AString base64Url[] = { 146999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("SGVsbG8gRnJpZW5kICE-Pw=="), 147999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("SGVsbG8gRnJpZW5kICE_"), 148999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("SGVsbG8gPz4-IEZyaWVuZCA_Pg"), 149999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong AString("") 150999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong }; 151999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 152999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong verifyEncode(base64Url, clearText); 153999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong} 154999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong 155999782fa3ff94607c0a814c8d447fad38c2c4c57Edwin Wong} // namespace android 156