Re: [PATCH] Remove double newline between headers and multipart body.

Rene Kita <[email protected]>
Newsgroups gmane.mail.mutt.devel
Message-ID <[email protected]>
On Mon, Apr 06, 2026 at 02:38:34PM +0800, Kevin J. McCarthy wrote:
> Many thanks to Matthijs Kooijman for the bug report, complete with a
> detailed explanation, pointers to the code causing the problem, and an
> anaylsis of the RFC in question.  He all but wrote the simple patch
> himself.
> 
> I've added comments around the change, to hopefully make it clear why
> the change was made to long standing behavior in mutt.
> 
> I've also separated out the one place in the code where it wasn't
> immediately obvious a header was being tied off with an extra newline,
> inside mutt_write_fcc().
> ---
>  sendlib.c | 25 +++++++++++++++++++++++--
>  1 file changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/sendlib.c b/sendlib.c
> index 3c8b0c7c..150bc72d 100644
> --- a/sendlib.c
> +++ b/sendlib.c
> @@ -310,6 +310,8 @@ static void encode_8bit(FGETCONV *fc, FILE *fout, int istext)
>  }
>  
>  
> +/* The caller is responsible for terminating the headers with an
> + * additional '\n' before writing the body. */
>  int mutt_write_mime_header(BODY *a, FILE *f)
>  {
>    PARAMETER *p;
> @@ -474,12 +476,30 @@ int mutt_write_mime_body(BODY *a, FILE *f)
>  
>      for (t = a->parts; t ; t = t->next)
>      {
> -      fprintf(f, "\n--%s\n", boundary);
> +      fprintf(f, "--%s\n", boundary);
>        if (mutt_write_mime_header(t, f) == -1)
>          return -1;
>        fputc('\n', f);
>        if (mutt_write_mime_body(t, f) == -1)
>          return -1;
> +
> +      /* This '\n' is part of the following delimiter.  The very
> +       * first dash-boundary printed in this loop already has a '\n'
> +       * printed prior to calling this function (to separate the
> +       * headers from the body).
> +       *
> +       * Reading RFC 2046, it's possible to conclude the '\n'
> +       * separator between headers and body is different from the '\n'
> +       * part of the first delimiter.  This is probably why mutt
> +       * previously included a '\n' in front of every dash-boundary in
> +       * this loop.
> +       *
> +       * However common practice and the examples shown in the RFC do
> +       * not have a double '\n' separator between the message headers
> +       * and a multipart body.
> +       */
> +      if (t->next)
> +        fputc('\n', f);
>      }
>      fprintf(f, "\n--%s--\n", boundary);
>      return (ferror(f) ? -1 : 0);
> @@ -3305,7 +3325,8 @@ int mutt_write_fcc(const char *path, SEND_CONTEXT *sctx, const char *msgid, int
>      while (fgets(sasha, sizeof(sasha), tempfp) != NULL)
>        lines++;
>      fprintf(msg->fp, "Content-Length: " OFF_T_FMT "\n", (LOFF_T) ftello(tempfp));
> -    fprintf(msg->fp, "Lines: %d\n\n", lines);
> +    fprintf(msg->fp, "Lines: %d\n", lines);
> +    fputc('\n', msg->fp); /* finish off the header */
>  
>      /* copy the body and clean up */
>      rewind(tempfp);
> -- 
> 2.53.0

Given only the patch and the contained comments the changes make sense
to me.

Don't know if it's right, but at least comments seem to match the
code. ;-)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.