Просмотр исходного кода

Update/php mailer (#2980)

* Update PHPMailer to  6.1.5

This PR update the bundled version of PHPMAiler
Brooke 5 лет назад
Родитель
Сommit
fa56f90223

+ 1 - 1
lib/PHPMailer/PHPMailer/Exception.php

@@ -23,7 +23,7 @@ namespace PHPMailer\PHPMailer;
 /**
  * PHPMailer exception handler.
  *
- * @author  Marcus Bointon <phpmailer@synchromedia.co.uk>
+ * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
  */
 class Exception extends \Exception
 {

Разница между файлами не показана из-за своего большого размера
+ 252 - 181
lib/PHPMailer/PHPMailer/PHPMailer.php


+ 90 - 45
lib/PHPMailer/PHPMailer/SMTP.php

@@ -9,7 +9,7 @@
  * @author    Jim Jagielski (jimjag) <jimjag@gmail.com>
  * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
  * @author    Brent R. Matzelle (original founder)
- * @copyright 2012 - 2017 Marcus Bointon
+ * @copyright 2012 - 2019 Marcus Bointon
  * @copyright 2010 - 2012 Jim Jagielski
  * @copyright 2004 - 2009 Andy Prevost
  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
@@ -24,8 +24,8 @@ namespace PHPMailer\PHPMailer;
  * PHPMailer RFC821 SMTP email transport class.
  * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server.
  *
- * @author  Chris Ryan
- * @author  Marcus Bointon <phpmailer@synchromedia.co.uk>
+ * @author Chris Ryan
+ * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
  */
 class SMTP
 {
@@ -34,7 +34,7 @@ class SMTP
      *
      * @var string
      */
-    const VERSION = '6.0.7';
+    const VERSION = '6.1.5';
 
     /**
      * SMTP line break constant.
@@ -51,34 +51,57 @@ class SMTP
     const DEFAULT_PORT = 25;
 
     /**
-     * The maximum line length allowed by RFC 2822 section 2.1.1.
+     * The maximum line length allowed by RFC 5321 section 4.5.3.1.6,
+     * *excluding* a trailing CRLF break.
+     *
+     * @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.6
      *
      * @var int
      */
     const MAX_LINE_LENGTH = 998;
 
+    /**
+     * The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5,
+     * *including* a trailing CRLF line break.
+     *
+     * @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.5
+     *
+     * @var int
+     */
+    const MAX_REPLY_LENGTH = 512;
+
     /**
      * Debug level for no output.
+     *
+     * @var int
      */
     const DEBUG_OFF = 0;
 
     /**
      * Debug level to show client -> server messages.
+     *
+     * @var int
      */
     const DEBUG_CLIENT = 1;
 
     /**
      * Debug level to show client -> server and server -> client messages.
+     *
+     * @var int
      */
     const DEBUG_SERVER = 2;
 
     /**
      * Debug level to show connection status, client -> server and server -> client messages.
+     *
+     * @var int
      */
     const DEBUG_CONNECTION = 3;
 
     /**
      * Debug level to show all messages.
+     *
+     * @var int
      */
     const DEBUG_LOWLEVEL = 4;
 
@@ -197,7 +220,7 @@ class SMTP
      *
      * @var string|null
      */
-    protected $helo_rply = null;
+    protected $helo_rply;
 
     /**
      * The set of SMTP extensions sent in reply to EHLO command.
@@ -209,7 +232,7 @@ class SMTP
      *
      * @var array|null
      */
-    protected $server_caps = null;
+    protected $server_caps;
 
     /**
      * The most recent reply received from the server.
@@ -239,7 +262,7 @@ class SMTP
             return;
         }
         //Avoid clash with built-in function names
-        if (!in_array($this->Debugoutput, ['error_log', 'html', 'echo']) and is_callable($this->Debugoutput)) {
+        if (is_callable($this->Debugoutput) && !in_array($this->Debugoutput, ['error_log', 'html', 'echo'])) {
             call_user_func($this->Debugoutput, $str, $level);
 
             return;
@@ -260,12 +283,12 @@ class SMTP
             case 'echo':
             default:
                 //Normalize line breaks
-                $str = preg_replace('/\r\n|\r/ms', "\n", $str);
+                $str = preg_replace('/\r\n|\r/m', "\n", $str);
                 echo gmdate('Y-m-d H:i:s'),
                 "\t",
                     //Trim trailing space
                 trim(
-                //Indent for readability, except for trailing break
+                    //Indent for readability, except for trailing break
                     str_replace(
                         "\n",
                         "\n                   \t                  ",
@@ -348,7 +371,7 @@ class SMTP
                 'Failed to connect to server',
                 '',
                 (string) $errno,
-                (string) $errstr
+                $errstr
             );
             $this->edebug(
                 'SMTP ERROR: ' . $this->error['error']
@@ -361,10 +384,10 @@ class SMTP
         $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
         // SMTP server can take longer to respond, give longer timeout for first read
         // Windows does not have support for this timeout function
-        if (substr(PHP_OS, 0, 3) != 'WIN') {
-            $max = ini_get('max_execution_time');
+        if (strpos(PHP_OS, 'WIN') !== 0) {
+            $max = (int) ini_get('max_execution_time');
             // Don't bother if unlimited
-            if (0 != $max and $timeout > $max) {
+            if (0 !== $max && $timeout > $max) {
                 @set_time_limit($timeout);
             }
             stream_set_timeout($this->smtp_conn, $timeout, 0);
@@ -444,14 +467,14 @@ class SMTP
                 return false;
             }
 
-            $this->edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNSPECIFIED'), self::DEBUG_LOWLEVEL);
+            $this->edebug('Auth method requested: ' . ($authtype ?: 'UNSPECIFIED'), self::DEBUG_LOWLEVEL);
             $this->edebug(
                 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']),
                 self::DEBUG_LOWLEVEL
             );
 
             //If we have requested a specific auth type, check the server supports it before trying others
-            if (null !== $authtype and !in_array($authtype, $this->server_caps['AUTH'])) {
+            if (null !== $authtype && !in_array($authtype, $this->server_caps['AUTH'], true)) {
                 $this->edebug('Requested auth method not available: ' . $authtype, self::DEBUG_LOWLEVEL);
                 $authtype = null;
             }
@@ -460,7 +483,7 @@ class SMTP
                 //If no auth mechanism is specified, attempt to use these, in this order
                 //Try CRAM-MD5 first as it's more secure than the others
                 foreach (['CRAM-MD5', 'LOGIN', 'PLAIN', 'XOAUTH2'] as $method) {
-                    if (in_array($method, $this->server_caps['AUTH'])) {
+                    if (in_array($method, $this->server_caps['AUTH'], true)) {
                         $authtype = $method;
                         break;
                     }
@@ -470,10 +493,10 @@ class SMTP
 
                     return false;
                 }
-                self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL);
+                $this->edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL);
             }
 
-            if (!in_array($authtype, $this->server_caps['AUTH'])) {
+            if (!in_array($authtype, $this->server_caps['AUTH'], true)) {
                 $this->setError("The requested authentication method \"$authtype\" is not supported by the server");
 
                 return false;
@@ -663,13 +686,13 @@ class SMTP
 
         $field = substr($lines[0], 0, strpos($lines[0], ':'));
         $in_headers = false;
-        if (!empty($field) and strpos($field, ' ') === false) {
+        if (!empty($field) && strpos($field, ' ') === false) {
             $in_headers = true;
         }
 
         foreach ($lines as $line) {
             $lines_out = [];
-            if ($in_headers and $line == '') {
+            if ($in_headers && $line === '') {
                 $in_headers = false;
             }
             //Break this line up into several smaller lines if it's too long
@@ -700,7 +723,7 @@ class SMTP
             //Send the lines to the server
             foreach ($lines_out as $line_out) {
                 //RFC2821 section 4.5.2
-                if (!empty($line_out) and $line_out[0] == '.') {
+                if (!empty($line_out) && $line_out[0] === '.') {
                     $line_out = '.' . $line_out;
                 }
                 $this->client_send($line_out . static::LE, 'DATA');
@@ -710,7 +733,7 @@ class SMTP
         //Message data has been sent, complete the command
         //Increase timelimit for end of DATA command
         $savetimelimit = $this->Timelimit;
-        $this->Timelimit = $this->Timelimit * 2;
+        $this->Timelimit *= 2;
         $result = $this->sendCommand('DATA END', '.', 250);
         $this->recordLastTransactionID();
         //Restore timelimit
@@ -745,7 +768,7 @@ class SMTP
      *
      * @return bool
      *
-     * @see    hello()
+     * @see hello()
      */
     protected function sendHello($hello, $host)
     {
@@ -838,7 +861,7 @@ class SMTP
     {
         $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
         $err = $this->error; //Save any error
-        if ($noerror or $close_on_error) {
+        if ($noerror || $close_on_error) {
             $this->close();
             $this->error = $err; //Restore any error from the quit command
         }
@@ -853,14 +876,35 @@ class SMTP
      * Implements from RFC 821: RCPT <SP> TO:<forward-path> <CRLF>.
      *
      * @param string $address The address the message is being sent to
+     * @param string $dsn     Comma separated list of DSN notifications. NEVER, SUCCESS, FAILURE
+     *                        or DELAY. If you specify NEVER all other notifications are ignored.
      *
      * @return bool
      */
-    public function recipient($address)
+    public function recipient($address, $dsn = '')
     {
+        if (empty($dsn)) {
+            $rcpt = 'RCPT TO:<' . $address . '>';
+        } else {
+            $dsn = strtoupper($dsn);
+            $notify = [];
+
+            if (strpos($dsn, 'NEVER') !== false) {
+                $notify[] = 'NEVER';
+            } else {
+                foreach (['SUCCESS', 'FAILURE', 'DELAY'] as $value) {
+                    if (strpos($dsn, $value) !== false) {
+                        $notify[] = $value;
+                    }
+                }
+            }
+
+            $rcpt = 'RCPT TO:<' . $address . '> NOTIFY=' . implode(',', $notify);
+        }
+
         return $this->sendCommand(
             'RCPT TO',
-            'RCPT TO:<' . $address . '>',
+            $rcpt,
             [250, 251]
         );
     }
@@ -894,7 +938,7 @@ class SMTP
             return false;
         }
         //Reject line breaks in all commands
-        if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
+        if ((strpos($commandstring, "\n") !== false) || (strpos($commandstring, "\r") !== false)) {
             $this->setError("Command '$command' contained line breaks");
 
             return false;
@@ -904,8 +948,8 @@ class SMTP
         $this->last_reply = $this->get_lines();
         // Fetch SMTP code and possible error code explanation
         $matches = [];
-        if (preg_match('/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/', $this->last_reply, $matches)) {
-            $code = $matches[1];
+        if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) {
+            $code = (int) $matches[1];
             $code_ex = (count($matches) > 2 ? $matches[2] : null);
             // Cut off error code from each response line
             $detail = preg_replace(
@@ -916,14 +960,14 @@ class SMTP
             );
         } else {
             // Fall back to simple parsing if regex fails
-            $code = substr($this->last_reply, 0, 3);
+            $code = (int) substr($this->last_reply, 0, 3);
             $code_ex = null;
             $detail = substr($this->last_reply, 4);
         }
 
         $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
 
-        if (!in_array($code, (array) $expect)) {
+        if (!in_array($code, (array) $expect, true)) {
             $this->setError(
                 "$command command failed",
                 $detail,
@@ -1014,9 +1058,9 @@ class SMTP
     {
         //If SMTP transcripts are left enabled, or debug output is posted online
         //it can leak credentials, so hide credentials in all but lowest level
-        if (self::DEBUG_LOWLEVEL > $this->do_debug and
+        if (self::DEBUG_LOWLEVEL > $this->do_debug &&
             in_array($command, ['User & Password', 'Username', 'Password'], true)) {
-            $this->edebug('CLIENT -> SERVER: <credentials hidden>', self::DEBUG_CLIENT);
+            $this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT);
         } else {
             $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT);
         }
@@ -1062,7 +1106,7 @@ class SMTP
      *
      * @param string $name Name of SMTP extension or 'HELO'|'EHLO'
      *
-     * @return mixed
+     * @return string|bool|null
      */
     public function getServerExt($name)
     {
@@ -1073,10 +1117,10 @@ class SMTP
         }
 
         if (!array_key_exists($name, $this->server_caps)) {
-            if ('HELO' == $name) {
+            if ('HELO' === $name) {
                 return $this->server_caps['EHLO'];
             }
-            if ('EHLO' == $name || array_key_exists('EHLO', $this->server_caps)) {
+            if ('EHLO' === $name || array_key_exists('EHLO', $this->server_caps)) {
                 return false;
             }
             $this->setError('HELO handshake was used; No information about server extensions available');
@@ -1120,7 +1164,7 @@ class SMTP
         }
         $selR = [$this->smtp_conn];
         $selW = null;
-        while (is_resource($this->smtp_conn) and !feof($this->smtp_conn)) {
+        while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
             //Must pass vars in here as params are by reference
             if (!stream_select($selR, $selW, $selW, $this->Timelimit)) {
                 $this->edebug(
@@ -1130,13 +1174,13 @@ class SMTP
                 break;
             }
             //Deliberate noise suppression - errors are handled afterwards
-            $str = @fgets($this->smtp_conn, 515);
+            $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH);
             $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL);
             $data .= $str;
             // If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
-            // or 4th character is a space, we are done reading, break the loop,
-            // string array access is a micro-optimisation over strlen
-            if (!isset($str[3]) or (isset($str[3]) and $str[3] == ' ')) {
+            // or 4th character is a space or a line break char, we are done reading, break the loop.
+            // String array access is a significant micro-optimisation over strlen
+            if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") {
                 break;
             }
             // Timed-out? Log and break
@@ -1149,7 +1193,7 @@ class SMTP
                 break;
             }
             // Now check if reads took too long
-            if ($endtime and time() > $endtime) {
+            if ($endtime && time() > $endtime) {
                 $this->edebug(
                     'SMTP -> get_lines(): timelimit reached (' .
                     $this->Timelimit . ' sec)',
@@ -1289,7 +1333,7 @@ class SMTP
      * If no reply has been received yet, it will return null.
      * If no pattern was matched, it will return false.
      *
-     * @return bool|null|string
+     * @return bool|string|null
      */
     protected function recordLastTransactionID()
     {
@@ -1300,6 +1344,7 @@ class SMTP
         } else {
             $this->last_smtp_transaction_id = false;
             foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) {
+                $matches = [];
                 if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) {
                     $this->last_smtp_transaction_id = trim($matches[1]);
                     break;
@@ -1315,7 +1360,7 @@ class SMTP
      * If no reply has been received yet, it will return null.
      * If no pattern was matched, it will return false.
      *
-     * @return bool|null|string
+     * @return bool|string|null
      *
      * @see recordLastTransactionID()
      */

Некоторые файлы не были показаны из-за большого количества измененных файлов