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