]> granicus.if.org Git - neomutt/commitdiff
Add edit-content-type helper and warning for decrypted attachments. (closes #3728)
authorKevin McCarthy <kevin@8t8.us>
Fri, 11 Aug 2017 01:18:28 +0000 (18:18 -0700)
committerRichard Russon <rich@flatcap.org>
Fri, 1 Sep 2017 12:44:58 +0000 (13:44 +0100)
Regenerating the actx index will overwrite any changes made to a
decrypted attachment.  Change the mutt_edit_content_type() function to
return 1 when a structural change is made.  Add a warning message when
that is the case and a decrypted message was edited, so the user is
not surprised.

Note: mutt_edit_content_type() appeared to regenerate multipart
subparts every time, leading to a memory leak.  I believe this was an
oversite, and it should have regenerated only when there were no
subparts, so have "fixed" this.

commands.c
protos.h
recvattach.c

index 2f9bbc883a0f1a26e9bfcc7e3db52ed7f2b46826..3bfaabb3522980a838c7c02724638b6dc1c6f290 100644 (file)
@@ -936,7 +936,13 @@ void mutt_version(void)
   mutt_message("NeoMutt %s%s (%s)", PACKAGE_VERSION, GitVer, MUTT_VERSION);
 }
 
-void mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
+/*
+ * Returns:
+ *   1 when a structural change is made.
+ *     recvattach requires this to know when to regenerate the actx.
+ *   0 otherwise.
+ */
+int mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
 {
   char buf[LONG_STRING];
   char obuf[LONG_STRING];
@@ -948,6 +954,7 @@ void mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
 
   short charset_changed = 0;
   short type_changed = 0;
+  short structure_changed = 0;
 
   cp = mutt_get_parameter("charset", b->parameter);
   strfcpy(charset, NONULL(cp), sizeof(charset));
@@ -968,7 +975,7 @@ void mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
   }
 
   if (mutt_get_field("Content-Type: ", buf, sizeof(buf), 0) != 0 || buf[0] == 0)
-    return;
+    return 0;
 
   /* clean up previous junk */
   mutt_free_parameter(&b->parameter);
@@ -1009,15 +1016,22 @@ void mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
   b->force_charset |= charset_changed ? 1 : 0;
 
   if (!is_multipart(b) && b->parts)
+  {
+    structure_changed = 1;
     mutt_free_body(&b->parts);
+  }
   if (!mutt_is_message_type(b->type, b->subtype) && b->hdr)
   {
+    structure_changed = 1;
     b->hdr->content = NULL;
     mutt_free_header(&b->hdr);
   }
 
-  if (fp && (is_multipart(b) || mutt_is_message_type(b->type, b->subtype)))
+  if (fp && !b->parts && (is_multipart(b) || mutt_is_message_type(b->type, b->subtype)))
+  {
+    structure_changed = 1;
     mutt_parse_part(fp, b);
+  }
 
   if (WithCrypto && h)
   {
@@ -1026,6 +1040,8 @@ void mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp)
 
     h->security |= crypt_query(b);
   }
+
+  return structure_changed;
 }
 
 static int _mutt_check_traditional_pgp(struct Header *h, int *redraw)
index 826dcc85f368f78c9deade6e4694cdd716d42f0e..674b8a8a62dae784fe227b799aaccb3f5fbe5aeb 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -164,7 +164,7 @@ void mutt_decode_base64(struct State *s, long len, int istext, iconv_t cd);
 void mutt_default_save(char *path, size_t pathlen, struct Header *hdr);
 void mutt_display_address(struct Envelope *env);
 void mutt_draw_statusline(int cols, const char *buf, int buflen);
-void mutt_edit_content_type(struct Header *h, struct Body *b, FILE *fp);
+int mutt_edit_content_type (struct Header *h, struct Body *b, FILE *fp);
 void mutt_edit_file(const char *editor, const char *data);
 void mutt_edit_headers(const char *editor, const char *body, struct Header *msg,
                        char *fcc, size_t fcclen);
index 9fca1b2014f765661f891e45760a409803e86b1e..b9b1fae6c68f29a7a8dca45ee4d2b7affcc0917b 100644 (file)
@@ -849,6 +849,27 @@ static int recvattach_pgp_check_traditional(struct AttachCtx *actx, struct Menu
   return rv;
 }
 
+static void recvattach_edit_content_type(struct AttachCtx *actx,
+                                         struct Menu *menu, struct Header *hdr)
+{
+  if (mutt_edit_content_type(hdr, CURATTACH->content, CURATTACH->fp) == 1)
+  {
+    /* The mutt_update_recvattach_menu() will overwrite any changes
+     * made to a decrypted CURATTACH->content, so warn the user. */
+    if (CURATTACH->decrypted)
+    {
+      mutt_message(
+          _("Structural changes to decrypted attachments are not supported"));
+      mutt_sleep(1);
+    }
+    /* Editing the content type can rewrite the body structure. */
+    for (int i = 0; i < actx->idxlen; i++)
+      actx->idx[i]->content = NULL;
+    mutt_actx_free_entries(actx);
+    mutt_update_recvattach_menu(actx, menu, 1);
+  }
+}
+
 int mutt_attach_display_loop(struct Menu *menu, int op, struct Header *hdr,
                              struct AttachCtx *actx, int recv)
 {
@@ -889,13 +910,11 @@ int mutt_attach_display_loop(struct Menu *menu, int op, struct Header *hdr,
            immediately */
         mutt_edit_content_type(hdr, CURATTACH->content, CURATTACH->fp);
         if (recv)
-        {
-          /* Editing the content type can rewrite the body structure. */
-          for (int i = 0; i < actx->idxlen; i++)
-            actx->idx[i]->content = NULL;
-          mutt_actx_free_entries(actx);
-          mutt_update_recvattach_menu(actx, menu, 1);
-        }
+          recvattach_edit_content_type(actx, menu, hdr);
+        else
+          mutt_edit_content_type(hdr, CURATTACH->content, CURATTACH->fp);
+
+        menu->redraw |= REDRAW_INDEX;
         op = OP_VIEW_ATTACH;
         break;
       /* functions which are passed through from the pager */
@@ -1094,7 +1113,6 @@ void mutt_view_attachments(struct Header *hdr)
   struct Menu *menu = NULL;
   struct Body *cur = NULL;
   struct Message *msg = NULL;
-  FILE *fp = NULL;
   struct AttachCtx *actx = NULL;
   int flags = 0;
   int op = OP_NULL;
@@ -1313,7 +1331,7 @@ void mutt_view_attachments(struct Header *hdr)
 #ifdef USE_NNTP
       case OP_FORWARD_TO_GROUP:
         CHECK_ATTACH;
-        mutt_attach_forward(fp, hdr, actx, menu->tagprefix ? NULL : CURATTACH->content, SENDNEWS);
+        mutt_attach_forward(CURATTACH->fp, hdr, actx, menu->tagprefix ? NULL : CURATTACH->content, SENDNEWS);
         menu->redraw = REDRAW_FULL;
         break;
 
@@ -1325,7 +1343,7 @@ void mutt_view_attachments(struct Header *hdr)
             query_quadoption(OPT_FOLLOW_UP_TO_POSTER,
                              _("Reply by mail as poster prefers?")) != MUTT_YES)
         {
-          mutt_attach_reply(fp, hdr, actx, menu->tagprefix ? NULL : CURATTACH->content,
+          mutt_attach_reply(CURATTACH->fp, hdr, actx, menu->tagprefix ? NULL : CURATTACH->content,
                             SENDNEWS | SENDREPLY);
           menu->redraw = REDRAW_FULL;
           break;
@@ -1345,12 +1363,8 @@ void mutt_view_attachments(struct Header *hdr)
         break;
 
       case OP_EDIT_TYPE:
-        mutt_edit_content_type(hdr, CURATTACH->content, fp);
-        /* Editing the content type can rewrite the body structure. */
-        for (i = 0; i < actx->idxlen; i++)
-          actx->idx[i]->content = NULL;
-        mutt_actx_free_entries(actx);
-        mutt_update_recvattach_menu(actx, menu, 1);
+        recvattach_edit_content_type(actx, menu, hdr);
+        menu->redraw |= REDRAW_INDEX;
         break;
 
       case OP_EXIT: