0

When a Subject header is MIME encoded and folded mail() results in PHP warning:

<?php
$mime_subject = "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\r\n =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=";
mail( "name@domain.com", $mime_subject , "Hallo");

=> mail(): Bad parameters to mail() function, mail not sent.

The subject line is one of the examples in RFC2047 (section 8). It is folded to two lines and mail() does not like it. Since it works fine on other hosts I suspect a wrong configuration. But which one would that be?

PHP is Version 5.4.0

Any ideas?

EDIT:

Some more info regarding the php configuration:

'./configure' '--prefix=/home/www/PHP/php-5.4.0' '--with-openssl'
    '--with-zlib-dir=/usr/lib/' '--with-jpeg-dir=/usr/lib/' '--with-mysql'
    '--enable-fastcgi' '--with-informix=/opt/informix'
    '--with-oci8=shared,instantclient,/opt/oracleclient/instantclient,10.2'
    '--enable-pcntl' '--with-gettext' '--with-ldap' '--with-curl'
    '--with-gd' '--with-freetype-dir=/usr/include/freetype2/' '--with-dom'
    '--enable-bcmath' '--enable-soap' '--enable-mbstring'
    '--with-mcrypt=shared,/usr/local/libmcrypt' '--enable-pdo'
    '--with-pdo-mysql' '--enable-zip' '--with-imap' '--with-kerberos'
    '--with-imap-ssl' '--with-ldap-sasl' '--with-icu-dir=/usr' '--enable-intl'

mail.add_x_header   Off Off
mail.force_extra_parameters no value    no value
mail.log    no value    no value
sendmail_from   no value    no value
sendmail_path   /usr/sbin/sendmail -t -i    /usr/sbin/sendmail -t -i 
SMTP    localhost   localhost
smtp_port   25  25

mailparse version 2.1.6
EricSchaefer
  • 25,272
  • 21
  • 67
  • 103
  • What's the purpose of the line break? You are not passing in anything human readable anyway, and I speculate that removing it would solve the problem. – tripleee Apr 26 '13 at 16:14
  • 2
    Because of RFC2047 Section 2. Syntax of encoded-words: An 'encoded-word' may not be more than 75 characters long, including 'charset', 'encoding', 'encoded-text', and delimiters. If it is desirable to encode more text than will fit in an 'encoded-word' of 75 characters, multiple 'encoded-word's (separated by CRLF SPACE) may be used. (http://www.ietf.org/rfc/rfc2047.txt) – EricSchaefer Apr 26 '13 at 17:27
  • Yes, but if this isn't what the PHP interface exposes towards you, it's not necessarily relevant. – tripleee Apr 26 '13 at 18:13
  • I am not sure I understand what you mean. According to http://php.net/manual/en/function.mail.php, the subject needs to adhere to 2047. I tested it on other machines where it worked. I just want to find out, why it is not working on the one machine. – EricSchaefer Apr 27 '13 at 09:46

1 Answers1

1

You are correct that the example should just work as 'I can read this'. But another note in the PHP docs mentions that some mail transfer agents automatically change the \n to \r\n and thus leading to problems if you already provided \r\n (becomes \r\r\n).

So you could try using the code below (although it does not comply to the standards, your mail agent might make it complient)

<?php
$mime_subject = "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\n=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=";
mail( "name@domain.com", $mime_subject , "Hallo");
?>

PHP has little check for valid subject in the code it self, so its all handled by your mail agent.

PHP sourcecode (only subject check, to see it doesnt do anything special):

if (subject_len > 0) {
  subject_r = estrndup(subject, subject_len);
  for (; subject_len; subject_len--) {
    if (!isspace((unsigned char) subject_r[subject_len - 1])) {
      break;
    }
    subject_r[subject_len - 1] = '\0';
  }
  for (i = 0; subject_r[i]; i++) {
    if (iscntrl((unsigned char) subject_r[i])) {

      /* According to RFC 822, section 3.1.1 long headers may be separated into
       * parts using CRLF followed at least one linear-white-space character ('\t' or ' ').
       * To prevent these separators from being replaced with a space, we use the
       * SKIP_LONG_HEADER_SEP to skip over them. */

      SKIP_LONG_HEADER_SEP(subject_r, i);
      subject_r[i] = ' ';
    }
  }
} else {
  subject_r = subject;
}
Hugo Delsing
  • 13,803
  • 5
  • 45
  • 72
  • The problem occurres with \n and \r\n. The extra space is required in the standard. I guess it is for detecting a multi line header. It even says so in the source you posted. – EricSchaefer Apr 29 '13 at 15:09
  • We are using sendmail. Do you happen to which configuration might cause this error? – EricSchaefer Apr 29 '13 at 15:10
  • Stupid, first typed the space part and then added the code. Removed it. The extra `\r` is in several but according to qmail is most known for it. Is it possible that your files/encoding is of? What if you use `utf8_encode($subject)` to send it? check http://stackoverflow.com/questions/8171856/mimetext-utf-8-encode-problems-when-sending-email for a python script with encoding issues on sendmail – Hugo Delsing Apr 29 '13 at 15:32
  • No UTF-8, only ISO-8859-1. Only non-english characters that are part of 8859-1 are used (german umlauts and french accented characters). – EricSchaefer Apr 29 '13 at 17:29
  • Its kind of a guessing game :) But my server has a few different settings then yours, if you can change it to test, might get it to work. For me `mail.add_x_header` is both on, `sendmail_from` has a local value (email adres), `sendmail_path` has no value. Also the `mail.log` is set, but I dont think that matters. But ofcourse setting the log could help you determine where it goes wrong. None of the settings are directly related to what you are doing, but since it should just work, you sometimes find a solution in the strangest places – Hugo Delsing May 02 '13 at 11:55