48683259f1a0a45139b52c7b885420f4effc04e7
[gnulib.git] / tests / test-base64.c
1 /* Self tests for base64.
2    Copyright (C) 2004, 2008, 2009 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 <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19
20 #include <stddef.h>
21 #include <stdio.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <string.h>
26 #include <stdint.h>
27
28 #include "base64.h"
29
30 #define ASSERT(expr)                                                    \
31   do                                                                    \
32     {                                                                   \
33       if (!(expr))                                                      \
34         {                                                               \
35           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
36           fflush (stderr);                                              \
37           abort ();                                                     \
38         }                                                               \
39     }                                                                   \
40   while (0)
41
42 int
43 main (void)
44 {
45   const char *in = "abcdefghijklmnop";
46   const char *b64in = "YWJjZGVmZw==";
47   char out[255];
48   size_t len;
49   bool ok;
50   char *p;
51
52   memset (out, 0x42, sizeof (out));
53   base64_encode (in, 0, out, 0);
54   ASSERT(out[0] == '\x42');
55
56   memset (out, 0x42, sizeof (out));
57   base64_encode (in, 1, out, 1);
58   ASSERT (memcmp (out, "YQ==", 1) == 0);
59
60   memset (out, 0x42, sizeof (out));
61   base64_encode (in, 1, out, 2);
62   ASSERT (memcmp (out, "YQ==", 2) == 0);
63
64   memset (out, 0x42, sizeof (out));
65   base64_encode (in, 1, out, 3);
66   ASSERT (memcmp (out, "YQ==", 3) == 0);
67
68   memset (out, 0x42, sizeof (out));
69   base64_encode (in, 1, out, 4);
70   ASSERT (memcmp (out, "YQ==", 4) == 0);
71
72   memset (out, 0x42, sizeof (out));
73   base64_encode (in, 1, out, 8);
74   ASSERT (memcmp (out, "YQ==", 4) == 0);
75
76   memset (out, 0x42, sizeof (out));
77   base64_encode (in, 2, out, 4);
78   ASSERT (memcmp (out, "YWI=", 4) == 0);
79
80   memset (out, 0x42, sizeof (out));
81   base64_encode (in, 3, out, 4);
82   ASSERT (memcmp (out, "YWJj", 4) == 0);
83
84   memset (out, 0x42, sizeof (out));
85   base64_encode (in, 4, out, 5);
86   ASSERT (memcmp (out, "YWJjZA==", 5) == 0);
87
88   memset (out, 0x42, sizeof (out));
89   base64_encode (in, 4, out, 100);
90   ASSERT (memcmp (out, "YWJjZA==", 6) == 0);
91
92   /* Decode. */
93
94   memset (out, 0x42, sizeof (out));
95   len = 0;
96   ok = base64_decode (b64in, 4, out, &len);
97   ASSERT (ok);
98   ASSERT (len == 0);
99
100   memset (out, 0x42, sizeof (out));
101   len = 1;
102   ok = base64_decode (b64in, 4, out, &len);
103   ASSERT (ok);
104   ASSERT (len == 1);
105   ASSERT (memcmp (out, "abcdefg", 1) == 0);
106
107   memset (out, 0x42, sizeof (out));
108   len = 2;
109   ok = base64_decode (b64in, 4, out, &len);
110   ASSERT (ok);
111   ASSERT (len == 2);
112   ASSERT (memcmp (out, "abcdefg", 2) == 0);
113
114   memset (out, 0x42, sizeof (out));
115   len = 3;
116   ok = base64_decode (b64in, 4, out, &len);
117   ASSERT (ok);
118   ASSERT (len == 3);
119   ASSERT (memcmp (out, "abcdefg", 3) == 0);
120
121   memset (out, 0x42, sizeof (out));
122   len = 4;
123   ok = base64_decode (b64in, 4, out, &len);
124   ASSERT (ok);
125   ASSERT (len == 3);
126   ASSERT (memcmp (out, "abcdefg", 3) == 0);
127
128   memset (out, 0x42, sizeof (out));
129   len = 100;
130   ok = base64_decode (b64in, strlen (b64in), out, &len);
131   ASSERT (ok);
132   ASSERT (len == 7);
133   ASSERT (memcmp (out, "abcdefg", 7) == 0);
134
135   /* Allocating encode */
136
137   len = base64_encode_alloc (in, strlen (in), &p);
138   ASSERT (len == 24);
139   ASSERT (strcmp (p, "YWJjZGVmZ2hpamtsbW5vcA==") == 0);
140   free (p);
141
142   len = base64_encode_alloc (in, SIZE_MAX - 5, &p);
143   ASSERT (len == 0);
144
145   /* Decode context function */
146   {
147     struct base64_decode_context ctx;
148
149     base64_decode_ctx_init (&ctx);
150
151     len = sizeof (out);
152     ok = base64_decode_ctx (&ctx, b64in, strlen (b64in), out, &len);
153     ASSERT (ok);
154     ASSERT (len == 7);
155     ASSERT (memcmp (out, "abcdefg", len) == 0);
156   }
157
158   /* Allocating decode context function */
159
160   ok = base64_decode_alloc_ctx (NULL, b64in, strlen (b64in), &p, &len);
161   ASSERT (ok);
162   ASSERT (len == 7);
163   ASSERT (memcmp (out, "abcdefg", len) == 0);
164
165   {
166     struct base64_decode_context ctx;
167     const char *newlineb64 = "YWJjZG\nVmZ2hp\namtsbW5vcA==";
168
169     base64_decode_ctx_init (&ctx);
170
171     ok = base64_decode_alloc_ctx (&ctx, newlineb64, strlen (newlineb64), &p, &len);
172     ASSERT (ok);
173     ASSERT (len == strlen (in));
174     ASSERT (memcmp (p, in, len) == 0);
175   }
176
177   {
178     struct base64_decode_context ctx;
179     base64_decode_ctx_init (&ctx);
180
181     ok = base64_decode_alloc_ctx (&ctx, "YW\nJjZGVmZ2hp", 13, &p, &len);
182     ASSERT (ok);
183     ASSERT (len == 9);
184     ASSERT (memcmp (p, "abcdefghi", len) == 0);
185
186     base64_decode_ctx_init (&ctx);
187
188     ok = base64_decode_alloc_ctx (&ctx, "YW\n", 3, &p, &len);
189     ASSERT (ok);
190     ASSERT (len == 0);
191
192     ok = base64_decode_alloc_ctx (&ctx, "JjZGVmZ2", 8, &p, &len);
193     ASSERT (ok);
194     ASSERT (len == 6);
195     ASSERT (memcmp (p, "abcdef", len) == 0);
196
197     ok = base64_decode_alloc_ctx (&ctx, "hp", 2, &p, &len);
198     ASSERT (ok);
199     ASSERT (len == 2);
200     /* Actually this looks buggy.  Shouldn't output be 'ghi'? */
201     ASSERT (memcmp (p, "gh", len) == 0);
202     ok = base64_decode_alloc_ctx (&ctx, "", 0, &p, &len);
203     ASSERT (ok);
204   }
205
206   {
207     struct base64_decode_context ctx;
208     const char *newlineb64 = "\n\n\n\n\n";
209
210     base64_decode_ctx_init (&ctx);
211
212     ok = base64_decode_alloc_ctx (&ctx, newlineb64, strlen (newlineb64), &p, &len);
213     ASSERT (ok);
214     ASSERT (len == 0);
215   }
216
217   ok = base64_decode_alloc_ctx (NULL, " ! ", 3, &p, &len);
218   ASSERT (!ok);
219
220   ok = base64_decode_alloc_ctx (NULL, "abc\ndef", 7, &p, &len);
221   ASSERT (!ok);
222
223   ok = base64_decode_alloc_ctx (NULL, "aa", 2, &p, &len);
224   ASSERT (!ok);
225
226   ok = base64_decode_alloc_ctx (NULL, "aa=", 3, &p, &len);
227   ASSERT (!ok);
228
229   ok = base64_decode_alloc_ctx (NULL, "aax", 3, &p, &len);
230   ASSERT (!ok);
231
232   ok = base64_decode_alloc_ctx (NULL, "aa=X", 4, &p, &len);
233   ASSERT (!ok);
234
235   ok = base64_decode_alloc_ctx (NULL, "aa=X", 4, &p, &len);
236   ASSERT (!ok);
237
238   ok = base64_decode_alloc_ctx (NULL, "aax=X", 5, &p, &len);
239   ASSERT (!ok);
240
241   return 0;
242 }