# HG changeset patch # User Paul Eggert # Date 1313004973 25200 # Node ID d15d71163ff3807bb9bbdccb7358b0e3cb88963e # Parent fcabcdea285ec38c0181cbef7b83fc37f1a63d5e base64: fix off-by-one buffer size bug Problem and (trivial) fix reported by Gijs van Tulder in . * lib/base64.c (base64_decode_alloc_ctx): Allocate one more byte. * tests/test-base64.c (main): Catch the bug. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-08-10 Paul Eggert + + base64: fix off-by-one buffer size bug + Problem and (trivial) fix reported by Gijs van Tulder in + . + * lib/base64.c (base64_decode_alloc_ctx): Allocate one more byte. + * tests/test-base64.c (main): Catch the bug. + 2011-08-10 Eric Blake closein: correct comments diff --git a/lib/base64.c b/lib/base64.c --- a/lib/base64.c +++ b/lib/base64.c @@ -552,10 +552,10 @@ { /* This may allocate a few bytes too many, depending on input, but it's not worth the extra CPU time to compute the exact size. - The exact size is 3 * inlen / 4, minus 1 if the input ends - with "=" and minus another 1 if the input ends with "==". + The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the + input ends with "=" and minus another 1 if the input ends with "==". Dividing before multiplying avoids the possibility of overflow. */ - size_t needlen = 3 * (inlen / 4) + 2; + size_t needlen = 3 * (inlen / 4) + 3; *out = malloc (needlen); if (!*out) diff --git a/tests/test-base64.c b/tests/test-base64.c --- a/tests/test-base64.c +++ b/tests/test-base64.c @@ -184,9 +184,8 @@ ok = base64_decode_alloc_ctx (&ctx, "hp", 2, &p, &len); ASSERT (ok); - ASSERT (len == 2); - /* Actually this looks buggy. Shouldn't output be 'ghi'? */ - ASSERT (memcmp (p, "gh", len) == 0); + ASSERT (len == 3); + ASSERT (memcmp (p, "ghi", len) == 0); ok = base64_decode_alloc_ctx (&ctx, "", 0, &p, &len); ASSERT (ok); }