bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Feature request - base64 Filename Safe Alphabet


From: Bo Borgerson
Subject: Re: Feature request - base64 Filename Safe Alphabet
Date: Wed, 30 Apr 2008 23:38:23 -0400
User-agent: Thunderbird 2.0.0.12 (X11/20080227)

Jim Meyering wrote:
> if you make him happy, I'll probably be happy, too ;-)


Hi Simon,

This is an attempt to merge the coreutils and gnulib base64 libraries.

My goal is to preserve the gnulib interface and behavior while also
supporting the coreutils extensions.

This version of the patch should have good performance in both cases, as
well.

Please let me know if this meets your requirements.

Thanks,

Bo
>From a302f7beca7d0e2bfcb7770ff31947e3d2965db2 Mon Sep 17 00:00:00 2001
From: Bo Borgerson <address@hidden>
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 <address@hidden>
---
 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..bfe4ad2 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 strict_newlines = ctx == NULL;
+  bool flush_ctx = false;
+  unsigned int ctx_i = 0;
+
+  if (!strict_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' && !strict_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 (strict_newlines)
+         non_nl = in;  /* Might have nl in this case. */
+       else
+         non_nl = get_4 (ctx, &in, in_end, &inlen);
 
        /* 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 && !strict_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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]