From 6dc310ec5fd37e85c91a565f709f809ef851d13c Mon Sep 17 00:00:00 2001
From: Manoj Srivastava <srivasta@golden-gryphon.com>
Date: Sun, 28 Apr 2013 00:00:11 -0700
Subject: [topc--base64fix]: base64_decode_multichunk_and_speedup.diff

 This patch fixes the problem (it simply stopped reading the output on
 the first = char, ie. on the first chunk though there were multiple in
 the stream) and also adds buffering to make the thing four times faster.

* base64-decode.c (main): Also fixed prototype for main, and included
  stdlib.h to get a prototype for exit.

* base64-encode.c (main): Ditto.

* qp-decode.c (main): Ditto

* qp-encode.c (main): Ditto

git-archimport-id: srivasta@debian.org--etch/vm--base64-fix--7.1--patch-1
cherry picked from commit 08f8ac77551cf14dfa8a4184bdc75610870a77d8

Signed-off-by: Manoj Srivastava <srivasta@golden-gryphon.com>
---
 src/base64-decode.c |  103 ++++++++++++++++++++++++++++++---------------------
 src/base64-encode.c |    3 +-
 src/qp-decode.c     |    7 ++--
 src/qp-encode.c     |    5 ++-
 4 files changed, 69 insertions(+), 49 deletions(-)

diff --git a/src/base64-decode.c b/src/base64-decode.c
index 5a1c86e..1b026f7 100644
--- a/src/base64-decode.c
+++ b/src/base64-decode.c
@@ -4,6 +4,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #ifdef _WIN32
 #ifndef WIN32
@@ -19,10 +20,10 @@
 unsigned char alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 int
-main()
+main(void)
 {
-	static char inalphabet[256], decoder[256];
-	int i, bits, c, char_count, errors = 0;
+    static char inalphabet[256], decoder[256];
+    int i, bits, char_count, errors = 0;
 
 #ifdef WIN32
 	_setmode( _fileno(stdout), _O_BINARY);
@@ -32,46 +33,62 @@ main()
 	inalphabet[alphabet[i]] = 1;
 	decoder[alphabet[i]] = i;
 	}
+#define BUFLEN 72*500 // must be multiple of 4
 
-	char_count = 0;
-	bits = 0;
-	while ((c = getchar()) != EOF) {
-	if (c == '=')
-	  break;
-	if (c > 255 || ! inalphabet[c])
-	  continue;
-	bits += decoder[c];
-	char_count++;
-	if (char_count == 4) {
-		putchar((bits >> 16));
-		putchar(((bits >> 8) & 0xff));
-		putchar((bits & 0xff));
-		bits = 0;
-		char_count = 0;
-	} else {
-		bits <<= 6;
-	}
-	}
-	if (c == EOF) {
-	if (char_count) {
-                fprintf(stderr, "base64-decode: base64 encoding incomplete: at least %d bits truncated",
-			((4 - char_count) * 6));
-		errors++;
-	}
-	} else { /* c == '=' */
-	switch (char_count) {
-	  case 1:
+    int len;
+    char buf[BUFLEN];
+    char outbuf[BUFLEN];
+
+    while(!feof(stdin)) {
+        unsigned char c;
+
+        int pos=0;
+        char *out=outbuf;
+        len=fread(buf, sizeof(c), BUFLEN, stdin);
+        if(!len) continue;
+
+cont_buffer:
+        char_count = 0;
+        bits = 0;
+        while(pos<len) {
+            c=buf[pos++];
+            if (c == '=')
+                break;
+            if (! inalphabet[c])
+                continue;
+            bits += decoder[c];
+            char_count++;
+            if (char_count == 4) {
+                *out++ = ((bits >> 16));
+                *out++ = (((bits >> 8) & 0xff));
+                *out++ = ((bits & 0xff));
+                bits = 0;
+                char_count = 0;
+            } else {
+                bits <<= 6;
+            }
+        }
+        switch (char_count) {
+            case 1:
                 fprintf(stderr, "base64-decode: base64 encoding incomplete: at least 2 bits missing");
-		errors++;
-		break;
-	  case 2:
-		putchar((bits >> 10));
-		break;
-	  case 3:
-		putchar((bits >> 16));
-		putchar(((bits >> 8) & 0xff));
-		break;
-	}
-	}
-	exit(errors ? 1 : 0);
+                errors++;
+                break;
+            case 2:
+                *out++ = ((bits >> 10));
+                break;
+            case 3:
+                *out++ = ((bits >> 16));
+                *out++ = (((bits >> 8) & 0xff));
+                break;
+            case 0:
+                break;
+            default:
+                fprintf(stderr, "base64-decode: base64 encoding incomplete: at least %d bits truncated",
+                        ((4 - char_count) * 6));
+        }
+        if(pos<len) // did not proceed the whole thing, continue
+            goto cont_buffer;
+        fwrite(outbuf, sizeof(char), (out-outbuf), stdout);
+    }
+    exit(errors ? 1 : 0);
 }
diff --git a/src/base64-encode.c b/src/base64-encode.c
index fd146fa..d9c6651 100644
--- a/src/base64-encode.c
+++ b/src/base64-encode.c
@@ -8,6 +8,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #ifdef _WIN32
 #ifndef WIN32
@@ -23,7 +24,7 @@
 unsigned char alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 int
-main()
+main(void)
 {
 	int cols, bits, c, char_count;
 
diff --git a/src/qp-decode.c b/src/qp-decode.c
index 09c97a8..9861f7b 100644
--- a/src/qp-decode.c
+++ b/src/qp-decode.c
@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 
 #ifdef _WIN32
 #ifndef WIN32
@@ -17,11 +18,11 @@
 #include <fcntl.h>
 #endif
 
-char *hexdigits  = "0123456789ABCDEF";
-char *hexdigits2 = "0123456789abcdef";
+const char *hexdigits  = "0123456789ABCDEF";
+const char *hexdigits2 = "0123456789abcdef";
 
 int
-main()
+main(void)
 {
     char line[2000], *start, *stop, *copy;
     char *d1, *d2, c;
diff --git a/src/qp-encode.c b/src/qp-encode.c
index e5796d0..8014d02 100644
--- a/src/qp-encode.c
+++ b/src/qp-encode.c
@@ -8,6 +8,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #ifdef _WIN32
 #ifndef WIN32
@@ -20,10 +21,10 @@
 #include <fcntl.h>
 #endif
 
-char *hexdigits  = "0123456789ABCDEF";
+const char *hexdigits  = "0123456789ABCDEF";
 
 int
-main()
+main(void)
 {
 	int c;
 	int cols = 0;
