Browse Source

PHPMailer 6.8.0 (#5389)

* PHPMailer 6.8.0
https://github.com/PHPMailer/PHPMailer/releases/tag/v6.8.0
https://github.com/PHPMailer/PHPMailer/releases

* Exclude unused DSNConfigurator
Alexandre Alapetite 2 years ago
parent
commit
4b2a94453f

+ 1 - 0
lib/.gitignore

@@ -18,5 +18,6 @@ phpmailer/phpmailer/COMMITMENT*
 phpmailer/phpmailer/composer.*
 phpmailer/phpmailer/composer.*
 phpmailer/phpmailer/language/
 phpmailer/phpmailer/language/
 phpmailer/phpmailer/SECURITY*
 phpmailer/phpmailer/SECURITY*
+phpmailer/phpmailer/src/DSNConfigurator.php
 phpmailer/phpmailer/src/OAuth*
 phpmailer/phpmailer/src/OAuth*
 phpmailer/phpmailer/src/POP3.php
 phpmailer/phpmailer/src/POP3.php

+ 1 - 1
lib/composer.json

@@ -13,7 +13,7 @@
     "require": {
     "require": {
         "marienfressinaud/lib_opml": "0.5.1",
         "marienfressinaud/lib_opml": "0.5.1",
         "phpgt/cssxpath": "dev-master#4fbe420aba3d9e729940107ded4236a835a1a132",
         "phpgt/cssxpath": "dev-master#4fbe420aba3d9e729940107ded4236a835a1a132",
-        "phpmailer/phpmailer": "6.6.0"
+        "phpmailer/phpmailer": "6.8.0"
     },
     },
     "config": {
     "config": {
         "sort-packages": true,
         "sort-packages": true,

+ 14 - 11
lib/phpmailer/phpmailer/README.md

@@ -1,3 +1,5 @@
+[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://supportukrainenow.org/)
+
 ![PHPMailer](https://raw.github.com/PHPMailer/PHPMailer/master/examples/images/phpmailer.png)
 ![PHPMailer](https://raw.github.com/PHPMailer/PHPMailer/master/examples/images/phpmailer.png)
 
 
 # PHPMailer – A full-featured email creation and transfer class for PHP
 # PHPMailer – A full-featured email creation and transfer class for PHP
@@ -8,12 +10,13 @@
 [![Total Downloads](https://poser.pugx.org/phpmailer/phpmailer/downloads)](https://packagist.org/packages/phpmailer/phpmailer)
 [![Total Downloads](https://poser.pugx.org/phpmailer/phpmailer/downloads)](https://packagist.org/packages/phpmailer/phpmailer)
 [![License](https://poser.pugx.org/phpmailer/phpmailer/license.svg)](https://packagist.org/packages/phpmailer/phpmailer)
 [![License](https://poser.pugx.org/phpmailer/phpmailer/license.svg)](https://packagist.org/packages/phpmailer/phpmailer)
 [![API Docs](https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg)](https://phpmailer.github.io/PHPMailer/)
 [![API Docs](https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg)](https://phpmailer.github.io/PHPMailer/)
+[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/PHPMailer/PHPMailer/badge)](https://api.securityscorecards.dev/projects/github.com/PHPMailer/PHPMailer)
 
 
 ## Features
 ## Features
 - Probably the world's most popular code for sending email from PHP!
 - Probably the world's most popular code for sending email from PHP!
 - Used by many open-source projects: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! and many more
 - Used by many open-source projects: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! and many more
 - Integrated SMTP support – send without a local mail server
 - Integrated SMTP support – send without a local mail server
-- Send emails with multiple To, CC, BCC and Reply-to addresses
+- Send emails with multiple To, CC, BCC, and Reply-to addresses
 - Multipart/alternative emails for mail clients that do not read HTML email
 - Multipart/alternative emails for mail clients that do not read HTML email
 - Add attachments, including inline
 - Add attachments, including inline
 - Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings
 - Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings
@@ -22,7 +25,7 @@
 - Protects against header injection attacks
 - Protects against header injection attacks
 - Error messages in over 50 languages!
 - Error messages in over 50 languages!
 - DKIM and S/MIME signing support
 - DKIM and S/MIME signing support
-- Compatible with PHP 5.5 and later, including PHP 8.1
+- Compatible with PHP 5.5 and later, including PHP 8.2
 - Namespaced to prevent name clashes
 - Namespaced to prevent name clashes
 - Much more!
 - Much more!
 
 
@@ -35,7 +38,7 @@ The PHP `mail()` function usually sends via a local mail server, typically front
 
 
 *Please* don't be tempted to do it yourself – if you don't use PHPMailer, there are many other excellent libraries that
 *Please* don't be tempted to do it yourself – if you don't use PHPMailer, there are many other excellent libraries that
 you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/)
 you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/)
-, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail) etc.
+, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc.
 
 
 ## License
 ## License
 This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
 This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
@@ -44,7 +47,7 @@ This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lg
 PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file:
 PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file:
 
 
 ```json
 ```json
-"phpmailer/phpmailer": "^6.5"
+"phpmailer/phpmailer": "^6.8.0"
 ```
 ```
 
 
 or run
 or run
@@ -133,14 +136,14 @@ try {
 }
 }
 ```
 ```
 
 
-You'll find plenty to play with in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder, which covers many common scenarios including sending through gmail, building contact forms, sending to mailing lists, and more.
+You'll find plenty to play with in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder, which covers many common scenarios including sending through Gmail, building contact forms, sending to mailing lists, and more.
 
 
 If you are re-using the instance (e.g. when sending to a mailing list), you may need to clear the recipient list to avoid sending duplicate messages. See [the mailing list example](https://github.com/PHPMailer/PHPMailer/blob/master/examples/mailing_list.phps) for further guidance.
 If you are re-using the instance (e.g. when sending to a mailing list), you may need to clear the recipient list to avoid sending duplicate messages. See [the mailing list example](https://github.com/PHPMailer/PHPMailer/blob/master/examples/mailing_list.phps) for further guidance.
 
 
 That's it. You should now be ready to use PHPMailer!
 That's it. You should now be ready to use PHPMailer!
 
 
 ## Localization
 ## Localization
-PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
+PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder, you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
 
 
 ```php
 ```php
 //To load the French version
 //To load the French version
@@ -175,9 +178,9 @@ Please disclose any vulnerabilities found responsibly – report security issues
 See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) and [PHPMailer's security advisories on GitHub](https://github.com/PHPMailer/PHPMailer/security). 
 See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) and [PHPMailer's security advisories on GitHub](https://github.com/PHPMailer/PHPMailer/security). 
 
 
 ## Contributing
 ## Contributing
-Please submit bug reports, suggestions and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues).
+Please submit bug reports, suggestions, and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues).
 
 
-We're particularly interested in fixing edge-cases, expanding test coverage and updating translations.
+We're particularly interested in fixing edge cases, expanding test coverage, and updating translations.
 
 
 If you found a mistake in the docs, or want to add something, go ahead and amend the wiki – anyone can edit it.
 If you found a mistake in the docs, or want to add something, go ahead and amend the wiki – anyone can edit it.
 
 
@@ -201,7 +204,7 @@ Donations are very welcome, whether in beer 🍺, T-shirts 👕, or cold, hard c
 Available as part of the Tidelift Subscription.
 Available as part of the Tidelift Subscription.
 
 
 The maintainers of PHPMailer and thousands of other packages are working with Tidelift to deliver commercial
 The maintainers of PHPMailer and thousands of other packages are working with Tidelift to deliver commercial
-support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and
+support and maintenance for the open-source packages you use to build your applications. Save time, reduce risk, and
 improve code health, while paying the maintainers of the exact packages you
 improve code health, while paying the maintainers of the exact packages you
 use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpmailer-phpmailer?utm_source=packagist-phpmailer-phpmailer&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
 use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpmailer-phpmailer?utm_source=packagist-phpmailer-phpmailer&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
 
 
@@ -219,9 +222,9 @@ See [changelog](changelog.md).
 ### What's changed since moving from SourceForge?
 ### What's changed since moving from SourceForge?
 - Official successor to the SourceForge and Google Code projects.
 - Official successor to the SourceForge and Google Code projects.
 - Test suite.
 - Test suite.
-- Continuous integration with Github Actions.
+- Continuous integration with GitHub Actions.
 - Composer support.
 - Composer support.
 - Public development.
 - Public development.
 - Additional languages and language strings.
 - Additional languages and language strings.
 - CRAM-MD5 authentication support.
 - CRAM-MD5 authentication support.
-- Preserves full repo history of authors, commits and branches from the original SourceForge project.
+- Preserves full repo history of authors, commits, and branches from the original SourceForge project.

+ 1 - 1
lib/phpmailer/phpmailer/VERSION

@@ -1 +1 @@
-6.6.0
+6.8.0

+ 99 - 44
lib/phpmailer/phpmailer/src/PHPMailer.php

@@ -350,8 +350,8 @@ class PHPMailer
     public $Password = '';
     public $Password = '';
 
 
     /**
     /**
-     * SMTP auth type.
-     * Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2, attempted in that order if not specified.
+     * SMTP authentication type. Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2.
+     * If not specified, the first one from that list that the server supports will be selected.
      *
      *
      * @var string
      * @var string
      */
      */
@@ -750,7 +750,7 @@ class PHPMailer
      *
      *
      * @var string
      * @var string
      */
      */
-    const VERSION = '6.6.0';
+    const VERSION = '6.8.0';
 
 
     /**
     /**
      * Error severity: message only, continue processing.
      * Error severity: message only, continue processing.
@@ -858,7 +858,7 @@ class PHPMailer
     private function mailPassthru($to, $subject, $body, $header, $params)
     private function mailPassthru($to, $subject, $body, $header, $params)
     {
     {
         //Check overloading of mail function to avoid double-encoding
         //Check overloading of mail function to avoid double-encoding
-        if (ini_get('mbstring.func_overload') & 1) {
+        if ((int)ini_get('mbstring.func_overload') & 1) {
             $subject = $this->secureHeader($subject);
             $subject = $this->secureHeader($subject);
         } else {
         } else {
             $subject = $this->encodeHeader($this->secureHeader($subject));
             $subject = $this->encodeHeader($this->secureHeader($subject));
@@ -1066,8 +1066,8 @@ class PHPMailer
      * Addresses that have been added already return false, but do not throw exceptions.
      * 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 $kind    One of 'to', 'cc', 'bcc', or 'ReplyTo'
-     * @param string $address The email address to send, resp. to reply to
-     * @param string $name
+     * @param string $address The email address
+     * @param string $name    An optional username associated with the address
      *
      *
      * @throws Exception
      * @throws Exception
      *
      *
@@ -1075,9 +1075,11 @@ class PHPMailer
      */
      */
     protected function addOrEnqueueAnAddress($kind, $address, $name)
     protected function addOrEnqueueAnAddress($kind, $address, $name)
     {
     {
-        $address = trim($address);
-        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
-        $pos = strrpos($address, '@');
+        $pos = false;
+        if ($address !== null) {
+            $address = trim($address);
+            $pos = strrpos($address, '@');
+        }
         if (false === $pos) {
         if (false === $pos) {
             //At-sign is missing.
             //At-sign is missing.
             $error_message = sprintf(
             $error_message = sprintf(
@@ -1094,8 +1096,14 @@ class PHPMailer
 
 
             return false;
             return false;
         }
         }
+        if ($name !== null && is_string($name)) {
+            $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
+        } else {
+            $name = '';
+        }
         $params = [$kind, $address, $name];
         $params = [$kind, $address, $name];
         //Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
         //Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
+        //Domain is assumed to be whatever is after the last @ symbol in the address
         if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) {
         if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) {
             if ('Reply-To' !== $kind) {
             if ('Reply-To' !== $kind) {
                 if (!array_key_exists($address, $this->RecipientsQueue)) {
                 if (!array_key_exists($address, $this->RecipientsQueue)) {
@@ -1116,6 +1124,22 @@ class PHPMailer
         return call_user_func_array([$this, 'addAnAddress'], $params);
         return call_user_func_array([$this, 'addAnAddress'], $params);
     }
     }
 
 
+    /**
+     * Set the boundaries to use for delimiting MIME parts.
+     * If you override this, ensure you set all 3 boundaries to unique values.
+     * The default boundaries include a "=_" sequence which cannot occur in quoted-printable bodies,
+     * as suggested by https://www.rfc-editor.org/rfc/rfc2045#section-6.7
+     *
+     * @return void
+     */
+    public function setBoundaries()
+    {
+        $this->uniqueid = $this->generateId();
+        $this->boundary[1] = 'b1=_' . $this->uniqueid;
+        $this->boundary[2] = 'b2=_' . $this->uniqueid;
+        $this->boundary[3] = 'b3=_' . $this->uniqueid;
+    }
+
     /**
     /**
      * Add an address to one of the recipient arrays or to the ReplyTo array.
      * Add an address to one of the recipient arrays or to the ReplyTo array.
      * Addresses that have been added already return false, but do not throw exceptions.
      * Addresses that have been added already return false, but do not throw exceptions.
@@ -1280,7 +1304,7 @@ class PHPMailer
      */
      */
     public function setFrom($address, $name = '', $auto = true)
     public function setFrom($address, $name = '', $auto = true)
     {
     {
-        $address = trim($address);
+        $address = trim((string)$address);
         $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
         $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
         //Don't validate now addresses with IDN. Will be done in send().
         //Don't validate now addresses with IDN. Will be done in send().
         $pos = strrpos($address, '@');
         $pos = strrpos($address, '@');
@@ -1547,17 +1571,17 @@ class PHPMailer
 
 
             //Validate From, Sender, and ConfirmReadingTo addresses
             //Validate From, Sender, and ConfirmReadingTo addresses
             foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
             foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
-                $this->$address_kind = trim($this->$address_kind);
-                if (empty($this->$address_kind)) {
+                $this->{$address_kind} = trim($this->{$address_kind});
+                if (empty($this->{$address_kind})) {
                     continue;
                     continue;
                 }
                 }
-                $this->$address_kind = $this->punyencodeAddress($this->$address_kind);
-                if (!static::validateAddress($this->$address_kind)) {
+                $this->{$address_kind} = $this->punyencodeAddress($this->{$address_kind});
+                if (!static::validateAddress($this->{$address_kind})) {
                     $error_message = sprintf(
                     $error_message = sprintf(
                         '%s (%s): %s',
                         '%s (%s): %s',
                         $this->lang('invalid_address'),
                         $this->lang('invalid_address'),
                         $address_kind,
                         $address_kind,
-                        $this->$address_kind
+                        $this->{$address_kind}
                     );
                     );
                     $this->setError($error_message);
                     $this->setError($error_message);
                     $this->edebug($error_message);
                     $this->edebug($error_message);
@@ -1657,17 +1681,17 @@ class PHPMailer
                 default:
                 default:
                     $sendMethod = $this->Mailer . 'Send';
                     $sendMethod = $this->Mailer . 'Send';
                     if (method_exists($this, $sendMethod)) {
                     if (method_exists($this, $sendMethod)) {
-                        return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
+                        return $this->{$sendMethod}($this->MIMEHeader, $this->MIMEBody);
                     }
                     }
 
 
                     return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
                     return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
             }
             }
         } catch (Exception $exc) {
         } catch (Exception $exc) {
-            if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true) {
-                $this->smtp->reset();
-            }
             $this->setError($exc->getMessage());
             $this->setError($exc->getMessage());
             $this->edebug($exc->getMessage());
             $this->edebug($exc->getMessage());
+            if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) {
+                $this->smtp->reset();
+            }
             if ($this->exceptions) {
             if ($this->exceptions) {
                 throw $exc;
                 throw $exc;
             }
             }
@@ -1855,7 +1879,7 @@ class PHPMailer
         if (!static::isPermittedPath($path)) {
         if (!static::isPermittedPath($path)) {
             return false;
             return false;
         }
         }
-        $readable = file_exists($path);
+        $readable = is_file($path);
         //If not a UNC path (expected to start with \\), check read permission, see #2069
         //If not a UNC path (expected to start with \\), check read permission, see #2069
         if (strpos($path, '\\\\') !== 0) {
         if (strpos($path, '\\\\') !== 0) {
             $readable = $readable && is_readable($path);
             $readable = $readable && is_readable($path);
@@ -1883,7 +1907,14 @@ class PHPMailer
         foreach ($this->to as $toaddr) {
         foreach ($this->to as $toaddr) {
             $toArr[] = $this->addrFormat($toaddr);
             $toArr[] = $this->addrFormat($toaddr);
         }
         }
-        $to = implode(', ', $toArr);
+        $to = trim(implode(', ', $toArr));
+
+        //If there are no To-addresses (e.g. when sending only to BCC-addresses)
+        //the following should be added to get a correct DKIM-signature.
+        //Compare with $this->preSend()
+        if ($to === '') {
+            $to = 'undisclosed-recipients:;';
+        }
 
 
         $params = null;
         $params = null;
         //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
         //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
@@ -2086,6 +2117,9 @@ class PHPMailer
         $this->smtp->setDebugLevel($this->SMTPDebug);
         $this->smtp->setDebugLevel($this->SMTPDebug);
         $this->smtp->setDebugOutput($this->Debugoutput);
         $this->smtp->setDebugOutput($this->Debugoutput);
         $this->smtp->setVerp($this->do_verp);
         $this->smtp->setVerp($this->do_verp);
+        if ($this->Host === null) {
+            $this->Host = 'localhost';
+        }
         $hosts = explode(';', $this->Host);
         $hosts = explode(';', $this->Host);
         $lastexception = null;
         $lastexception = null;
 
 
@@ -2192,7 +2226,8 @@ class PHPMailer
         //As we've caught all exceptions, just report whatever the last one was
         //As we've caught all exceptions, just report whatever the last one was
         if ($this->exceptions && null !== $lastexception) {
         if ($this->exceptions && null !== $lastexception) {
             throw $lastexception;
             throw $lastexception;
-        } elseif ($this->exceptions) {
+        }
+        if ($this->exceptions) {
             // no exception was thrown, likely $this->smtp->connect() failed
             // no exception was thrown, likely $this->smtp->connect() failed
             $message = $this->getSmtpErrorMessage('connect_host');
             $message = $this->getSmtpErrorMessage('connect_host');
             throw new Exception($message);
             throw new Exception($message);
@@ -2388,7 +2423,7 @@ class PHPMailer
      */
      */
     public function addrFormat($addr)
     public function addrFormat($addr)
     {
     {
-        if (empty($addr[1])) { //No name provided
+        if (!isset($addr[1]) || ($addr[1] === '')) { //No name provided
             return $this->secureHeader($addr[0]);
             return $this->secureHeader($addr[0]);
         }
         }
 
 
@@ -2775,10 +2810,7 @@ class PHPMailer
     {
     {
         $body = '';
         $body = '';
         //Create unique IDs and preset boundaries
         //Create unique IDs and preset boundaries
-        $this->uniqueid = $this->generateId();
-        $this->boundary[1] = 'b1_' . $this->uniqueid;
-        $this->boundary[2] = 'b2_' . $this->uniqueid;
-        $this->boundary[3] = 'b3_' . $this->uniqueid;
+        $this->setBoundaries();
 
 
         if ($this->sign_key_file) {
         if ($this->sign_key_file) {
             $body .= $this->getMailMIME() . static::$LE;
             $body .= $this->getMailMIME() . static::$LE;
@@ -2814,7 +2846,7 @@ class PHPMailer
             $altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
             $altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
         }
         }
         //Use this as a preamble in all multipart message types
         //Use this as a preamble in all multipart message types
-        $mimepre = 'This is a multi-part message in MIME format.' . static::$LE . static::$LE;
+        $mimepre = '';
         switch ($this->message_type) {
         switch ($this->message_type) {
             case 'inline':
             case 'inline':
                 $body .= $mimepre;
                 $body .= $mimepre;
@@ -3050,6 +3082,18 @@ class PHPMailer
         return $body;
         return $body;
     }
     }
 
 
+    /**
+     * Get the boundaries that this message will use
+     * @return array
+     */
+    public function getBoundaries()
+    {
+        if (empty($this->boundary)) {
+            $this->setBoundaries();
+        }
+        return $this->boundary;
+    }
+
     /**
     /**
      * Return the start of a message boundary.
      * Return the start of a message boundary.
      *
      *
@@ -3705,20 +3749,21 @@ class PHPMailer
      * These differ from 'regular' attachments in that they are intended to be
      * These differ from 'regular' attachments in that they are intended to be
      * displayed inline with the message, not just attached for download.
      * displayed inline with the message, not just attached for download.
      * This is used in HTML messages that embed the images
      * This is used in HTML messages that embed the images
-     * the HTML refers to using the $cid value.
+     * the HTML refers to using the `$cid` value in `img` tags, for example `<img src="cid:mylogo">`.
      * Never use a user-supplied path to a file!
      * Never use a user-supplied path to a file!
      *
      *
      * @param string $path        Path to the attachment
      * @param string $path        Path to the attachment
      * @param string $cid         Content ID of the attachment; Use this to reference
      * @param string $cid         Content ID of the attachment; Use this to reference
      *                            the content when using an embedded image in HTML
      *                            the content when using an embedded image in HTML
-     * @param string $name        Overrides the attachment name
-     * @param string $encoding    File encoding (see $Encoding)
-     * @param string $type        File MIME type
-     * @param string $disposition Disposition to use
+     * @param string $name        Overrides the attachment filename
+     * @param string $encoding    File encoding (see $Encoding) defaults to `base64`
+     * @param string $type        File MIME type (by default mapped from the `$path` filename's extension)
+     * @param string $disposition Disposition to use: `inline` (default) or `attachment`
+     *                            (unlikely you want this – {@see `addAttachment()`} instead)
      *
      *
+     * @return bool True on successfully adding an attachment
      * @throws Exception
      * @throws Exception
      *
      *
-     * @return bool True on successfully adding an attachment
      */
      */
     public function addEmbeddedImage(
     public function addEmbeddedImage(
         $path,
         $path,
@@ -4096,12 +4141,8 @@ class PHPMailer
             //Is it a valid IPv4 address?
             //Is it a valid IPv4 address?
             return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
             return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
         }
         }
-        if (filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false) {
-            //Is it a syntactically valid hostname?
-            return true;
-        }
-
-        return false;
+        //Is it a syntactically valid hostname (when embeded in a URL)?
+        return filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false;
     }
     }
 
 
     /**
     /**
@@ -4170,6 +4211,7 @@ class PHPMailer
      * @param string      $name  Custom header name
      * @param string      $name  Custom header name
      * @param string|null $value Header value
      * @param string|null $value Header value
      *
      *
+     * @return bool True if a header was set successfully
      * @throws Exception
      * @throws Exception
      */
      */
     public function addCustomHeader($name, $value = null)
     public function addCustomHeader($name, $value = null)
@@ -4464,6 +4506,7 @@ class PHPMailer
             'ics' => 'text/calendar',
             'ics' => 'text/calendar',
             'xml' => 'text/xml',
             'xml' => 'text/xml',
             'xsl' => 'text/xml',
             'xsl' => 'text/xml',
+            'csv' => 'text/csv',
             'wmv' => 'video/x-ms-wmv',
             'wmv' => 'video/x-ms-wmv',
             'mpeg' => 'video/mpeg',
             'mpeg' => 'video/mpeg',
             'mpe' => 'video/mpeg',
             'mpe' => 'video/mpeg',
@@ -4571,7 +4614,7 @@ class PHPMailer
     public function set($name, $value = '')
     public function set($name, $value = '')
     {
     {
         if (property_exists($this, $name)) {
         if (property_exists($this, $name)) {
-            $this->$name = $value;
+            $this->{$name} = $value;
 
 
             return true;
             return true;
         }
         }
@@ -4618,17 +4661,29 @@ class PHPMailer
     }
     }
 
 
     /**
     /**
-     * Remove trailing breaks from a string.
+     * Remove trailing whitespace from a string.
      *
      *
      * @param string $text
      * @param string $text
      *
      *
-     * @return string The text to remove breaks from
+     * @return string The text to remove whitespace from
      */
      */
     public static function stripTrailingWSP($text)
     public static function stripTrailingWSP($text)
     {
     {
         return rtrim($text, " \r\n\t");
         return rtrim($text, " \r\n\t");
     }
     }
 
 
+    /**
+     * Strip trailing line breaks from a string.
+     *
+     * @param string $text
+     *
+     * @return string The text to remove breaks from
+     */
+    public static function stripTrailingBreaks($text)
+    {
+        return rtrim($text, "\r\n");
+    }
+
     /**
     /**
      * Return the current line break format string.
      * Return the current line break format string.
      *
      *
@@ -4792,7 +4847,7 @@ class PHPMailer
         $body = static::normalizeBreaks($body, self::CRLF);
         $body = static::normalizeBreaks($body, self::CRLF);
 
 
         //Reduce multiple trailing line breaks to a single one
         //Reduce multiple trailing line breaks to a single one
-        return static::stripTrailingWSP($body) . self::CRLF;
+        return static::stripTrailingBreaks($body) . self::CRLF;
     }
     }
 
 
     /**
     /**

+ 13 - 3
lib/phpmailer/phpmailer/src/SMTP.php

@@ -35,7 +35,7 @@ class SMTP
      *
      *
      * @var string
      * @var string
      */
      */
-    const VERSION = '6.6.0';
+    const VERSION = '6.8.0';
 
 
     /**
     /**
      * SMTP line break constant.
      * SMTP line break constant.
@@ -51,6 +51,13 @@ class SMTP
      */
      */
     const DEFAULT_PORT = 25;
     const DEFAULT_PORT = 25;
 
 
+    /**
+     * The SMTPs port to use if one is not specified.
+     *
+     * @var int
+     */
+    const DEFAULT_SECURE_PORT = 465;
+
     /**
     /**
      * The maximum line length allowed by RFC 5321 section 4.5.3.1.6,
      * The maximum line length allowed by RFC 5321 section 4.5.3.1.6,
      * *excluding* a trailing CRLF break.
      * *excluding* a trailing CRLF break.
@@ -187,6 +194,7 @@ class SMTP
         'SendGrid' => '/[\d]{3} Ok: queued as (.*)/',
         'SendGrid' => '/[\d]{3} Ok: queued as (.*)/',
         'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/',
         'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/',
         'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
         'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
+        'ZoneMTA' => '/[\d]{3} Message queued as (.*)/',
         'Mailjet' => '/[\d]{3} OK queued as (.*)/',
         'Mailjet' => '/[\d]{3} OK queued as (.*)/',
     ];
     ];
 
 
@@ -682,7 +690,6 @@ class SMTP
      */
      */
     public function close()
     public function close()
     {
     {
-        $this->setError('');
         $this->server_caps = null;
         $this->server_caps = null;
         $this->helo_rply = null;
         $this->helo_rply = null;
         if (is_resource($this->smtp_conn)) {
         if (is_resource($this->smtp_conn)) {
@@ -1037,7 +1044,10 @@ class SMTP
             return false;
             return false;
         }
         }
 
 
-        $this->setError('');
+        //Don't clear the error store when using keepalive
+        if ($command !== 'RSET') {
+            $this->setError('');
+        }
 
 
         return true;
         return true;
     }
     }