From 0fa95186090448ead097867b93fd597782190dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20B?= Date: Wed, 14 Oct 2015 21:39:29 +0200 Subject: [PATCH] Allow addresses with IDN Accepts Internationalized Domain Name everywhere PHPMailler expects email addresses (To, CC, BCC, Reply-To, From, Sender and ConfirmReadingTo). Requires PHP >= 5.3 with "intl" extension installed and "mbstring" extension enabled. Earlier versions don't see a change, i.e. specifying an address with IDN still fails validation. Follow-up to PR #516. Ran test/phpmailerTest.php Other changes: - From, Sender and ConfirmReadingTo addresses are now validated in send(). Previously, only From and Sender addresses would be validated only if specified via the setFrom() method. ConfirmReadingTo was never validated. - Half language strings for the 'invalid_address' message used colon at the end and half didn't. Harmonized messages to always include colon, and not add a second one with PHP code. --- changelog.md | 1 + class.phpmailer.php | 197 +++++++++++++++++++++++++++--- language/phpmailer.lang-ar.php | 2 +- language/phpmailer.lang-bg.php | 2 +- language/phpmailer.lang-ca.php | 2 +- language/phpmailer.lang-ch.php | 2 +- language/phpmailer.lang-de.php | 2 +- language/phpmailer.lang-dk.php | 2 +- language/phpmailer.lang-el.php | 2 +- language/phpmailer.lang-fi.php | 2 +- language/phpmailer.lang-fo.php | 2 +- language/phpmailer.lang-he.php | 2 +- language/phpmailer.lang-hr.php | 2 +- language/phpmailer.lang-ja.php | 2 +- language/phpmailer.lang-ko.php | 2 +- language/phpmailer.lang-lt.php | 2 +- language/phpmailer.lang-lv.php | 2 +- language/phpmailer.lang-ms.php | 2 +- language/phpmailer.lang-nl.php | 2 +- language/phpmailer.lang-ro.php | 2 +- language/phpmailer.lang-se.php | 2 +- language/phpmailer.lang-sl.php | 4 +- language/phpmailer.lang-sr.php | 2 +- language/phpmailer.lang-vi.php | 2 +- language/phpmailer.lang-zh_cn.php | 2 +- test/phpmailerTest.php | 142 ++++++++++++++++++++- 26 files changed, 345 insertions(+), 43 deletions(-) diff --git a/changelog.md b/changelog.md index 074f7029..a9d96489 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,6 @@ # ChangeLog +* Allow addresses with IDN (Internationalized Domain Name) in PHP 5.3+ * Allow access to POP3 errors * Make all POP3 private properties and methods protected diff --git a/class.phpmailer.php b/class.phpmailer.php index dd3f6fc0..0ce8de93 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -184,7 +184,7 @@ class PHPMailer public $PluginDir = ''; /** - * The email address that a reading confirmation should be sent to. + * The email address that a reading confirmation should be sent to, also known as read receipt. * @var string */ public $ConfirmReadingTo = ''; @@ -490,6 +490,28 @@ class PHPMailer */ protected $all_recipients = array(); + /** + * An array of names and addresses queued for validation. + * In send(), valid and non duplicate entries are moved to $all_recipients + * and one of $to, $cc, or $bcc. + * This array is used only for addresses with IDN. + * @var array + * @access protected + * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc + * @see PHPMailer::$all_recipients + */ + protected $RecipientsQueue = array(); + + /** + * An array of reply-to names and addresses queued for validation. + * In send(), valid and non duplicate entries are moved to $ReplyTo. + * This array is used only for addresses with IDN. + * @var array + * @access protected + * @see PHPMailer::$ReplyTo + */ + protected $ReplyToQueue = array(); + /** * The array of attachments. * @var array @@ -772,7 +794,7 @@ class PHPMailer */ public function addAddress($address, $name = '') { - return $this->addAnAddress('to', $address, $name); + return $this->addOrEnqueueAnAddress('to', $address, $name); } /** @@ -784,7 +806,7 @@ class PHPMailer */ public function addCC($address, $name = '') { - return $this->addAnAddress('cc', $address, $name); + return $this->addOrEnqueueAnAddress('cc', $address, $name); } /** @@ -796,7 +818,7 @@ class PHPMailer */ public function addBCC($address, $name = '') { - return $this->addAnAddress('bcc', $address, $name); + return $this->addOrEnqueueAnAddress('bcc', $address, $name); } /** @@ -807,7 +829,53 @@ class PHPMailer */ public function addReplyTo($address, $name = '') { - return $this->addAnAddress('Reply-To', $address, $name); + return $this->addOrEnqueueAnAddress('Reply-To', $address, $name); + } + + /** + * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer + * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still + * modified after calling this function), addition of such addresses is delayed until send(). + * Addresses that have been added already return false, but do not throw exceptions. + * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo' + * @param string $address The email address to send, resp. to reply to + * @param string $name + * @throws phpmailerException + * @return boolean true on success, false if address already used or invalid in some way + * @access protected + */ + protected function addOrEnqueueAnAddress($kind, $address, $name) + { + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (($pos = strrpos($address, '@')) === false) { + // At-sign is misssing. + $error_message = $this->lang('invalid_address') . $address; + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new phpmailerException($error_message); + } + return false; + } + $params = array($kind, $address, $name); + // Enqueue addresses with IDN until we know the PHPMailer::$CharSet. + if ($this->has8bitChars(substr($address, ++$pos)) and $this->idnSupported()) { + if ($kind != 'Reply-To') { + if (!array_key_exists($address, $this->RecipientsQueue)) { + $this->RecipientsQueue[$address] = $params; + return true; + } + } else { + if (!array_key_exists($address, $this->ReplyToQueue)) { + $this->ReplyToQueue[$address] = $params; + return true; + } + } + return false; + } + // Immediately add standard addresses without IDN. + return call_user_func_array(array($this, 'addAnAddress'), $params); } /** @@ -823,7 +891,7 @@ class PHPMailer protected function addAnAddress($kind, $address, $name = '') { if (!in_array($kind, array('to', 'cc', 'bcc', 'Reply-To'))) { - $error_message = $this->lang('Invalid recipient array') . ': ' . $kind; + $error_message = $this->lang('Invalid recipient kind: ') . $kind; $this->setError($error_message); $this->edebug($error_message); if ($this->exceptions) { @@ -831,10 +899,8 @@ class PHPMailer } return false; } - $address = trim($address); - $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim if (!$this->validateAddress($address)) { - $error_message = $this->lang('invalid_address') . ': ' . $address; + $error_message = $this->lang('invalid_address') . $address; $this->setError($error_message); $this->edebug($error_message); if ($this->exceptions) { @@ -924,8 +990,11 @@ class PHPMailer { $address = trim($address); $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim - if (!$this->validateAddress($address)) { - $error_message = $this->lang('invalid_address') . ': ' . $address; + // Don't validate now addresses with IDN. Will be done in send(). + if (($pos = strrpos($address, '@')) === false or + (!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and + !$this->validateAddress($address)) { + $error_message = $this->lang('invalid_address') . $address; $this->setError($error_message); $this->edebug($error_message); if ($this->exceptions) { @@ -1050,6 +1119,48 @@ class PHPMailer } } + /** + * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the + * "intl" and "mbstring" PHP extensions. + * @return bool "true" if required functions for IDN support are present + */ + public function idnSupported() + { + // @TODO: Write our own "idn_to_ascii" function for PHP <= 5.2. + return function_exists('idn_to_ascii') and function_exists('mb_convert_encoding'); + } + + /** + * Converts IDN in given email address to its ASCII form, also known as punycode, if possible. + * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet. + * This function silently returns unmodified address if: + * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form) + * - Conversion to punycode is impossible (e.g. required PHP functions are not available) + * or fails for any reason (e.g. domain has characters not allowed in an IDN) + * @see PHPMailer::$CharSet + * @param string $address The email address to convert + * @return string The encoded address in ASCII form + */ + public function punyencodeAddress($address) + { + // Verify we have required functions, CharSet, and at-sign. + if ($this->idnSupported() and + !empty($this->CharSet) and + ($pos = strrpos($address, '@')) !== false) { + $domain = substr($address, ++$pos); + // Verify CharSet string is a valid one, and domain properly encoded in this CharSet. + if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) { + $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet); + if (($punycode = defined('INTL_IDNA_VARIANT_UTS46') ? + idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) : + idn_to_ascii($domain)) !== false) { + return substr($address, 0, $pos) . $punycode; + } + } + } + return $address; + } + /** * Create a message and send it. * Uses the sending method specified by $Mailer. @@ -1081,17 +1192,41 @@ class PHPMailer public function preSend() { try { + $this->error_count = 0; // Reset errors $this->mailHeader = ''; + + // Dequeue recipient and Reply-To addresses with IDN + foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) { + $params[1] = $this->punyencodeAddress($params[1]); + call_user_func_array(array($this, 'addAnAddress'), $params); + } if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL); } + // Validate From, Sender, and ConfirmReadingTo addresses + foreach (array('From', 'Sender', 'ConfirmReadingTo') as $address_kind) { + $this->$address_kind = trim($this->$address_kind); + if (empty($this->$address_kind)) { + continue; + } + $this->$address_kind = $this->punyencodeAddress($this->$address_kind); + if (!$this->validateAddress($this->$address_kind)) { + $error_message = $this->lang('invalid_address') . $this->$address_kind; + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new phpmailerException($error_message); + } + return false; + } + } + // Set whether the message is multipart/alternative if (!empty($this->AltBody)) { $this->ContentType = 'multipart/alternative'; } - $this->error_count = 0; // Reset errors $this->setMessageType(); // Refuse to send an empty message unless we are specifically allowing it if (!$this->AllowEmpty and empty($this->Body)) { @@ -1526,7 +1661,7 @@ class PHPMailer 'file_open' => 'File Error: Could not open file: ', 'from_failed' => 'The following From address failed: ', 'instantiate' => 'Could not instantiate mail function.', - 'invalid_address' => 'Invalid address', + 'invalid_address' => 'Invalid address: ', 'mailer_not_supported' => ' mailer is not supported.', 'provide_address' => 'You must provide at least one recipient email address.', 'recipients_failed' => 'SMTP Error: The following recipients failed: ', @@ -1855,7 +1990,7 @@ class PHPMailer } if ($this->ConfirmReadingTo != '') { - $result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); + $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>'); } // Add custom headers @@ -2884,6 +3019,30 @@ class PHPMailer return !empty($this->AltBody); } + /** + * Clear queued addresses of given kind. + * @access protected + * @param string $kind 'to', 'cc', or 'bcc' + * @return void + */ + protected function clearQueuedAddresses($kind) + { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + $RecipientsQueue = $this->RecipientsQueue; + foreach ($RecipientsQueue as $address => $params) { + if ($params[0] == $kind) { + unset($this->RecipientsQueue[$address]); + } + } + } else { + $this->RecipientsQueue = array_filter( + $this->RecipientsQueue, + function ($params) use ($kind) { + return $params[0] != $kind; + }); + } + } + /** * Clear all To recipients. * @return void @@ -2894,6 +3053,7 @@ class PHPMailer unset($this->all_recipients[strtolower($to[0])]); } $this->to = array(); + $this->clearQueuedAddresses('to'); } /** @@ -2906,6 +3066,7 @@ class PHPMailer unset($this->all_recipients[strtolower($cc[0])]); } $this->cc = array(); + $this->clearQueuedAddresses('cc'); } /** @@ -2918,6 +3079,7 @@ class PHPMailer unset($this->all_recipients[strtolower($bcc[0])]); } $this->bcc = array(); + $this->clearQueuedAddresses('bcc'); } /** @@ -2927,6 +3089,7 @@ class PHPMailer public function clearReplyTos() { $this->ReplyTo = array(); + $this->ReplyToQueue = array(); } /** @@ -2939,6 +3102,7 @@ class PHPMailer $this->cc = array(); $this->bcc = array(); $this->all_recipients = array(); + $this->RecipientsQueue = array(); } /** @@ -3633,6 +3797,7 @@ class PHPMailer /** * Allows for public read access to 'to' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ @@ -3643,6 +3808,7 @@ class PHPMailer /** * Allows for public read access to 'cc' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ @@ -3653,6 +3819,7 @@ class PHPMailer /** * Allows for public read access to 'bcc' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ @@ -3663,6 +3830,7 @@ class PHPMailer /** * Allows for public read access to 'ReplyTo' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ @@ -3673,6 +3841,7 @@ class PHPMailer /** * Allows for public read access to 'all_recipients' property. + * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public * @return array */ diff --git a/language/phpmailer.lang-ar.php b/language/phpmailer.lang-ar.php index b8c02c7e..790e2a5e 100644 --- a/language/phpmailer.lang-ar.php +++ b/language/phpmailer.lang-ar.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'لا يمكن الوصول للملف $PHPMAILER_LANG['file_open'] = 'خطأ في الملف: لا يمكن فتحه: '; $PHPMAILER_LANG['from_failed'] = 'خطأ على مستوى عنوان المرسل : '; $PHPMAILER_LANG['instantiate'] = 'لا يمكن توفير خدمة البريد.'; -$PHPMAILER_LANG['invalid_address'] = 'الإرسال غير ممكن لأن عنوان البريد الإلكتروني غير صالح.'; +$PHPMAILER_LANG['invalid_address'] = 'الإرسال غير ممكن لأن عنوان البريد الإلكتروني غير صالح: '; $PHPMAILER_LANG['mailer_not_supported'] = ' برنامج الإرسال غير مدعوم.'; $PHPMAILER_LANG['provide_address'] = 'يجب توفير عنوان البريد الإلكتروني لمستلم واحد على الأقل.'; $PHPMAILER_LANG['recipients_failed'] = 'خطأ SMTP: الأخطاء التالية ' . diff --git a/language/phpmailer.lang-bg.php b/language/phpmailer.lang-bg.php index 6b5c4a11..b22941f6 100644 --- a/language/phpmailer.lang-bg.php +++ b/language/phpmailer.lang-bg.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Няма достъп до файл: $PHPMAILER_LANG['file_open'] = 'Файлова грешка: Не може да се отвори файл: '; $PHPMAILER_LANG['from_failed'] = 'Следните адреси за подател са невалидни: '; $PHPMAILER_LANG['instantiate'] = 'Не може да се инстанцира функцията mail.'; -$PHPMAILER_LANG['invalid_address'] = 'Невалиден адрес'; +$PHPMAILER_LANG['invalid_address'] = 'Невалиден адрес: '; $PHPMAILER_LANG['mailer_not_supported'] = ' - пощенски сървър не се поддържа.'; $PHPMAILER_LANG['provide_address'] = 'Трябва да предоставите поне един email адрес за получател.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP грешка: Следните адреси за Получател са невалидни: '; diff --git a/language/phpmailer.lang-ca.php b/language/phpmailer.lang-ca.php index 5620d395..4117596c 100644 --- a/language/phpmailer.lang-ca.php +++ b/language/phpmailer.lang-ca.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'No es pot accedir a l’arxiu: '; $PHPMAILER_LANG['file_open'] = 'Error d’Arxiu: No es pot obrir l’arxiu: '; $PHPMAILER_LANG['from_failed'] = 'La(s) següent(s) adreces de remitent han fallat: '; $PHPMAILER_LANG['instantiate'] = 'No s’ha pogut crear una instància de la funció Mail.'; -$PHPMAILER_LANG['invalid_address'] = 'Adreça d’email invalida'; +$PHPMAILER_LANG['invalid_address'] = 'Adreça d’email invalida: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer no està suportat'; $PHPMAILER_LANG['provide_address'] = 'S’ha de proveir almenys una adreça d’email com a destinatari.'; $PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Els següents destinataris han fallat: '; diff --git a/language/phpmailer.lang-ch.php b/language/phpmailer.lang-ch.php index 1c6ebaf3..4fda6b85 100644 --- a/language/phpmailer.lang-ch.php +++ b/language/phpmailer.lang-ch.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = '不能访问文件:'; $PHPMAILER_LANG['file_open'] = '文件错误:不能打开文件:'; $PHPMAILER_LANG['from_failed'] = '下面的发送地址邮件发送失败了: '; $PHPMAILER_LANG['instantiate'] = '不能实现mail方法。'; -//$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; $PHPMAILER_LANG['mailer_not_supported'] = ' 您所选择的发送邮件的方法并不支持。'; $PHPMAILER_LANG['provide_address'] = '您必须提供至少一个 收信人的email地址。'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误: 下面的 收件人失败了: '; diff --git a/language/phpmailer.lang-de.php b/language/phpmailer.lang-de.php index 233aa75e..43057efc 100644 --- a/language/phpmailer.lang-de.php +++ b/language/phpmailer.lang-de.php @@ -14,7 +14,7 @@ $PHPMAILER_LANG['file_access'] = 'Zugriff auf folgende Datei fehlgeschl $PHPMAILER_LANG['file_open'] = 'Datei Fehler: konnte folgende Datei nicht öffnen: '; $PHPMAILER_LANG['from_failed'] = 'Die folgende Absenderadresse ist nicht korrekt: '; $PHPMAILER_LANG['instantiate'] = 'Mail Funktion konnte nicht initialisiert werden.'; -$PHPMAILER_LANG['invalid_address'] = 'E-Mail wird nicht gesendet, die Adresse ist ungültig.'; +$PHPMAILER_LANG['invalid_address'] = 'E-Mail wird nicht gesendet, die Adresse ist ungültig: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer wird nicht unterstützt.'; $PHPMAILER_LANG['provide_address'] = 'Bitte geben Sie mindestens eine Empfänger E-Mailadresse an.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP Fehler: Die folgenden Empfänger sind nicht korrekt: '; diff --git a/language/phpmailer.lang-dk.php b/language/phpmailer.lang-dk.php index 8968c07c..e725f4b4 100644 --- a/language/phpmailer.lang-dk.php +++ b/language/phpmailer.lang-dk.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Ingen adgang til fil: '; $PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: '; $PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: '; $PHPMAILER_LANG['instantiate'] = 'Kunne ikke initialisere email funktionen.'; -//$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.'; $PHPMAILER_LANG['provide_address'] = 'Du skal indtaste mindst en modtagers emailadresse.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: '; diff --git a/language/phpmailer.lang-el.php b/language/phpmailer.lang-el.php index 08c5f119..7109641e 100644 --- a/language/phpmailer.lang-el.php +++ b/language/phpmailer.lang-el.php @@ -14,7 +14,7 @@ $PHPMAILER_LANG['file_access'] = 'Αδυναμία προσπέλαση $PHPMAILER_LANG['file_open'] = 'Σφάλμα Αρχείου: Δεν είναι δυνατό το άνοιγμα του ακόλουθου αρχείου: '; $PHPMAILER_LANG['from_failed'] = 'Η παρακάτω διεύθυνση αποστολέα δεν είναι σωστή: '; $PHPMAILER_LANG['instantiate'] = 'Αδυναμία εκκίνησης Mail function.'; -$PHPMAILER_LANG['invalid_address'] = 'Το μήνυμα δεν εστάλη, η διεύθυνση δεν είναι έγκυρη.'; +$PHPMAILER_LANG['invalid_address'] = 'Το μήνυμα δεν εστάλη, η διεύθυνση δεν είναι έγκυρη: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer δεν υποστηρίζεται.'; $PHPMAILER_LANG['provide_address'] = 'Παρακαλούμε δώστε τουλάχιστον μια e-mail διεύθυνση παραλήπτη.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP Σφάλμα: Οι παρακάτω διευθύνσεις παραλήπτη δεν είναι έγκυρες: '; diff --git a/language/phpmailer.lang-fi.php b/language/phpmailer.lang-fi.php index 739c2350..ec4e7523 100644 --- a/language/phpmailer.lang-fi.php +++ b/language/phpmailer.lang-fi.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Seuraavaan tiedostoon ei ole oikeuksi $PHPMAILER_LANG['file_open'] = 'Tiedostovirhe: Ei voida avata tiedostoa: '; $PHPMAILER_LANG['from_failed'] = 'Seuraava lähettäjän osoite on virheellinen: '; $PHPMAILER_LANG['instantiate'] = 'mail-funktion luonti epäonnistui.'; -//$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; $PHPMAILER_LANG['mailer_not_supported'] = 'postivälitintyyppiä ei tueta.'; $PHPMAILER_LANG['provide_address'] = 'Aseta vähintään yksi vastaanottajan sähköpostiosoite.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.'; diff --git a/language/phpmailer.lang-fo.php b/language/phpmailer.lang-fo.php index 724f3ed3..68cdef1d 100644 --- a/language/phpmailer.lang-fo.php +++ b/language/phpmailer.lang-fo.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Kundi ikki tilganga fílu: '; $PHPMAILER_LANG['file_open'] = 'Fílu feilur: Kundi ikki opna fílu: '; $PHPMAILER_LANG['from_failed'] = 'fylgjandi Frá/From adressa miseydnaðist: '; $PHPMAILER_LANG['instantiate'] = 'Kuni ikki instantiera mail funktión.'; -//$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; $PHPMAILER_LANG['mailer_not_supported'] = ' er ikki supporterað.'; $PHPMAILER_LANG['provide_address'] = 'Tú skal uppgeva minst móttakara-emailadressu(r).'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP Feilur: Fylgjandi móttakarar miseydnaðust: '; diff --git a/language/phpmailer.lang-he.php b/language/phpmailer.lang-he.php index 857f7239..5a08b986 100644 --- a/language/phpmailer.lang-he.php +++ b/language/phpmailer.lang-he.php @@ -9,7 +9,7 @@ $PHPMAILER_LANG['authenticate'] = 'שגיאת SMTP: פעולת האימ $PHPMAILER_LANG['connect_host'] = 'שגיאת SMTP: לא הצלחתי להתחבר לשרת SMTP.'; $PHPMAILER_LANG['data_not_accepted'] = 'שגיאת SMTP: מידע לא התקבל.'; $PHPMAILER_LANG['empty_message'] = 'גוף ההודעה ריק'; -$PHPMAILER_LANG['invalid_address'] = 'כתובת שגויה'; +$PHPMAILER_LANG['invalid_address'] = 'כתובת שגויה: '; $PHPMAILER_LANG['encoding'] = 'קידוד לא מוכר: '; $PHPMAILER_LANG['execute'] = 'לא הצלחתי להפעיל את: '; $PHPMAILER_LANG['file_access'] = 'לא ניתן לגשת לקובץ: '; diff --git a/language/phpmailer.lang-hr.php b/language/phpmailer.lang-hr.php index 5fedae02..3822920a 100644 --- a/language/phpmailer.lang-hr.php +++ b/language/phpmailer.lang-hr.php @@ -16,7 +16,7 @@ $PHPMAILER_LANG['file_open'] = 'Nije moguće otvoriti datoteku: '; $PHPMAILER_LANG['from_failed'] = 'SMTP Greška: Slanje s navedenih e-mail adresa nije uspjelo: '; $PHPMAILER_LANG['recipients_failed'] = 'SMTP Greška: Slanje na navedenih e-mail adresa nije uspjelo: '; $PHPMAILER_LANG['instantiate'] = 'Ne mogu pokrenuti mail funkcionalnost.'; -$PHPMAILER_LANG['invalid_address'] = 'E-mail nije poslan. Neispravna e-mail adresa.'; +$PHPMAILER_LANG['invalid_address'] = 'E-mail nije poslan. Neispravna e-mail adresa: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer nije podržan.'; $PHPMAILER_LANG['provide_address'] = 'Definirajte barem jednu adresu primatelja.'; $PHPMAILER_LANG['signing'] = 'Greška prilikom prijave: '; diff --git a/language/phpmailer.lang-ja.php b/language/phpmailer.lang-ja.php index 29f8662c..2d778728 100644 --- a/language/phpmailer.lang-ja.php +++ b/language/phpmailer.lang-ja.php @@ -16,7 +16,7 @@ $PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできま $PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: '; $PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: '; $PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。'; -//$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; $PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。'; $PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。'; $PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: '; diff --git a/language/phpmailer.lang-ko.php b/language/phpmailer.lang-ko.php index 72838810..9599fa68 100644 --- a/language/phpmailer.lang-ko.php +++ b/language/phpmailer.lang-ko.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = '파일 접근 불가: '; $PHPMAILER_LANG['file_open'] = '파일 오류: 파일을 열 수 없습니다: '; $PHPMAILER_LANG['from_failed'] = '다음 From 주소에서 오류가 발생했습니다: '; $PHPMAILER_LANG['instantiate'] = 'mail 함수를 인스턴스화할 수 없습니다'; -$PHPMAILER_LANG['invalid_address'] = '잘못된 주소'; +$PHPMAILER_LANG['invalid_address'] = '잘못된 주소: '; $PHPMAILER_LANG['mailer_not_supported'] = ' 메일러는 지원되지 않습니다.'; $PHPMAILER_LANG['provide_address'] = '적어도 한 개 이상의 수신자 메일 주소를 제공해야 합니다.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP 오류: 다음 수신자에서 오류가 발생했습니다: '; diff --git a/language/phpmailer.lang-lt.php b/language/phpmailer.lang-lt.php index 27267730..1253a4fd 100644 --- a/language/phpmailer.lang-lt.php +++ b/language/phpmailer.lang-lt.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Byla nepasiekiama: '; $PHPMAILER_LANG['file_open'] = 'Bylos klaida: Nepavyksta atidaryti: '; $PHPMAILER_LANG['from_failed'] = 'Neteisingas siuntėjo adresas: '; $PHPMAILER_LANG['instantiate'] = 'Nepavyko paleisti mail funkcijos.'; -$PHPMAILER_LANG['invalid_address'] = 'Neteisingas adresas'; +$PHPMAILER_LANG['invalid_address'] = 'Neteisingas adresas: '; $PHPMAILER_LANG['mailer_not_supported'] = ' pašto stotis nepalaikoma.'; $PHPMAILER_LANG['provide_address'] = 'Nurodykite bent vieną gavėjo adresą.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP klaida: nepavyko išsiųsti šiems gavėjams: '; diff --git a/language/phpmailer.lang-lv.php b/language/phpmailer.lang-lv.php index b2ab55f6..39bf9a19 100644 --- a/language/phpmailer.lang-lv.php +++ b/language/phpmailer.lang-lv.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Fails nav pieejams: '; $PHPMAILER_LANG['file_open'] = 'Faila kļūda: Nevar atvērt failu: '; $PHPMAILER_LANG['from_failed'] = 'Nepareiza sūtītāja adrese: '; $PHPMAILER_LANG['instantiate'] = 'Nevar palaist sūtīšanas funkciju.'; -$PHPMAILER_LANG['invalid_address'] = 'Nepareiza adrese'; +$PHPMAILER_LANG['invalid_address'] = 'Nepareiza adrese: '; $PHPMAILER_LANG['mailer_not_supported'] = ' sūtītājs netiek atbalstīts.'; $PHPMAILER_LANG['provide_address'] = 'Lūdzu, norādiet vismaz vienu adresātu.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP kļūda: neizdevās nosūtīt šādiem saņēmējiem: '; diff --git a/language/phpmailer.lang-ms.php b/language/phpmailer.lang-ms.php index 11d3daa4..4e2c3408 100644 --- a/language/phpmailer.lang-ms.php +++ b/language/phpmailer.lang-ms.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Tidak dapat mengakses fail: '; $PHPMAILER_LANG['file_open'] = 'Ralat Fail: Tidak dapat membuka fail: '; $PHPMAILER_LANG['from_failed'] = 'Berikut merupakan ralat dari alamat e-mel: '; $PHPMAILER_LANG['instantiate'] = 'Tidak dapat memberi contoh fungsi e-mel.'; -$PHPMAILER_LANG['invalid_address'] = 'Alamat emel tidak sah'; +$PHPMAILER_LANG['invalid_address'] = 'Alamat emel tidak sah: '; $PHPMAILER_LANG['mailer_not_supported'] = ' jenis penghantar emel tidak disokong.'; $PHPMAILER_LANG['provide_address'] = 'Anda perlu menyediakan sekurang-kurangnya satu alamat e-mel penerima.'; $PHPMAILER_LANG['recipients_failed'] = 'Ralat SMTP: Penerima e-mel berikut telah gagal: '; diff --git a/language/phpmailer.lang-nl.php b/language/phpmailer.lang-nl.php index 54a8f9af..0fc38bec 100644 --- a/language/phpmailer.lang-nl.php +++ b/language/phpmailer.lang-nl.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: '; $PHPMAILER_LANG['file_open'] = 'Bestandsfout: kon bestand niet openen: '; $PHPMAILER_LANG['from_failed'] = 'Het volgende afzendersadres is mislukt: '; $PHPMAILER_LANG['instantiate'] = 'Kon mailfunctie niet initialiseren.'; -$PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres'; +$PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.'; $PHPMAILER_LANG['provide_address'] = 'Er moet minstens één ontvanger worden opgegeven.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP-fout: de volgende ontvangers zijn mislukt: '; diff --git a/language/phpmailer.lang-ro.php b/language/phpmailer.lang-ro.php index e8a56fa9..cf37cc1e 100644 --- a/language/phpmailer.lang-ro.php +++ b/language/phpmailer.lang-ro.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Nu pot accesa fisierul: '; $PHPMAILER_LANG['file_open'] = 'Eroare de fisier: Nu pot deschide fisierul: '; $PHPMAILER_LANG['from_failed'] = 'Urmatoarele adrese From au dat eroare: '; $PHPMAILER_LANG['instantiate'] = 'Nu am putut instantia functia mail.'; -$PHPMAILER_LANG['invalid_address'] = 'Adresa de email nu este valida. '; +$PHPMAILER_LANG['invalid_address'] = 'Adresa de email nu este valida: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.'; $PHPMAILER_LANG['provide_address'] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).'; $PHPMAILER_LANG['recipients_failed'] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: '; diff --git a/language/phpmailer.lang-se.php b/language/phpmailer.lang-se.php index c71cb51e..2c9ececa 100644 --- a/language/phpmailer.lang-se.php +++ b/language/phpmailer.lang-se.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Ingen åtkomst till fil: '; $PHPMAILER_LANG['file_open'] = 'Fil fel: Kunde inte öppna fil: '; $PHPMAILER_LANG['from_failed'] = 'Följande avsändaradress är felaktig: '; $PHPMAILER_LANG['instantiate'] = 'Kunde inte initiera e-postfunktion.'; -//$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: '; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; $PHPMAILER_LANG['provide_address'] = 'Du måste ange minst en mottagares e-postadress.'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP fel: Följande mottagare är felaktig: '; diff --git a/language/phpmailer.lang-sl.php b/language/phpmailer.lang-sl.php index 14fa2a5c..54c95725 100644 --- a/language/phpmailer.lang-sl.php +++ b/language/phpmailer.lang-sl.php @@ -4,7 +4,7 @@ * @package PHPMailer * @author Klemen Tušar */ - + $PHPMAILER_LANG['authenticate'] = 'SMTP napaka: Avtentikacija ni uspela.'; $PHPMAILER_LANG['connect_host'] = 'SMTP napaka: Ne morem vzpostaviti povezave s SMTP gostiteljem.'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTP napaka: Strežnik zavrača podatke.'; @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Nimam dostopa do datoteke: '; $PHPMAILER_LANG['file_open'] = 'Ne morem odpreti datoteke: '; $PHPMAILER_LANG['from_failed'] = 'Neveljaven e-naslov pošiljatelja: '; $PHPMAILER_LANG['instantiate'] = 'Ne morem inicializirati mail funkcije.'; -$PHPMAILER_LANG['invalid_address'] = 'E-poštno sporočilo ni bilo poslano. E-naslov je neveljaven.'; +$PHPMAILER_LANG['invalid_address'] = 'E-poštno sporočilo ni bilo poslano. E-naslov je neveljaven: '; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer ni podprt.'; $PHPMAILER_LANG['provide_address'] = 'Prosim vnesite vsaj enega naslovnika.'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP napaka: Sledeči naslovniki so neveljavni: '; diff --git a/language/phpmailer.lang-sr.php b/language/phpmailer.lang-sr.php index 26360b20..ed95ca6e 100644 --- a/language/phpmailer.lang-sr.php +++ b/language/phpmailer.lang-sr.php @@ -16,7 +16,7 @@ $PHPMAILER_LANG['file_open'] = 'Није могуће отворит $PHPMAILER_LANG['from_failed'] = 'SMTP грешка: слање са следећих адреса није успело: '; $PHPMAILER_LANG['recipients_failed'] = 'SMTP грешка: слање на следеће адресе није успело: '; $PHPMAILER_LANG['instantiate'] = 'Није могуће покренути mail функцију.'; -$PHPMAILER_LANG['invalid_address'] = 'Порука није послата због неисправне адресе.'; +$PHPMAILER_LANG['invalid_address'] = 'Порука није послата због неисправне адресе: '; $PHPMAILER_LANG['mailer_not_supported'] = ' мејлер није подржан.'; $PHPMAILER_LANG['provide_address'] = 'Потребно је задати најмање једну адресу.'; $PHPMAILER_LANG['signing'] = 'Грешка приликом пријављивања: '; diff --git a/language/phpmailer.lang-vi.php b/language/phpmailer.lang-vi.php index 8a3ea719..c60dadeb 100644 --- a/language/phpmailer.lang-vi.php +++ b/language/phpmailer.lang-vi.php @@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'Không thể truy cập tệp tin '; $PHPMAILER_LANG['file_open'] = 'Lỗi Tập tin: Không thể mở tệp tin: '; $PHPMAILER_LANG['from_failed'] = 'Lỗi địa chỉ gửi đi: '; $PHPMAILER_LANG['instantiate'] = 'Không dùng được các hàm gửi thư.'; -$PHPMAILER_LANG['invalid_address'] = 'Đại chỉ emai không đúng'; +$PHPMAILER_LANG['invalid_address'] = 'Đại chỉ emai không đúng: '; $PHPMAILER_LANG['mailer_not_supported'] = ' trình gửi thư không được hỗ trợ.'; $PHPMAILER_LANG['provide_address'] = 'Bạn phải cung cấp ít nhất một địa chỉ người nhận.'; $PHPMAILER_LANG['recipients_failed'] = 'Lỗi SMTP: lỗi địa chỉ người nhận: '; diff --git a/language/phpmailer.lang-zh_cn.php b/language/phpmailer.lang-zh_cn.php index 1586dbad..d85a0b1a 100644 --- a/language/phpmailer.lang-zh_cn.php +++ b/language/phpmailer.lang-zh_cn.php @@ -16,7 +16,7 @@ $PHPMAILER_LANG['file_access'] = '无法访问文件:'; $PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; $PHPMAILER_LANG['from_failed'] = '发送地址错误:'; $PHPMAILER_LANG['instantiate'] = '未知函数调用。'; -$PHPMAILER_LANG['invalid_address'] = '发送失败,电子邮箱地址是无效的。'; +$PHPMAILER_LANG['invalid_address'] = '发送失败,电子邮箱地址是无效的:'; $PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; $PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:'; diff --git a/test/phpmailerTest.php b/test/phpmailerTest.php index cb1330ac..762c641c 100644 --- a/test/phpmailerTest.php +++ b/test/phpmailerTest.php @@ -107,7 +107,6 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase $this->Mail->Mailer = 'smtp'; } else { $this->Mail->Mailer = 'mail'; - $this->Mail->Sender = 'unit_test@phpmailer.example.com'; } if (array_key_exists('mail_to', $_REQUEST)) { $this->setAddress($_REQUEST['mail_to'], 'Test User', 'to'); @@ -468,7 +467,7 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase 'first.last@[IPv6:a1::b2:11.22.33.44]', 'test@test.com', 'test@xn--example.com', - 'test@example.com' + 'test@example.com', ); $invalidaddresses = array( 'first.last@sub.do,com', @@ -608,16 +607,27 @@ class PHPMailerTest extends PHPUnit_Framework_TestCase 'first.last@[IPv6::a2::b4]', 'first.last@[IPv6:a1:a2:a3:a4:b1:b2:b3:]', 'first.last@[IPv6::a2:a3:a4:b1:b2:b3:b4]', - 'first.last@[IPv6:a1:a2:a3:a4::b1:b2:b3:b4]' + 'first.last@[IPv6:a1:a2:a3:a4::b1:b2:b3:b4]', + ); + // IDNs in Unicode and ASCII forms. + $unicodeaddresses = array( + 'first.last@bücher.ch', + 'first.last@кто.рф', + 'first.last@phplíst.com', + ); + $asciiaddresses = array( + 'first.last@xn--bcher-kva.ch', + 'first.last@xn--j1ail.xn--p1ai', + 'first.last@xn--phplst-6va.com', ); $goodfails = array(); - foreach ($validaddresses as $address) { + foreach (array_merge($validaddresses, $asciiaddresses) as $address) { if (!PHPMailer::validateAddress($address)) { $goodfails[] = $address; } } $badpasses = array(); - foreach ($invalidaddresses as $address) { + foreach (array_merge($invalidaddresses, $unicodeaddresses) as $address) { if (PHPMailer::validateAddress($address)) { $badpasses[] = $address; } @@ -1910,6 +1920,128 @@ EOT; array('Content-Type', ' application/json') ), $this->Mail->getCustomHeaders()); } + + /** + * Tests setting and retrieving ConfirmReadingTo address, also known as "read receipt" address. + */ + public function testConfirmReadingTo() + { + $this->Mail->CharSet = 'utf-8'; + $this->buildBody(); + + $this->Mail->ConfirmReadingTo = 'test@example..com'; //Invalid address + $this->assertFalse($this->Mail->send(), $this->Mail->ErrorInfo); + + $this->Mail->ConfirmReadingTo = ' test@example.com'; //Extra space to trim + $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo); + $this->assertEquals( + 'test@example.com', + $this->Mail->ConfirmReadingTo, + 'Unexpected read receipt address'); + + $this->Mail->ConfirmReadingTo = 'test@françois.ch'; //Address with IDN + if ($this->Mail->idnSupported()) { + $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo); + $this->assertEquals( + 'test@xn--franois-xxa.ch', + $this->Mail->ConfirmReadingTo, + 'IDN address not converted to punycode'); + } else { + $this->assertFalse($this->Mail->send(), $this->Mail->ErrorInfo); + } + } + + /** + * Tests CharSet and Unicode -> ASCII conversions for addresses with IDN. + */ + public function testConvertEncoding() + { + if (!$this->Mail->idnSupported()) { + $this->markTestSkipped('intl and/or mbstring extensions are not available'); + } + + $this->Mail->clearAllRecipients(); + $this->Mail->clearReplyTos(); + + // This file is UTF-8 encoded. Create a domain encoded in "iso-8859-1". + $domain = '@' . mb_convert_encoding('françois.ch', 'ISO-8859-1', 'UTF-8'); + $this->Mail->addAddress('test' . $domain); + $this->Mail->addCC('test+cc' . $domain); + $this->Mail->addBCC('test+bcc' . $domain); + $this->Mail->addReplyTo('test+replyto' . $domain); + + // Queued addresses are not returned by get*Addresses() before send() call. + $this->assertEmpty($this->Mail->getToAddresses(), 'Bad "to" recipients'); + $this->assertEmpty($this->Mail->getCcAddresses(), 'Bad "cc" recipients'); + $this->assertEmpty($this->Mail->getBccAddresses(), 'Bad "bcc" recipients'); + $this->assertEmpty($this->Mail->getReplyToAddresses(), 'Bad "reply-to" recipients'); + + // Clear queued BCC recipient. + $this->Mail->clearBCCs(); + + $this->buildBody(); + $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo); + + // Addresses with IDN are returned by get*Addresses() after send() call. + $domain = $this->Mail->punyencodeAddress($domain); + $this->assertEquals( + array(array('test' . $domain, '')), + $this->Mail->getToAddresses(), + 'Bad "to" recipients'); + $this->assertEquals( + array(array('test+cc' . $domain, '')), + $this->Mail->getCcAddresses(), + 'Bad "cc" recipients'); + $this->assertEmpty($this->Mail->getBccAddresses(), 'Bad "bcc" recipients'); + $this->assertEquals( + array('test+replyto' . $domain => array('test+replyto' . $domain, '')), + $this->Mail->getReplyToAddresses(), + 'Bad "reply-to" addresses'); + } + + /** + * Tests removal of duplicate recipients and reply-tos. + */ + public function testDuplicateIDNRemoved() + { + if (!$this->Mail->idnSupported()) { + $this->markTestSkipped('intl and/or mbstring extensions are not available'); + } + + $this->Mail->clearAllRecipients(); + $this->Mail->clearReplyTos(); + + $this->Mail->CharSet = 'utf-8'; + + $this->assertTrue($this->Mail->addAddress('test@françois.ch')); + $this->assertFalse($this->Mail->addAddress('test@françois.ch')); + $this->assertTrue($this->Mail->addAddress('test@FRANÇOIS.CH')); + $this->assertFalse($this->Mail->addAddress('test@FRANÇOIS.CH')); + $this->assertTrue($this->Mail->addAddress('test@xn--franois-xxa.ch')); + $this->assertFalse($this->Mail->addAddress('test@xn--franois-xxa.ch')); + $this->assertFalse($this->Mail->addAddress('test@XN--FRANOIS-XXA.CH')); + + $this->assertTrue($this->Mail->addReplyTo('test+replyto@françois.ch')); + $this->assertFalse($this->Mail->addReplyTo('test+replyto@françois.ch')); + $this->assertTrue($this->Mail->addReplyTo('test+replyto@FRANÇOIS.CH')); + $this->assertFalse($this->Mail->addReplyTo('test+replyto@FRANÇOIS.CH')); + $this->assertTrue($this->Mail->addReplyTo('test+replyto@xn--franois-xxa.ch')); + $this->assertFalse($this->Mail->addReplyTo('test+replyto@xn--franois-xxa.ch')); + $this->assertFalse($this->Mail->addReplyTo('test+replyto@XN--FRANOIS-XXA.CH')); + + $this->buildBody(); + $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo); + + // There should be only one "To" address and one "Reply-To" address. + $this->assertEquals( + 1, + count($this->Mail->getToAddresses()), + 'Bad count of "to" recipients'); + $this->assertEquals( + 1, + count($this->Mail->getReplyToAddresses()), + 'Bad count of "reply-to" addresses'); + } } /**