djcb / mu

maildir indexer/searcher + emacs mail client + guile bindings
http://www.djcbsoftware.nl/code/mu
GNU General Public License v3.0
1.61k stars 389 forks source link

[mu4e bug] `mu4e-compose-wide-reply` creates invalid `Cc:` header. #2680

Closed joostkremers closed 5 months ago

joostkremers commented 6 months ago

When creating a wide reply to a (mailing list?) message, mu4e sometimes creates an invalid Cc: header. One particular case happened on the mu-discuss mailing list. The headers of the original message are these:

Original headers

When I reply (using W), the headers of the reply look like this (with whitespace-mode enabled):

Reply headers

When trying to send this message, Emacs responds with:

Email address  looks invalid; send anyway? (y or n)

Note that the Cc: header has a comma and three spaces after the e-mail address. The spaces probably are not the problem, but the comma is. Removing it makes it possible to send the message.

Environment

Emacs version 29.3, mu/mu4e version 1.12.0, Linux (Arch).

[edit]

Just upgraded mu/mu4e to 1.12.2: this bug still exists.

djcb commented 6 months ago

Can't reproduce. Can you reproduce with a minimal setup? I.e, emacs -Q and bare-bones mu4e?

joostkremers commented 6 months ago

Well, I think I found out where things go wrong, I just don't know why they go wrong... It appears to be happening in the function message-get-reply-headers. At the top of this function (which I copied below for ease of reference), all relevant headers are set; among others,the variable cc is set to the original message's Cc: header and the variable author is set to the mail-reply-to or reply-to header. For the message I'm replying to, cc is empty (the message has no Cc:), while author is set to the mailing list address, "mu-discuss@googlegroups.com".

Then a few lines below, cc is set to a concatenation of author and cc, separated by a comma:

      (when (and wide author)
    (setq cc (concat author ", " cc)))

This sets cc to the value "mu-discuss@googlegroups.com, " (note the comma) and this mistake is not corrected in the remainder of the function.

Like I said, though, I don't understand why this is happening. Going by the code, I don't see how my mu4e configuration could play a role, but on the other hand if it were so simple, I can't imagine I'm the first person to run into this... Plus, you mention you can't reproduce it. So I guess I'll go and look at my config...

(defun message-get-reply-headers (wide &optional to-address address-headers)
  (let (follow-to mct never-mct to cc author mft recipients extra)
    ;; Find all relevant headers we need.
    (save-restriction
      (message-narrow-to-headers-or-head)
      ;; Gmane renames "To".  Look at "Original-To", too, if it is present in
      ;; message-header-synonyms.
      (setq to (or (message-fetch-field "to")
           (and (cl-loop for synonym in message-header-synonyms
                     when (memq 'Original-To synonym)
                     return t)
            (message-fetch-field "original-to")))
        cc (message-fetch-field "cc")
        extra (when message-extra-wide-headers
            (mapconcat #'identity
                   (mapcar #'message-fetch-field
                       message-extra-wide-headers)
                   ", "))
        mct (message-fetch-field "mail-copies-to")
        author (or (message-fetch-field "mail-reply-to")
               (message-fetch-field "reply-to"))
        mft (and message-use-mail-followup-to
             (message-fetch-field "mail-followup-to")))
      ;; Make sure this message goes to the author if this is a wide
      ;; reply, since Reply-To address may be a list address a mailing
      ;; list server added.
      (when (and wide author)
    (setq cc (concat author ", " cc)))
      (when (or wide (not author))
    (setq author (or (message-fetch-field "from") ""))))
theophilusx commented 6 months ago

There might be other issues with wide reply.

For example, if I do M-x mu4e-compose-wide-reply on this message, I get the following headers added

To: Joost Kremers @.> Cc: djcb/mu @.>, djcb/mu @.>, Subscribed @.> Subject: Re: [djcb/mu] [mu4e bug] mu4e-compose-wide-reply creates invalid Cc: header. (Issue #2680)

but the original message has these headers

From: Joost Kremers @.> Reply-To: djcb/mu @.> To: djcb/mu @.> Cc: Subscribed @.>

Note that wide reply does not appear to respect the Reply-To header. This header is respected if you just do a normal reply.

joostkremers commented 6 months ago

Narrowing it down further: I have set message-dont-reply-to-names to #'mu4e-personal-or-alternative-address-p. If I unset this variable, the problem does not occur.

Since this setting is actually mentioned in the Mu4e info manual (see (info "(mu4e) Other settings") ), I'm inclined to consider this a Mu4e bug.

It could be just a documentation bug, though, because when I set message-dont-reply-to-names to nil, my address is not included in the Cc: headers, even when I'm wide-replying to a message that was (also) sent to me. So it looks like setting message-dont-reply-to-names to #'mu4e-personal-or-alternative-address-p is not necessary anymore.

joostkremers commented 6 months ago

Note that wide reply does not appear to respect the Reply-To header. This header is respected if you just do a normal reply.

You mean in the sense that the original To: is still included in the recipients of the wide reply? But isn't that what a wide reply (a.k.a. "Reply to all") is supposed to do?

theophilusx commented 6 months ago

I guess interpretation of what 'wide reply' is supposed to mean is likely the stumbling block.

For me, my interpretation is that with wide reply, if there is a Reply-To header, then that is what the 'To' field should be, but in addition to that field, the Cc should include whatever was Cc'd in the original. However, if there is a Reply-To, then the original 'To' would NOT be included (it would be replaced by the Reply-To). My thinking is that in most cases, if someone has included a Reply-To, then that is what they want replies addressed to. All wide reply means is include the Cc addressses as well.

Joost Kremers @.***> writes:

Note that wide reply does not appear to respect the Reply-To header. This header is respected if you just do a normal reply.

You mean in the sense that the original To: is still included in the recipients of the wide reply? But isn't that what a wide reply (a.k.a. "Reply to all") is supposed to do?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.

joostkremers commented 6 months ago

I think I was confused earlier... "Reply-To:" of course means not to include the original "From:" in the reply's recipients, not "To;", as I wrote earlier. But yes, in a wide reply, it is included nonetheless, and you may be right that it shouldn't. I have no opinion on the matter, though. My first thought is to do what (most) other mail clients do, but I don't know what that is, so...

It might make sense to take this to the mailing list, BTW.

djcb commented 5 months ago

FWIW, when I manually add a trailing , it's happily accepted, and I don't get that warning. I.e.

(ietf-drums-parse-addresses "foo@bar.org,cuux@fnorb.com,")
=> (("foo@bar.org") ("cuux@fnorb.com"))

It's indeed weird it gets added in message-get-reply-headers.

djcb commented 5 months ago

Moreover, with emacs 29.3, and a minimal setup, ie. emacs -Q and then something like:

(add-to-list 'load-path "~/Sources/mu/build/mu4e")
(setq mu4e-mu-binary "~/Sources/mu/build/mu/mu")
(require 'mu4e)

and then M-x mu4e and W to that very message mentioned here, I cannot reproduce the problem.

@joostkremers can you repro still?

joostkremers commented 5 months ago

I can reproduce the problem with emacs -Q, but only when message-dont-reply-to-names is set to #'mu4e-personal-or-alternative-address-p. If message-dont-reply-to-names has its default value of nil, the problem does not occur.

djcb commented 5 months ago

Ah, yes, then I can reproduce. Have no time go through the precise machinations in Gnus... but here's a work-around:

(defun mu4e-personal-or-alternative-address-or-empty-p (addr)
  "Is ADDR either a personal, alternative address or nil?

This is like `mu4e-personal-or-alternative-address-p' but also
return t for _empty_ ADDR. This can be useful for use with
`message-dont-reply-to-names' since it can receive empty strings;
those can be filtered-out by returning t here.

See #2680 for further details. "
  (or (and addr (string= addr ""))
      (mu4e-personal-or-alternative-address-p addr)))