web-dev-qa-db-fra.com

Erreur avec PHP mail (): newlines multiples ou malformées trouvées dans additional_header

Soudain, ont commencé à recevoir l'erreur ci-dessus sans qu'aucune modification n'ait été apportée au script.

L'hôte est 1and1 (je sais ...)

Le script fonctionne toujours correctement sur un autre serveur. Je pense donc que certains changements de configuration du serveur ont conduit à cette situation, bien que les hôtes invoquent leur ignorance.

Je ne trouve aucune information sur l'erreur susmentionnée dans Google. Quelqu'un a-t-il des idées? Le serveur exécute Apache si cela aide.

37
freestate

Aucune des réponses ci-dessus n'a résolu ce problème pour moi. J'ai donc élargi ma recherche à "courrier avec problèmes de pièce jointe et de message HTML". Rassemblant ensemble des informations de différents articles, je les ai trouvées. Il permet [~ # ~] à la fois [~ # ~] Un email HTML et une pièce jointe.

Mon code d'en-tête d'origine:

$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 8bit\r\n";
$header .= $body."\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: application/pdf; name=\"".$filename."\"\r\n"; 
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n";
$header .= $content."\r\n";
$header .= "--".$uid."--";

if (mail($mail_to, $subject, "", $header))
{
    return "mail_success";
}
else
{
    return "mail_error";
}

Mon nouveau code (complet): Notez que $ body est le code HTML en cours d'assemblage par une fonction différente.

$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);

$eol = PHP_EOL;

// Basic headers
$header = "From: ".$from_name." <".$from_mail.">".$eol;
$header .= "Reply-To: ".$replyto.$eol;
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"";

// Put everything else in $message
$message = "--".$uid.$eol;
$message .= "Content-Type: text/html; charset=ISO-8859-1".$eol;
$message .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$message .= $body.$eol;
$message .= "--".$uid.$eol;
$message .= "Content-Type: application/pdf; name=\"".$filename."\"".$eol;
$message .= "Content-Transfer-Encoding: base64".$eol;
$message .= "Content-Disposition: attachment; filename=\"".$filename."\"".$eol;
$message .= $content.$eol;
$message .= "--".$uid."--";

if (mail($mail_to, $subject, $message, $header))
{
    return "mail_success";
}
else
{
    return "mail_error";
}

Deux changements clés ici. (1) a supprimé tous les trucs en plusieurs parties des en-têtes dans $ message. (2) a supprimé tous les "\ r\n" et ajouté $eol = PHP_EOL; au code.

Ensemble, ces modifications m'ont permis d'envoyer à nouveau un courrier électronique HTML avec des pièces jointes.

42
seveninstl

Avait le même problème: Suppression de la limite de mime et le message de l'en-tête et tout a fonctionné.

    $header = "From: ".$from_name." <".$from_mail.">\n";
    $header .= "Reply-To: ".$replyto."\n";
    $header .= "MIME-Version: 1.0\n";
    $header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\n\n";
    $emessage= "--".$uid."\n";
    $emessage.= "Content-type:text/plain; charset=iso-8859-1\n";
    $emessage.= "Content-Transfer-Encoding: 7bit\n\n";
    $emessage .= $message."\n\n";
    $emessage.= "--".$uid."\n";
    $emessage .= "Content-Type: application/octet-stream; name=\"".$filename."\"\n"; // use different content types here
    $emessage .= "Content-Transfer-Encoding: base64\n";
    $emessage .= "Content-Disposition: attachment; filename=\"".$filename."\"\n\n";
    $emessage .= $content."\n\n";
    $emessage .= "--".$uid."--";
    mail($mailto,$subject,$emessage,$header);
11
Frank

Aucune de ce qui précède ne l'a corrigé pour moi - le problème principal est que vous ne devez rien mettre d'autre que des définitions d'en-tête dans les en-têtes. Les vieux scripts bloquaient quoi que ce soit à l'intérieur. Donc, déplacez le texte ou les pièces jointes qui ont été insérés dans les en-têtes du corps du message. Logique..

Ceci a un explication
(Je suppose que c'est la même solution que celle de Frank ci-dessus, plus "pas de doubles lignes nouvelles" de Davisca - mais vous avez besoin de doubler de nouvelles lignes pour les pièces jointes)

5
anoldermark

mon PHP version - 5.4.43, contient probablement le bogue corrigé n ° 68776.

google à la même erreur a montré [ http://fossies.org/diffs/php/5.4.42_vs_5.4.43/ext/standard/mail.c-diff.html]

=> Je ne peux pas utiliser de chaînes vides comme paramètres mail ().

mon ancien code:

$headers = 'From: ' . $frm . "\r\n";
$headers .= 'To: ' . $contactEmail . "\r\n";
if ( $flag ) {
  $headers .= 'To: ' . $contactEmail2 . "\r\n";
}
$headers .= 'Cc: ' . $contactEmailCc . "\r\n";
$headers .= 'Bcc: ' . $contactEmailBcc . "\r\n";
$headers .= 'Return-Path: ' . $frm . "\r\n";
$headers .= 'MIME-Version: 1.0' ."\r\n";
$headers .= 'Content-Type: text/HTML; charset=ISO-8859-1' . "\r\n";
$headers .= 'Content-Transfer-Encoding: 8bit'. "\n\r\n";

$headers .= $htmlText . "\r\n";

if (!mail('', $strSubject, '', $headers)) {    // !!! note the empty parameters.

mon nouveau code:

$headers = 'From: ' . $frm . "\r\n";
// note: no "To: " !!!
$headers .= 'Cc: ' . $contactEmailCc . "\r\n";
$headers .= 'Bcc: ' . $contactEmailBcc . "\r\n";
$headers .= 'Return-Path: ' . $frm . "\r\n";
$headers .= 'MIME-Version: 1.0' ."\r\n";   
$headers .= 'Content-Type: text/HTML; charset=ISO-8859-1' . "\r\n";
$headers .= 'Content-Transfer-Encoding: 8bit'. "\n\r\n";
// note: no $htmlText !!!

// note: new parameters:  
$mTo = $contactEmail;
if ( $flag ) {
  $mTo .= ', ' . $contactEmail2;
}

$mMessage .= $htmlText . "\r\n";

if (!mail($mTo, $strSubject, $mMessage, $headers)) {
2
Atara

Cela résoudra votre problème. J'ai changé un peu le code de Frank. Ce code supportera les pièces jointes et html.

 <?php

$filename  = "certificate.jpg";
$path      = "/home/omnibl/subdomains/test/certificate/certimage/";
$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);

$eol     = PHP_EOL;
$subject = "Mail Out Certificate";
$message = '<h1>Hi i m mashpy</h1>';

$from_name = "[email protected]";
$from_mail = "[email protected]";
$replyto   = "[email protected]";
$mailto    = "[email protected]";
$header    = "From: " . $from_name . " <" . $from_mail . ">\n";
$header .= "Reply-To: " . $replyto . "\n";
$header .= "MIME-Version: 1.0\n";
$header .= "Content-Type: multipart/mixed; boundary=\"" . $uid . "\"\n\n";
$emessage = "--" . $uid . "\n";
$emessage .= "Content-type:text/html; charset=iso-8859-1\n";
$emessage .= "Content-Transfer-Encoding: 7bit\n\n";
$emessage .= $message . "\n\n";
$emessage .= "--" . $uid . "\n";
$emessage .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"\n"; // use different content types here
$emessage .= "Content-Transfer-Encoding: base64\n";
$emessage .= "Content-Disposition: attachment; filename=\"" . $filename . "\"\n\n";
$emessage .= $content . "\n\n";
$emessage .= "--" . $uid . "--";
mail($mailto, $subject, $emessage, $header);
2
Mashpy Says

Si vous n'envoyez aucun en-tête à la commande "mail", un autre scénario qui génère la même nouvelle erreur est le même. Auparavant, il utilisait simplement une valeur par défaut et donnait maintenant l'erreur trompeuse: "Les retours à la ligne multiples ou mal formés trouvés dans additional_header".

Peut être corrigé en ajoutant ceci:

$header = "From: ".$from_name." <".$from_mail.">\n";
$header .= "Reply-To: ".$replyto."\n";
$header .= "MIME-Version: 1.0\n";

...

mail($mailto,$subject,$emessage,$header);
2
eyal_katz

Vous rencontrez peut-être bug n ° 69874 ne peut pas définir de additional_headers vides pour mail () si vous n’avez rien fait de stupide (c’est-à-dire que vous avez oublié de nettoyer les en-têtes).

Test du bug

$ php -d display_errors=1 -d display_startup_errors=1 -d error_reporting=30719 -r 'mail("[email protected]","Subject Here", "Message Here",NULL);'

Warning: mail(): Multiple or malformed newlines found in additional_header in Command line code on line 1

Alternativement, si vous connaissez votre version PHP version (indice: php -v) vous pouvez vérifier le changelog pour le numéro de bogue (69874) pour voir si le correctif a été appliqué pour votre version.

Une solution à court terme consiste à remplacer les appels à mail () comme ceci

 function fix_mail(  $to ,  $subject ,  $message , $additional_headers =NULL,  $additional_parameters=NULL ) {
            $to=filter_var($to, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES| FILTER_FLAG_STRIP_LOW| FILTER_FLAG_STRIP_HIGH);
            $subject=filter_var($subject, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES| FILTER_FLAG_STRIP_LOW| FILTER_FLAG_STRIP_HIGH);             

            if (!$additional_headers)
                    return mail(  $to ,  $subject ,  $message );

            if (!$additional_parameters)
                     return mail(  $to ,  $subject ,  $message , $additional_headers );

            return mail(  $to ,  $subject ,  $message , $additional_headers, $additional_parameters );
    }
1
b7kich

Il est fort probable que quelqu'un essaie de tirer parti de votre code pour injecter des en-têtes de courrier électronique.

http://resources.infosecinstitute.com/email-injection/

Je vous suggérerais d’examiner les journaux d’accès, etc. et de rechercher une activité inhabituelle. Le fait que vous obteniez des messages d'erreur signifie, espérons-le, que votre script n'a pas été compromis et qu'il est erroné à la place. Vous devez vous assurer cependant.

0
edmondscommerce