Mark Sapiro wrote:
Thus, the issue occurs downstream of lmtp runner. It will take more investigation to determine where.
The issue occurs in mailman/handlers/avoid_duplicates.py. That module will rewrite the Cc: header after possibly deleting some of the entries.
That module calls msg.get_all('cc') to get the original Ccs and calls email.utils.getaddresses() on that to get a list of all the name, address pairs.
In our case, msg.get_all('cc') returns one of two things. If the message came via LMTP with CRLF line endings, it returns
['"ABC DEF\r\n (XYZ)" <mark@msapiro.net>']
If the message came from mailman inject
with LF line endings, it returns
['"ABC DEF\n (XYZ)" <mark@msapiro.net>']
then email.utils.getaddresses() calls internally email.utils.parseaddr
on each item in the list to make a list (of one in our case) of name,
address pairs. The result is different depending on the line endings
which explains why it works with mailman inject
but not with LMTP.
In the case where the line endings are LF, the return is
[('ABC DEF\n (XYZ)', 'mark@msapiro.net')]
but if the line endings are CRLF, the return is
[('XYZ', 'ABC DEF')]
If the "folding" is not quoted as in
ABC DEF (XYZ) <mark@msapiro.net>
then the return is
('ABC DEF (XYZ)', 'mark@msapiro.net')
regardless of the line ending as it should be. I can't really fault parseaddr() here because the only time it produces an unexpected result is when the CRLF line folding occurs in the middle of a quoted string which is clearly non-compliant.
For Mailman to defend against this, something like the attached patch would do.
-- Mark Sapiro <mark@msapiro.net> The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan