CMS 3D CMS Logo

base64.cc
Go to the documentation of this file.
1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* base64.c -- Encode binary data using printable characters.
4  Copyright (C) 1999-2001, 2004-2006, 2009-2011 Free Software Foundation, Inc.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3, or (at your option)
9  any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software Foundation,
18  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19 
20 /* Written by Simon Josefsson. Partially adapted from GNU MailUtils
21  * (mailbox/filter_trans.c, as of 2004-11-28). Improved by review
22  * from Paul Eggert, Bruno Haible, and Stepan Kasal.
23  *
24  * See also RFC 4648 <http://www.ietf.org/rfc/rfc4648.txt>.
25  *
26  * Be careful with error checking. Here is how you would typically
27  * use these functions:
28  *
29  * bool ok = base64_decode_alloc (in, inlen, &out, &outlen);
30  * if (!ok)
31  * FAIL: input was not valid base64
32  * if (out == NULL)
33  * FAIL: memory allocation error
34  * OK: data in OUT/OUTLEN
35  *
36  * size_t outlen = base64_encode_alloc (in, inlen, &out);
37  * if (out == NULL && outlen == 0 && inlen != 0)
38  * FAIL: input too long
39  * if (out == NULL)
40  * FAIL: memory allocation error
41  * OK: data in OUT/OUTLEN.
42  *
43  */
44 
45 //#include <config.h>
46 
47 /* Get prototype. */
48 #include "base64.h"
49 
50 /* Get malloc. */
51 #include <stdlib.h>
52 
53 /* Get UCHAR_MAX. */
54 #include <limits.h>
55 
56 #include <string.h>
57 
58 /* C89 compliant way to cast 'char' to 'unsigned char'. */
59 static inline unsigned char
60 to_uchar (char ch)
61 {
62  return ch;
63 }
64 
65 /* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
66  If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
67  possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
68  terminate the output buffer. */
69 void
70 base64_encode (const char *in, size_t inlen,
71  char *out, size_t outlen)
72 {
73  static const char* b64str =
74  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
75 
76  while (inlen && outlen)
77  {
78  *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
79  if (!--outlen)
80  break;
81  *out++ = b64str[((to_uchar (in[0]) << 4)
82  + (--inlen ? to_uchar (in[1]) >> 4 : 0))
83  & 0x3f];
84  if (!--outlen)
85  break;
86  *out++ =
87  (inlen
88  ? b64str[((to_uchar (in[1]) << 2)
89  + (--inlen ? to_uchar (in[2]) >> 6 : 0))
90  & 0x3f]
91  : '=');
92  if (!--outlen)
93  break;
94  *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
95  if (!--outlen)
96  break;
97  if (inlen)
98  inlen--;
99  if (inlen)
100  in += 3;
101  }
102 
103  if (outlen)
104  *out = '\0';
105 }
106 
107 /* Allocate a buffer and store zero terminated base64 encoded data
108  from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
109  the length of the encoded data, excluding the terminating zero. On
110  return, the OUT variable will hold a pointer to newly allocated
111  memory that must be deallocated by the caller. If output string
112  length would overflow, 0 is returned and OUT is set to NULL. If
113  memory allocation failed, OUT is set to NULL, and the return value
114  indicates length of the requested memory block, i.e.,
115  BASE64_LENGTH(inlen) + 1. */
116 size_t
117 base64_encode_alloc (const char *in, size_t inlen, char **out)
118 {
119  size_t outlen = 1 + BASE64_LENGTH (inlen);
120 
121  /* Check for overflow in outlen computation.
122  *
123  * If there is no overflow, outlen >= inlen.
124  *
125  * If the operation (inlen + 2) overflows then it yields at most +1, so
126  * outlen is 0.
127  *
128  * If the multiplication overflows, we lose at least half of the
129  * correct value, so the result is < ((inlen + 2) / 3) * 2, which is
130  * less than (inlen + 2) * 0.66667, which is less than inlen as soon as
131  * (inlen > 4).
132  */
133  if (inlen > outlen)
134  {
135  *out = NULL;
136  return 0;
137  }
138 
139  *out = static_cast<char*>(malloc (outlen));
140  if (!*out)
141  return outlen;
142 
143  base64_encode (in, inlen, *out, outlen);
144 
145  return outlen - 1;
146 }
147 
148 /* With this approach this file works independent of the charset used
149  (think EBCDIC). However, it does assume that the characters in the
150  Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255. POSIX
151  1003.1-2001 require that char and unsigned char are 8-bit
152  quantities, though, taking care of that problem. But this may be a
153  potential problem on non-POSIX C99 platforms.
154 
155  IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
156  as the formal parameter rather than "x". */
157 #define B64(_) \
158  ((_) == 'A' ? 0 \
159  : (_) == 'B' ? 1 \
160  : (_) == 'C' ? 2 \
161  : (_) == 'D' ? 3 \
162  : (_) == 'E' ? 4 \
163  : (_) == 'F' ? 5 \
164  : (_) == 'G' ? 6 \
165  : (_) == 'H' ? 7 \
166  : (_) == 'I' ? 8 \
167  : (_) == 'J' ? 9 \
168  : (_) == 'K' ? 10 \
169  : (_) == 'L' ? 11 \
170  : (_) == 'M' ? 12 \
171  : (_) == 'N' ? 13 \
172  : (_) == 'O' ? 14 \
173  : (_) == 'P' ? 15 \
174  : (_) == 'Q' ? 16 \
175  : (_) == 'R' ? 17 \
176  : (_) == 'S' ? 18 \
177  : (_) == 'T' ? 19 \
178  : (_) == 'U' ? 20 \
179  : (_) == 'V' ? 21 \
180  : (_) == 'W' ? 22 \
181  : (_) == 'X' ? 23 \
182  : (_) == 'Y' ? 24 \
183  : (_) == 'Z' ? 25 \
184  : (_) == 'a' ? 26 \
185  : (_) == 'b' ? 27 \
186  : (_) == 'c' ? 28 \
187  : (_) == 'd' ? 29 \
188  : (_) == 'e' ? 30 \
189  : (_) == 'f' ? 31 \
190  : (_) == 'g' ? 32 \
191  : (_) == 'h' ? 33 \
192  : (_) == 'i' ? 34 \
193  : (_) == 'j' ? 35 \
194  : (_) == 'k' ? 36 \
195  : (_) == 'l' ? 37 \
196  : (_) == 'm' ? 38 \
197  : (_) == 'n' ? 39 \
198  : (_) == 'o' ? 40 \
199  : (_) == 'p' ? 41 \
200  : (_) == 'q' ? 42 \
201  : (_) == 'r' ? 43 \
202  : (_) == 's' ? 44 \
203  : (_) == 't' ? 45 \
204  : (_) == 'u' ? 46 \
205  : (_) == 'v' ? 47 \
206  : (_) == 'w' ? 48 \
207  : (_) == 'x' ? 49 \
208  : (_) == 'y' ? 50 \
209  : (_) == 'z' ? 51 \
210  : (_) == '0' ? 52 \
211  : (_) == '1' ? 53 \
212  : (_) == '2' ? 54 \
213  : (_) == '3' ? 55 \
214  : (_) == '4' ? 56 \
215  : (_) == '5' ? 57 \
216  : (_) == '6' ? 58 \
217  : (_) == '7' ? 59 \
218  : (_) == '8' ? 60 \
219  : (_) == '9' ? 61 \
220  : (_) == '+' ? 62 \
221  : (_) == '/' ? 63 \
222  : -1)
223 
224 static const signed char b64[0x100] = {
225  B64 (0), B64 (1), B64 (2), B64 (3),
226  B64 (4), B64 (5), B64 (6), B64 (7),
227  B64 (8), B64 (9), B64 (10), B64 (11),
228  B64 (12), B64 (13), B64 (14), B64 (15),
229  B64 (16), B64 (17), B64 (18), B64 (19),
230  B64 (20), B64 (21), B64 (22), B64 (23),
231  B64 (24), B64 (25), B64 (26), B64 (27),
232  B64 (28), B64 (29), B64 (30), B64 (31),
233  B64 (32), B64 (33), B64 (34), B64 (35),
234  B64 (36), B64 (37), B64 (38), B64 (39),
235  B64 (40), B64 (41), B64 (42), B64 (43),
236  B64 (44), B64 (45), B64 (46), B64 (47),
237  B64 (48), B64 (49), B64 (50), B64 (51),
238  B64 (52), B64 (53), B64 (54), B64 (55),
239  B64 (56), B64 (57), B64 (58), B64 (59),
240  B64 (60), B64 (61), B64 (62), B64 (63),
241  B64 (64), B64 (65), B64 (66), B64 (67),
242  B64 (68), B64 (69), B64 (70), B64 (71),
243  B64 (72), B64 (73), B64 (74), B64 (75),
244  B64 (76), B64 (77), B64 (78), B64 (79),
245  B64 (80), B64 (81), B64 (82), B64 (83),
246  B64 (84), B64 (85), B64 (86), B64 (87),
247  B64 (88), B64 (89), B64 (90), B64 (91),
248  B64 (92), B64 (93), B64 (94), B64 (95),
249  B64 (96), B64 (97), B64 (98), B64 (99),
250  B64 (100), B64 (101), B64 (102), B64 (103),
251  B64 (104), B64 (105), B64 (106), B64 (107),
252  B64 (108), B64 (109), B64 (110), B64 (111),
253  B64 (112), B64 (113), B64 (114), B64 (115),
254  B64 (116), B64 (117), B64 (118), B64 (119),
255  B64 (120), B64 (121), B64 (122), B64 (123),
256  B64 (124), B64 (125), B64 (126), B64 (127),
257  B64 (128), B64 (129), B64 (130), B64 (131),
258  B64 (132), B64 (133), B64 (134), B64 (135),
259  B64 (136), B64 (137), B64 (138), B64 (139),
260  B64 (140), B64 (141), B64 (142), B64 (143),
261  B64 (144), B64 (145), B64 (146), B64 (147),
262  B64 (148), B64 (149), B64 (150), B64 (151),
263  B64 (152), B64 (153), B64 (154), B64 (155),
264  B64 (156), B64 (157), B64 (158), B64 (159),
265  B64 (160), B64 (161), B64 (162), B64 (163),
266  B64 (164), B64 (165), B64 (166), B64 (167),
267  B64 (168), B64 (169), B64 (170), B64 (171),
268  B64 (172), B64 (173), B64 (174), B64 (175),
269  B64 (176), B64 (177), B64 (178), B64 (179),
270  B64 (180), B64 (181), B64 (182), B64 (183),
271  B64 (184), B64 (185), B64 (186), B64 (187),
272  B64 (188), B64 (189), B64 (190), B64 (191),
273  B64 (192), B64 (193), B64 (194), B64 (195),
274  B64 (196), B64 (197), B64 (198), B64 (199),
275  B64 (200), B64 (201), B64 (202), B64 (203),
276  B64 (204), B64 (205), B64 (206), B64 (207),
277  B64 (208), B64 (209), B64 (210), B64 (211),
278  B64 (212), B64 (213), B64 (214), B64 (215),
279  B64 (216), B64 (217), B64 (218), B64 (219),
280  B64 (220), B64 (221), B64 (222), B64 (223),
281  B64 (224), B64 (225), B64 (226), B64 (227),
282  B64 (228), B64 (229), B64 (230), B64 (231),
283  B64 (232), B64 (233), B64 (234), B64 (235),
284  B64 (236), B64 (237), B64 (238), B64 (239),
285  B64 (240), B64 (241), B64 (242), B64 (243),
286  B64 (244), B64 (245), B64 (246), B64 (247),
287  B64 (248), B64 (249), B64 (250), B64 (251),
288  B64 (252), B64 (253), B64 (254), B64 (255)
289 };
290 
291 #if UCHAR_MAX == 255
292 # define uchar_in_range(c) true
293 #else
294 # define uchar_in_range(c) ((c) <= 255)
295 #endif
296 
297 /* Return true if CH is a character from the Base64 alphabet, and
298  false otherwise. Note that '=' is padding and not considered to be
299  part of the alphabet. */
300 bool
301 isbase64 (char ch)
302 {
303  return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
304 }
305 
306 /* Initialize decode-context buffer, CTX. */
307 void
309 {
310  ctx->i = 0;
311 }
312 
313 /* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and
314  none of those four is a newline, then return *IN. Otherwise, copy up to
315  4 - CTX->i non-newline bytes from that range into CTX->buf, starting at
316  index CTX->i and setting CTX->i to reflect the number of bytes copied,
317  and return CTX->buf. In either case, advance *IN to point to the byte
318  after the last one processed, and set *N_NON_NEWLINE to the number of
319  verified non-newline bytes accessible through the returned pointer. */
320 static inline char *
322  char const **in, char const *in_end,
323  size_t *n_non_newline)
324 {
325  if (ctx->i == 4)
326  ctx->i = 0;
327 
328  if (ctx->i == 0)
329  {
330  char const *t = *in;
331  if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL)
332  {
333  /* This is the common case: no newline. */
334  *in += 4;
335  *n_non_newline = 4;
336  return (char *) t;
337  }
338  }
339 
340  {
341  /* Copy non-newline bytes into BUF. */
342  char const *p = *in;
343  while (p < in_end)
344  {
345  char c = *p++;
346  if (c != '\n')
347  {
348  ctx->buf[ctx->i++] = c;
349  if (ctx->i == 4)
350  break;
351  }
352  }
353 
354  *in = p;
355  *n_non_newline = ctx->i;
356  return ctx->buf;
357  }
358 }
359 
360 #define return_false \
361  do \
362  { \
363  *outp = out; \
364  return false; \
365  } \
366  while (false)
367 
368 /* Decode up to four bytes of base64-encoded data, IN, of length INLEN
369  into the output buffer, *OUT, of size *OUTLEN bytes. Return true if
370  decoding is successful, false otherwise. If *OUTLEN is too small,
371  as many bytes as possible are written to *OUT. On return, advance
372  *OUT to point to the byte after the last one written, and decrement
373  *OUTLEN to reflect the number of bytes remaining in *OUT. */
374 static inline bool
375 decode_4 (char const *in, size_t inlen,
376  char **outp, size_t *outleft)
377 {
378  char *out = *outp;
379  if (inlen < 2)
380  return false;
381 
382  if (!isbase64 (in[0]) || !isbase64 (in[1]))
383  return false;
384 
385  if (*outleft)
386  {
387  *out++ = ((b64[to_uchar (in[0])] << 2)
388  | (b64[to_uchar (in[1])] >> 4));
389  --*outleft;
390  }
391 
392  if (inlen == 2)
393  return_false;
394 
395  if (in[2] == '=')
396  {
397  if (inlen != 4)
398  return_false;
399 
400  if (in[3] != '=')
401  return_false;
402  }
403  else
404  {
405  if (!isbase64 (in[2]))
406  return_false;
407 
408  if (*outleft)
409  {
410  *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
411  | (b64[to_uchar (in[2])] >> 2));
412  --*outleft;
413  }
414 
415  if (inlen == 3)
416  return_false;
417 
418  if (in[3] == '=')
419  {
420  if (inlen != 4)
421  return_false;
422  }
423  else
424  {
425  if (!isbase64 (in[3]))
426  return_false;
427 
428  if (*outleft)
429  {
430  *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
431  | b64[to_uchar (in[3])]);
432  --*outleft;
433  }
434  }
435  }
436 
437  *outp = out;
438  return true;
439 }
440 
441 /* Decode base64-encoded input array IN of length INLEN to output array
442  OUT that can hold *OUTLEN bytes. The input data may be interspersed
443  with newlines. Return true if decoding was successful, i.e. if the
444  input was valid base64 data, false otherwise. If *OUTLEN is too
445  small, as many bytes as possible will be written to OUT. On return,
446  *OUTLEN holds the length of decoded bytes in OUT. Note that as soon
447  as any non-alphabet, non-newline character is encountered, decoding
448  is stopped and false is returned. If INLEN is zero, then process
449  only whatever data is stored in CTX.
450 
451  Initially, CTX must have been initialized via base64_decode_ctx_init.
452  Subsequent calls to this function must reuse whatever state is recorded
453  in that buffer. It is necessary for when a quadruple of base64 input
454  bytes spans two input buffers.
455 
456  If CTX is NULL then newlines are treated as garbage and the input
457  buffer is processed as a unit. */
458 
459 bool
461  const char *in, size_t inlen,
462  char *out, size_t *outlen)
463 {
464  size_t outleft = *outlen;
465  bool ignore_newlines = ctx != NULL;
466  bool flush_ctx = false;
467  unsigned int ctx_i = 0;
468 
469  if (ignore_newlines)
470  {
471  ctx_i = ctx->i;
472  flush_ctx = inlen == 0;
473  }
474 
475 
476  while (true)
477  {
478  size_t outleft_save = outleft;
479  if (ctx_i == 0 && !flush_ctx)
480  {
481  while (true)
482  {
483  /* Save a copy of outleft, in case we need to re-parse this
484  block of four bytes. */
485  outleft_save = outleft;
486  if (!decode_4 (in, inlen, &out, &outleft))
487  break;
488 
489  in += 4;
490  inlen -= 4;
491  }
492  }
493 
494  if (inlen == 0 && !flush_ctx)
495  break;
496 
497  /* Handle the common case of 72-byte wrapped lines.
498  This also handles any other multiple-of-4-byte wrapping. */
499  if (inlen && *in == '\n' && ignore_newlines)
500  {
501  ++in;
502  --inlen;
503  continue;
504  }
505 
506  /* Restore OUT and OUTLEFT. */
507  out -= outleft_save - outleft;
508  outleft = outleft_save;
509 
510  {
511  char const *in_end = in + inlen;
512  char const *non_nl;
513 
514  if (ignore_newlines)
515  non_nl = get_4 (ctx, &in, in_end, &inlen);
516  else
517  non_nl = in; /* Might have nl in this case. */
518 
519  /* If the input is empty or consists solely of newlines (0 non-newlines),
520  then we're done. Likewise if there are fewer than 4 bytes when not
521  flushing context and not treating newlines as garbage. */
522  if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines))
523  {
524  inlen = 0;
525  break;
526  }
527  if (!decode_4 (non_nl, inlen, &out, &outleft))
528  break;
529 
530  inlen = in_end - in;
531  }
532  }
533 
534  *outlen -= outleft;
535 
536  return inlen == 0;
537 }
538 
539 /* Allocate an output buffer in *OUT, and decode the base64 encoded
540  data stored in IN of size INLEN to the *OUT buffer. On return, the
541  size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL,
542  if the caller is not interested in the decoded length. *OUT may be
543  NULL to indicate an out of memory error, in which case *OUTLEN
544  contains the size of the memory block needed. The function returns
545  true on successful decoding and memory allocation errors. (Use the
546  *OUT and *OUTLEN parameters to differentiate between successful
547  decoding and memory error.) The function returns false if the
548  input was invalid, in which case *OUT is NULL and *OUTLEN is
549  undefined. */
550 bool
552  const char *in, size_t inlen, char **out,
553  size_t *outlen)
554 {
555  /* This may allocate a few bytes too many, depending on input,
556  but it's not worth the extra CPU time to compute the exact size.
557  The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the
558  input ends with "=" and minus another 1 if the input ends with "==".
559  Dividing before multiplying avoids the possibility of overflow. */
560  size_t needlen = 3 * (inlen / 4) + 3;
561 
562  *out = static_cast<char*>(malloc (needlen));
563  if (!*out)
564  return true;
565 
566  if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen))
567  {
568  free (*out);
569  *out = NULL;
570  return false;
571  }
572 
573  if (outlen)
574  *outlen = needlen;
575 
576  return true;
577 }
static const signed char b64[0x100]
Definition: base64.cc:224
bool isbase64(char ch)
Definition: base64.cc:301
void base64_encode(const char *in, size_t inlen, char *out, size_t outlen)
Definition: base64.cc:70
#define NULL
Definition: scimark2.h:8
static const char * b64str
Definition: DecodingKey.cc:17
static unsigned char to_uchar(char ch)
Definition: base64.cc:60
#define BASE64_LENGTH(inlen)
Definition: base64.h:32
void base64_decode_ctx_init(struct base64_decode_context *ctx)
Definition: base64.cc:308
unsigned int i
Definition: base64.h:36
size_t base64_encode_alloc(const char *in, size_t inlen, char **out)
Definition: base64.cc:117
#define return_false
Definition: base64.cc:360
static bool decode_4(char const *in, size_t inlen, char **outp, size_t *outleft)
Definition: base64.cc:375
bool base64_decode_ctx(struct base64_decode_context *ctx, const char *in, size_t inlen, char *out, size_t *outlen)
Definition: base64.cc:460
#define uchar_in_range(c)
Definition: base64.cc:294
bool base64_decode_alloc_ctx(struct base64_decode_context *ctx, const char *in, size_t inlen, char **out, size_t *outlen)
Definition: base64.cc:551
static char * get_4(struct base64_decode_context *ctx, char const **in, char const *in_end, size_t *n_non_newline)
Definition: base64.cc:321
#define B64(_)
Definition: base64.cc:157