(linenum→info "unix/slp.c:2238")

coreutils/6.9/lib/base64.c

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