From 94e11d7e11992304cbb13074bdfde11e8965f0cf Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Sat, 4 Jul 2020 14:01:42 -0400 Subject: [PATCH] decode: Don't write past the end of the input buffer By changing the test program to allocate exactly the correct amount of space for the decode buffer, we can see (using valgrind) that the previous algorithm would (depending on the length) write one byte past the end of the buffer. Preserve the extra bits in a local variable to be added into the next byte, rather than storing them in the next byte itself. --- base64.c | 14 ++++++++------ main.c | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/base64.c b/base64.c index eeded25..742c563 100644 --- a/base64.c +++ b/base64.c @@ -124,11 +124,13 @@ base64_decode(const char *in, unsigned int inlen, unsigned char *out) unsigned int i; unsigned int j; unsigned char c; + unsigned char l; if (inlen & 0x3) { return 0; } + l = 0; for (i = j = 0; i < inlen; i++) { if (in[i] == BASE64_PAD) { break; @@ -144,18 +146,18 @@ base64_decode(const char *in, unsigned int inlen, unsigned char *out) switch (i & 0x3) { case 0: - out[j] = (c << 2) & 0xFF; + l = (c << 2) & 0xFF; break; case 1: - out[j++] |= (c >> 4) & 0x3; - out[j] = (c & 0xF) << 4; + out[j++] = l | ((c >> 4) & 0x3); + l = (c & 0xF) << 4; break; case 2: - out[j++] |= (c >> 2) & 0xF; - out[j] = (c & 0x3) << 6; + out[j++] = l | ((c >> 2) & 0xF); + l = (c & 0x3) << 6; break; case 3: - out[j++] |= c; + out[j++] = l | c; break; } } diff --git a/main.c b/main.c index 1bfbc72..f516965 100644 --- a/main.c +++ b/main.c @@ -13,7 +13,7 @@ test(unsigned char *encode, unsigned int encodelen, unsigned char *decode_out; encode_out = malloc(BASE64_ENCODE_OUT_SIZE(encodelen)); - decode_out = malloc(BASE64_DECODE_OUT_SIZE(decodelen)); + decode_out = malloc(encodelen); assert(encode_out); assert(decode_out);