Jim Meyering wrote:
> I found "strict_newlines" to be a little unclear.
> If you use something like "ignore_newlines" instead, that's not
> only clearer to me, but with its reversed semantics it also lets
> you avoid three negations.


Thanks, that's much nicer.

The attached patch contains this change and is rebased against the
current HEAD.

I've also made this available via:

$ git fetch git://repo.or.cz/coreutils/bo.git base64-merge:base64-merge


Thanks,

Bo
>From 9131d82c32e00b606eb79d083ef8309178460ac5 Mon Sep 17 00:00:00 2001
From: Bo Borgerson <[EMAIL PROTECTED]>
Date: Wed, 30 Apr 2008 17:40:38 -0400
Subject: [PATCH] An upstream compatible base64

* gl/lib/base64.c (base64_decode_ctx): If no context structure was passed in,
treat newlines as garbage (this is the historical behavior).  Formerly
base64_decode.
(base64_decode_alloc_ctx): Formerly base64_decode_alloc.
* gl/lib/base64.h (base64_decode): Macro for four-argument calls.
(base64_decode_alloc): Likewise.
* src/base64.c (do_decode): Call base64_decode_ctx instead of base64_decode.

Signed-off-by: Bo Borgerson <[EMAIL PROTECTED]>
---
 gl/lib/base64.c |   45 +++++++++++++++++++++++++++++++--------------
 gl/lib/base64.h |   19 +++++++++++++------
 src/base64.c    |    2 +-
 3 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/gl/lib/base64.c b/gl/lib/base64.c
index 43f12c6..a33f102 100644
--- a/gl/lib/base64.c
+++ b/gl/lib/base64.c
@@ -449,20 +449,32 @@ decode_4 (char const *restrict in, size_t inlen,
    Initially, CTX must have been initialized via base64_decode_ctx_init.
    Subsequent calls to this function must reuse whatever state is recorded
    in that buffer.  It is necessary for when a quadruple of base64 input
-   bytes spans two input buffers.  */
+   bytes spans two input buffers.
+
+   If CTX is NULL then newlines are treated as garbage and the input
+   buffer is processed as a unit.  */
 
 bool
-base64_decode (struct base64_decode_context *ctx,
-	       const char *restrict in, size_t inlen,
-	       char *restrict out, size_t *outlen)
+base64_decode_ctx (struct base64_decode_context *ctx,
+		   const char *restrict in, size_t inlen,
+		   char *restrict out, size_t *outlen)
 {
   size_t outleft = *outlen;
-  bool flush_ctx = inlen == 0;
+  bool ignore_newlines = ctx != NULL;
+  bool flush_ctx = false;
+  unsigned int ctx_i = 0;
+
+  if (ignore_newlines)
+    {
+      ctx_i = ctx->i;
+      flush_ctx = inlen == 0;
+    }
+
 
   while (true)
     {
       size_t outleft_save = outleft;
-      if (ctx->i == 0 && !flush_ctx)
+      if (ctx_i == 0 && !flush_ctx)
 	{
 	  while (true)
 	    {
@@ -482,7 +494,7 @@ base64_decode (struct base64_decode_context *ctx,
 
       /* Handle the common case of 72-byte wrapped lines.
 	 This also handles any other multiple-of-4-byte wrapping.  */
-      if (inlen && *in == '\n')
+      if (inlen && *in == '\n' && ignore_newlines)
 	{
 	  ++in;
 	  --inlen;
@@ -495,12 +507,17 @@ base64_decode (struct base64_decode_context *ctx,
 
       {
 	char const *in_end = in + inlen;
-	char const *non_nl = get_4 (ctx, &in, in_end, &inlen);
+	char const *non_nl;
+
+	if (ignore_newlines)
+	  non_nl = get_4 (ctx, &in, in_end, &inlen);
+	else
+	  non_nl = in;  /* Might have nl in this case. */
 
 	/* If the input is empty or consists solely of newlines (0 non-newlines),
 	   then we're done.  Likewise if there are fewer than 4 bytes when not
-	   flushing context.  */
-	if (inlen == 0 || (inlen < 4 && !flush_ctx))
+	   flushing context and not treating newlines as garbage.  */
+	if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines))
 	  {
 	    inlen = 0;
 	    break;
@@ -529,9 +546,9 @@ base64_decode (struct base64_decode_context *ctx,
    input was invalid, in which case *OUT is NULL and *OUTLEN is
    undefined. */
 bool
-base64_decode_alloc (struct base64_decode_context *ctx,
-		     const char *in, size_t inlen, char **out,
-		     size_t *outlen)
+base64_decode_alloc_ctx (struct base64_decode_context *ctx,
+			 const char *in, size_t inlen, char **out,
+			 size_t *outlen)
 {
   /* This may allocate a few bytes too many, depending on input,
      but it's not worth the extra CPU time to compute the exact size.
@@ -544,7 +561,7 @@ base64_decode_alloc (struct base64_decode_context *ctx,
   if (!*out)
     return true;
 
-  if (!base64_decode (ctx, in, inlen, *out, &needlen))
+  if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen))
     {
       free (*out);
       *out = NULL;
diff --git a/gl/lib/base64.h b/gl/lib/base64.h
index ba436e0..fa242c8 100644
--- a/gl/lib/base64.h
+++ b/gl/lib/base64.h
@@ -42,12 +42,19 @@ extern void base64_encode (const char *restrict in, size_t inlen,
 extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out);
 
 extern void base64_decode_ctx_init (struct base64_decode_context *ctx);
-extern bool base64_decode (struct base64_decode_context *ctx,
-			   const char *restrict in, size_t inlen,
-			   char *restrict out, size_t *outlen);
 
-extern bool base64_decode_alloc (struct base64_decode_context *ctx,
-				 const char *in, size_t inlen,
-				 char **out, size_t *outlen);
+extern bool base64_decode_ctx (struct base64_decode_context *ctx,
+			       const char *restrict in, size_t inlen,
+			       char *restrict out, size_t *outlen);
+
+extern bool base64_decode_alloc_ctx (struct base64_decode_context *ctx,
+				     const char *in, size_t inlen,
+				     char **out, size_t *outlen);
+
+#define base64_decode(in, inlen, out, outlen) \
+	base64_decode_ctx (NULL, in, inlen, out, outlen)
+
+#define base64_decode_alloc(in, inlen, out, outlen) \
+	base64_decode_alloc_ctx (NULL, in, inlen, out, outlen)
 
 #endif /* BASE64_H */
diff --git a/src/base64.c b/src/base64.c
index aa2fc8f..983b8cb 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -223,7 +223,7 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage)
 	  if (k == 1 && ctx.i == 0)
 	    break;
 	  n = BLOCKSIZE;
-	  ok = base64_decode (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
+	  ok = base64_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
 
 	  if (fwrite (outbuf, 1, n, out) < n)
 	    error (EXIT_FAILURE, errno, _("write error"));
-- 
1.5.4.3

_______________________________________________
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to