diff options
author | Jim Meyering <jim@meyering.net> | 2007-01-04 11:52:52 +0100 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2007-01-04 11:52:52 +0100 |
commit | 3b933f1e33197fec6a59466df1337292ec7bfa56 (patch) | |
tree | 407732a747d2622577c8366b93a01744dfa8845b /src | |
parent | 99d9e13b9c7e53db7620e5b34550a114adfa22d3 (diff) | |
download | coreutils-3b933f1e33197fec6a59466df1337292ec7bfa56.tar.xz |
[ChangeLog]
When decoding, always allow newlines in input, with almost no
performance impact.
* src/base64.c (do_decode): Initialize decode context.
Call base64_decode one more time, after all input is processed.
(usage): When decoding, newlines are always accepted.
* tests/misc/base64: Add a bunch of tests, for the above.
* gl/lib/base64.c: Include <string.h>.
(base64_decode_ctx_init, get_4, decode_4): New functions.
(base64_decode): Efficiently handle interspersed newlines.
(base64_decode_alloc): Update signature.
* gl/lib/base64.h (struct base64_decode_context): Define.
(base64_decode_ctx_init): Add prototype.
(base64_decode, base64_decode_alloc): Update prototypes.
[doc/ChangeLog]
* coreutils.texi (base64 invocation): When decoding, newlines
are always accepted.
Diffstat (limited to 'src')
-rw-r--r-- | src/base64.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/src/base64.c b/src/base64.c index 36afbe4df..9f8ff417c 100644 --- a/src/base64.c +++ b/src/base64.c @@ -1,5 +1,5 @@ /* Base64 encode/decode strings or files. - Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of Base64. @@ -83,9 +83,10 @@ With no FILE, or when FILE is -, read standard input.\n"), stdout); fputs (_("\ \n\ The data are encoded as described for the base64 alphabet in RFC 3548.\n\ -Decoding require compliant input by default, use --ignore-garbage to\n\ -attempt to recover from non-alphabet characters (such as newlines) in\n\ -the encoded stream.\n"), stdout); +When decoding, the input may contain newlines in addition to the bytes of\n\ +the formal base64 alphabet. Use --ignore-garbage to attempt to recover\n\ +from any other non-alphabet bytes in the encoded stream.\n"), + stdout); printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); } @@ -183,11 +184,15 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage) char inbuf[B64BLOCKSIZE]; char outbuf[BLOCKSIZE]; size_t sum; + struct base64_decode_context ctx; + + base64_decode_ctx_init (&ctx); do { bool ok; size_t n; + unsigned int k; sum = 0; do @@ -211,14 +216,23 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage) } while (sum < B64BLOCKSIZE && !feof (in)); - n = BLOCKSIZE; - ok = base64_decode (inbuf, sum, outbuf, &n); + /* The following "loop" is usually iterated just once. + However, when it processes the final input buffer, we want + to iterate it one additional time, but with an indicator + telling it to flush what is in CTX. */ + for (k = 0; k < 1 + feof (in); k++) + { + if (k == 1 && ctx.i == 0) + break; + n = BLOCKSIZE; + ok = base64_decode (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n); - if (fwrite (outbuf, 1, n, out) < n) - error (EXIT_FAILURE, errno, _("write error")); + if (fwrite (outbuf, 1, n, out) < n) + error (EXIT_FAILURE, errno, _("write error")); - if (!ok) - error (EXIT_FAILURE, 0, _("invalid input")); + if (!ok) + error (EXIT_FAILURE, 0, _("invalid input")); + } } while (!feof (in)); } |