summaryrefslogtreecommitdiff
path: root/src/base64.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2007-01-04 11:52:52 +0100
committerJim Meyering <jim@meyering.net>2007-01-04 11:52:52 +0100
commit3b933f1e33197fec6a59466df1337292ec7bfa56 (patch)
tree407732a747d2622577c8366b93a01744dfa8845b /src/base64.c
parent99d9e13b9c7e53db7620e5b34550a114adfa22d3 (diff)
downloadcoreutils-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/base64.c')
-rw-r--r--src/base64.c34
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));
}