* "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[] =
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];
*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;
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);
}