1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2011-2012 Couchbase, Inc.
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 #include "config.h"
18 #include <gtest/gtest.h>
19 
20 extern "C" {
21 extern int lcb_base64_encode(const char *src, size_t nsrc, char *dst, size_t ndst);
22 extern int lcb_base64_decode(const char *src, size_t nsrc, char *dst, size_t ndst);
23 
24 extern int lcb_base64_encode2(const char *src, size_t nsrc, char **dst, size_t *ndst);
25 extern int lcb_base64_decode2(const char *src, size_t nsrc, char **dst, size_t *ndst);
26 }
27 
28 class Base64 : public ::testing::Test
29 {
30   protected:
validate(const char * src,const char * result)31     void validate(const char *src, const char *result)
32     {
33         char dest[1024];
34         ASSERT_GE(lcb_base64_encode(src, strlen(src), dest, sizeof(dest)), 0);
35         EXPECT_STREQ(result, dest);
36         memset(dest, 0, sizeof(dest));
37         ASSERT_GE(lcb_base64_decode(result, strlen(result), dest, sizeof(dest)), 0);
38         EXPECT_STREQ(src, dest);
39 
40         char *tmp = NULL;
41         size_t ntmp = 0;
42         ASSERT_GE(lcb_base64_encode2(src, strlen(src), &tmp, &ntmp), 0);
43         EXPECT_STREQ(result, tmp);
44         free(tmp);
45         tmp = NULL;
46         ntmp = 0;
47         ASSERT_GE(lcb_base64_decode2(result, strlen(result), &tmp, &ntmp), 0);
48         EXPECT_STREQ(src, tmp);
49         free(tmp);
50     }
51 };
52 
TEST_F(Base64,testRFC4648)53 TEST_F(Base64, testRFC4648)
54 {
55     validate("", "");
56     validate("f", "Zg==");
57     validate("fo", "Zm8=");
58     validate("foo", "Zm9v");
59     validate("foob", "Zm9vYg==");
60     validate("fooba", "Zm9vYmE=");
61     validate("foobar", "Zm9vYmFy");
62 }
63 
TEST_F(Base64,testWikipediaExample)64 TEST_F(Base64, testWikipediaExample)
65 {
66     /* Examples from http://en.wikipedia.org/wiki/Base64 */
67     validate("Man is distinguished, not only by his reason, but by this singular "
68              "passion from other animals, which is a lust of the mind, that by a "
69              "perseverance of delight in the continued and indefatigable generation"
70              " of knowledge, exceeds the short vehemence of any carnal pleasure.",
71              "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
72              "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
73              "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
74              "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
75              "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
76     validate("pleasure.", "cGxlYXN1cmUu");
77     validate("leasure.", "bGVhc3VyZS4=");
78     validate("easure.", "ZWFzdXJlLg==");
79     validate("asure.", "YXN1cmUu");
80     validate("sure.", "c3VyZS4=");
81 }
82 
TEST_F(Base64,testStuff)83 TEST_F(Base64, testStuff)
84 {
85     // Dummy test data. It looks like the "base64" command line
86     // utility from gnu coreutils adds the "\n" to the encoded data...
87     validate("Administrator:password", "QWRtaW5pc3RyYXRvcjpwYXNzd29yZA==");
88     validate("@", "QA==");
89     validate("@\n", "QAo=");
90     validate("@@", "QEA=");
91     validate("@@\n", "QEAK");
92     validate("@@@", "QEBA");
93     validate("@@@\n", "QEBACg==");
94     validate("@@@@", "QEBAQA==");
95     validate("@@@@\n", "QEBAQAo=");
96     validate("blahblah:bla@@h", "YmxhaGJsYWg6YmxhQEBo");
97     validate("blahblah:bla@@h\n", "YmxhaGJsYWg6YmxhQEBoCg==");
98 }
99 
TEST_F(Base64,testTooSmallOutputBuffer)100 TEST_F(Base64, testTooSmallOutputBuffer)
101 {
102     const char *plain = "foobar";
103     const char *base64 = "Zm9vYmFy";
104 
105     char dest[2];
106 
107     ASSERT_EQ(lcb_base64_encode(plain, strlen(plain), dest, sizeof(dest)), -1);
108     ASSERT_EQ(lcb_base64_decode(base64, strlen(base64), dest, sizeof(dest)), -1);
109 }
110