2010-08-25 [colin] 3.7.6cvs31
authorColin Leroy <colin@colino.net>
Wed, 25 Aug 2010 06:37:16 +0000 (06:37 +0000)
committerColin Leroy <colin@colino.net>
Wed, 25 Aug 2010 06:37:16 +0000 (06:37 +0000)
* src/procmime.c
* AUTHORS
* src/gtk/authors.h
* src/common/base64.c
* src/common/base64.h
Fix bug #2245, "base64 decoding fails with line breaks"
Patch by Yotam Medini

AUTHORS
ChangeLog
PATCHSETS
configure.ac
src/common/base64.c
src/common/base64.h
src/gtk/authors.h
src/procmime.c

diff --git a/AUTHORS b/AUTHORS
index 5804363..a254aa9 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -279,3 +279,4 @@ contributors (in addition to the above; based on Changelog)
        Jacob Head
        Fabian Keil
        Didier Barvaux
+       Yotam Medini
index f10b062..8f8be4e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-08-25 [colin]     3.7.6cvs31
+
+       * src/procmime.c
+       * AUTHORS
+       * src/gtk/authors.h
+       * src/common/base64.c
+       * src/common/base64.h
+               Fix bug #2245, "base64 decoding fails with line breaks"
+               Patch by Yotam Medini
+
 2010-08-25 [colin]     3.7.6cvs30
 
        * src/main.c
index b0bdf5b..86edbe3 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.115.2.227 -r 1.115.2.228 src/main.c;  ) > 3.7.6cvs28.patchset
 ( cvs diff -u -r 1.149.2.100 -r 1.149.2.101 src/inc.c;  cvs diff -u -r 1.17.2.56 -r 1.17.2.57 src/send_message.c;  cvs diff -u -r 1.5.2.26 -r 1.5.2.27 src/statusbar.c;  cvs diff -u -r 1.43.2.116 -r 1.43.2.117 src/toolbar.c;  ) > 3.7.6cvs29.patchset
 ( cvs diff -u -r 1.115.2.228 -r 1.115.2.229 src/main.c;  ) > 3.7.6cvs30.patchset
+( cvs diff -u -r 1.49.2.132 -r 1.49.2.133 src/procmime.c;  cvs diff -u -r 1.100.2.74 -r 1.100.2.75 AUTHORS;  cvs diff -u -r 1.1.2.67 -r 1.1.2.68 src/gtk/authors.h;  cvs diff -u -r 1.1.4.9 -r 1.1.4.10 src/common/base64.c;  cvs diff -u -r 1.1.4.7 -r 1.1.4.8 src/common/base64.h;  ) > 3.7.6cvs31.patchset
index d0d4d82..081ff6c 100644 (file)
@@ -12,7 +12,7 @@ MINOR_VERSION=7
 MICRO_VERSION=6
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=30
+EXTRA_VERSION=31
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 9d754b2..4128b2f 100644 (file)
@@ -128,9 +128,12 @@ void base64_decoder_free(Base64Decoder *decoder)
 }
 
 gint base64_decoder_decode(Base64Decoder *decoder,
-                          const gchar *in, guchar *out)
+                          const gchar *in, guchar *out, gint inlen)
 {
+       const gchar *in_end = in + inlen;
        gint len, total_len = 0;
+       gboolean in_more = inlen > 0;
+       gboolean got_eq = FALSE;
        gint buf_len;
        gchar buf[4];
 
@@ -138,32 +141,31 @@ gint base64_decoder_decode(Base64Decoder *decoder,
        cm_return_val_if_fail(in != NULL, -1);
        cm_return_val_if_fail(out != NULL, -1);
 
+       /* Start with previous saved tail */    
        buf_len = decoder->buf_len;
        memcpy(buf, decoder->buf, sizeof(buf));
 
-       for (;;) {
-               while (buf_len < 4) {
+       while (in_more) {
+               while (buf_len < 4 && in_more) {
                        gchar c = *in;
 
                        in++;
-                       if (c == '\0') break;
-                       if (c == '\r' || c == '\n') continue;
-                       if (c != '=' && BASE64VAL(c) == -1)
-                               return -1;
-                       buf[buf_len++] = c;
+                       got_eq = (c == '=');
+                       if (got_eq || BASE64VAL(c) >= 0)
+                               buf[buf_len++] = c;
+                       in_more = (in < in_end) && !(got_eq && (buf_len == 4));
                }
-               if (buf_len < 4 || buf[0] == '=' || buf[1] == '=') {
-                       decoder->buf_len = buf_len;
-                       memcpy(decoder->buf, buf, sizeof(buf));
-                       return total_len;
-               }
-               len = base64_decode(out, buf, 4);
-               out += len;
-               total_len += len;
-               buf_len = 0;
-               if (len < 3) {
-                       decoder->buf_len = 0;
-                       return total_len;
+               if (buf_len == 4) {
+                       len = base64_decode(out, buf, 4);
+                       out += len;
+                       total_len += len;
+                       buf_len = 0;
                }
        }
+       if (buf_len < 4) { 
+               /* Save tail for next iteration call. It wll be ignored if ends here. */
+               decoder->buf_len = buf_len;
+               memcpy(decoder->buf, buf, buf_len);
+       }
+       return total_len;
 }
index 0d3aafc..8bcf83b 100644 (file)
@@ -43,6 +43,7 @@ Base64Decoder *base64_decoder_new     (void);
 void          base64_decoder_free      (Base64Decoder  *decoder);
 gint          base64_decoder_decode    (Base64Decoder  *decoder,
                                         const gchar    *in,
-                                        guchar         *out);
+                                        guchar         *out,
+                                        gint           inlen);
 
 #endif /* __BASE64_H__ */
index c02c6f9..facf084 100644 (file)
@@ -176,6 +176,7 @@ static char *CONTRIBS_LIST[] = {
 "HIRAMATSU Masami",
 "Yasuzaki Masayoshi",
 "Jason McCarver",
+"Yotam Medini",
 "David Mehrmann",
 "Christian Mertes",
 "Bram Metsch",
index 2365be5..88b9c18 100644 (file)
@@ -345,7 +345,7 @@ gboolean procmime_decode_content(MimeInfo *mimeinfo)
                        FLUSH_LASTLINE();
        } else if (encoding == ENC_BASE64) {
                gchar outbuf[BUFFSIZE];
-               gint len;
+               gint len, inlen, inread;
                Base64Decoder *decoder;
                gboolean got_error = FALSE;
                gboolean uncanonicalize = FALSE;
@@ -366,14 +366,15 @@ gboolean procmime_decode_content(MimeInfo *mimeinfo)
                }
 
                decoder = base64_decoder_new();
-               while ((ftell(infp) < readend) && (fgets(buf, sizeof(buf), infp) != NULL)) {
-                       len = base64_decoder_decode(decoder, buf, outbuf);
+               while ((inlen = MIN(readend - ftell(infp), sizeof(buf))) > 0 && !err) {
+                       inread = fread(buf, 1, inlen, infp);
+                       len = base64_decoder_decode(decoder, buf, outbuf, inread);
                        if (uncanonicalize == TRUE && strlen(outbuf) < len && starting) {
                                uncanonicalize = FALSE;
                                null_bytes = TRUE;
                        }
                        starting = FALSE;
-                       if (len < 0 && !got_error) {
+                       if (((inread != inlen) || len < 0) && !got_error) {
                                g_warning("Bad BASE64 content.\n");
                                if (fwrite(_("[Error decoding BASE64]\n"),
                                        sizeof(gchar),