Subject: bug#79376: [PATCH] [WIP] Fix mm multibyte

From: Eli Zaretskii <[email-masked]>
Date: Sat, 13 Sep 2025 11:17:21 +0300

> From: Manuel Giraud <[email-masked]>
> Cc: Lars Magne Ingebrigtsen <[email-masked]>,  MORIOKA Tomohiko
>  <[email-masked]>,
>     Eli Zaretskii <[email-masked]>
> Date: Thu, 04 Sep 2025 11:47:48 +0200
> 
> Hopefully, this new patch is a better fix.  AFAIU, with this, the
> content of the temporary MIME buffer is preserved as unibyte (as it
> should?) and its content is encoded from a possibly multibyte buffer.

I'm still not convinced this is the correct fix, see below.

> FWIW, I did not used `insert-buffer-substring' anymore as this is using
> `string-make-unibyte' that does not do TRT.

How is that not TRT, can you tell the details?  (In any case, the doc
string of insert-buffer-substring is misleading, since the function
doesn't call string-make-unibyte, at least not directly.

I feel that we should take a step back and examine your original
problem in more detail.  In your OP, you said "I'm trying to fix an
issue in Gnus where some Atom sources (namely
planet.emacslife.com/atom.xml, here) are not rendered correctly", but
never told the details.  Can we please see those details?

I'm asking because it is not clear to me that unconditionally making
the buffer returned by mm-copy-to-buffer unibyte is TRT.  And if it
must be unibyte, it isn't clear to me how why inserting stuff there
like it does in the existing code base is incorrect.

>  (defun mm-copy-to-buffer ()
>    "Copy the contents of the current buffer to a fresh buffer."
> -  (let ((obuf (current-buffer))
> -        (mb enable-multibyte-characters)
> -        beg)
> +  (let (content)
>      (goto-char (point-min))
>      (search-forward-regexp "^\n" nil 'move) ;; There might be no body.
> -    (setq beg (point))
> +    (setq content (buffer-substring (point) (point-max)))
>      (with-current-buffer
>            (generate-new-buffer " *mm*")
>        ;; Preserve the data's unibyteness (for url-insert-file-contents).
> -      (set-buffer-multibyte mb)
> -      (insert-buffer-substring obuf beg)
> +      (set-buffer-multibyte nil)
> +      (insert (encode-coding-string content 'undecided))
>        (current-buffer))))

The ELisp manual explicitly recommends against using 'undecided' when
encoding, so at the very least this needs to be rethought.  Also, your
change has the disadvantage of consing a string, where the original
code doesn't.  But these details should be considered once we have a
clear understanding of the problem which prompted your to make changes
there.

Thanks.