Fix bug 3571, 'recipient list lost and truncated'
authorwwp <wwp@free.fr>
Mon, 16 Jan 2017 15:35:13 +0000 (16:35 +0100)
committerwwp <wwp@free.fr>
Mon, 16 Jan 2017 15:35:13 +0000 (16:35 +0100)
by replacing lots of fixed-size buffers with dynamically
allocated ones.
Also enforce checks by adding or fixing few sanity tests,
fix returned value of some functions in some tricky cases.

12 files changed:
src/account.c
src/common/utils.c
src/compose.c
src/filtering.c
src/matcher.c
src/messageview.c
src/plugins/perl/perl_plugin.c
src/plugins/python/messageinfotype.c
src/plugins/spam_report/spam_report.c
src/procheader.c
src/procheader.h
src/procmsg.c

index 9c34f97..9c44ef0 100644 (file)
@@ -1402,13 +1402,14 @@ PrefsAccount *account_get_reply_account(MsgInfo *msginfo, gboolean reply_autosel
        else if (folder_has_parent_of_type(msginfo->folder, F_QUEUE) ||
                 folder_has_parent_of_type(msginfo->folder, F_OUTBOX) ||
                 folder_has_parent_of_type(msginfo->folder, F_DRAFT)) {
-                       gchar from[BUFFSIZE];
+                       gchar *from = NULL;
                        if (!procheader_get_header_from_msginfo
-                               (msginfo, from, sizeof from, "From:")) {
+                               (msginfo, &from, "From:")) {
                                gchar *buf = from + strlen("From:");
                                extract_address(buf);
                                account = account_find_from_address(buf, FALSE);
-                       }
+                       g_free(from);
+                       }
        }
        /* select account by to: and cc: header if enabled */
        if (reply_autosel) {
@@ -1438,13 +1439,14 @@ PrefsAccount *account_get_reply_account(MsgInfo *msginfo, gboolean reply_autosel
                        }
                }
                if (!account) {
-                       gchar deliveredto[BUFFSIZE];
+                       gchar *deliveredto = NULL;
                        if (!procheader_get_header_from_msginfo
-                               (msginfo, deliveredto,sizeof deliveredto , "Delivered-To:")) { 
+                               (msginfo, &deliveredto, "Delivered-To:")) {
                                gchar *buf = deliveredto + strlen("Delivered-To:");
                                extract_address(buf);
                                account = account_find_from_address(buf, FALSE);
-                       }
+                       g_free(deliveredto);
+                       }
                }
        }
 
index 10c3764..b13d09a 100644 (file)
@@ -1604,7 +1604,6 @@ gint scan_mailto_url(const gchar *mailto, gchar **from, gchar **to, gchar **cc,
                                g_warning("couldn't set insert file '%s' in body", value);
                        }
                        g_free(tmp);
-                       tmp = NULL;
                } else if (attach && !g_ascii_strcasecmp(field, "attach")) {
                        int i = 0;
                        gchar *tmp = decode_uri_gdup(value);
@@ -1613,7 +1612,6 @@ gint scan_mailto_url(const gchar *mailto, gchar **from, gchar **to, gchar **cc,
                                        g_print("Refusing to attach '%s', potential private data leak\n",
                                                        tmp);
                                        g_free(tmp);
-                                       tmp = NULL;
                                        break;
                                }
                        }
index bdb14b4..3308f3c 100644 (file)
@@ -2224,7 +2224,6 @@ Compose *compose_reedit(MsgInfo *msginfo, gboolean batch)
        GtkTextMark *mark;
        GtkTextIter iter;
        FILE *fp;
-       gchar buf[BUFFSIZE];
        gboolean use_signing = FALSE;
        gboolean use_encryption = FALSE;
        gchar *privacy_system = NULL;
@@ -2244,124 +2243,141 @@ Compose *compose_reedit(MsgInfo *msginfo, gboolean batch)
         if (folder_has_parent_of_type(msginfo->folder, F_QUEUE) ||
            folder_has_parent_of_type(msginfo->folder, F_DRAFT) ||
            folder_has_parent_of_type(msginfo->folder, F_OUTBOX)) {
-               gchar queueheader_buf[BUFFSIZE];
+               gchar *queueheader_buf = NULL;
                gint id, param;
 
                /* Select Account from queue headers */
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Claws-Account-Id:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                                       "X-Claws-Account-Id:")) {
                        id = atoi(&queueheader_buf[strlen("X-Claws-Account-Id:")]);
                        account = account_find_from_id(id);
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Sylpheed-Account-Id:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                                       "X-Sylpheed-Account-Id:")) {
                        id = atoi(&queueheader_buf[strlen("X-Sylpheed-Account-Id:")]);
                        account = account_find_from_id(id);
+                       g_free(queueheader_buf);
                }
-               if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "NAID:")) {
+               if (!account && !procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                                       "NAID:")) {
                        id = atoi(&queueheader_buf[strlen("NAID:")]);
                        account = account_find_from_id(id);
+                       g_free(queueheader_buf);
                }
-               if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                                   sizeof(queueheader_buf), "MAID:")) {
+               if (!account && !procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                                       "MAID:")) {
                        id = atoi(&queueheader_buf[strlen("MAID:")]);
                        account = account_find_from_id(id);
+                       g_free(queueheader_buf);
                }
-               if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                                               sizeof(queueheader_buf), "S:")) {
+               if (!account && !procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                                       "S:")) {
                        account = account_find_from_address(queueheader_buf, FALSE);
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Claws-Sign:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                               "X-Claws-Sign:")) {
                        param = atoi(&queueheader_buf[strlen("X-Claws-Sign:")]);
                        use_signing = param;
-                       
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Sylpheed-Sign:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                               "X-Sylpheed-Sign:")) {
                        param = atoi(&queueheader_buf[strlen("X-Sylpheed-Sign:")]);
                        use_signing = param;
-                       
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Claws-Encrypt:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                               "X-Claws-Encrypt:")) {
                        param = atoi(&queueheader_buf[strlen("X-Claws-Encrypt:")]);
                        use_encryption = param;
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Sylpheed-Encrypt:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                               "X-Sylpheed-Encrypt:")) {
                        param = atoi(&queueheader_buf[strlen("X-Sylpheed-Encrypt:")]);
                        use_encryption = param;
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Claws-Auto-Wrapping:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                               "X-Claws-Auto-Wrapping:")) {
                        param = atoi(&queueheader_buf[strlen("X-Claws-Auto-Wrapping:")]);
                        autowrap = param;
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Claws-Auto-Indent:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                               "X-Claws-Auto-Indent:")) {
                        param = atoi(&queueheader_buf[strlen("X-Claws-Auto-Indent:")]);
                        autoindent = param;
+                       g_free(queueheader_buf);
                }
-                if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Claws-Privacy-System:")) {
-                        privacy_system = g_strdup(&queueheader_buf[strlen("X-Claws-Privacy-System:")]);
-                }
-                if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Sylpheed-Privacy-System:")) {
-                        privacy_system = g_strdup(&queueheader_buf[strlen("X-Sylpheed-Privacy-System:")]);
-                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Priority: ")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                       "X-Claws-Privacy-System:")) {
+                       privacy_system = g_strdup(&queueheader_buf[strlen("X-Claws-Privacy-System:")]);
+                       g_free(queueheader_buf);
+               }
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                       "X-Sylpheed-Privacy-System:")) {
+                       privacy_system = g_strdup(&queueheader_buf[strlen("X-Sylpheed-Privacy-System:")]);
+                       g_free(queueheader_buf);
+               }
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                               "X-Priority: ")) {
                        param = atoi(&queueheader_buf[strlen("X-Priority: ")]); /* mind the space */
                        priority = param;
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "RMID:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf,
+                                                                                       "RMID:")) {
                        gchar **tokens = g_strsplit(&queueheader_buf[strlen("RMID:")], "\t", 0);
-                       if (tokens[0] && tokens[1] && tokens[2]) {
+                       if (tokens && tokens[0] && tokens[1] && tokens[2]) {
                                FolderItem *orig_item = folder_find_item_from_identifier(tokens[0]);
                                if (orig_item != NULL) {
                                        replyinfo = folder_item_get_msginfo_by_msgid(orig_item, tokens[2]);
                                }
+                               g_strfreev(tokens);
                        }
-                       g_strfreev(tokens);
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "FMID:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, 
+                                                                               "FMID:")) {
                        gchar **tokens = g_strsplit(&queueheader_buf[strlen("FMID:")], "\t", 0);
-                       if (tokens[0] && tokens[1] && tokens[2]) {
+                       if (tokens && tokens[0] && tokens[1] && tokens[2]) {
                                FolderItem *orig_item = folder_find_item_from_identifier(tokens[0]);
                                if (orig_item != NULL) {
                                        fwdinfo = folder_item_get_msginfo_by_msgid(orig_item, tokens[2]);
                                }
+                               g_strfreev(tokens);
                        }
-                       g_strfreev(tokens);
+                       g_free(queueheader_buf);
                }
                /* Get manual headers */
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "X-Claws-Manual-Headers:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf,
+                                                                                       "X-Claws-Manual-Headers:")) {
                        gchar *listmh = g_strdup(&queueheader_buf[strlen("X-Claws-Manual-Headers:")]);
-                       if (*listmh != '\0') {
+                       if (listmh && *listmh != '\0') {
                                debug_print("Got manual headers: %s\n", listmh);
                                manual_headers = procheader_entries_from_str(listmh);
+                               g_free(listmh);
                        }
-                       g_free(listmh);
+                       g_free(queueheader_buf);
                }
        } else {
                account = msginfo->folder->folder->account;
        }
 
        if (!account && prefs_common.reedit_account_autosel) {
-                       gchar from[BUFFSIZE];
-               if (!procheader_get_header_from_msginfo(msginfo, from, sizeof(from), "FROM:")) {
-                       extract_address(from);
-                       account = account_find_from_address(from, FALSE);
-                }
-       }
-        if (!account) {
-               account = cur_account;
-        }
+               gchar *from = NULL;
+               if (!procheader_get_header_from_msginfo(msginfo, &from, "FROM:")) {
+                       extract_address(from);
+                       account = account_find_from_address(from, FALSE);
+                       g_free(from);
+               }
+       }
+       if (!account) {
+               account = cur_account;
+       }
        cm_return_val_if_fail(account != NULL, NULL);
 
        compose = compose_create(account, msginfo->folder, COMPOSE_REEDIT, batch);
@@ -2388,21 +2404,23 @@ Compose *compose_reedit(MsgInfo *msginfo, gboolean batch)
 
        compose_extract_original_charset(compose);
 
-        if (folder_has_parent_of_type(msginfo->folder, F_QUEUE) ||
+       if (folder_has_parent_of_type(msginfo->folder, F_QUEUE) ||
            folder_has_parent_of_type(msginfo->folder, F_DRAFT) ||
            folder_has_parent_of_type(msginfo->folder, F_OUTBOX)) {
-               gchar queueheader_buf[BUFFSIZE];
+               gchar *queueheader_buf = NULL;
 
                /* Set message save folder */
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "SCF:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, "SCF:")) {
                        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), TRUE);
                        compose_set_save_to(compose, &queueheader_buf[4]);
+                       g_free(queueheader_buf);
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "RRCPT:")) {
+               if (!procheader_get_header_from_msginfo(msginfo, &queueheader_buf, "RRCPT:")) {
                        gint active = atoi(&queueheader_buf[strlen("RRCPT:")]);
                        if (active) {
                                cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Options/RequestRetRcpt", TRUE);
                        }
+                       g_free(queueheader_buf);
                }
        }
        
@@ -2437,6 +2455,7 @@ Compose *compose_reedit(MsgInfo *msginfo, gboolean batch)
        }
 
        if (fp != NULL) {
+               gchar buf[BUFFSIZE];
                gboolean prev_autowrap;
                GtkTextBuffer *buffer;
                BLOCK_WRAP();
@@ -5488,7 +5507,8 @@ static gint compose_redirect_write_to_file(Compose *compose, FILE *fdest)
 {
        FILE *fp;
        size_t len;
-       gchar buf[BUFFSIZE];
+       gchar *buf = NULL;
+       gchar rewrite_buf[BUFFSIZE];
        int i = 0;
        gboolean skip = FALSE;
        gboolean err = FALSE;
@@ -5509,24 +5529,34 @@ static gint compose_redirect_write_to_file(Compose *compose, FILE *fdest)
                "X-Claws-Auto-Wrapping:", "X-Claws-Auto-Indent:",
                NULL
                };
+       gint ret = 0;
+
        if ((fp = g_fopen(compose->redirect_filename, "rb")) == NULL) {
                FILE_OP_ERROR(compose->redirect_filename, "fopen");
                return -1;
        }
 
-       while (procheader_get_one_field_asis(buf, sizeof(buf), fp) != -1) {
+       while ((ret = procheader_get_one_field_asis(&buf, fp)) != -1) {
                skip = FALSE;
                for (i = 0; not_included[i] != NULL; i++) {
                        if (g_ascii_strncasecmp(buf, not_included[i],
                                                strlen(not_included[i])) == 0) {
                                skip = TRUE;
+                               g_free(buf);
+                               buf = NULL;
                                break;
                        }
                }
-               if (skip)
+               if (skip) {
+                       g_free(buf);
+                       buf = NULL;
                        continue;
-               if (fputs(buf, fdest) == -1)
+               }
+               if (fputs(buf, fdest) == -1) {
+                       g_free(buf);
+                       buf = NULL;
                        goto error;
+               }
 
                if (!prefs_common.redirect_keep_from) {
                        if (g_ascii_strncasecmp(buf, "From:",
@@ -5549,24 +5579,27 @@ static gint compose_redirect_write_to_file(Compose *compose, FILE *fdest)
                        }
                }
 
+               g_free(buf);
+               buf = NULL;
                if (fputs("\n", fdest) == -1)
                        goto error;
        }
 
-       if (err)
+       if (err || ret == -1)
                goto error;
 
        if (compose_redirect_write_headers(compose, fdest))
                goto error;
 
-       while ((len = fread(buf, sizeof(gchar), sizeof(buf), fp)) > 0) {
-               if (fwrite(buf, sizeof(gchar), len, fdest) != len)
+       while ((len = fread(rewrite_buf, sizeof(gchar), sizeof(rewrite_buf), fp)) > 0) {
+               if (fwrite(rewrite_buf, sizeof(gchar), len, fdest) != len)
                        goto error;
        }
 
        fclose(fp);
 
        return 0;
+
 error:
        fclose(fp);
 
@@ -11813,23 +11846,25 @@ static PrefsAccount *compose_find_account(MsgInfo *msginfo)
        }
 
        if (!account && prefs_common.forward_account_autosel) {
-               gchar cc[BUFFSIZE];
+               gchar *cc = NULL;
                if (!procheader_get_header_from_msginfo
-                       (msginfo, cc,sizeof cc , "Cc:")) { 
+                               (msginfo, &cc, "Cc:")) { 
                        gchar *buf = cc + strlen("Cc:");
-                       extract_address(buf);
-                       account = account_find_from_address(buf, FALSE);
-                }
+                       extract_address(buf);
+                       account = account_find_from_address(buf, FALSE);
+                       g_free(cc);
+               }
        }
        
        if (!account && prefs_common.forward_account_autosel) {
-               gchar deliveredto[BUFFSIZE];
+               gchar *deliveredto = NULL;
                if (!procheader_get_header_from_msginfo
-                       (msginfo, deliveredto,sizeof deliveredto , "Delivered-To:")) { 
+                               (msginfo, &deliveredto, "Delivered-To:")) { 
                        gchar *buf = deliveredto + strlen("Delivered-To:");
-                       extract_address(buf);
-                       account = account_find_from_address(buf, FALSE);
-                }
+                       extract_address(buf);
+                       account = account_find_from_address(buf, FALSE);
+                       g_free(deliveredto);
+               }
        }
 
        if (!account)
index 7b604a8..e4f3d01 100644 (file)
@@ -473,7 +473,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                        AddressBookFile *abf = NULL;
                        ItemFolder *folder = NULL;
 #endif
-                       gchar buf[BUFFSIZE];
+                       gchar *buf;
                        Header *header;
                        gint errors = 0;
 
@@ -490,11 +490,11 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                        abf = book->rawDataSource;
 #endif
                        /* get the header */
-                       if (procheader_get_header_from_msginfo(info, buf, 
-                               sizeof(buf), action->header) < 0)
+                       if (procheader_get_header_from_msginfo(info, &buf, action->header) < 0)
                                return FALSE;
 
                        header = procheader_parse_header(buf);
+                       g_free(buf);
 
                        /* add all addresses that are not already in */
                        if (header && *header->body && (*header->body != '\0')) {
index 64000e1..89b6232 100644 (file)
@@ -1287,10 +1287,10 @@ void matcherlist_free(MatcherList *cond)
  */
 static void matcherlist_skip_headers(FILE *fp)
 {
-       gchar buf[BUFFSIZE];
+       gchar *buf = NULL;
 
-       while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1)
-               ;
+       while (procheader_get_one_field(&buf, fp, NULL) != -1)
+               g_free(buf);
 }
 
 /*!
@@ -1470,9 +1470,10 @@ static gboolean matcherprop_criteria_message(MatcherProp *matcher)
 static gboolean matcherlist_match_headers(MatcherList *matchers, FILE *fp)
 {
        GSList *l;
-       gchar buf[BUFFSIZE];
+       gchar *buf = NULL;
+       gint ret;
 
-       while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1) {
+       while ((ret = procheader_get_one_field(&buf, fp, NULL)) != -1) {
                for (l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) {
                        MatcherProp *matcher = (MatcherProp *) l->data;
                        gint match = MATCH_ANY;
@@ -1537,10 +1538,14 @@ static gboolean matcherlist_match_headers(MatcherList *matchers, FILE *fp)
                        /* if the rule matched and the matchers are OR, no need to
                         * check the others */
                        if (matcher->result && matcher->done) {
-                               if (!matchers->bool_and)
+                               if (!matchers->bool_and) {
+                                       g_free(buf);
                                        return TRUE;
+                               }
                        }
                }
+               g_free(buf);
+               buf = NULL;
        }
 
        return FALSE;
index ac8ab4f..7052ff8 100644 (file)
@@ -771,32 +771,38 @@ void messageview_init(MessageView *messageview)
        noticeview_hide(messageview->noticeview);
 }
 
-static void notification_convert_header(gchar *dest, gint len, 
+static void notification_convert_header(gchar **dest,
                                        const gchar *src_,
                                        gint header_len)
 {
        char *src;
 
        cm_return_if_fail(src_ != NULL);
-       cm_return_if_fail(dest != NULL);
 
-       if (len < 1) return;
+       if (header_len < 1) {
+               *dest = g_strdup("");
+               return;
+       }
 
-       Xstrndup_a(src, src_, len, return);
+       Xstrndup_a(src, src_, strlen(src_), return);
 
        remove_return(src);
 
        if (is_ascii_str(src)) {
-               strncpy2(dest, src, len);
-               dest[len - 1] = '\0';
+               *dest = g_strdup(src);
                return;
-       } else
-               conv_encode_header(dest, len, src, header_len, FALSE);
+       } else {
+               *dest = g_malloc(BUFFSIZE);
+               if (*dest)
+                       conv_encode_header(*dest, sizeof(dest), src, header_len, FALSE);
+               else
+                       debug_print("notification_convert_header: alloc");
+       }
 }
 
 static gint disposition_notification_send(MsgInfo *msginfo)
 {
-       gchar buf[BUFFSIZE];
+       gchar *buf = NULL;
        gchar tmp[MAXPATHLEN + 1];
        FILE *fp;
        GList *ac_list;
@@ -811,6 +817,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
        gchar *foo = NULL;
        gboolean queued_removed = FALSE;
        gchar *boundary = NULL;
+       gchar buf_date[BUFFSIZE];
        gchar *date = NULL;
        gchar *orig_to = NULL;
        gchar *enc_sub = NULL;
@@ -827,8 +834,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
        else
                to = msginfo->extradata->returnreceiptto;
 
-       ok = procheader_get_header_from_msginfo(msginfo, buf, sizeof(buf),
-                               "Return-Path:");
+       ok = procheader_get_header_from_msginfo(msginfo, &buf, "Return-Path:");
        if (ok == 0) {
                gchar *to_addr = g_strdup(to);
                extract_address(to_addr);
@@ -836,8 +842,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                ok = strcasecmp(to_addr, buf);
                g_free(to_addr);
        } else {
-               g_strlcpy(buf, _("<No Return-Path found>"), 
-                               sizeof(buf));
+               buf = g_strdup(_("<No Return-Path found>"));
        }
        
        if (ok != 0) {
@@ -854,9 +859,13 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                                _("_Don't Send"), _("_Send"), NULL, FALSE,
                                NULL, ALERT_WARNING, G_ALERTDEFAULT);
                g_free(message);                                
-               if (val != G_ALERTALTERNATE)
+               if (val != G_ALERTALTERNATE) {
+                       g_free(buf);
                        return -1;
+               }
        }
+       g_free(buf);
+       buf = NULL;
 
        ac_list = account_find_all_from_address(NULL, msginfo->to);
        ac_list = account_find_all_from_address(ac_list, msginfo->cc);
@@ -959,17 +968,21 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                goto FILE_ERROR;
 
        /* Date */
-       get_rfc822_date(buf, sizeof(buf));
+       get_rfc822_date(buf_date, sizeof(buf_date));
        if (fprintf(fp, "Date: %s\n", buf) < 0)
                goto FILE_ERROR;
 
        /* From */
        if (account->name && *account->name) {
-               notification_convert_header
-                       (buf, sizeof(buf), account->name,
-                        strlen("From: "));
-               if (fprintf(fp, "From: %s <%s>\n", buf, account->address) < 0)
+               notification_convert_header(&buf, account->name, strlen("From: "));
+               if (buf == NULL)
+                       goto FILE_ERROR;
+               if (fprintf(fp, "From: %s <%s>\n", buf, account->address) < 0) {
+                       g_free(buf);
                        goto FILE_ERROR;
+               }
+               g_free(buf);
+               buf = NULL;
        } else
                if (fprintf(fp, "From: %s\n", account->address) < 0)
                        goto FILE_ERROR;
@@ -978,10 +991,15 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                goto FILE_ERROR;
 
        /* Subject */
-       notification_convert_header(buf, sizeof(buf), msginfo->subject,
-                                   strlen("Subject: "));
-       if (fprintf(fp, "Subject: Disposition notification: %s\n", buf) < 0)
+       notification_convert_header(&buf, msginfo->subject, strlen("Subject: "));
+       if (buf == NULL)
+               goto FILE_ERROR;
+       if (fprintf(fp, "Subject: Disposition notification: %s\n", buf) < 0) {
+               g_free(buf);
                goto FILE_ERROR;
+       }
+       g_free(buf);
+       buf = NULL;
 
        /* Message ID */
        if (account->gen_msgid) {
@@ -994,8 +1012,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
        }
 
        boundary = generate_mime_boundary("DN");
-       get_rfc822_date(buf, sizeof(buf));
-       date = g_strdup(buf);
+       date = g_strdup(buf_date);
        if (msginfo->to) {
                orig_to = g_strdup(msginfo->to);
                extract_address(orig_to);
index 6db4c41..fc26555 100644 (file)
@@ -651,7 +651,6 @@ static XS(XS_ClawsMail_filter_init)
 static XS(XS_ClawsMail_open_mail_file)
 {
   char *file;
-  gchar buf[BUFFSIZE];
 
   dXSARGS;
   if(items != 0) {
@@ -661,13 +660,13 @@ static XS(XS_ClawsMail_open_mail_file)
   file = procmsg_get_message_file_path(msginfo);
   if(!file)
     XSRETURN_UNDEF;
-  strncpy2(buf,file,sizeof(buf));
-  g_free(file);
-  if((message_file = fopen(buf, "rb")) == NULL) {
-    FILE_OP_ERROR(buf, "fopen");
+  if((message_file = fopen(file, "rb")) == NULL) {
+    FILE_OP_ERROR(file, "fopen");
     g_warning("Perl Plugin: File open error in ClawsMail::C::open_mail_file");
+    g_free(file);
     XSRETURN_UNDEF;
   }
+  g_free(file);
 }
 
 /* ClawsMail::C::close_mail_file */
@@ -686,7 +685,7 @@ static XS(XS_ClawsMail_close_mail_file)
 /* ClawsMail::C::get_next_header */
 static XS(XS_ClawsMail_get_next_header)
 {
-  gchar buf[BUFFSIZE];
+  gchar *buf;
   Header *header;
 
   dXSARGS;
@@ -698,7 +697,7 @@ static XS(XS_ClawsMail_get_next_header)
     g_warning("Perl Plugin: Message file not open. Use ClawsMail::C::open_message_file first.");
     XSRETURN_EMPTY;
   }
-  if(procheader_get_one_field(buf, sizeof(buf), message_file, NULL) != -1) {
+  if(procheader_get_one_field(&buf, message_file, NULL) != -1) {
     header = procheader_parse_header(buf);
     EXTEND(SP, 2);
     if(header) {
@@ -710,6 +709,7 @@ static XS(XS_ClawsMail_get_next_header)
       XST_mPV(0,"");
       XST_mPV(1,"");
     }
+    g_free(buf);
     XSRETURN(2);
   }
   else
index ea98320..2d20a3e 100644 (file)
@@ -35,8 +35,6 @@
 
 #include <string.h>
 
-#define HEADER_CONTENT_SIZE BUFFSIZE
-
 typedef struct {
     PyObject_HEAD
     MsgInfo *msginfo;
@@ -194,7 +192,7 @@ static PyObject* get_header(PyObject *self, PyObject *args)
   char *header_str;
   char *header_str_dup;
   MsgInfo *msginfo;
-  gchar header_content[HEADER_CONTENT_SIZE];
+  gchar *header_content = NULL;
 
   retval = PyArg_ParseTuple(args, "s", &header_str);
   if(!retval)
@@ -203,7 +201,7 @@ static PyObject* get_header(PyObject *self, PyObject *args)
   msginfo = ((clawsmail_MessageInfoObject*)self)->msginfo;
 
   header_str_dup = g_strdup(header_str);
-  retval = procheader_get_header_from_msginfo(msginfo, header_content, HEADER_CONTENT_SIZE, header_str);
+  retval = procheader_get_header_from_msginfo(msginfo, &header_content, header_str);
   g_free(header_str_dup);
   if(retval == 0) {
     PyObject *header_content_object;
@@ -219,9 +217,11 @@ static PyObject* get_header(PyObject *self, PyObject *args)
     while(*content_start == ' ')
       content_start++;
     header_content_object = Py_BuildValue("s", content_start);
+    g_free(header_content);
     return header_content_object;
   }
   else {
+    g_free(header_content);
     Py_RETURN_NONE;
   }
 }
index e1987c5..826281d 100644 (file)
@@ -141,11 +141,13 @@ static gchar *spamreport_strreplace(gchar *source, gchar *pattern,
 
 static gboolean check_debian_listid(MsgInfo *msginfo)
 {
-       gchar buf[1024];
-       if (!procheader_get_header_from_msginfo(msginfo, buf, sizeof(buf), "List-Id:")) {
+       gchar *buf = NULL;
+       if (!procheader_get_header_from_msginfo(msginfo, &buf, "List-Id:") && buf != NULL) {
                if (strstr(buf, "lists.debian.org")) {
+                       g_free(buf);
                        return TRUE;
                }
+               g_free(buf);
        }
        return FALSE;
 }
index a9bfa5d..2aa4e6f 100644 (file)
@@ -49,15 +49,15 @@ static gchar monthstr[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
 typedef char *(*getlinefunc) (char *, size_t, void *);
 typedef int (*peekcharfunc) (void *);
 typedef int (*getcharfunc) (void *);
-typedef gint (*get_one_field_func) (gchar *, size_t, void *, HeaderEntry[]);
+typedef gint (*get_one_field_func) (gchar **, void *, HeaderEntry[]);
 
-static gint string_get_one_field(gchar *buf, size_t len, char **str,
+static gint string_get_one_field(gchar **buf, char **str,
                                 HeaderEntry hentry[]);
 
 static char *string_getline(char *buf, size_t len, char **str);
 static int string_peekchar(char **str);
 static int file_peekchar(FILE *fp);
-static gint generic_get_one_field(gchar *buf, size_t len, void *data,
+static gint generic_get_one_field(gchar **bufptr, void *data,
                                  HeaderEntry hentry[],
                                  getlinefunc getline, 
                                  peekcharfunc peekchar,
@@ -66,18 +66,18 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                             gboolean full, gboolean decrypted);
 
 
-gint procheader_get_one_field(gchar *buf, size_t len, FILE *fp,
+gint procheader_get_one_field(gchar **buf, FILE *fp,
                              HeaderEntry hentry[])
 {
-       return generic_get_one_field(buf, len, fp, hentry,
+       return generic_get_one_field(buf, fp, hentry,
                                     (getlinefunc)fgets_crlf, (peekcharfunc)file_peekchar,
                                     TRUE);
 }
 
-static gint string_get_one_field(gchar *buf, size_t len, char **str,
+static gint string_get_one_field(gchar **buf, char **str,
                                 HeaderEntry hentry[])
 {
-       return generic_get_one_field(buf, len, str, hentry,
+       return generic_get_one_field(buf, str, hentry,
                                     (getlinefunc)string_getline,
                                     (peekcharfunc)string_peekchar,
                                     TRUE);
@@ -119,23 +119,48 @@ static int file_peekchar(FILE *fp)
        return ungetc(getc(fp), fp);
 }
 
-static gint generic_get_one_field(gchar *buf, size_t len, void *data,
+static gint generic_get_one_field(gchar **bufptr, void *data,
                          HeaderEntry *hentry,
                          getlinefunc getline, peekcharfunc peekchar,
                          gboolean unfold)
 {
+       /* returns -1 in case of failure of any kind, whatever it's a parsing error
+          or an allocation error. if returns -1, *bufptr is always NULL, and vice-versa,
+          and if returning 0 (OK), *bufptr is always non-NULL, so callers just have to
+          test the return value
+       */
        gint nexthead;
        gint hnum = 0;
        HeaderEntry *hp = NULL;
+       size_t len;
+       gchar *buf;
 
+/*     cm_return_val_if_fail(bufptr != NULL, -1); TODO */
+
+       len = BUFFSIZE;
+       buf = g_malloc(len);
+       if (buf == NULL) {
+               debug_print("generic_get_one_field: primary allocation error\n");
+               *bufptr = NULL;
+               return -1;
+       }
        if (hentry != NULL) {
                /* skip non-required headers */
+               /* and get hentry header line */
                do {
                        do {
-                               if (getline(buf, len, data) == NULL)
+                               if (getline(buf, len, data) == NULL) {
+                                       debug_print("generic_get_one_field: getline\n");
+                                       g_free(buf);
+                                       *bufptr = NULL;
                                        return -1;
-                               if (buf[0] == '\r' || buf[0] == '\n')
+                               }
+                               if (buf[0] == '\r' || buf[0] == '\n') {
+                                       debug_print("generic_get_one_field: empty line\n");
+                                       g_free(buf);
+                                       *bufptr = NULL;
                                        return -1;
+                               }
                        } while (buf[0] == ' ' || buf[0] == '\t');
 
                        for (hp = hentry, hnum = 0; hp->name != NULL;
@@ -146,8 +171,27 @@ static gint generic_get_one_field(gchar *buf, size_t len, void *data,
                        }
                } while (hp->name == NULL);
        } else {
-               if (getline(buf, len, data) == NULL) return -1;
-               if (buf[0] == '\r' || buf[0] == '\n') return -1;
+               /* read first line */
+               if (getline(buf, len, data) == NULL) {
+                       debug_print("generic_get_one_field: getline\n");
+                       g_free(buf);
+                       *bufptr = NULL;
+                       return -1;
+               }
+               if (buf[0] == '\r' || buf[0] == '\n') {
+                       debug_print("generic_get_one_field: empty line\n");
+                       g_free(buf);
+                       *bufptr = NULL;
+                       return -1;
+               }
+       }
+       /* reduce initial buffer to its useful part */
+       len = strlen(buf)+1;
+       buf = g_realloc(buf, len);
+       if (buf == NULL) {
+               debug_print("generic_get_one_field: reallocation error\n");
+               *bufptr = NULL;
+               return -1;
        }
 
        /* unfold line */
@@ -156,6 +200,9 @@ static gint generic_get_one_field(gchar *buf, size_t len, void *data,
                /* ([*WSP CRLF] 1*WSP) */
                if (nexthead == ' ' || nexthead == '\t') {
                        size_t buflen;
+                       gchar *tmpbuf;
+                       size_t tmplen;
+
                        gboolean skiptab = (nexthead == '\t');
                        /* trim previous trailing \n if requesting one header or
                         * unfolding was requested */
@@ -164,15 +211,34 @@ static gint generic_get_one_field(gchar *buf, size_t len, void *data,
 
                        buflen = strlen(buf);
                        
-                       /* concatenate next line */
-                       if ((len - buflen) > 2) {
-                               if (getline(buf + buflen, len - buflen, data) == NULL)
-                                       break;
-                               if (skiptab) { /* replace tab with space */
-                                       *(buf + buflen) = ' ';
-                               }
-                       } else
+                       /* read next line */
+                       tmpbuf = g_malloc(BUFFSIZE);
+                       if (tmpbuf == NULL) {
+                               debug_print("generic_get_one_field: secondary allocation error\n");
+                               g_free(buf);
+                               *bufptr = NULL;
+                               return -1;
+                       }
+                       if (getline(tmpbuf, BUFFSIZE, data) == NULL) {
+                               g_free(tmpbuf);
                                break;
+                       }
+                       tmplen = strlen(tmpbuf)+1;
+
+                       /* extend initial buffer and concatenate next line */
+                       len += tmplen;
+                       buf = g_realloc(buf, len);
+                       if (buf == NULL) {
+                               debug_print("generic_get_one_field: reallocation error\n");
+                               g_free(buf);
+                               *bufptr = NULL;
+                               return -1;
+                       }
+                       memcpy(buf+buflen, tmpbuf, tmplen);
+                       g_free(tmpbuf);
+                       if (skiptab) { /* replace tab with space */
+                               *(buf + buflen) = ' ';
+                       }
                } else {
                        /* remove trailing new line */
                        strretchomp(buf);
@@ -180,12 +246,14 @@ static gint generic_get_one_field(gchar *buf, size_t len, void *data,
                }
        }
 
+       *bufptr = buf;
+
        return hnum;
 }
 
-gint procheader_get_one_field_asis(gchar *buf, size_t len, FILE *fp)
+gint procheader_get_one_field_asis(gchar **buf, FILE *fp)
 {
-       return generic_get_one_field(buf, len, fp, NULL,
+       return generic_get_one_field(buf, fp, NULL,
                                     (getlinefunc)fgets_crlf, 
                                     (peekcharfunc)file_peekchar,
                                     FALSE);
@@ -193,7 +261,7 @@ gint procheader_get_one_field_asis(gchar *buf, size_t len, FILE *fp)
 
 GPtrArray *procheader_get_header_array_asis(FILE *fp)
 {
-       gchar buf[BUFFSIZE];
+       gchar *buf = NULL;
        GPtrArray *headers;
        Header *header;
 
@@ -201,9 +269,11 @@ GPtrArray *procheader_get_header_array_asis(FILE *fp)
 
        headers = g_ptr_array_new();
 
-       while (procheader_get_one_field_asis(buf, sizeof(buf), fp) != -1) {
+       while (procheader_get_one_field_asis(&buf, fp) != -1 && buf != NULL) {
                if ((header = procheader_parse_header(buf)) != NULL)
                        g_ptr_array_add(headers, header);
+               g_free(buf);
+               buf = NULL;
        }
 
        return headers;
@@ -214,6 +284,8 @@ void procheader_header_array_destroy(GPtrArray *harray)
        gint i;
        Header *header;
 
+       cm_return_if_fail(harray != NULL);
+
        for (i = 0; i < harray->len; i++) {
                header = g_ptr_array_index(harray, i);
                procheader_header_free(header);
@@ -290,6 +362,8 @@ Header * procheader_parse_header(gchar * buf)
        Header * header;
        gboolean addr_field = FALSE;
 
+       cm_return_val_if_fail(buf != NULL, NULL);
+
        if ((*buf == ':') || (*buf == ' '))
                return NULL;
 
@@ -309,15 +383,14 @@ Header * procheader_parse_header(gchar * buf)
 
 void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
 {
-       gchar buf[BUFFSIZE];
+       gchar *buf = NULL;
        HeaderEntry *hp;
        gint hnum;
        gchar *p;
 
        if (hentry == NULL) return;
 
-       while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, hentry))
-              != -1) {
+       while ((hnum = procheader_get_one_field(&buf, fp, hentry)) != -1 && buf != NULL) {
                hp = hentry + hnum;
 
                p = buf + strlen(hp->name);
@@ -331,6 +404,8 @@ void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
                        hp->body = g_strconcat(tp, ", ", p, NULL);
                        g_free(tp);
                }
+               g_free(buf);
+               buf = NULL;
        }
 }
 
@@ -490,7 +565,7 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                             gboolean full, gboolean decrypted)
 {
        MsgInfo *msginfo;
-       gchar buf[BUFFSIZE];
+       gchar *buf = NULL;
        gchar *p, *tmp;
        gchar *hp;
        HeaderEntry *hentry;
@@ -504,7 +579,7 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
        hentry = procheader_get_headernames(full);
 
        if (MSG_IS_QUEUED(flags) || MSG_IS_DRAFT(flags)) {
-               while (get_one_field(buf, sizeof(buf), data, NULL) != -1) {
+               while (get_one_field(&buf, data, NULL) != -1 && buf != NULL) {
                        if ((!strncmp(buf, "X-Claws-End-Special-Headers: 1",
                                strlen("X-Claws-End-Special-Headers:"))) ||
                            (!strncmp(buf, "X-Sylpheed-End-Special-Headers: 1",
@@ -519,8 +594,12 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                                        data = orig_data;
                                else 
                                        rewind((FILE *)data);
+                               g_free(buf);
+                               buf = NULL;
                                break;
                        }
+                       g_free(buf);
+                       buf = NULL;
                }
        }
 
@@ -540,8 +619,7 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                avatar_hook_id = 0;
        }
 
-       while ((hnum = get_one_field(buf, sizeof(buf), data, hentry))
-              != -1) {
+       while ((hnum = get_one_field(&buf, data, hentry)) != -1 && buf != NULL) {
                hp = buf + strlen(hentry[hnum].name);
                while (*hp == ' ' || *hp == '\t') hp++;
 
@@ -743,6 +821,8 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                        hooks_invoke(AVATAR_HEADER_UPDATE_HOOKLIST, (gpointer)acd);
                        g_free(acd);
                }
+               g_free(buf);
+               buf = NULL;
        }
 
        if (!msginfo->inreplyto && msginfo->references)
@@ -1052,34 +1132,50 @@ void procheader_date_get_localtime(gchar *dest, gint len, const time_t timer)
 
 /* Added by Mel Hadasht on 27 Aug 2001 */
 /* Get a header from msginfo */
-gint procheader_get_header_from_msginfo(MsgInfo *msginfo, gchar *buf, gint len, gchar *header)
+gint procheader_get_header_from_msginfo(MsgInfo *msginfo, gchar **buf, gchar *header)
 {
        gchar *file;
        FILE *fp;
        HeaderEntry hentry[]={ { NULL, NULL, TRUE  },
-                               { NULL, NULL, FALSE } };
+                                                  { NULL, NULL, FALSE } };
        gint val;
 
-        hentry[0].name = header;
-       
        cm_return_val_if_fail(msginfo != NULL, -1);
+       cm_return_val_if_fail(buf != NULL, -1);
+       cm_return_val_if_fail(header != NULL, -1);
+
+       hentry[0].name = header;
+
        file = procmsg_get_message_file_path(msginfo);
        if ((fp = g_fopen(file, "rb")) == NULL) {
-               FILE_OP_ERROR(file, "fopen");
-               g_free(file);
-               return -1;
+               FILE_OP_ERROR(file, "fopen");
+               g_free(file);
+               g_free(*buf);
+               *buf = NULL;
+               return -1;
+       }
+       val = procheader_get_one_field(buf, fp, hentry);
+       if (buf == NULL) {
+               claws_unlink(file);
+               g_free(file);
+               g_free(*buf);
+               *buf = NULL;
+               return -1;
        }
-       val = procheader_get_one_field(buf,len, fp, hentry);
        if (fclose(fp) == EOF) {
                FILE_OP_ERROR(file, "fclose");
                claws_unlink(file);
                g_free(file);
+               g_free(*buf);
+               *buf = NULL;
                return -1;
        }
 
        g_free(file);
-        if (val == -1)
+       if (val == -1) {
+               /* *buf is already NULL in that case, see procheader_get_one_field() */
                return -1;
+       }
 
        return 0;
 }
index e4cb92d..0588f30 100644 (file)
@@ -41,15 +41,10 @@ struct _Header
        gchar *body;
 };
 
-gint procheader_get_one_field          (gchar          *buf,
-                                        size_t          len,
+gint procheader_get_one_field          (gchar          **buf,
                                         FILE           *fp,
                                         HeaderEntry     hentry[]);
-gint procheader_get_one_field_asis     (gchar          *buf,
-                                        size_t          len,
-                                        FILE           *fp);
-gchar *procheader_get_unfolded_line    (gchar          *buf,
-                                        size_t          len,
+gint procheader_get_one_field_asis     (gchar          **buf,
                                         FILE           *fp);
 
 GPtrArray *procheader_get_header_array_asis    (FILE           *fp);
@@ -89,8 +84,7 @@ gboolean procheader_headername_equal    (char * hdr1, char * hdr2);
 void procheader_header_free             (Header * header);
 
 gint procheader_get_header_from_msginfo        (MsgInfo        *msginfo,
-                                        gchar          *buf,
-                                        gint           len,
+                                        gchar          **buf,
                                         gchar          *header);
 
 HeaderEntry *procheader_entries_from_str(const gchar   *str);
index aa3c9a8..c9b077e 100644 (file)
@@ -724,7 +724,7 @@ static PrefsAccount *procmsg_get_account_from_file(const gchar *file)
        PrefsAccount *mailac = NULL;
        FILE *fp;
        int hnum;
-       gchar buf[BUFFSIZE];
+       gchar *buf = NULL;
        static HeaderEntry qentry[] = {{"S:",    NULL, FALSE},
                                       {"SSV:",  NULL, FALSE},
                                       {"R:",    NULL, FALSE},
@@ -750,14 +750,15 @@ static PrefsAccount *procmsg_get_account_from_file(const gchar *file)
                return NULL;
        }
 
-       while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, qentry))
-              != -1) {
+       while ((hnum = procheader_get_one_field(&buf, fp, qentry)) != -1 && buf != NULL) {
                gchar *p = buf + strlen(qentry[hnum].name);
 
                if (hnum == Q_MAIL_ACCOUNT_ID) {
                        mailac = account_find_from_id(atoi(p));
                        break;
                }
+               g_free(buf);
+               buf = NULL;
        }
        fclose(fp);
        return mailac;
@@ -1542,7 +1543,7 @@ static gint procmsg_send_message_queue_full(const gchar *file, gboolean keep_ses
        gchar *savecopyfolder = NULL;
        gchar *replymessageid = NULL;
        gchar *fwdmessageid = NULL;
-       gchar buf[BUFFSIZE];
+       gchar *buf;
        gint hnum;
        PrefsAccount *mailac = NULL, *newsac = NULL;
        gboolean encrypt = FALSE;
@@ -1559,8 +1560,7 @@ static gint procmsg_send_message_queue_full(const gchar *file, gboolean keep_ses
                return -1;
        }
 
-       while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, qentry))
-              != -1) {
+       while ((hnum = procheader_get_one_field(&buf, fp, qentry)) != -1 && buf != NULL) {
                gchar *p = buf + strlen(qentry[hnum].name);
 
                switch (hnum) {
@@ -1607,6 +1607,8 @@ static gint procmsg_send_message_queue_full(const gchar *file, gboolean keep_ses
                        goto send_mail; /* can't "break;break;" */
                }
        }
+       g_free(buf);
+
 send_mail:
        filepos = ftell(fp);
        if (filepos < 0) {
@@ -1679,6 +1681,7 @@ send_mail:
        if (newsgroup_list && newsac && (mailval == 0)) {
                Folder *folder;
                gchar *tmp = NULL;
+               gchar buf[BUFFSIZE];
                FILE *tmpfp;
 
                /* write to temporary file */