X-Git-Url: https://git.distorted.org.uk/~mdw/mLib/blobdiff_plain/0bfb14313759dbbb677c373eac9b980972cf498d..4aee39a18184ae8595936a03ad254c27d149a0eb:/base64.c diff --git a/base64.c b/base64.c index 10ce91e..8fda2b5 100644 --- a/base64.c +++ b/base64.c @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: base64.c,v 1.3 1999/05/21 22:14:30 mdw Exp $ + * $Id: base64.c,v 1.7 2004/04/08 01:36:11 mdw Exp $ * * Base64 encoding and decoding. * * (c) 1997 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of the mLib utilities library. * @@ -15,32 +15,18 @@ * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * mLib is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with mLib; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: base64.c,v $ - * Revision 1.3 1999/05/21 22:14:30 mdw - * Take advantage of the new dynamic string macros. - * - * Revision 1.2 1999/05/18 21:45:27 mdw - * Allow Base64 encode and decode of arbitrary rubbish. - * - * Revision 1.1 1999/05/17 20:35:00 mdw - * Base64 encoding and decoding support. - * - */ - /*----- Header files ------------------------------------------------------*/ #include @@ -52,11 +38,11 @@ /*----- Important tables --------------------------------------------------*/ -static const char base64_encodeMap[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/" }; +static const char encodemap[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/" }; -static const signed char base64_decodeMap[] = { +static const signed char decodemap[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 1x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 2x */ @@ -65,7 +51,7 @@ static const signed char base64_decodeMap[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 5x */ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 ,37, 38, 39, 40, /* 6x */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 7x */ -}; +}; /*----- Main code ---------------------------------------------------------*/ @@ -96,10 +82,10 @@ void base64_encode(base64_ctx *ctx, qsz++; sz--; if (qsz == 3) { - DPUTC(d, base64_encodeMap[(acc >> 18) & 0x3f]); - DPUTC(d, base64_encodeMap[(acc >> 12) & 0x3f]); - DPUTC(d, base64_encodeMap[(acc >> 6) & 0x3f]); - DPUTC(d, base64_encodeMap[(acc >> 0) & 0x3f]); + DPUTC(d, encodemap[(acc >> 18) & 0x3f]); + DPUTC(d, encodemap[(acc >> 12) & 0x3f]); + DPUTC(d, encodemap[(acc >> 6) & 0x3f]); + DPUTC(d, encodemap[(acc >> 0) & 0x3f]); ctx->lnlen += 4; if (ctx->maxline && ctx->lnlen >= ctx->maxline) { dstr_puts(d, ctx->indent); @@ -121,17 +107,17 @@ void base64_encode(base64_ctx *ctx, break; case 1: acc <<= 16; - DPUTC(d, base64_encodeMap[(acc >> 18) & 0x3f]); - DPUTC(d, base64_encodeMap[(acc >> 12) & 0x3f]); + DPUTC(d, encodemap[(acc >> 18) & 0x3f]); + DPUTC(d, encodemap[(acc >> 12) & 0x3f]); DPUTC(d, '='); DPUTC(d, '='); ctx->lnlen += 4; break; case 2: acc <<= 8; - DPUTC(d, base64_encodeMap[(acc >> 18) & 0x3f]); - DPUTC(d, base64_encodeMap[(acc >> 12) & 0x3f]); - DPUTC(d, base64_encodeMap[(acc >> 6) & 0x3f]); + DPUTC(d, encodemap[(acc >> 18) & 0x3f]); + DPUTC(d, encodemap[(acc >> 12) & 0x3f]); + DPUTC(d, encodemap[(acc >> 6) & 0x3f]); DPUTC(d, '='); ctx->lnlen += 4; break; @@ -172,7 +158,7 @@ void base64_decode(base64_ctx *ctx, if (ch >= 128 || ch < 0) ch = -1; else - ch = base64_decodeMap[ch]; + ch = decodemap[ch]; sz--; if (ch == -1) continue; @@ -212,14 +198,24 @@ void base64_decode(base64_ctx *ctx, unsigned long acc = ctx->acc; unsigned qsz = ctx->qsz; - /* --- Now fiddle with everything else --- */ + /* --- Now fiddle with everything else --- * + * + * There's a bodge here for invalid encodings which have only one hextet + * in the final group. I'm not sure this is really worth having, but it + * might save some unexpected behaviour. (Not that you won't still get + * unexpected behaviour if the stream is completely empty, of course.) + */ - acc <<= 6 * (4 - qsz); - qsz *= 6; - while (qsz > 8) { - DPUTC(d, (acc >> 16) & 0xff); - acc <<= 8; - qsz -= 8; + if (qsz) { + acc <<= 6 * (4 - qsz); + qsz *= 6; + if (qsz < 8) + qsz = 8; + while (qsz >= 8) { + DPUTC(d, (acc >> 16) & 0xff); + acc <<= 8; + qsz -= 8; + } } /* --- That seems to be good enough --- */ @@ -256,7 +252,7 @@ int main(int argc, char *argv[]) unsigned char buf[BUFSIZ]; dstr d = DSTR_INIT; base64_ctx ctx; - void (*proc)(base64_ctx *, const unsigned char *, size_t, dstr *); + void (*proc)(base64_ctx *, const void *, size_t, dstr *); size_t sz; base64_init(&ctx);