<<< Date Index >>>     <<< Thread Index >>>

Re: mutt/2110: decode-copy decode-save create empty parts / messages in case of decoding errors



* Wed Oct 12 2005 Derek Martin <invalid@xxxxxxxxxxxxxx>
> On Tue, Oct 11, 2005 at 02:15:02AM +0200, TAKAHASHI Tamotsu wrote:
> >  > Nontheless a message with an empty body is copied/saved.
> >  
> >  True.
> >  While decode-copying, mutt tries to decrypt the message *after*
> >  copying the header. So, only the header is left even if aborted.
> >  Hmmm...
> 
> It strikes me that the "right" behavior is for mutt to attempt the
> decode first, writing the results to a temporary file.  If and only if
> this succeeds, mutt should begin to write the new message,
> concatenating the first temporary file with the rest of the message as
> appropriate.

Here is a patch.
But, as usual, more than one bugs per line are expected. ;)


> In cases where there are multiple encrypted parts (unusual but
> possible), I think the right thing to do is attempt to decrypt all of
> the encrypted parts first, and ask the user how to proceed if any of
> them fails.

Sounds good, but beyond my ability.

-- 
tamo
diff -r 4c45a538cc33 copy.c
--- a/copy.c    Tue Oct 11 07:04:24 2005
+++ b/copy.c    Fri Oct 14 20:19:28 2005
@@ -766,17 +766,46 @@
   char buf[STRING];
   MESSAGE *msg;
   int r;
+  char tmpfname[_POSIX_PATH_MAX];
+  FILE *tmpfp = NULL;
 
   fseek(fpin, hdr->offset, 0);
   if (fgets (buf, sizeof (buf), fpin) == NULL)
     return -1;
   
-  if ((msg = mx_open_new_message (dest, hdr, is_from (buf, NULL, 0, NULL) ? 0 
: M_ADD_FROM)) == NULL)
-    return -1;
   if (dest->magic == M_MBOX || dest->magic == M_MMDF)
     chflags |= CH_FROM | CH_FORCE_FROM;
   chflags |= (dest->magic == M_MAILDIR ? CH_NOSTATUS : CH_UPDATE);
-  r = _mutt_copy_message (msg->fp, fpin, hdr, body, flags, chflags);
+
+  /* copy to a temporary file because decryption can fail */
+  mutt_mktemp (tmpfname);
+  if ((tmpfp = safe_fopen (tmpfname, "w+")) == NULL)
+  {
+    mutt_perror (tmpfname);
+    return -1;
+  }
+  if ((r = _mutt_copy_message (tmpfp, fpin, hdr, body, flags, chflags)) != 0)
+  {
+    if (tmpfp)
+    {
+      safe_fclose (&tmpfp);
+      mutt_unlink (tmpfname);
+    }
+    return r;
+  }
+  fflush (tmpfp);
+
+  /* actually copy to the dest */
+  if ((msg = mx_open_new_message (dest, hdr, is_from (buf, NULL, 0, NULL) ? 0 
: M_ADD_FROM)) == NULL)
+    return -1;
+  rewind (tmpfp);
+  if (mutt_copy_stream (tmpfp, msg->fp))
+    r=-1;
+  if (tmpfp)
+  {
+    safe_fclose (&tmpfp);
+    mutt_unlink (tmpfname);
+  }
   if (mx_commit_message (msg, dest) != 0)
     r = -1;