Fork me on GitHub
Subscribe 6

Ticket #897 (fixed bug)

"\r\n" breaks headers in email in certain conditions

  • Created: 2013-09-04 19:51:16
  • Reported by: sklerder
  • Assigned to: quy
  • Milestone: 1.5.5
  • Component: email
  • Priority: normal

This ticket is a continuation of ticket #830, which should have solved the problem with line-breakings in headers.

The problem is more complicated, depending on the OS and much more on the MTA used.

A piece of discussion related to this problem is available here.


The proposal of solution would be the following :
- First, define a "FLUXBB_EOL" constant in "/config.php" :

// To handle line breaks in mail headers
// possible values can be : PHP_EOL, "\r\n", "\n" or "\r"
// Original value is PHP_EOL (handled by the OS)
define ('FLUXBB_EOL', PHP_EOL);

- Then, modify the two lines defining "$headers" that were modified by 1.5.4 in "/include/email.php" :

	$headers = 'From: '.$from.FLUXBB_EOL.'Date: '.gmdate('r').FLUXBB_EOL.'MIME-Version: 1.0'.FLUXBB_EOL.'Content-transfer-encoding: 8bit'.FLUXBB_EOL.'Content-type: text/plain; charset=utf-8'.FLUXBB_EOL.'X-Mailer: FluxBB Mailer';

	// If we specified a reply-to email, we deal with it here
	if (!empty($reply_to_email))
	{
		$reply_to = '"'.encode_mail_text($reply_to_name).'" <'.$reply_to_email.'>';

		$headers .= FLUXBB_EOL.'Reply-To: '.$reply_to;

And the results, on CentOS 6.3 with Postfix 2.6.6 as MTA :
- With FLUXBB_EOL defined to PHP_EOL, it's OK (headers are not broken, UTF-8 is OK)
- With FLUXBB_EOL defined to "\n", it's OK (headers are not broken, UTF-8 is OK)
- With FLUXBB_EOL defined to "\r\n", it's not OK (headers are broken, UTF-8 is bad)
- With FLUXBB_EOL defined to "\r", it's not OK (headers are not broken, UTF-8 is bad)

History

sklerder 2013-09-04 19:53:19

  • Component set to email.

Studio384 2013-09-04 19:58:23

  • Milestone set to 1.5.5.

sklerder 2013-09-05 21:20:35

  • Description changed. (Diff)

JohnLewis 2013-09-08 13:50:39

  • Owner set to JohnLewis.

quy 2013-10-10 17:48:06

Please review this solution:

In email.php find:

require PUN_ROOT.'include/utf8/utils/ascii.php';

Above add:

// Define line breaks in mail headers; possible values can be PHP_EOL, "\r\n", "\n" or "\r"
if (!defined('FORUM_EOL'))
	define('FORUM_EOL', PHP_EOL);

Find:

	$headers = 'From: '.$from."\r\n".'Date: '.gmdate('r')."\r\n".'MIME-Version: 1.0'."\r\n".'Content-transfer-encoding: 8bit'."\r\n".'Content-type: text/plain; charset=utf-8'."\r\n".'X-Mailer: FluxBB Mailer';

	// If we specified a reply-to email, we deal with it here
	if (!empty($reply_to_email))
	{
		$reply_to = '"'.encode_mail_text($reply_to_name).'" <'.$reply_to_email.'>';

		$headers .= "\r\n".'Reply-To: '.$reply_to;
	}

Replace:

	$headers = 'From: '.$from.FORUM_EOL.'Date: '.gmdate('r').FORUM_EOL.'MIME-Version: 1.0'.FORUM_EOL.'Content-transfer-encoding: 8bit'.FORUM_EOL.'Content-type: text/plain; charset=utf-8'.FORUM_EOL.'X-Mailer: FluxBB Mailer';

	// If we specified a reply-to email, we deal with it here
	if (!empty($reply_to_email))
	{
		$reply_to = '"'.encode_mail_text($reply_to_name).'" <'.$reply_to_email.'>';

		$headers .= FORUM_EOL.'Reply-To: '.$reply_to;
	}

To override FORUM_EOL, add the following line to config.php:

define('FORUM_EOL', PHP_EOL);

quy 2013-10-12 19:29:08

  • Owner changed from JohnLewis to quy.
  • Status changed from open to fixed.

quy 2013-10-12 19:29:26

Commit 7d06069 to fluxbb master

#897: Define FORUM_EOL constant to deal with line breaks in mail headers. Thank sklerder.

seven 2014-02-05 17:57:13

I don't believe this to be the solution.

\r\n should be used always with smtp_mail(), because we're opening a socket and talking directly to a remote SMTP server, therefore we have to adhere to the standard.

PHP_EOL should be used with mail(), because all it does is to pass the data to the local MTA. The MTA expects newlines to be the operating system default. PHP_EOL holds the default. It's the MTA who will replace newlines if needed.

Very much like big endian/little endian. You don't have to worry about the endianness of your system when sending data-this is done by the abstraction layers, unless you're opening the socket yourself in C.

Therefore I'd set $headers with PHP_EOL.

Only if we're about to call smtp_mail() I'd do:

// .....
if(PHP_EOL != "\r\n")
{
    $headers = str_replace(PHP_EOL, "\r\n", $headers);
    $message = str_replace(PHP_EOL, "\r\n", $message);
}
smtp_mail($to, $subject, $message, $headers);
// .....

Franz 2014-02-06 10:09:17

Thank you, this makes sense. I opened a new ticket for this.