Error with PHP mail(): Multiple or malformed newlines found in additional_header

Attention: open in a new window. PDFPrintE-mail

A new update for PHP has broken a few mailing scripts that a few of our clients use (https://bugs.php.net/bug.php?id=68776)

More specifically, the script sends an email with an attachment - I wrote these using some guides from other sites however it now appears that i've been ill advised as its not technically the correct way to do it.

Original (now broken code) below:

function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = "From: ".$from_name." \r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= $message."\r\n\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$header .= $content."\r\n\r\n";
$header .= "--".$uid."--";
error_reporting(E_ALL);
if (mail($mailto, $subject, "", $header)) {
echo "Mail Sent Successfully to " . $mailto .""; // or use booleans here
} else {
echo "Mail NOT Sent to " .$mailto ."";
}

There are now more checks on the header field, which means data which was being stuffed into the header should now really be in the message. See the changes I made to get this working with our webservers (highlighted in yellow):

function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = "From: ".$from_name." \r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
(THIS ENTIRE LINE HAS BEEN REMOVED)
$nmessage = "--".$uid."\r\n";
$nmessage .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$nmessage .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$nmessage .= $message."\r\n\r\n";
$nmessage .= "--".$uid."\r\n";
$nmessage .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$nmessage .= "Content-Transfer-Encoding: base64\r\n";
$nmessage .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$nmessage .= $content."\r\n\r\n";
$nmessage .= "--".$uid."--";
error_reporting(E_ALL);
if (mail($mailto, $subject, $nmessage, $header)) {
echo "Mail Sent Successfully to " . $mailto .""; // or use booleans here
} else {
echo "Mail NOT Sent to " .$mailto ."";
}

}

And that sorted it out - I hope this helps someone as I had a hell of a time trying to work out what the error message meant and its been pretty vague. Add to this the comments on the PHP bug fix page which aren't that helpful and its quite difficult to sort out. Please +1/share this if it helps you so it can help others