1 /* Self tests for base64.
2 Copyright (C) 2004, 2008-2023 Free Software Foundation, Inc.
3 Written by Simon Josefsson.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17
18 #include <config.h>
19
20 #include "base64.h"
21
22 #include <stddef.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdint.h>
26
27 #include "macros.h"
28
29 int
30 main (void)
31 {
32 const char *in = "abcdefghijklmnop";
33 const char *b64in = "YWJjZGVmZw==";
34 char out[255];
35 idx_t len;
36 bool ok;
37 char *p;
38
39 memset (out, 0x42, sizeof (out));
40 base64_encode (in, 0, out, 0);
41 ASSERT (out[0] == '\x42');
42
43 memset (out, 0x42, sizeof (out));
44 base64_encode (in, 1, out, 1);
45 ASSERT (memcmp (out, "YQ==", 1) == 0);
46
47 memset (out, 0x42, sizeof (out));
48 base64_encode (in, 1, out, 2);
49 ASSERT (memcmp (out, "YQ==", 2) == 0);
50
51 memset (out, 0x42, sizeof (out));
52 base64_encode (in, 1, out, 3);
53 ASSERT (memcmp (out, "YQ==", 3) == 0);
54
55 memset (out, 0x42, sizeof (out));
56 base64_encode (in, 1, out, 4);
57 ASSERT (memcmp (out, "YQ==", 4) == 0);
58
59 memset (out, 0x42, sizeof (out));
60 base64_encode (in, 1, out, 8);
61 ASSERT (memcmp (out, "YQ==", 4) == 0);
62
63 memset (out, 0x42, sizeof (out));
64 base64_encode (in, 2, out, 4);
65 ASSERT (memcmp (out, "YWI=", 4) == 0);
66
67 memset (out, 0x42, sizeof (out));
68 base64_encode (in, 3, out, 4);
69 ASSERT (memcmp (out, "YWJj", 4) == 0);
70
71 memset (out, 0x42, sizeof (out));
72 base64_encode (in, 4, out, 5);
73 ASSERT (memcmp (out, "YWJjZA==", 5) == 0);
74
75 memset (out, 0x42, sizeof (out));
76 base64_encode (in, 4, out, 100);
77 ASSERT (memcmp (out, "YWJjZA==", 6) == 0);
78
79 /* Decode. */
80
81 memset (out, 0x42, sizeof (out));
82 len = 0;
83 ok = base64_decode (b64in, 4, out, &len);
84 ASSERT (ok);
85 ASSERT (len == 0);
86
87 memset (out, 0x42, sizeof (out));
88 len = 1;
89 ok = base64_decode (b64in, 4, out, &len);
90 ASSERT (ok);
91 ASSERT (len == 1);
92 ASSERT (memcmp (out, "abcdefg", 1) == 0);
93
94 memset (out, 0x42, sizeof (out));
95 len = 2;
96 ok = base64_decode (b64in, 4, out, &len);
97 ASSERT (ok);
98 ASSERT (len == 2);
99 ASSERT (memcmp (out, "abcdefg", 2) == 0);
100
101 memset (out, 0x42, sizeof (out));
102 len = 3;
103 ok = base64_decode (b64in, 4, out, &len);
104 ASSERT (ok);
105 ASSERT (len == 3);
106 ASSERT (memcmp (out, "abcdefg", 3) == 0);
107
108 memset (out, 0x42, sizeof (out));
109 len = 4;
110 ok = base64_decode (b64in, 4, out, &len);
111 ASSERT (ok);
112 ASSERT (len == 3);
113 ASSERT (memcmp (out, "abcdefg", 3) == 0);
114
115 memset (out, 0x42, sizeof (out));
116 len = 100;
117 ok = base64_decode (b64in, strlen (b64in), out, &len);
118 ASSERT (ok);
119 ASSERT (len == 7);
120 ASSERT (memcmp (out, "abcdefg", 7) == 0);
121
122 /* Allocating encode */
123
124 len = base64_encode_alloc (in, strlen (in), &p);
125 ASSERT (len == 24);
126 ASSERT (strcmp (p, "YWJjZGVmZ2hpamtsbW5vcA==") == 0);
127 free (p);
128
129 len = base64_encode_alloc (in, IDX_MAX - 5, &p);
130 ASSERT (len == 0);
131
132 /* Decode context function */
133 {
134 struct base64_decode_context ctx;
135
136 base64_decode_ctx_init (&ctx);
137
138 len = sizeof (out);
139 ok = base64_decode_ctx (&ctx, b64in, strlen (b64in), out, &len);
140 ASSERT (ok);
141 ASSERT (len == 7);
142 ASSERT (memcmp (out, "abcdefg", len) == 0);
143 }
144
145 /* Allocating decode context function */
146
147 ok = base64_decode_alloc_ctx (NULL, b64in, strlen (b64in), &p, &len);
148 ASSERT (ok);
149 ASSERT (len == 7);
150 ASSERT (memcmp (out, "abcdefg", len) == 0);
151 free (p);
152
153 {
154 struct base64_decode_context ctx;
155 const char *newlineb64 = "YWJjZG\nVmZ2hp\namtsbW5vcA==";
156
157 base64_decode_ctx_init (&ctx);
158
159 ok = base64_decode_alloc_ctx (&ctx, newlineb64, strlen (newlineb64), &p, &len);
160 ASSERT (ok);
161 ASSERT (len == strlen (in));
162 ASSERT (memcmp (p, in, len) == 0);
163 free (p);
164 }
165
166 {
167 struct base64_decode_context ctx;
168 base64_decode_ctx_init (&ctx);
169
170 ok = base64_decode_alloc_ctx (&ctx, "YW\nJjZGVmZ2hp", 13, &p, &len);
171 ASSERT (ok);
172 ASSERT (len == 9);
173 ASSERT (memcmp (p, "abcdefghi", len) == 0);
174 free (p);
175
176 base64_decode_ctx_init (&ctx);
177
178 ok = base64_decode_alloc_ctx (&ctx, "YW\n", 3, &p, &len);
179 ASSERT (ok);
180 ASSERT (len == 0);
181 free (p);
182
183 ok = base64_decode_alloc_ctx (&ctx, "JjZGVmZ2", 8, &p, &len);
184 ASSERT (ok);
185 ASSERT (len == 6);
186 ASSERT (memcmp (p, "abcdef", len) == 0);
187 free (p);
188
189 ok = base64_decode_alloc_ctx (&ctx, "hp", 2, &p, &len);
190 ASSERT (ok);
191 ASSERT (len == 3);
192 ASSERT (memcmp (p, "ghi", len) == 0);
193 free (p);
194
195 ok = base64_decode_alloc_ctx (&ctx, "", 0, &p, &len);
196 ASSERT (ok);
197 free (p);
198 }
199
200 {
201 struct base64_decode_context ctx;
202 const char *newlineb64 = "\n\n\n\n\n";
203
204 base64_decode_ctx_init (&ctx);
205
206 ok = base64_decode_alloc_ctx (&ctx, newlineb64, strlen (newlineb64), &p, &len);
207 ASSERT (ok);
208 ASSERT (len == 0);
209 free (p);
210 }
211
212 ok = base64_decode_alloc_ctx (NULL, " ! ", 3, &p, &len);
213 ASSERT (!ok);
214
215 ok = base64_decode_alloc_ctx (NULL, "abc\ndef", 7, &p, &len);
216 ASSERT (!ok);
217
218 ok = base64_decode_alloc_ctx (NULL, "aa", 2, &p, &len);
219 ASSERT (!ok);
220
221 ok = base64_decode_alloc_ctx (NULL, "aa=", 3, &p, &len);
222 ASSERT (!ok);
223
224 ok = base64_decode_alloc_ctx (NULL, "aax", 3, &p, &len);
225 ASSERT (!ok);
226
227 ok = base64_decode_alloc_ctx (NULL, "aa=X", 4, &p, &len);
228 ASSERT (!ok);
229
230 ok = base64_decode_alloc_ctx (NULL, "aa=X", 4, &p, &len);
231 ASSERT (!ok);
232
233 ok = base64_decode_alloc_ctx (NULL, "aax=X", 5, &p, &len);
234 ASSERT (!ok);
235
236 return 0;
237 }