CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/CondCore/DBCommon/src/base64.cc

Go to the documentation of this file.
00001 /* -*- buffer-read-only: t -*- vi: set ro: */
00002 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
00003 /* base64.c -- Encode binary data using printable characters.
00004    Copyright (C) 1999-2001, 2004-2006, 2009-2011 Free Software Foundation, Inc.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3, or (at your option)
00009    any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software Foundation,
00018    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
00019 
00020 /* Written by Simon Josefsson.  Partially adapted from GNU MailUtils
00021  * (mailbox/filter_trans.c, as of 2004-11-28).  Improved by review
00022  * from Paul Eggert, Bruno Haible, and Stepan Kasal.
00023  *
00024  * See also RFC 4648 <http://www.ietf.org/rfc/rfc4648.txt>.
00025  *
00026  * Be careful with error checking.  Here is how you would typically
00027  * use these functions:
00028  *
00029  * bool ok = base64_decode_alloc (in, inlen, &out, &outlen);
00030  * if (!ok)
00031  *   FAIL: input was not valid base64
00032  * if (out == NULL)
00033  *   FAIL: memory allocation error
00034  * OK: data in OUT/OUTLEN
00035  *
00036  * size_t outlen = base64_encode_alloc (in, inlen, &out);
00037  * if (out == NULL && outlen == 0 && inlen != 0)
00038  *   FAIL: input too long
00039  * if (out == NULL)
00040  *   FAIL: memory allocation error
00041  * OK: data in OUT/OUTLEN.
00042  *
00043  */
00044 
00045 //#include <config.h>
00046 
00047 /* Get prototype. */
00048 #include "base64.h"
00049 
00050 /* Get malloc. */
00051 #include <stdlib.h>
00052 
00053 /* Get UCHAR_MAX. */
00054 #include <limits.h>
00055 
00056 #include <string.h>
00057 
00058 /* C89 compliant way to cast 'char' to 'unsigned char'. */
00059 static inline unsigned char
00060 to_uchar (char ch)
00061 {
00062   return ch;
00063 }
00064 
00065 /* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
00066    If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
00067    possible.  If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
00068    terminate the output buffer. */
00069 void
00070 base64_encode (const char *in, size_t inlen,
00071                char *out, size_t outlen)
00072 {
00073   static const char* b64str =
00074     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00075 
00076   while (inlen && outlen)
00077     {
00078       *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
00079       if (!--outlen)
00080         break;
00081       *out++ = b64str[((to_uchar (in[0]) << 4)
00082                        + (--inlen ? to_uchar (in[1]) >> 4 : 0))
00083                       & 0x3f];
00084       if (!--outlen)
00085         break;
00086       *out++ =
00087         (inlen
00088          ? b64str[((to_uchar (in[1]) << 2)
00089                    + (--inlen ? to_uchar (in[2]) >> 6 : 0))
00090                   & 0x3f]
00091          : '=');
00092       if (!--outlen)
00093         break;
00094       *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
00095       if (!--outlen)
00096         break;
00097       if (inlen)
00098         inlen--;
00099       if (inlen)
00100         in += 3;
00101     }
00102 
00103   if (outlen)
00104     *out = '\0';
00105 }
00106 
00107 /* Allocate a buffer and store zero terminated base64 encoded data
00108    from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
00109    the length of the encoded data, excluding the terminating zero.  On
00110    return, the OUT variable will hold a pointer to newly allocated
00111    memory that must be deallocated by the caller.  If output string
00112    length would overflow, 0 is returned and OUT is set to NULL.  If
00113    memory allocation failed, OUT is set to NULL, and the return value
00114    indicates length of the requested memory block, i.e.,
00115    BASE64_LENGTH(inlen) + 1. */
00116 size_t
00117 base64_encode_alloc (const char *in, size_t inlen, char **out)
00118 {
00119   size_t outlen = 1 + BASE64_LENGTH (inlen);
00120 
00121   /* Check for overflow in outlen computation.
00122    *
00123    * If there is no overflow, outlen >= inlen.
00124    *
00125    * If the operation (inlen + 2) overflows then it yields at most +1, so
00126    * outlen is 0.
00127    *
00128    * If the multiplication overflows, we lose at least half of the
00129    * correct value, so the result is < ((inlen + 2) / 3) * 2, which is
00130    * less than (inlen + 2) * 0.66667, which is less than inlen as soon as
00131    * (inlen > 4).
00132    */
00133   if (inlen > outlen)
00134     {
00135       *out = NULL;
00136       return 0;
00137     }
00138 
00139   *out = static_cast<char*>(malloc (outlen));
00140   if (!*out)
00141     return outlen;
00142 
00143   base64_encode (in, inlen, *out, outlen);
00144 
00145   return outlen - 1;
00146 }
00147 
00148 /* With this approach this file works independent of the charset used
00149    (think EBCDIC).  However, it does assume that the characters in the
00150    Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255.  POSIX
00151    1003.1-2001 require that char and unsigned char are 8-bit
00152    quantities, though, taking care of that problem.  But this may be a
00153    potential problem on non-POSIX C99 platforms.
00154 
00155    IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
00156    as the formal parameter rather than "x".  */
00157 #define B64(_)                                  \
00158   ((_) == 'A' ? 0                               \
00159    : (_) == 'B' ? 1                             \
00160    : (_) == 'C' ? 2                             \
00161    : (_) == 'D' ? 3                             \
00162    : (_) == 'E' ? 4                             \
00163    : (_) == 'F' ? 5                             \
00164    : (_) == 'G' ? 6                             \
00165    : (_) == 'H' ? 7                             \
00166    : (_) == 'I' ? 8                             \
00167    : (_) == 'J' ? 9                             \
00168    : (_) == 'K' ? 10                            \
00169    : (_) == 'L' ? 11                            \
00170    : (_) == 'M' ? 12                            \
00171    : (_) == 'N' ? 13                            \
00172    : (_) == 'O' ? 14                            \
00173    : (_) == 'P' ? 15                            \
00174    : (_) == 'Q' ? 16                            \
00175    : (_) == 'R' ? 17                            \
00176    : (_) == 'S' ? 18                            \
00177    : (_) == 'T' ? 19                            \
00178    : (_) == 'U' ? 20                            \
00179    : (_) == 'V' ? 21                            \
00180    : (_) == 'W' ? 22                            \
00181    : (_) == 'X' ? 23                            \
00182    : (_) == 'Y' ? 24                            \
00183    : (_) == 'Z' ? 25                            \
00184    : (_) == 'a' ? 26                            \
00185    : (_) == 'b' ? 27                            \
00186    : (_) == 'c' ? 28                            \
00187    : (_) == 'd' ? 29                            \
00188    : (_) == 'e' ? 30                            \
00189    : (_) == 'f' ? 31                            \
00190    : (_) == 'g' ? 32                            \
00191    : (_) == 'h' ? 33                            \
00192    : (_) == 'i' ? 34                            \
00193    : (_) == 'j' ? 35                            \
00194    : (_) == 'k' ? 36                            \
00195    : (_) == 'l' ? 37                            \
00196    : (_) == 'm' ? 38                            \
00197    : (_) == 'n' ? 39                            \
00198    : (_) == 'o' ? 40                            \
00199    : (_) == 'p' ? 41                            \
00200    : (_) == 'q' ? 42                            \
00201    : (_) == 'r' ? 43                            \
00202    : (_) == 's' ? 44                            \
00203    : (_) == 't' ? 45                            \
00204    : (_) == 'u' ? 46                            \
00205    : (_) == 'v' ? 47                            \
00206    : (_) == 'w' ? 48                            \
00207    : (_) == 'x' ? 49                            \
00208    : (_) == 'y' ? 50                            \
00209    : (_) == 'z' ? 51                            \
00210    : (_) == '0' ? 52                            \
00211    : (_) == '1' ? 53                            \
00212    : (_) == '2' ? 54                            \
00213    : (_) == '3' ? 55                            \
00214    : (_) == '4' ? 56                            \
00215    : (_) == '5' ? 57                            \
00216    : (_) == '6' ? 58                            \
00217    : (_) == '7' ? 59                            \
00218    : (_) == '8' ? 60                            \
00219    : (_) == '9' ? 61                            \
00220    : (_) == '+' ? 62                            \
00221    : (_) == '/' ? 63                            \
00222    : -1)
00223 
00224 static const signed char b64[0x100] = {
00225   B64 (0), B64 (1), B64 (2), B64 (3),
00226   B64 (4), B64 (5), B64 (6), B64 (7),
00227   B64 (8), B64 (9), B64 (10), B64 (11),
00228   B64 (12), B64 (13), B64 (14), B64 (15),
00229   B64 (16), B64 (17), B64 (18), B64 (19),
00230   B64 (20), B64 (21), B64 (22), B64 (23),
00231   B64 (24), B64 (25), B64 (26), B64 (27),
00232   B64 (28), B64 (29), B64 (30), B64 (31),
00233   B64 (32), B64 (33), B64 (34), B64 (35),
00234   B64 (36), B64 (37), B64 (38), B64 (39),
00235   B64 (40), B64 (41), B64 (42), B64 (43),
00236   B64 (44), B64 (45), B64 (46), B64 (47),
00237   B64 (48), B64 (49), B64 (50), B64 (51),
00238   B64 (52), B64 (53), B64 (54), B64 (55),
00239   B64 (56), B64 (57), B64 (58), B64 (59),
00240   B64 (60), B64 (61), B64 (62), B64 (63),
00241   B64 (64), B64 (65), B64 (66), B64 (67),
00242   B64 (68), B64 (69), B64 (70), B64 (71),
00243   B64 (72), B64 (73), B64 (74), B64 (75),
00244   B64 (76), B64 (77), B64 (78), B64 (79),
00245   B64 (80), B64 (81), B64 (82), B64 (83),
00246   B64 (84), B64 (85), B64 (86), B64 (87),
00247   B64 (88), B64 (89), B64 (90), B64 (91),
00248   B64 (92), B64 (93), B64 (94), B64 (95),
00249   B64 (96), B64 (97), B64 (98), B64 (99),
00250   B64 (100), B64 (101), B64 (102), B64 (103),
00251   B64 (104), B64 (105), B64 (106), B64 (107),
00252   B64 (108), B64 (109), B64 (110), B64 (111),
00253   B64 (112), B64 (113), B64 (114), B64 (115),
00254   B64 (116), B64 (117), B64 (118), B64 (119),
00255   B64 (120), B64 (121), B64 (122), B64 (123),
00256   B64 (124), B64 (125), B64 (126), B64 (127),
00257   B64 (128), B64 (129), B64 (130), B64 (131),
00258   B64 (132), B64 (133), B64 (134), B64 (135),
00259   B64 (136), B64 (137), B64 (138), B64 (139),
00260   B64 (140), B64 (141), B64 (142), B64 (143),
00261   B64 (144), B64 (145), B64 (146), B64 (147),
00262   B64 (148), B64 (149), B64 (150), B64 (151),
00263   B64 (152), B64 (153), B64 (154), B64 (155),
00264   B64 (156), B64 (157), B64 (158), B64 (159),
00265   B64 (160), B64 (161), B64 (162), B64 (163),
00266   B64 (164), B64 (165), B64 (166), B64 (167),
00267   B64 (168), B64 (169), B64 (170), B64 (171),
00268   B64 (172), B64 (173), B64 (174), B64 (175),
00269   B64 (176), B64 (177), B64 (178), B64 (179),
00270   B64 (180), B64 (181), B64 (182), B64 (183),
00271   B64 (184), B64 (185), B64 (186), B64 (187),
00272   B64 (188), B64 (189), B64 (190), B64 (191),
00273   B64 (192), B64 (193), B64 (194), B64 (195),
00274   B64 (196), B64 (197), B64 (198), B64 (199),
00275   B64 (200), B64 (201), B64 (202), B64 (203),
00276   B64 (204), B64 (205), B64 (206), B64 (207),
00277   B64 (208), B64 (209), B64 (210), B64 (211),
00278   B64 (212), B64 (213), B64 (214), B64 (215),
00279   B64 (216), B64 (217), B64 (218), B64 (219),
00280   B64 (220), B64 (221), B64 (222), B64 (223),
00281   B64 (224), B64 (225), B64 (226), B64 (227),
00282   B64 (228), B64 (229), B64 (230), B64 (231),
00283   B64 (232), B64 (233), B64 (234), B64 (235),
00284   B64 (236), B64 (237), B64 (238), B64 (239),
00285   B64 (240), B64 (241), B64 (242), B64 (243),
00286   B64 (244), B64 (245), B64 (246), B64 (247),
00287   B64 (248), B64 (249), B64 (250), B64 (251),
00288   B64 (252), B64 (253), B64 (254), B64 (255)
00289 };
00290 
00291 #if UCHAR_MAX == 255
00292 # define uchar_in_range(c) true
00293 #else
00294 # define uchar_in_range(c) ((c) <= 255)
00295 #endif
00296 
00297 /* Return true if CH is a character from the Base64 alphabet, and
00298    false otherwise.  Note that '=' is padding and not considered to be
00299    part of the alphabet.  */
00300 bool
00301 isbase64 (char ch)
00302 {
00303   return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
00304 }
00305 
00306 /* Initialize decode-context buffer, CTX.  */
00307 void
00308 base64_decode_ctx_init (struct base64_decode_context *ctx)
00309 {
00310   ctx->i = 0;
00311 }
00312 
00313 /* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and
00314    none of those four is a newline, then return *IN.  Otherwise, copy up to
00315    4 - CTX->i non-newline bytes from that range into CTX->buf, starting at
00316    index CTX->i and setting CTX->i to reflect the number of bytes copied,
00317    and return CTX->buf.  In either case, advance *IN to point to the byte
00318    after the last one processed, and set *N_NON_NEWLINE to the number of
00319    verified non-newline bytes accessible through the returned pointer.  */
00320 static inline char *
00321 get_4 (struct base64_decode_context *ctx,
00322        char const **in, char const *in_end,
00323        size_t *n_non_newline)
00324 {
00325   if (ctx->i == 4)
00326     ctx->i = 0;
00327 
00328   if (ctx->i == 0)
00329     {
00330       char const *t = *in;
00331       if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL)
00332         {
00333           /* This is the common case: no newline.  */
00334           *in += 4;
00335           *n_non_newline = 4;
00336           return (char *) t;
00337         }
00338     }
00339 
00340   {
00341     /* Copy non-newline bytes into BUF.  */
00342     char const *p = *in;
00343     while (p < in_end)
00344       {
00345         char c = *p++;
00346         if (c != '\n')
00347           {
00348             ctx->buf[ctx->i++] = c;
00349             if (ctx->i == 4)
00350               break;
00351           }
00352       }
00353 
00354     *in = p;
00355     *n_non_newline = ctx->i;
00356     return ctx->buf;
00357   }
00358 }
00359 
00360 #define return_false                            \
00361   do                                            \
00362     {                                           \
00363       *outp = out;                              \
00364       return false;                             \
00365     }                                           \
00366   while (false)
00367 
00368 /* Decode up to four bytes of base64-encoded data, IN, of length INLEN
00369    into the output buffer, *OUT, of size *OUTLEN bytes.  Return true if
00370    decoding is successful, false otherwise.  If *OUTLEN is too small,
00371    as many bytes as possible are written to *OUT.  On return, advance
00372    *OUT to point to the byte after the last one written, and decrement
00373    *OUTLEN to reflect the number of bytes remaining in *OUT.  */
00374 static inline bool
00375 decode_4 (char const *in, size_t inlen,
00376           char **outp, size_t *outleft)
00377 {
00378   char *out = *outp;
00379   if (inlen < 2)
00380     return false;
00381 
00382   if (!isbase64 (in[0]) || !isbase64 (in[1]))
00383     return false;
00384 
00385   if (*outleft)
00386     {
00387       *out++ = ((b64[to_uchar (in[0])] << 2)
00388                 | (b64[to_uchar (in[1])] >> 4));
00389       --*outleft;
00390     }
00391 
00392   if (inlen == 2)
00393     return_false;
00394 
00395   if (in[2] == '=')
00396     {
00397       if (inlen != 4)
00398         return_false;
00399 
00400       if (in[3] != '=')
00401         return_false;
00402     }
00403   else
00404     {
00405       if (!isbase64 (in[2]))
00406         return_false;
00407 
00408       if (*outleft)
00409         {
00410           *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
00411                     | (b64[to_uchar (in[2])] >> 2));
00412           --*outleft;
00413         }
00414 
00415       if (inlen == 3)
00416         return_false;
00417 
00418       if (in[3] == '=')
00419         {
00420           if (inlen != 4)
00421             return_false;
00422         }
00423       else
00424         {
00425           if (!isbase64 (in[3]))
00426             return_false;
00427 
00428           if (*outleft)
00429             {
00430               *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
00431                         | b64[to_uchar (in[3])]);
00432               --*outleft;
00433             }
00434         }
00435     }
00436 
00437   *outp = out;
00438   return true;
00439 }
00440 
00441 /* Decode base64-encoded input array IN of length INLEN to output array
00442    OUT that can hold *OUTLEN bytes.  The input data may be interspersed
00443    with newlines.  Return true if decoding was successful, i.e. if the
00444    input was valid base64 data, false otherwise.  If *OUTLEN is too
00445    small, as many bytes as possible will be written to OUT.  On return,
00446    *OUTLEN holds the length of decoded bytes in OUT.  Note that as soon
00447    as any non-alphabet, non-newline character is encountered, decoding
00448    is stopped and false is returned.  If INLEN is zero, then process
00449    only whatever data is stored in CTX.
00450 
00451    Initially, CTX must have been initialized via base64_decode_ctx_init.
00452    Subsequent calls to this function must reuse whatever state is recorded
00453    in that buffer.  It is necessary for when a quadruple of base64 input
00454    bytes spans two input buffers.
00455 
00456    If CTX is NULL then newlines are treated as garbage and the input
00457    buffer is processed as a unit.  */
00458 
00459 bool
00460 base64_decode_ctx (struct base64_decode_context *ctx,
00461                    const char *in, size_t inlen,
00462                    char *out, size_t *outlen)
00463 {
00464   size_t outleft = *outlen;
00465   bool ignore_newlines = ctx != NULL;
00466   bool flush_ctx = false;
00467   unsigned int ctx_i = 0;
00468 
00469   if (ignore_newlines)
00470     {
00471       ctx_i = ctx->i;
00472       flush_ctx = inlen == 0;
00473     }
00474 
00475 
00476   while (true)
00477     {
00478       size_t outleft_save = outleft;
00479       if (ctx_i == 0 && !flush_ctx)
00480         {
00481           while (true)
00482             {
00483               /* Save a copy of outleft, in case we need to re-parse this
00484                  block of four bytes.  */
00485               outleft_save = outleft;
00486               if (!decode_4 (in, inlen, &out, &outleft))
00487                 break;
00488 
00489               in += 4;
00490               inlen -= 4;
00491             }
00492         }
00493 
00494       if (inlen == 0 && !flush_ctx)
00495         break;
00496 
00497       /* Handle the common case of 72-byte wrapped lines.
00498          This also handles any other multiple-of-4-byte wrapping.  */
00499       if (inlen && *in == '\n' && ignore_newlines)
00500         {
00501           ++in;
00502           --inlen;
00503           continue;
00504         }
00505 
00506       /* Restore OUT and OUTLEFT.  */
00507       out -= outleft_save - outleft;
00508       outleft = outleft_save;
00509 
00510       {
00511         char const *in_end = in + inlen;
00512         char const *non_nl;
00513 
00514         if (ignore_newlines)
00515           non_nl = get_4 (ctx, &in, in_end, &inlen);
00516         else
00517           non_nl = in;  /* Might have nl in this case. */
00518 
00519         /* If the input is empty or consists solely of newlines (0 non-newlines),
00520            then we're done.  Likewise if there are fewer than 4 bytes when not
00521            flushing context and not treating newlines as garbage.  */
00522         if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines))
00523           {
00524             inlen = 0;
00525             break;
00526           }
00527         if (!decode_4 (non_nl, inlen, &out, &outleft))
00528           break;
00529 
00530         inlen = in_end - in;
00531       }
00532     }
00533 
00534   *outlen -= outleft;
00535 
00536   return inlen == 0;
00537 }
00538 
00539 /* Allocate an output buffer in *OUT, and decode the base64 encoded
00540    data stored in IN of size INLEN to the *OUT buffer.  On return, the
00541    size of the decoded data is stored in *OUTLEN.  OUTLEN may be NULL,
00542    if the caller is not interested in the decoded length.  *OUT may be
00543    NULL to indicate an out of memory error, in which case *OUTLEN
00544    contains the size of the memory block needed.  The function returns
00545    true on successful decoding and memory allocation errors.  (Use the
00546    *OUT and *OUTLEN parameters to differentiate between successful
00547    decoding and memory error.)  The function returns false if the
00548    input was invalid, in which case *OUT is NULL and *OUTLEN is
00549    undefined. */
00550 bool
00551 base64_decode_alloc_ctx (struct base64_decode_context *ctx,
00552                          const char *in, size_t inlen, char **out,
00553                          size_t *outlen)
00554 {
00555   /* This may allocate a few bytes too many, depending on input,
00556      but it's not worth the extra CPU time to compute the exact size.
00557      The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the
00558      input ends with "=" and minus another 1 if the input ends with "==".
00559      Dividing before multiplying avoids the possibility of overflow.  */
00560   size_t needlen = 3 * (inlen / 4) + 3;
00561 
00562   *out = static_cast<char*>(malloc (needlen));
00563   if (!*out)
00564     return true;
00565 
00566   if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen))
00567     {
00568       free (*out);
00569       *out = NULL;
00570       return false;
00571     }
00572 
00573   if (outlen)
00574     *outlen = needlen;
00575 
00576   return true;
00577 }