Hello,
 This patch makes the base64 decoding tolerant on carriage returns,
spaces and tabs. It is quite common to find PEM encoded files (base64
with new lines) containing such characters and having a tolerant decoder
is a plus.

regards,
Nikos
>From c56e7ecd745c7e49bbf17bd907c7d305009b19d9 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <n...@gnutls.org>
Date: Mon, 30 Jan 2012 22:16:47 +0100
Subject: [PATCH] Base64 decoding is tolerant on carriage returns spaces and
 tabs in addition to newlines.

---
 lib/base64.c        |   24 +++++++++++++++++++++---
 tests/test-base64.c |    4 ++--
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/lib/base64.c b/lib/base64.c
index eafa277..7b1c994 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -308,6 +308,24 @@ base64_decode_ctx_init (struct base64_decode_context *ctx)
   ctx->i = 0;
 }
 
+inline static int is_nl(char c)
+{
+  if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
+    return 1;
+  return 0;
+}
+
+inline static int search_for_nl(char const *t, size_t t_size)
+{
+int i;
+
+  for (i=0;i<t_size;i++)
+    if (t[i] == ' ' || t[i] == '\t' || t[i] == '\n' || t[i] == '\r')
+      return 1;
+  
+  return 0;
+}
+
 /* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and
    none of those four is a newline, then return *IN.  Otherwise, copy up to
    4 - CTX->i non-newline bytes from that range into CTX->buf, starting at
@@ -326,7 +344,7 @@ get_4 (struct base64_decode_context *ctx,
   if (ctx->i == 0)
     {
       char const *t = *in;
-      if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL)
+      if (4 <= in_end - *in && search_for_nl(t, 4) == 0)
         {
           /* This is the common case: no newline.  */
           *in += 4;
@@ -341,7 +359,7 @@ get_4 (struct base64_decode_context *ctx,
     while (p < in_end)
       {
         char c = *p++;
-        if (c != '\n')
+        if (!is_nl(c))
           {
             ctx->buf[ctx->i++] = c;
             if (ctx->i == 4)
@@ -494,7 +512,7 @@ base64_decode_ctx (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' && ignore_newlines)
+      if (inlen && is_nl(*in) && ignore_newlines)
         {
           ++in;
           --inlen;
diff --git a/tests/test-base64.c b/tests/test-base64.c
index 9a533c5..a71ffba 100644
--- a/tests/test-base64.c
+++ b/tests/test-base64.c
@@ -153,7 +153,7 @@ main (void)
 
   {
     struct base64_decode_context ctx;
-    const char *newlineb64 = "YWJjZG\nVmZ2hp\namtsbW5vcA==";
+    const char *newlineb64 = "YWJjZG\nVmZ2hp\r\n\tamtsbW5vcA==";
 
     base64_decode_ctx_init (&ctx);
 
@@ -168,7 +168,7 @@ main (void)
     struct base64_decode_context ctx;
     base64_decode_ctx_init (&ctx);
 
-    ok = base64_decode_alloc_ctx (&ctx, "YW\nJjZGVmZ2hp", 13, &p, &len);
+    ok = base64_decode_alloc_ctx (&ctx, "YW\n JjZGVmZ2hp", 14, &p, &len);
     ASSERT (ok);
     ASSERT (len == 9);
     ASSERT (memcmp (p, "abcdefghi", len) == 0);
-- 
1.7.8.3

Reply via email to