]> Pileus Git - ~andy/fetchmail/blobdiff - base64.c
Merge branch 'legacy_63'
[~andy/fetchmail] / base64.c
index 490cd7f3adaf34434bf78cd72c61ac733a2b5d5e..1453257b501ac87d79d0a2ffa7d5baa77a7d9998 100644 (file)
--- a/base64.c
+++ b/base64.c
@@ -7,6 +7,8 @@
  * "Base64 Content-Transfer-Encoding", but lines must not be broken in the
  * scheme used here.
  */
+#include "config.h"
+#include "fetchmail.h"
 #include <ctype.h>
 
 static const char base64digits[] =
@@ -23,11 +25,13 @@ static const char base64val[] = {
     BAD, 26, 27, 28,  29, 30, 31, 32,  33, 34, 35, 36,  37, 38, 39, 40,
      41, 42, 43, 44,  45, 46, 47, 48,  49, 50, 51,BAD, BAD,BAD,BAD,BAD
 };
-#define DECODE64(c)  (isascii(c) ? base64val[c] : BAD)
+#define DECODE64(c)  (isascii((unsigned char)(c)) ? base64val[c] : BAD)
 
-void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
+void to64frombits(char *out, const void *in_, int inlen)
 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
 {
+    const unsigned char *in = (const unsigned char *)in_;
+
     for (; inlen >= 3; inlen -= 3)
     {
        *out++ = base64digits[in[0] >> 2];
@@ -51,11 +55,13 @@ void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
     *out = '\0';
 }
 
-int from64tobits(char *out, const char *in)
+int from64tobits(void *out_, const char *in, int maxlen)
 /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */
+/* maxlen limits output buffer size, set to zero to ignore */
 {
     int len = 0;
-    register char digit1, digit2, digit3, digit4;
+    register unsigned char digit1, digit2, digit3, digit4;
+    unsigned char *out = (unsigned char *)out_;
 
     if (in[0] == '+' && in[1] == ' ')
        in += 2;
@@ -76,20 +82,26 @@ int from64tobits(char *out, const char *in)
        if (digit4 != '=' && DECODE64(digit4) == BAD)
            return(-1);
        in += 4;
-       *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
        ++len;
+       if (maxlen && len > maxlen)
+           return(-1);
+       *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
        if (digit3 != '=')
        {
-           *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
            ++len;
+           if (maxlen && len > maxlen)
+               return(-1);
+           *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
            if (digit4 != '=')
            {
+               ++len;
+               if (maxlen && len > maxlen)
+                   return(-1);
                *out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
-               ++len;
            }
        }
     } while 
-       (*in != '\r' && digit4 != '=');
+       (*in && *in != '\r' && digit4 != '=');
 
     return (len);
 }