Package: mime-codecs Version: 7.19-7 Severity: grave Tags: patch Justification: renders package unusable
It appears that the buffering recently introduced to base64-decode has some major flaws in it that render of all base64-encoded files that are larger than the input buffer size (~36K) unreadable with the new base64-decode. This appears to be the case despite the same encoded files decoding cleanly with both - sarge's version of base64-decode (7.19-4), and - perl -M"MIME::Base64" -ne 'print decode_base64($_)' i'm attaching a file that appears to fail for me as "test1", but since i don't want people who are trying to replicate this to rely on the base64-decode in their MUA i've provided the same file here: http://lair.fifthhorseman.net/~dkg/src/vm/test1 Doing what should be an identity transformation on this file highlights the problem right at the end of the file: [EMAIL PROTECTED] test]$ <test1 base64-encode | base64-decode >test1.out [EMAIL PROTECTED] test]$ ls -l test1 test1.out -rw-r--r-- 1 dkg dkg 26632 2005-11-08 01:16 test1 -rw-r--r-- 1 dkg dkg 26632 2005-11-08 03:52 test1.out [EMAIL PROTECTED] test]$ cmp -bl test1 test1.out 26631 32 ^Z 150 h 26632 36 ^^ 170 x [EMAIL PROTECTED] test]$ As you can see, the last two bytes are both left-shifted by two bits. The input buffer is filling up a couple bytes shy of the end of the base64-encoded version, and then the special-case handling of the ending bytes kicks in inappropriately. It should be kicking in only at the end of the input stream, not at the end of the buffer. i'm attaching a patch which appears to resolve the problem for me by straightening out the flow of control, properly initializing some variables, and removing the goto (considered harmful!) which doesn't appear to be needed. The type of failure you get from base64-decode appears to depend exclusively on the length of the program's stdin relative to its input buffer. If you want to generate more test cases to see that things fail right around 26631 bytes of un-encoded data (assuming BUFLEN is still 72*500), try: for N in 26630 26631 26632 26633; do dd if=/dev/urandom of=test$N bs=$N count=1 2>/dev/null <test$N base64-encode | base64-decode >test$N.out if (cmp -bl test$N test$N.out); then echo OK fi done when N=26631, you get errors from the decode that look like: base64-decode: base64 encoding incomplete: at least 2 bits missing which are a result of the same buffering failure. I hope these diagnostics are helpful. Thanks for maintaining this package! If i can provide any more examples or test cases, please let me know. Regards, --dkg -- System Information: Debian Release: testing/unstable APT prefers testing APT policy: (700, 'testing'), (700, 'stable'), (600, 'unstable') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.12-1-686 Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1) Versions of packages mime-codecs depends on: ii libc6 2.3.5-6 GNU C Library: Shared libraries an mime-codecs recommends no packages. -- no debconf information
test1
Description: Binary data
--- vm/base64-decode.c 2005-11-08 03:38:45.000000000 -0500 +++ vm.basic-fix/base64-decode.c 2005-11-08 03:37:02.000000000 -0500 @@ -4,6 +4,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #ifdef _WIN32 #ifndef WIN32 @@ -22,7 +23,7 @@ main(void) { static char inalphabet[256], decoder[256]; - int i, bits, char_count, errors = 0; + int i, bits = 0, char_count = 0, errors = 0; #ifdef WIN32 _setmode( _fileno(stdout), _O_BINARY); @@ -47,9 +48,6 @@ len=fread(buf, sizeof(c), BUFLEN, stdin); if(!len) continue; -cont_buffer: - char_count = 0; - bits = 0; while(pos<len) { c=buf[pos++]; if (c == '=') @@ -68,17 +66,20 @@ bits <<= 6; } } + fwrite(outbuf, sizeof(char), (out-outbuf), stdout); + } + switch (char_count) { case 1: fprintf(stderr, "base64-decode: base64 encoding incomplete: at least 2 bits missing"); errors++; break; case 2: - *out++ = ((bits >> 10)); + fputc((bits >> 10), stdout); break; case 3: - *out++ = ((bits >> 16)); - *out++ = (((bits >> 8) & 0xff)); + fputc((bits >> 16), stdout); + fputc(((bits >> 8) & 0xff), stdout); break; case 0: break; @@ -86,9 +87,5 @@ fprintf(stderr, "base64-decode: base64 encoding incomplete: at least %d bits truncated", ((4 - char_count) * 6)); } - if(pos<len) // did not proceed the whole thing, continue - goto cont_buffer; - fwrite(outbuf, sizeof(char), (out-outbuf), stdout); - } exit(errors ? 1 : 0); }