php / php-src

The PHP Interpreter
https://www.php.net
Other
37.98k stars 7.73k forks source link

mail() breaks quoted_printable_encode()d subject #14084

Closed hornschorsch closed 2 months ago

hornschorsch commented 4 months ago

Description

The following code:

$subject = "=?$charset?Q?" . quoted_printable_encode("Onlinetreffen $thema $datum $zeit") . "?=";
[...]
mail("$mailname <$email>", $subject, $mailtext, $headers, "-f $mailfrom");

Resulted in an email with this header:

Subject: =?iso-8859-1?Q?Onlinetreffen Starke Leistungen - fairer Beitrag: Das sollten ver.di Mitgli=  eder unbedingt wissen 14.05.2024 17:00:00?=

But I expected this header instead:

Subject: =?iso-8859-1?Q?Onlinetreffen Starke Leistungen - fairer Beitrag: Das sollten ver.di Mitgli=
 eder unbedingt wissen 14.05.2024 17:00:00?=

This happens because quoted_printable_encode() wraps lines at 75 characters and therefore inserts a "=\r\n" but the mail() function replaces every control character, that is not a \r followed by \n followed by space, with a space.

So quoted_printable_encode() should insert an additional space to prevent mail() from replacing the \r\n with spaces or the check in mail() should not check for a space after "\r\n" but for a "=" before the "\r\n"

https://github.com/php/php-src/blob/master/ext/standard/quot_print.c#L175 https://github.com/php/php-src/blob/master/ext/standard/mail.c#L307 https://github.com/php/php-src/blob/master/ext/standard/mail.c#L49

PHP Version

current version, see links to sourcecode

Operating System

No response

SakiTakamachi commented 4 months ago

I have a question, is the notation using = still valid? That's code written a long time ago...

hornschorsch commented 4 months ago

According to http://www.faqs.org/rfcs/rfc2045.html it is the correct notation:

(Soft Line Breaks) The Quoted-Printable encoding REQUIRES that encoded lines be no more than 76 characters long. If longer lines are to be encoded with the Quoted-Printable encoding, "soft" line breaks must be used. An equal sign as the last character on a encoded line indicates such a non-significant ("soft") line break in the encoded text.

Perhaps quoted_printable_encode() is not the right function to encode the subject for the mail() function? How do you encode it then?

cmb69 commented 2 months ago

I don't think there is a bug, since quoted_printable_encode() is documented to encode according to RFC 2045, but mail()s $subject parameter must satisfy RFC 2047 (what is also documented). Besides this possibly minor difference, there might be issues regarding the line length, since quoted_printable_encode() doesn't know the charset, nor is aware that you're producing a Subject: line.

Perhaps quoted_printable_encode() is not the right function to encode the subject for the mail() function? How do you encode it then?

The simplest solution is to use a well tested mailer library.

cmb69 commented 2 months ago

Per my comment above I'm closing this ticket as "invalid".