2005-03-18 [paul] 1.0.3cvs2.4
authorPaul Mangan <paul@claws-mail.org>
Fri, 18 Mar 2005 07:56:55 +0000 (07:56 +0000)
committerPaul Mangan <paul@claws-mail.org>
Fri, 18 Mar 2005 07:56:55 +0000 (07:56 +0000)
* src/addrharvest.c
* src/codeconv.c
* src/codeconv.h
* src/compose.c
* src/news.c
* src/procheader.c
* src/procmime.c
* src/unmime.c
* src/unmime.h
fix buffer overflow, CAN-2005-0667, see
http://secunia.com/advisories/14491/
Patch by Alfons

12 files changed:
ChangeLog-gtk2.claws
PATCHSETS
configure.ac
src/addrharvest.c
src/codeconv.c
src/codeconv.h
src/compose.c
src/news.c
src/procheader.c
src/procmime.c
src/unmime.c
src/unmime.h

index b2e3741..5bfa732 100644 (file)
@@ -1,3 +1,18 @@
+2005-03-18 [paul]      1.0.3cvs2.4
+
+       * src/addrharvest.c
+       * src/codeconv.c
+       * src/codeconv.h
+       * src/compose.c
+       * src/news.c
+       * src/procheader.c
+       * src/procmime.c
+       * src/unmime.c
+       * src/unmime.h
+               fix buffer overflow, CAN-2005-0667, see
+               http://secunia.com/advisories/14491/
+               Patch by Alfons
+
 2005-03-17 [colin]     1.0.3cvs2.3
 
        * src/prefs_fonts.c
index ce6a2ad..d3e28d2 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.2504.2.52 -r 1.2504.2.53 ChangeLog.claws; cvs diff -u -r 1.654.2.445 -r 1.654.2.446 configure.ac; cvs diff -u -r 1.53.2.8 -r 1.53.2.9 po/POTFILES.in; cvs diff -u -r 1.14.2.15 -r 1.14.2.16 src/plugins/trayicon/trayicon.c; ) > 1.0.3cvs2.1.patchset
 ( cvs diff -u -r 1.5.2.12 -r 1.5.2.13 src/gtk/pluginwindow.c; ) > 1.0.3cvs2.2.patchset
 ( cvs diff -u -r 1.4.2.8 -r 1.4.2.9 src/prefs_fonts.c; cvs diff -u -r 1.395.2.58 -r 1.395.2.59 src/summaryview.c; ) > 1.0.3cvs2.3.patchset
+( cvs diff -u -r 1.6.10.3 -r 1.6.10.4 src/addrharvest.c; cvs diff -u -r 1.65.2.25 -r 1.65.2.26 src/codeconv.c; cvs diff -u -r 1.15.2.5 -r 1.15.2.6 src/codeconv.h; cvs diff -u -r 1.382.2.110 -r 1.382.2.111 src/compose.c; cvs diff -u -r 1.101.2.8 -r 1.101.2.9 src/news.c; cvs diff -u -r 1.47.2.16 -r 1.47.2.17 src/procheader.c; cvs diff -u -r 1.49.2.35 -r 1.49.2.36 src/procmime.c; cvs diff -u -r 1.8.2.3 -r 1.8.2.4 src/unmime.c; cvs diff -u -r 1.2 -r 1.3 src/unmime.h; ) > 1.0.3cvs2.4.patchset
index 6b1891e..f684ced 100644 (file)
@@ -13,7 +13,7 @@ INTERFACE_AGE=0
 BINARY_AGE=0
 EXTRA_VERSION=2
 EXTRA_RELEASE=
-EXTRA_GTK2_VERSION=.3
+EXTRA_GTK2_VERSION=.4
 
 if test \( $EXTRA_VERSION -eq 0 \) -o \( "x$EXTRA_RELEASE" != "x" \); then
     VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}${EXTRA_RELEASE}${EXTRA_GTK2_VERSION}
index e6f00ea..e80a8e8 100644 (file)
@@ -555,8 +555,10 @@ static void addrharvest_parse_address(
                                name = "";
                        }
                        else {
-                               name = buffer;
-                               conv_unmime_header_overwrite(name);
+                                gchar *tmp = conv_unmime_header(buffer, NULL);
+                                strncpy2(buffer, tmp, sizeof buffer);
+                                name = buffer;
+                                g_free(tmp);
                        }
 
                        /* Insert into address book */
index 89a2e5a..4d2c74d 100644 (file)
@@ -21,6 +21,8 @@
 #  include "config.h"
 #endif
 
+#include "defs.h"
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <string.h>
@@ -1541,37 +1543,33 @@ const gchar *conv_get_current_locale(void)
        return cur_locale;
 }
 
-void conv_unmime_header_overwrite(gchar *str)
+gchar *conv_unmime_header(const gchar *str, const gchar *default_encoding)
 {
-       gchar *buf;
-       gint buflen;
-
-       buflen = strlen(str) * 2 + 1;
-       Xalloca(buf, buflen, return);
+       gchar buf[BUFFSIZE];
 
-       if (conv_get_locale_charset() == C_EUC_JP)
-               conv_anytodisp(buf, buflen, str);
-       else
-               conv_localetodisp(buf, buflen, str);
+       if (is_ascii_str(str))
+               return unmime_header(str);
 
-       unmime_header(str, buf);
-}
+       if (default_encoding) {
+               gchar *utf8_buf;
 
-void conv_unmime_header(gchar *outbuf, gint outlen, const gchar *str,
-                       const gchar *charset)
-{
-       gchar *buf;
-       gint buflen;
+               utf8_buf = conv_codeset_strdup
+                       (str, default_encoding, CS_INTERNAL);
+               if (utf8_buf) {
+                       gchar *decoded_str;
 
-       buflen = strlen(str) * 2 + 1;
-       Xalloca(buf, buflen, return);
+                       decoded_str = unmime_header(utf8_buf);
+                       g_free(utf8_buf);
+                       return decoded_str;
+               }
+       }
 
        if (conv_get_locale_charset() == C_EUC_JP)
-               conv_anytodisp(buf, buflen, str);
+               conv_anytodisp(buf, sizeof(buf), str);
        else
-               conv_localetodisp(buf, buflen, str);
+               conv_localetodisp(buf, sizeof(buf), str);
 
-       unmime_header(outbuf, buf);
+       return unmime_header(buf);
 }
 
 #define MAX_LINELEN            76
index abd2a98..9139f54 100644 (file)
@@ -208,11 +208,8 @@ gboolean conv_is_multibyte_encoding                (CharSet         encoding);
 
 const gchar *conv_get_current_locale           (void);
 
-void conv_unmime_header_overwrite      (gchar          *str);
-void conv_unmime_header                        (gchar          *outbuf,
-                                        gint            outlen,
-                                        const gchar    *str,
-                                        const gchar    *charset);
+gchar *conv_unmime_header              (const gchar    *str,
+                                         const gchar   *default_encoding);
 void conv_encode_header                        (gchar          *dest,
                                         gint            len,
                                         const gchar    *src,
index 674b2f2..e8ca331 100644 (file)
@@ -1669,13 +1669,14 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
        fclose(fp);
 
        if (hentry[H_REPLY_TO].body != NULL) {
-               conv_unmime_header_overwrite(hentry[H_REPLY_TO].body);
-               compose->replyto = hentry[H_REPLY_TO].body;
+               compose->replyto =
+                       conv_unmime_header(hentry[H_REPLY_TO].body, NULL);
+               g_free(hentry[H_REPLY_TO].body);
                hentry[H_REPLY_TO].body = NULL;
        }
        if (hentry[H_CC].body != NULL) {
-               conv_unmime_header_overwrite(hentry[H_CC].body);
-               compose->cc = hentry[H_CC].body;
+               compose->cc = conv_unmime_header(hentry[H_CC].body, NULL);
+               g_free(hentry[H_CC].body);
                hentry[H_CC].body = NULL;
        }
        if (hentry[H_REFERENCES].body != NULL) {
@@ -1689,21 +1690,20 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
                hentry[H_REFERENCES].body = NULL;
        }
        if (hentry[H_BCC].body != NULL) {
-               if (compose->mode == COMPOSE_REEDIT) {
-                       conv_unmime_header_overwrite(hentry[H_BCC].body);
-                       compose->bcc = hentry[H_BCC].body;
-               } else
-                       g_free(hentry[H_BCC].body);
+               if (compose->mode == COMPOSE_REEDIT)
+                       compose->bcc =
+                               conv_unmime_header(hentry[H_BCC].body, NULL);
+               g_free(hentry[H_BCC].body);
                hentry[H_BCC].body = NULL;
        }
        if (hentry[H_NEWSGROUPS].body != NULL) {
-               conv_unmime_header_overwrite(hentry[H_NEWSGROUPS].body);
                compose->newsgroups = hentry[H_NEWSGROUPS].body;
                hentry[H_NEWSGROUPS].body = NULL;
        }
        if (hentry[H_FOLLOWUP_TO].body != NULL) {
-               conv_unmime_header_overwrite(hentry[H_FOLLOWUP_TO].body);
-               compose->followup_to = hentry[H_FOLLOWUP_TO].body;
+               compose->followup_to =
+                       conv_unmime_header(hentry[H_FOLLOWUP_TO].body, NULL);
+               g_free(hentry[H_FOLLOWUP_TO].body);
                hentry[H_FOLLOWUP_TO].body = NULL;
        }
        if (hentry[H_LIST_POST].body != NULL) {
index d4d2f1a..ea361dc 100644 (file)
@@ -608,7 +608,6 @@ static gint news_select_group(NNTPSession *session, const gchar *group,
 static MsgInfo *news_parse_xover(const gchar *xover_str)
 {
        MsgInfo *msginfo;
-       gchar buf[NNTPBUFSIZE];
        gchar *subject, *sender, *size, *line, *date, *msgid, *ref, *tmp;
        gchar *p;
        gint num, size_int, line_int;
@@ -648,12 +647,10 @@ static MsgInfo *news_parse_xover(const gchar *xover_str)
        msginfo->date = g_strdup(date);
        msginfo->date_t = procheader_date_parse(NULL, date, 0);
 
-       conv_unmime_header(buf, sizeof(buf), sender, NULL);
-       msginfo->from = g_strdup(buf);
-       msginfo->fromname = procheader_get_fromname(buf);
+        msginfo->from = conv_unmime_header(sender, NULL);
+       msginfo->fromname = procheader_get_fromname(msginfo->from);
 
-       conv_unmime_header(buf, sizeof(buf), subject, NULL);
-       msginfo->subject = g_strdup(buf);
+        msginfo->subject = conv_unmime_header(subject, NULL);
 
        extract_parenthesis(msgid, '<', '>');
        remove_space(msgid);
index 49b2d73..398f93b 100644 (file)
@@ -412,7 +412,6 @@ gboolean procheader_headername_equal(char * hdr1, char * hdr2)
 
 Header * procheader_parse_header(gchar * buf)
 {
-       gchar tmp[BUFFSIZE];
        gchar *p = buf;
        Header * header;
 
@@ -425,11 +424,7 @@ Header * procheader_parse_header(gchar * buf)
                        header->name = g_strndup(buf, p - buf + 1);
                        p++;
                        while (*p == ' ' || *p == '\t') p++;
-                       conv_unmime_header(tmp, sizeof(tmp), p, NULL);
-                       if(tmp == NULL) 
-                               header->body = g_strdup(p);
-                       else    
-                               header->body = g_strdup(tmp);
+                        header->body = conv_unmime_header(p, NULL);
                        return header;
                }
        }
@@ -582,9 +577,9 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                             gboolean full, gboolean decrypted)
 {
        MsgInfo *msginfo;
-       gchar buf[BUFFSIZE], tmp[BUFFSIZE];
+       gchar buf[BUFFSIZE];
        gchar *reference = NULL;
-       gchar *p;
+       gchar *p, *tmp;
        gchar *hp;
        HeaderEntry *hentry;
        gint hnum;
@@ -622,12 +617,11 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                        break;
                case H_FROM:
                        if (msginfo->from) break;
-                       conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
-                       msginfo->from = g_strdup(tmp);
-                       msginfo->fromname = procheader_get_fromname(tmp);
+                        msginfo->from = conv_unmime_header(hp, NULL);
+                       msginfo->fromname = procheader_get_fromname(msginfo->from);
                        break;
                case H_TO:
-                       conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
+                        tmp = conv_unmime_header(hp, NULL);
                        if (msginfo->to) {
                                p = msginfo->to;
                                msginfo->to =
@@ -635,9 +629,10 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                                g_free(p);
                        } else
                                msginfo->to = g_strdup(tmp);
+                        g_free(tmp);                                
                        break;
                case H_CC:
-                       conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
+                        tmp = conv_unmime_header(hp, NULL);
                        if (msginfo->cc) {
                                p = msginfo->cc;
                                msginfo->cc =
@@ -645,6 +640,7 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                                g_free(p);
                        } else
                                msginfo->cc = g_strdup(tmp);
+                        g_free(tmp);                                
                        break;
                case H_NEWSGROUPS:
                        if (msginfo->newsgroups) {
@@ -657,8 +653,7 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                        break;
                case H_SUBJECT:
                        if (msginfo->subject) break;
-                       conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
-                       msginfo->subject = g_strdup(tmp);
+                        msginfo->subject = conv_unmime_header(hp, NULL);
                        break;
                case H_MSG_ID:
                        if (msginfo->msgid) break;
index 6add501..467dd54 100644 (file)
@@ -1227,6 +1227,7 @@ void procmime_parse_message_rfc822(MimeInfo *mimeinfo)
        guint content_start, i;
        FILE *fp;
        gint mime_major, mime_minor;
+        gchar *tmp;
 
        procmime_decode_content(mimeinfo);
 
@@ -1237,12 +1238,21 @@ void procmime_parse_message_rfc822(MimeInfo *mimeinfo)
        }
        fseek(fp, mimeinfo->offset, SEEK_SET);
        procheader_get_header_fields(fp, hentry);
-       if (hentry[0].body != NULL)
-               conv_unmime_header_overwrite(hentry[0].body);
-       if (hentry[2].body != NULL)
-               conv_unmime_header_overwrite(hentry[2].body);
-       if (hentry[4].body != NULL)
-               conv_unmime_header_overwrite(hentry[4].body);
+       if (hentry[0].body != NULL) {
+                tmp = conv_unmime_header(hentry[0].body, NULL);
+                g_free(hentry[0].body);
+                hentry[0].body = tmp;
+        }                
+       if (hentry[2].body != NULL) {
+                tmp = conv_unmime_header(hentry[2].body, NULL);
+                g_free(hentry[2].body);
+                hentry[2].body = tmp;
+        }                
+       if (hentry[4].body != NULL) {
+                tmp = conv_unmime_header(hentry[4].body, NULL);
+                g_free(hentry[4].body);
+                hentry[4].body = tmp;
+        }                
        content_start = ftell(fp);
        fclose(fp);
 
@@ -1287,7 +1297,7 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
                                {"Content-Disposition:",
                                                   NULL, TRUE},
                                {NULL,             NULL, FALSE}};
-       gchar *p;
+       gchar *p, *tmp;
        gchar *boundary;
        gint boundary_len = 0, lastoffset = -1, i;
        gchar buf[BUFFSIZE];
@@ -1329,12 +1339,21 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
                                hentry[i].body = NULL;
                        }
                        procheader_get_header_fields(fp, hentry);
-                       if (hentry[0].body != NULL)
-                               conv_unmime_header_overwrite(hentry[0].body);
-                       if (hentry[2].body != NULL)
-                               conv_unmime_header_overwrite(hentry[2].body);
-                       if (hentry[4].body != NULL)
-                               conv_unmime_header_overwrite(hentry[4].body);
+                        if (hentry[0].body != NULL) {
+                                tmp = conv_unmime_header(hentry[0].body, NULL);
+                                g_free(hentry[0].body);
+                                hentry[0].body = tmp;
+                        }                
+                        if (hentry[2].body != NULL) {
+                                tmp = conv_unmime_header(hentry[2].body, NULL);
+                                g_free(hentry[2].body);
+                                hentry[2].body = tmp;
+                        }                
+                        if (hentry[4].body != NULL) {
+                                tmp = conv_unmime_header(hentry[4].body, NULL);
+                                g_free(hentry[4].body);
+                                hentry[4].body = tmp;
+                        }                
                        lastoffset = ftell(fp);
                }
        }
index 65d279f..1365c3c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2005 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 /* Decodes headers based on RFC2045 and RFC2047. */
 
-void unmime_header(gchar *out, const gchar *str)
+gchar *unmime_header(const gchar *encoded_str)
 {
-       const gchar *p = str;
-       gchar *outp = out;
+       const gchar *p = encoded_str;
        const gchar *eword_begin_p, *encoding_begin_p, *text_begin_p,
                    *eword_end_p;
        gchar charset[32];
        gchar encoding;
        gchar *conv_str;
-       gint len;
+       GString *outbuf;
+       gchar *out_str;
+       gsize out_len;
+
+       outbuf = g_string_sized_new(strlen(encoded_str) * 2);
 
        while (*p != '\0') {
                gchar *decoded_text = NULL;
+               gint len;
 
                eword_begin_p = strstr(p, ENCODED_WORD_BEGIN);
                if (!eword_begin_p) {
-                       strcpy(outp, p);
-                       return;
+                       g_string_append(outbuf, p);
+                       break;
                }
                encoding_begin_p = strchr(eword_begin_p + 2, '?');
                if (!encoding_begin_p) {
-                       strcpy(outp, p);
-                       return;
+                       g_string_append(outbuf, p);
+                       break;
                }
                text_begin_p = strchr(encoding_begin_p + 1, '?');
                if (!text_begin_p) {
-                       strcpy(outp, p);
-                       return;
+                       g_string_append(outbuf, p);
+                       break;
                }
                eword_end_p = strstr(text_begin_p + 1, ENCODED_WORD_END);
                if (!eword_end_p) {
-                       strcpy(outp, p);
-                       return;
+                       g_string_append(outbuf, p);
+                       break;
                }
 
-               if (p == str) {
-                       memcpy(outp, p, eword_begin_p - p);
-                       outp += eword_begin_p - p;
+               if (p == encoded_str) {
+                       g_string_append_len(outbuf, p, eword_begin_p - p);
                        p = eword_begin_p;
                } else {
                        /* ignore spaces between encoded words */
                        const gchar *sp;
 
                        for (sp = p; sp < eword_begin_p; sp++) {
-                               if (!isspace(*(const guchar *)sp)) {
-                                       memcpy(outp, p, eword_begin_p - p);
-                                       outp += eword_begin_p - p;
+                               if (!g_ascii_isspace(*sp)) {
+                                       g_string_append_len
+                                               (outbuf, p, eword_begin_p - p);
                                        p = eword_begin_p;
                                        break;
                                }
@@ -91,7 +94,7 @@ void unmime_header(gchar *out, const gchar *str)
                          encoding_begin_p - (eword_begin_p + 2));
                memcpy(charset, eword_begin_p + 2, len);
                charset[len] = '\0';
-               encoding = toupper(*(encoding_begin_p + 1));
+               encoding = g_ascii_toupper(*(encoding_begin_p + 1));
 
                if (encoding == 'B') {
                        decoded_text = g_malloc
@@ -106,28 +109,28 @@ void unmime_header(gchar *out, const gchar *str)
                                (decoded_text, text_begin_p + 1,
                                 eword_end_p - (text_begin_p + 1));
                } else {
-                       memcpy(outp, p, eword_end_p + 2 - p);
-                       outp += eword_end_p + 2 - p;
+                       g_string_append_len(outbuf, p, eword_end_p + 2 - p);
                        p = eword_end_p + 2;
                        continue;
                }
 
                /* convert to UTF-8 */
                conv_str = conv_codeset_strdup(decoded_text, charset, NULL);
-               if (conv_str) {
-                       len = strlen(conv_str);
-                       memcpy(outp, conv_str, len);
-                       g_free(conv_str);
-               } else {
-                       len = strlen(decoded_text);
-                       conv_utf8todisp(outp, len + 1, decoded_text);
+               if (!conv_str) {
+                       conv_str = g_malloc(len + 1);
+                       conv_utf8todisp(conv_str, len + 1, decoded_text);
                }
-               outp += len;
+               g_string_append(outbuf, conv_str);
+               g_free(conv_str);
 
                g_free(decoded_text);
 
                p = eword_end_p + 2;
        }
 
-       *outp = '\0';
+       out_str = outbuf->str;
+       out_len = outbuf->len;
+       g_string_free(outbuf, FALSE);
+
+       return g_realloc(out_str, out_len + 1);
 }
index 8e6d839..be9f390 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2005 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,8 +22,6 @@
 
 #include <glib.h>
 
-void unmime_header                     (gchar          *out,
-                                        const gchar    *str);
-gint unmime_quoted_printable_line      (gchar          *str);
+gchar *unmime_header   (const gchar    *encoded_str);
 
 #endif /* __UNMIME_H__ */