php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #15841 CRLF to separate mail headers is incorrect
Submitted: 2002-03-02 20:05 UTC Modified: 2007-02-07 10:05 UTC
Votes:122
Avg. Score:4.5 ± 0.8
Reproduced:109 of 113 (96.5%)
Same Version:36 (33.0%)
Same OS:71 (65.1%)
From: rha at juggernaut dot com dot au Assigned: yohgaki (profile)
Status: No Feedback Package: Mail related
PHP Version: 4.1.2 OS: Linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: rha at juggernaut dot com dot au
New email:
PHP Version: OS:

 

 [2002-03-02 20:05 UTC] rha at juggernaut dot com dot au
Last November the mail documentation was changed from saying:
"Multiple extra headers are separated with a newline."
to:
"Multiple extra headers are separated with a carriage return and newline. Note: You must use \r\n to seperate headers, although some Unix mail transfer agents may work with just a single newline (\n)."

This change is inaccurate. 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.

Use of CRLF is known to break qmail systems where no conversion of line breaks occurs on the input data. In this case using CRLF causes all but the first extra header to appear in the message body (CRLF is interpreted as two line breaks).

Possibly the best resolution to this problem would be for the mail() function to convert any line breaks in arg 4 into the system's native line breaks.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-03-03 16:27 UTC] jhaar at trimble dot co dot nz
This is causing mail generated by PHP to be BLOCKED as being potentially a virus by some anti-virus SMTP servers.

The presence of "\r\n" in headers is typically a sign of a virus trying to reach Outlook. Some antivirus products now totally block MIME mail containing "\r\n".

This means all mail generated by PHP programs...
 [2002-03-04 05:36 UTC] hholzgra@php.net
on windows we *do* talk STMP ...
 [2002-03-06 11:04 UTC] pcg-php at ais dot cx
The Right Thing(TM), then, is to determine which method (direct or SMTP injection) is being done. If SMTP, use \r\n. If direct, determine what the OS' line terminator is (\r\n for Windows, \n for Unix, \r for Mac (?!)) and use that instead.
 [2002-03-06 12:28 UTC] hholzgra@php.net
i still do not see the point, even for unix/sendmail

even /usr/lib/sendmail will transfer the message
using SMTP, and during this step you will have
\r\n line endings anyway, or am i missing something?
 [2002-03-06 14:58 UTC] rha at juggernaut dot com dot au
The point is that it is incorrect to send DOS line endings to a Unix command line program.

Sending a message through qmail (for example) with \r\n line endings results in extraneous \r's in the delivered email. qmail assumes the user knows what they're doing and converts only the '\r' characters to '\r\n'. So if you use '\r\n' it injects '\r\r\n' into the SMTP conversation.

e.g. 
Headers:
"X-1: test1\nX-2: test2\r\nX-3: test3\r\nX-4: test4:

Message:
Subject: test message
X-1: test1
X-2: test2^M
X-3: test3^M
X-4: test4

I notice that some mail readers sanitize the incoming message and strip the extra \r's (e.g. Eudora) but Mozilla doesn't and only the first extra header is displayed as a header while the others appear in the body of the message.
 [2002-03-07 04:48 UTC] hholzgra@php.net
ok

1) blame qmail, it should know better ...
2) lets have SMTP as a default implementation
   for Unix mail(), too, instead of relying
   on external programs

the "it isn't broken, so don't fix it" argument
got even weaker right now ...
 [2002-04-23 00:43 UTC] sniper@php.net
reclassified
 [2002-05-25 11:41 UTC] david at acz dot org
I would be VERY nice if PHP would at least have the option of sending mail using SMTP when running under Unix.  It seems silly to support the option only when running under Windows, especially when the code is already written.
 [2002-05-25 19:09 UTC] yohgaki@php.net
I looked for CRLF in source, but I cannot find CRLF with quick glance of current CVS source.
It seems mail.c is not converting LF to CRLF.

Are you using qmail-inject or qmail sendmail wrapper?
I don't have any problem with qmail-inject nor qmail's sendmail wrapper.




 [2002-05-25 19:33 UTC] rha at juggernaut dot com dot au
My phpinfo() says:
sendmail_path    /usr/bin/sendmail -t -i 

I'm running a vanilla qmail installation.

The mail() function works fine... it passes to the MTA whatever data the user supplies for headers, with whatever line breaks the user supplied.

The problem is that the line breaks should be unix-style on a Unix system. But they need to be DOS-style on Windows. This creates a portability issue for PHP scripts.

See my comment of 6 Mar 2:58pm for an example of the problem when using DOS-style line breaks on a Unix system.
 [2002-05-25 21:43 UTC] mfischer@php.net
mail() is NOT the all-in-one solution, nor is it really platform compatible. In fact, win32/mail() is a completely different kind of story (using native socket interface to talk to sendmail daemon on port 25) then on unix (calling another executeable and exchanging data)
 [2002-06-26 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2004-04-18 14:46 UTC] phpbug at labres dot at
Documentation of mail() states:

"Note:  You must use \r\n to separate headers, although some Unix mail transfer agents may work with just a single newline (\n)."

This is WRONG. On Unix systems, any line ending (also between header fields) has to be \n. On Windows Systems, it has to be \r\n.

Here is part of the sounce code in mail.c (in case of a Unix system):
	sendmail = popen(sendmail_cmd, "w");
	fprintf(sendmail, "To: %s\n", to);
	fprintf(sendmail, "Subject: %s\n", subject);
	if (headers != NULL) {
		fprintf(sendmail, "%s\n", headers);
	}
	fprintf(sendmail, "\n%s\n", message);
	ret = pclose(sendmail);

On Windows Systems, the SMTP session is handled within SendText() in sendmail.c, which sends headers and message as is, so the line endings have to be \r\n.

Please correct the above cited note and any samples.

There is a further bug in example 4:
| $headers .= "Bcc: birthdaycheck@example.com\r\n";
     remove the ending line break

The header must not end with a line break. As you can see in above code snipet, the mail implementation adds a \n at the end of the header.

BTW, this is a documentation problem.
 [2004-06-09 09:25 UTC] patpro at patpro dot net
Hi,

I would really want official PHP Team confirmation for 
comments [18 Apr 2:46pm CEST] and [6 Mar 2002 11:04am 
CET].
I'm facing the same problem on FreeBSD 5.x, mod_php4
-4.3.6_1,1
If you follow the documentation (using \r\n) mail() will 
output badly formated headers. Many SMTPds or Filters 
will rewrite headers (sendmail does, Amavisd-new does, 
..., but postfix alone doesn't, for example)

I've set up a shell script to pipe mail()'s output into 
a file rather than into a SMTP : 

  $ more /usr/local/sbin/sendmail.cat 
  #!/bin/sh
  cat > /tmp/mailout

then I've set sendmail path to /usr/local/sbin/
sendmail.cat in httpd.conf : 

  php_admin_value sendmail_path "/usr/local/sbin/
sendmail.cat"

using \r\n as a header separator results in a mix of \n 
and \r\n :

  $ cat -v /tmp/mailout
  To: patpro@example.com
  Subject: un dernier test
  From: patpro@example.com^M
  Reply-To: patpro@example.com^M
  Content-Type: text/html; charset=iso-8859-1^M
  MIME-Version: 1.0^M
  Content-Transfer-Encoding: 8bit^M

this mix is not RFC compliant and breaks rendering in 
many mail clients.

It would be nice to change the php documentation 
accordingly, and even nicer to provide mail() with the 
ability to reformat headers.
 [2004-09-28 00:41 UTC] zap at cyborganic dot net
I suddenly had header problems. Perhaps my host changed mail configs or updated PHP (they never reply to my email, so I don't ask many question). In any case, all my beautiful HTML emails were being sent out with broken headers that yturned them into ugly unreadable text and code.

I am on a Unix server, so I changed all my /r/n newlines to /n. This fixed the issue immediately. If you find this happens to you, just use the appropriate newline characters for your host OS.

THANKS for pointing out this bug!
 [2005-06-27 21:41 UTC] guy dot kastenbaum at filnet dot net
I agree with @patpro, mail() should reformate the headers.

This is my quick-and-dirty workaround (from a Q&D specialist) , in /etc/php.ini :

sendmail_path = "unix2dos|dos2unix|sendmail -t -i"


Guyzmo -- (don't let me programm after midnight)
 [2005-07-27 16:01 UTC] mark at thelecks dot com
So has there been any resolution to this? Has PHP made any modifications to their mail function? or provided a better work around?
 [2006-07-11 18:30 UTC] bug at bug dot com
what php needs is to make the $headers argument for the mail() function an array instead of a string and then php will automagically put the correct line endings depending on what OS it's running on. \n for unix, \r\n for windows, \r for mac

you can keep it backwards compatiable by accepting a string as well. also add another option in the php.ini to enable/disable the mangling of the header line endings.

could we get an update on this bug please?
 [2006-07-11 20:03 UTC] bug at bug dot com
nevermind, please delete my previous comment. qmail is broken and dead. let's just move forward instead of trying to support legacy software and holding technology back.

please close this ticket and label it as "will not fix," which i suppose is the correct status.
 [2006-11-30 08:10 UTC] tech+ohtf dot cuc dot arg at onlineopinion dot com dot au
The PHP documentation now asks for "\n" , which is correct for its implementation in Unix systems, so the bug as originally reported is solved. I can't comment on whether this change might have caused problems in Windows, but I assume not.

Note: This was not just an issue with qmail; it also affected postfix's implementation of 'sendmail'.
 [2007-02-07 09:55 UTC] bigtree at donotspam dot 29a dot nl
Might I suggest to add a platform-dependant PHP constant (for example MAIL_HEADER_SEPARATOR) so we can use the mail() function with platform-independent code?

The constant value would be '\n' on unix and '\r\n' on windows.
 [2007-02-07 10:05 UTC] tony2001@php.net
http://www.php.net/manual/en/reserved.constants.php

PHP_EOL (string) 
Available since PHP 4.3.10 and PHP 5.0.2
 [2007-02-21 09:16 UTC] m_alpka at tlen dot pl
I discovered another temporary solution. It's similar to @guy's but it is not using additional scripts that have to be installed (unix2dos,dos2unix). Also php didn't allow me to use piped sendmail in sendmail_path (php.ini)
I'm using qmail.

---
cd /var/qmail/bin
cat > sendmailfix

#!/bin/sh
sed 's/^M$//' | /var/qmail/bin/sendmail ${1+"$@"}
[Ctrl+D]

chmod 555 sendmailfix
chgrp popuser sendmailfix
---
^M is a combination of [Ctrl+V, Ctrl+M]

Finally set the value of sendmail_path in php.ini to our script

---
sendmail_path = /var/qmail/bin/sendmailfix -t -i
 [2008-10-16 13:12 UTC] devnull at div dot org
I just had a little run-in with the postfix developers over at postfix-users about this issue.

http://tech.groups.yahoo.com/group/postfix-users/message/244799

Quote:Wietse Venema:
>> Specifically, Postfix accepts local submissions in UNIX format
>> (LF) or MSDOS format (CRLF) format BUT YOU MIST NOT MIX FORMATS.
>
> So how does postfix determine what format you are using?
> Is there a way to explicitly tell it what to expect?
>
Postfix looks at the first input line. There currently is no
way to override this, so your best bet is to use the same line
terminator consistently (having a first line with CRLF might
work "best" for hybrid mail, but that behavior is not promised).

The current behavior originates from the time when binary transparency
was considered a good thing.
--

There seemed to me to be a marked hostility towards the idea of trying to be helpful about this, but on the other hand I got the impression they might not be hostile if someone offered a patch for a 
SENDMAIL_EOF_COMPAT_MODE or similar.

Personally I am not much good at C, but the challenge is hereby issued :)
 [2009-02-28 12:48 UTC] philipp dot kempgen at amooma dot de
Ok guys, if it's not mail() which is wrong then
it's a documentation problem.
---cut---
Note: If messages are not received, try using a LF (\n) only. Some poor quality Unix mail transfer agents replace LF by CRLF automatically (which leads to doubling CR if CRLF is used). This should be a last resort, as it does not comply with ? RFC 2822.
---cut---

This is _not_ about "poor quality" MTAs or a "last resort".

The note should read:
Note: mail() talks to the sendmail command on Unix/Linux which
expects line endings to be the platform's native line endings
which is LF (\n) only on Unix/Linux and CRLF (\r\n) on Windows.
The sendmail will replace LF (\n) by CRLF (\r\n) automatically
to comply with RFC 2822. Thus you should use the special PHP_EOL
constant to separate mail headers.
 [2009-04-23 12:47 UTC] bernardo at tsolucio dot com
I agree totally with Philipp, the current documentation note is ridiculous.Can't developers understand that they're not dealing with a STMP server on Linux? If you don't want to fix it, at least document the flaw correctly.
 [2013-06-04 16:54 UTC] butesa at freenet dot de
This Code:
mail('nobody@example.com','test','Message Body',"From: me@example.com\r\nContent-Type: text/plain");

passes this to sendmail:

To: nobody@example.com\n
Subject: test\n
From: me@example.com\r\n
Content-Type: text/plain\n
\n
Message Body\n

(on a Ubuntu 10.04 installation from ubuntu repository)
So PHP uses \n to terminate the headers it creates on its own. It makes no sense to terminate additional headers with \r\n.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 06 18:01:28 2024 UTC