My-Little-Forum / mylittleforum

A simple PHP and MySQL based internet forum that displays the messages in classical threaded view (tree structure)
GNU General Public License v3.0
121 stars 47 forks source link

Invalid mail seperator #646

Closed loesler closed 6 months ago

loesler commented 1 year ago

Hej,

I have noticed that the mail separator (currently '\n') has not been working for me for some time. The mail header is corrupted, cf. attached screenshot. According to RFC 2047, I changed the separator to '\r\n' which solves the issue. However, even the separator is correct, there is a comment "\r\n" complies with RFC 2822 but might cause problems in some cases and, thus, the change may lead to some side effects. So, can anyone try the modified code?

$mail_header_separator = "\r\n";

/Micha

mail

auge8472 commented 1 year ago

When Alex, Alfie and I reworked the e-mail creation code to support e-mails in UTF-8 (around 12 years ago, the discussion took place in my meanwhile closed MLF-1-test-forum) we encountered several problems in several corners. One was the codeline separator for e-mail-headers. We was aware of the standard, that says, the line separator has to be \r\n, but we saw problems in a few e-mail-clients (OS-native and web clients). The only solution to solve these problems without breaking other clients was to use the Unix-like line separator \n. We never saw this bypass to break one of the tested e-mail-clients.

Meanwhile 12 years have passed. I don't know, if one of the clients breaks nowadays when the script would use the standard line separator \r\n for e-mail-headers.

At the end this is a problem on the recipients side. We tried to circumvent the problem but your example shows, that the bypass can break. We should change to use the standard line break and tell the forum operators, that problems at this point are problems of the e-mail-clients and are not solvable in the script.

loesler commented 1 year ago

In my case, I believe the problem is the host and not the client. I don't change the mail client but the problem occurs after maintenance of my provider. Is it possible to configure the accepted separator of a mail server?

auge8472 commented 1 year ago

If you are the operator of the e-mail server and you have access to the configuration it might be possible to configure the accepted separators. But this is my pure speculation. At that point a next question (that may not influence the issue at all) comes into my mind.

What, if the server can change the line separators itself? Storybook: the server gets an e-mail to be sent and the server accepts only \r\n. You as the script operator have to follow the rules of the server and you change to \r\n. Because it is known, that a few recipients cannot cope with the standard line separator \r\n, the server changes it to the better supported nonstandard \n.

Long story short: As far as I am aware, the line breaks for the e-mail-headers are configured in a few functions (encode_mail_name, my_mb_encode_mimeheader, overwritten in my_mail, currently in line 2057). The previous listing is valid for the use of the scripts own e-mail-handling functions. If you use the PHP-Mailer class, the handling will differ. As example, I see no setting for the line separator and also no handling of self defined e-mail headers.

loesler commented 1 year ago

No, I don't operate a server, so my provider manged the settings of the mail-server.

In PHP-Mailer, afaik \r\n is used.

auge8472 commented 6 months ago

For documentation

There is a problem with PHP in the versions 8.0 and 8.1. The PHP-developers decided to follow the RFC 2822 when executing PHPs own function mail. Until PHP 7.4 the function transferred the e-mail-headers per default with \n on a unixoid system. The discussion around the bug report (and also an earlier bug report for PHP 4.1.2) made it clear to me why \r\n and \n are involved (after a very long time of doing it right without knowing why).

The function mail does not send e-mails by itself but hands over the e-mails to a Mail Transfer Agent (MTA) in a local terminal. This requires the use of the unixoid line break \n under Linux/Unix because of the local context of the machine, even the e-mail-headers must end with \r\n in context of an e-mail. Problem here is, that we are not in the context of an e-mail at this moment.

Cited from the bug report for PHP 4.1.2:

Line breaks in headers should be the native line endings for the system on which PHP is running.

The mail() function is not talking to an SMTP server, so RFC2822 does not apply here. mail() is talking to a command line program on the local system, and it is reasonable to expect that program to require system-native line breaks.

Cited from a comment in the bug report for PHP 8.0 and 8.1:

BTW why are people pointing to rfc822? The introduction seems very clear to me:

Some message systems may store messages in formats that differ from the one specified in this standard. This specification is intended strictly as a definition of what message content format is to be passed BETWEEN hosts.

Note: This standard is NOT intended to dictate the internal formats used by sites, the specific message system features that they are expected to support, or any of the characteristics of user interface programs that create or read messages.

I have added the highlights.


PHP 8.2.4 and 8.3.4RC1 introduced a setting in the php.ini to switch back to the old behaviour with mixed line breaks (mail.mixed_lf_and_crlf). This new setting was not backported to PHP 8.0 and 8.1 and its value depends on the diligence of the server operator. So using PHPMailer in the SMTP-mode is the way to go because in that mode the class works correct by using \r\n as line separator when sending e-mails directly with a SMTP-server. Using the mail-mode of PHPMailer (the class uses the PHP function mail then) unter PHP 8.0 or 8.1 instead, would end in the same trap as described above.

Long story short: separating the e-mail-headers with \n when using the function mail on a unixoid OS to send the e-mails is not invalid because RFC 822 and RFC 2822 does not apply to the local terminal of a Unix/Linux machine. It's up to the MTA to change the line separators from \n to the e-mail-standard-compliant \r\n.