X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=base64.c;h=1453257b501ac87d79d0a2ffa7d5baa77a7d9998;hb=910d5a2f852edb8c4e54c0e875da6a90385ab790;hp=ef36be6f721787eceec1d8e4ca041ca4d0386a94;hpb=85f067d97fdf18769eefd8419ab10c3a9a113195;p=~andy%2Ffetchmail diff --git a/base64.c b/base64.c index ef36be6f..1453257b 100644 --- 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 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 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); }