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