diff options
author | Matthias Andree <matthias.andree@gmx.de> | 2018-04-14 21:39:58 +0200 |
---|---|---|
committer | Matthias Andree <matthias.andree@gmx.de> | 2018-04-14 21:39:58 +0200 |
commit | 9deaf399553050b3b426e8a39d0ffd22430bf72d (patch) | |
tree | 9bf7de273c7a2936ff07a0da67b1cbec2aab72a5 /base64.c | |
parent | 3a36394465a4e6e3c64bb5b1255717df753bb4a9 (diff) | |
download | fetchmail-9deaf399553050b3b426e8a39d0ffd22430bf72d.tar.gz fetchmail-9deaf399553050b3b426e8a39d0ffd22430bf72d.tar.bz2 fetchmail-9deaf399553050b3b426e8a39d0ffd22430bf72d.zip |
In-depth fix for to64frombits() BASE64 encoder buffer sizing.
Diffstat (limited to 'base64.c')
-rw-r--r-- | base64.c | 10 |
1 files changed, 8 insertions, 2 deletions
@@ -27,23 +27,27 @@ static const char base64val[] = { }; #define DECODE64(c) (isascii((unsigned char)(c)) ? base64val[c] : BAD) -void to64frombits(char *out, const void *in_, int inlen) +int to64frombits(char *out, const void *in_, int inlen, size_t outlen) /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ { + int rc = 0; const unsigned char *in = (const unsigned char *)in_; for (; inlen >= 3; inlen -= 3) { + if (outlen < 5) { rc = -1; goto fail; } /* buffer too small */ *out++ = base64digits[in[0] >> 2]; *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; *out++ = base64digits[in[2] & 0x3f]; in += 3; + outlen -= 4; } if (inlen > 0) { unsigned char fragment; + if (outlen < 5) { rc = -1; goto fail; } /* buffer too small */ *out++ = base64digits[in[0] >> 2]; fragment = (in[0] << 4) & 0x30; if (inlen > 1) @@ -52,7 +56,9 @@ void to64frombits(char *out, const void *in_, int inlen) *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c]; *out++ = '='; } +fail: *out = '\0'; + return rc; } int from64tobits(void *out_, const char *in, int maxlen) @@ -103,7 +109,7 @@ int from64tobits(void *out_, const char *in, int maxlen) } while (*in && *in != '\r' && digit4 != '='); - return (len); + return len; } /* base64.c ends here */ |