talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 70ce86405fd0e7b24fbf6f7ff5bc19d49e7b2147
parent f9259e9578b3f7cfdf66f119d2df744a39b0da3c
Author: Colin Leroy <colin@colino.net>
Date:   Wed, 25 Aug 2010 06:37:16 +0000

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

Diffstat:
MAUTHORS | 1+
MChangeLog | 10++++++++++
MPATCHSETS | 1+
Mconfigure.ac | 2+-
Msrc/common/base64.c | 42++++++++++++++++++++++--------------------
Msrc/common/base64.h | 3++-
Msrc/gtk/authors.h | 1+
Msrc/procmime.c | 9+++++----
8 files changed, 43 insertions(+), 26 deletions(-)

diff --git 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 diff --git 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 diff --git a/PATCHSETS b/PATCHSETS @@ -4026,3 +4026,4 @@ ( 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 diff --git a/configure.ac b/configure.ac @@ -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= diff --git a/src/common/base64.c b/src/common/base64.c @@ -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; } diff --git a/src/common/base64.h b/src/common/base64.h @@ -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__ */ diff --git a/src/gtk/authors.h b/src/gtk/authors.h @@ -176,6 +176,7 @@ static char *CONTRIBS_LIST[] = { "HIRAMATSU Masami", "Yasuzaki Masayoshi", "Jason McCarver", +"Yotam Medini", "David Mehrmann", "Christian Mertes", "Bram Metsch", diff --git a/src/procmime.c b/src/procmime.c @@ -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),