-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subject Encoding #133
Comments
I think you're getting a bit enthusiastic with the encoding. If I start with your subject line:
I decode that and I get:
which is what appears in your screen shot. First thought: "it failed to decode!"; Second thought: "It's encoded twice!"! Decode it again, and hey presto:
Are you, by any chance, encoding the header before passing it to PHPMailer? If so, just don't. PHPMailer will encode it for you. Just say: $this->mail->Subject = 'Gleez CMS - Проверка регистрационных данных для Sergey'; PHPMailer is actually cleverer than that too. B-encoding is quite an overhead if only a few chars actually need encoding, so it checks which of B and Q encoding (or none) will produce the shorter result. |
@Synchro For experimental purposes, I really tried use a simple, test string: $this->mail->Subject = 'Gleez CMS - Проверка регистрационных данных для Sergey'; and received it
I do not quite guess what is wrong. |
I can't reproduce this error. This is my complete test script. I'm sending to a local fake mail server and the subject appears correctly. <?php
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->isSMTP();
$mail->Host = 'localhost';
$mail->Port = 2500;
$mail->setFrom('[email protected]', 'Gleez CMS');
$mail->addAddress('[email protected]');
$mail->WordWrap = 70;
$mail->CharSet = 'UTF-8'; // the same as 'utf-8'
$mail->XMailer = 'Gleez CMS 0.10.5';
$mail->setLanguage('ru');
$mail->Subject = 'Gleez CMS - Проверка регистрационных данных для Sergey';
$mail->Body = 'hello';
$mail->send(); When I open the resulting email, it looks like this: Maybe try a fake mail server, or enable debug output in SMTP to see what's going out. Also try putting a breakpoint or an echo in the |
@Synchro Yes, I spent a small exeperimental $str = '=?UTF-8?B?PT91dGYtOD9CP1IyeGxaWG9nUTAxVElDMGcw?=
=?UTF-8?B?Si9SZ05DKzBMTFF0ZEdBMExyUXNDRFJnTkMxMExQUXVOR0IwWUxSZ05Ddz89?=
=?UTF-8?B?CiA9P3V0Zi04P0I/MFliUXVOQyswTDNRdmRHTDBZVWcwTFRRc05DOTBMM1Jp?=
=?UTF-8?B?OUdGSU5DMDBMdlJqeUJUWlhKblpYaz0/PQ==?=';
$decoded = imap_utf8(imap_utf8($str));
// Gleez CMS - Проверка регистрационных данных для Sergey
$decoded = mb_decode_mimeheader(mb_decode_mimeheader($str));
// Gleez CMS - Проверка регистрационных данных для Sergey It's good - at least I now understand what is happening. But frankly I'm not quite (yet) know what can I do |
I spotted something suspicious. The double-encoded header you are getting has a charset of |
Full listing First class class Email {
protected $mail;
public static function factory() {
return new Email();
}
public function __construct()
{
require 'PHPMailerAutoload.php';
// Create phpmailer object
$this->mail = new PHPMailer(true);
// Set some defaults
$this->mail->setFrom('[email protected]', 'Gleez CMS');
$this->mail->WordWrap = 70;
$this->mail->CharSet = 'utf-8';
$this->mail->XMailer = 'Gleez CMS 0.10.5';
$this->mail->setLanguage('ru');
$this->mail->Debugoutput = 'error_log';
}
public function subject($subject)
{
$this->mail->Subject = $subject;
return $this;
}
public function to($email, $name = NULL)
{
$this->mail->addAddress($email, $name);
return $this;
}
public function message($body, $type = NULL)
{
if ( ! $type OR $type === 'text/plain')
{
// Set the main text/plain body
$this->mail->Body = $body;
}
else
{
// Add a custom mime type
$this->mail->msgHTML($body);
}
return $this;
} Another class // Create an email message
$email = Email::factory()
->subject('Gleez CMS - Проверка регистрационных данных для Sergey')
->to('[email protected]', 'Sergey')
->message('hello');
// Send the message
$email->send(); Now result is (Source of mail in GMail)
Subject in GMail
It turns out indeed, something is trying to encode a 2 times Subject. But then how can I decode the string before passing it to the class? |
OK, I set up a test using your code (I added a send function to the class), and sending via SMTP or sendmail (using the fakesendmail script in the tests folder), just adding these lines to the constructor: $this->mail->isSendmail();
$this->mail->Sendmail = './test/fakesendmail.sh'; both sending mechanisms produced identical, correct subject lines. Maybe your mail server is doing something strange? Can you try using the fake smtp or sendmail servers? |
Hm... Maybe mail server is doing something strange... |
Done! I manually created fake sendmail server (shell script) and used test described above. |
Hm. So it's still double-encoding. Next step is to track down how that's happening. If you have a debugger configured (e.g. xdebug in PHPStorm), set a breakpoint in the encodeHeader function around line 2269 which is |
To my regret I am having difficulty with the debugger. At least further index.php I was not able to pass. Tomorrow I'll try to understand. I'll let you know results of debugging. Sorry to trouble you. |
What I was suggesting is that with the breakpoint set there, and the problem you're seeing, we would expect to hit that line twice. in your screen shot we can see that it's being called from preSend, as expected, and $str contains the unencoded subject line - what I want to know is how and when it gets called again. |
What should I do? What kind of special debugging techniques? Any ideas? |
Nothing too special - the lower left-hand panel shows the call stack, so you can see how it got to this point. If you click the green arrow on the left, it will continue until it hits the breakpoint for the second time (or not, if it doesn't happen), at which point we'll (hopefully) know how it got there. |
Aha! I think we've found it. The subject is encoded during |
Ok! Good night :) Catch you later |
I think I spoke too soon. While <?php
$headers = "To: Sergey <[email protected]>\r\n".
"Date: Fri, 8 Nov 2013 10:21:26 +0100\r\n".
"From: Gleez CMS <[email protected]>\r\n".
"Message-ID: <[email protected]>\r\n".
"X-Priority: 3\r\n".
"X-Mailer: Gleez CMS 0.10.5\r\n".
"MIME-Version: 1.0\r\n".
"Content-Type: text/plain; charset=utf-8\r\n".
"Content-Transfer-Encoding: 8bit\r\n".
"\r\n";
$subject = 'Gleez CMS - Проверка регистрационных данных для Sergey';
$mailto = '[email protected]';
$body = 'hello';
mail($mailto, "=?utf-8?B?".base64_encode($subject)."?=", $body, $headers); That works fine for me, but see if it still has the same problem for you. |
Now, I don't understand anything :( I has received the following:
Evidently should have started with this test. I distract you in vain ... Best regards |
The main problem was that the Subject is encoded twice. Then I began to think that may overlap in general is a standard work php mail()... Yes this is Mbstring!
I look at my php.ini and saw Thanks! |
Bah! Oh well, at least we know now, and it will show up in searches here if anyone runs into it again... |
Yep ) |
Could we maybe check for mb overloading and disable manual encoding? |
Yes, that's a good idea. Got a PR? :) |
Fixed in master. |
Good work! 👍 |
thank you "=?utf-8?B?".base64_encode($subject)."?=" it solved my problem |
Thank you really much, after some times to look everywhere, that's solution work for me too !! |
Please don't use that ancient version. I'm surprised it still works at all, but it also likely means you are vulnerable to several major security holes. Fix it properly and use the latest version. |
Thank you for your reply, Yes I will purpose to update to my customer ! |
Hello, I am having the same problem and I can't figure out what the solution actually is. The problem appears in a forum installation, vanilla forums: https://open.vanillaforums.com/ =?UTF-8?B?W86azr/Ouc69z4zPhM63z4TOsSDOn86jzpTOlV0gzpcgzpHOr8+EzrfPg86u?= =?UTF-8?B?IM6czq3Ou86/z4XPgiDOlc6zzrrPgc6vzrjOt866zrUg? What else could I do? The non-latin language used there is Greek. Thanks. |
It's likely that the calling script is applying encoding before passing the value to PHPMailer, which then encodes what it's given in a way that preserves its original unnecessarily-encoded value. |
Indeed I found this inside an email class of the software:
just for the subject. All the other parts are sent unencoded. I replaced the second part with just the value of $subject and it is ok. Thanks. |
Good – it would help if you could report that problem upstream so it gets fixed for all the others that use it, rather than having them all turn up here! |
Yes, of course I already did so :) |
Still getting $str = '=?utf-8?B?R2xlZXogQ01TIC0g0J/RgNC+0LLQtdGA0LrQsCDRgNC10LPQuNGB0YLRgNCw?= =?utf-8?B?0YbQuNC+0L3QvdGL0YUg0LTQsNC90L3Ri9GFINC00LvRjyBTZXJnZXk=?=';
if (mb_detect_encoding($str, 'UTF-8, ISO-8859-1') === 'UTF-8'){
echo "the string is encoded in UTF-8";
} else {
echo "not encoded in UTF-8";
} |
That code isn't doing what you think it is. |
You're right, the code example isn't giving correct results. Just to make this issue totally solved once and for all, I'd be satisfied with a simple approach, avoid double-encoding a subject that is already encoded. PHPmailer could use a regex to |
Unfortunately that's an overly simplistic approach that would not solve the problem, and would cause other issues. RFC2047 is more subtle than that (e.g. you can mix multiple charsets in the same line, you should be able to have a subject line containing |
Hi!
I want to know any special settings needed for Subject consisting of the non-Latin characters? I am interested in UTF-8.
Of course I understand that need to set
$CharSet
value. I do this in my application, after creating a PHPMailer object:Please see screenshot
Mail body is displayed correctly (in Russian), but Subject - no.
Mail header for this screenshot
I sent mail using the localhost:
I use smarthost setting for Gmail
Locale:
Excuse me, I'm not sure what other information I should provide.
It seem to me this issue associated with the UTF-8 string which is divided into blocks of 78 bytes. Probably with short strings is no problem. I really have tried different methods of decoding/encoding the Subject (
mb_encode_mimeheader
,utf_encode
,base64_encode
,strtolower($CharSet)
- any tricks that I could find on the google.) and not found solutions.Another tip that will help you understand the cause of the issue: Subject consists of Latin and non-Latin characters. The first and last word in English (Latin), the rest - Russian words (Cyrillic).
Any ideas?
The text was updated successfully, but these errors were encountered: