<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[60813] trunk/src/wp-includes: External Libraries: Upgrade PHPMailer to version 6.11.0.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/60813">60813</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/60813","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>SergeyBiryukov</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2025-09-30 12:46:53 +0000 (Tue, 30 Sep 2025)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>External Libraries: Upgrade PHPMailer to version 6.11.0.
This is a large maintenance release with address parser improvements.
References:
* [https://github.com/PHPMailer/PHPMailer/releases/tag/v6.11.0 PHPMailer 6.11.0 release notes]
* [https://github.com/PHPMailer/PHPMailer/compare/v6.10.0...v6.11.0 Full list of changes in PHPMailer 6.11.0]
Follow-up to <a href="https://core.trac.wordpress.org/changeset/54937">[54937]</a>, <a href="https://core.trac.wordpress.org/changeset/55557">[55557]</a>, <a href="https://core.trac.wordpress.org/changeset/56484">[56484]</a>, <a href="https://core.trac.wordpress.org/changeset/57137">[57137]</a>, <a href="https://core.trac.wordpress.org/changeset/59246">[59246]</a>, <a href="https://core.trac.wordpress.org/changeset/59481">[59481]</a>, <a href="https://core.trac.wordpress.org/changeset/60623">[60623]</a>.
Props SirLouen, jrf, mukesh27, SergeyBiryukov.
Fixes <a href="https://core.trac.wordpress.org/ticket/64052">#64052</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesPHPMailerPHPMailerphp">trunk/src/wp-includes/PHPMailer/PHPMailer.php</a></li>
<li><a href="#trunksrcwpincludesPHPMailerPOP3php">trunk/src/wp-includes/PHPMailer/POP3.php</a></li>
<li><a href="#trunksrcwpincludesPHPMailerSMTPphp">trunk/src/wp-includes/PHPMailer/SMTP.php</a></li>
<li><a href="#trunksrcwpincludesclasswpphpmailerphp">trunk/src/wp-includes/class-wp-phpmailer.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesPHPMailerPHPMailerphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/PHPMailer/PHPMailer.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/PHPMailer/PHPMailer.php 2025-09-29 19:11:01 UTC (rev 60812)
+++ trunk/src/wp-includes/PHPMailer/PHPMailer.php 2025-09-30 12:46:53 UTC (rev 60813)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -561,9 +561,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * string $body the email body
</span><span class="cx" style="display: block; padding: 0 10px"> * string $from email address of sender
</span><span class="cx" style="display: block; padding: 0 10px"> * string $extra extra information of possible use
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * "smtp_transaction_id' => last smtp transaction id
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * 'smtp_transaction_id' => last smtp transaction id
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @var string
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @var callable|callable-string
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public $action_function = '';
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -711,7 +711,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- protected $language = [];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ protected static $language = [];
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * The number of errors encountered.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -768,7 +768,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var string
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- const VERSION = '6.10.0';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const VERSION = '6.11.0';
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Error severity: message only, continue processing.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1102,7 +1102,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> //At-sign is missing.
</span><span class="cx" style="display: block; padding: 0 10px"> $error_message = sprintf(
</span><span class="cx" style="display: block; padding: 0 10px"> '%s (%s): %s',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->lang('invalid_address'),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ self::lang('invalid_address'),
</ins><span class="cx" style="display: block; padding: 0 10px"> $kind,
</span><span class="cx" style="display: block; padding: 0 10px"> $address
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1187,7 +1187,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $error_message = sprintf(
</span><span class="cx" style="display: block; padding: 0 10px"> '%s: %s',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->lang('Invalid recipient kind'),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ self::lang('Invalid recipient kind'),
</ins><span class="cx" style="display: block; padding: 0 10px"> $kind
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> $this->setError($error_message);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1201,7 +1201,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!static::validateAddress($address)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $error_message = sprintf(
</span><span class="cx" style="display: block; padding: 0 10px"> '%s (%s): %s',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->lang('invalid_address'),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ self::lang('invalid_address'),
</ins><span class="cx" style="display: block; padding: 0 10px"> $kind,
</span><span class="cx" style="display: block; padding: 0 10px"> $address
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1220,12 +1220,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- } elseif (!array_key_exists(strtolower($address), $this->ReplyTo)) {
- $this->ReplyTo[strtolower($address)] = [$address, $name];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } else {
+ foreach ($this->ReplyTo as $replyTo) {
+ if (0 === strcasecmp($replyTo[0], $address)) {
+ return false;
+ }
+ }
+ $this->ReplyTo[] = [$address, $name];
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1237,16 +1241,19 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @see https://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $addrstr The address list string
- * @param bool $useimap Whether to use the IMAP extension to parse the list
- * @param string $charset The charset to use when decoding the address list string.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $addrstr The address list string
+ * @param string|null $deprecatedArg Deprecated argument since 6.11.0.
+ * @param string $charset The charset to use when decoding the address list string.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @return array
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public static function parseAddresses($addrstr, $useimap = true, $charset = self::CHARSET_ISO88591)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function parseAddresses($addrstr, $deprecatedArg = null, $charset = self::CHARSET_ISO88591)
</ins><span class="cx" style="display: block; padding: 0 10px"> {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($deprecatedArg !== null) {
+ trigger_error(self::lang('deprecated_argument'), E_USER_DEPRECATED);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> $addresses = [];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($useimap && function_exists('imap_rfc822_parse_adrlist')) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (function_exists('imap_rfc822_parse_adrlist')) {
</ins><span class="cx" style="display: block; padding: 0 10px"> //Use this built-in parser if it's available
</span><span class="cx" style="display: block; padding: 0 10px"> $list = imap_rfc822_parse_adrlist($addrstr, '');
</span><span class="cx" style="display: block; padding: 0 10px"> // Clear any potential IMAP errors to get rid of notices being thrown at end of script.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1256,20 +1263,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> '.SYNTAX-ERROR.' !== $address->host &&
</span><span class="cx" style="display: block; padding: 0 10px"> static::validateAddress($address->mailbox . '@' . $address->host)
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- //Decode the name part if it's present and encoded
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Decode the name part if it's present and maybe encoded
</ins><span class="cx" style="display: block; padding: 0 10px"> if (
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- property_exists($address, 'personal') &&
- //Check for a Mbstring constant rather than using extension_loaded, which is sometimes disabled
- defined('MB_CASE_UPPER') &&
- preg_match('/^=\?.*\?=$/s', $address->personal)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ property_exists($address, 'personal')
+ && is_string($address->personal)
+ && $address->personal !== ''
</ins><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $origCharset = mb_internal_encoding();
- mb_internal_encoding($charset);
- //Undo any RFC2047-encoded spaces-as-underscores
- $address->personal = str_replace('_', '=20', $address->personal);
- //Decode the name
- $address->personal = mb_decode_mimeheader($address->personal);
- mb_internal_encoding($origCharset);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $address->personal = static::decodeHeader($address->personal, $charset);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $addresses[] = [
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1280,41 +1280,52 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> //Use this simpler parser
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $list = explode(',', $addrstr);
- foreach ($list as $address) {
- $address = trim($address);
- //Is there a separate name part?
- if (strpos($address, '<') === false) {
- //No separate name, just use the whole thing
- if (static::validateAddress($address)) {
- $addresses[] = [
- 'name' => '',
- 'address' => $address,
- ];
- }
- } else {
- list($name, $email) = explode('<', $address);
- $email = trim(str_replace('>', '', $email));
- $name = trim($name);
- if (static::validateAddress($email)) {
- //Check for a Mbstring constant rather than using extension_loaded, which is sometimes disabled
- //If this name is encoded, decode it
- if (defined('MB_CASE_UPPER') && preg_match('/^=\?.*\?=$/s', $name)) {
- $origCharset = mb_internal_encoding();
- mb_internal_encoding($charset);
- //Undo any RFC2047-encoded spaces-as-underscores
- $name = str_replace('_', '=20', $name);
- //Decode the name
- $name = mb_decode_mimeheader($name);
- mb_internal_encoding($origCharset);
- }
- $addresses[] = [
- //Remove any surrounding quotes and spaces from the name
- 'name' => trim($name, '\'" '),
- 'address' => $email,
- ];
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $addresses = static::parseSimplerAddresses($addrstr, $charset);
+ }
+
+ return $addresses;
+ }
+
+ /**
+ * Parse a string containing one or more RFC822-style comma-separated email addresses
+ * with the form "display name <address>" into an array of name/address pairs.
+ * Uses a simpler parser that does not require the IMAP extension but doesnt support
+ * the full RFC822 spec. For full RFC822 support, use the PHP IMAP extension.
+ *
+ * @param string $addrstr The address list string
+ * @param string $charset The charset to use when decoding the address list string.
+ *
+ * @return array
+ */
+ protected static function parseSimplerAddresses($addrstr, $charset)
+ {
+ // Emit a runtime notice to recommend using the IMAP extension for full RFC822 parsing
+ trigger_error(self::lang('imap_recommended'), E_USER_NOTICE);
+
+ $addresses = [];
+ $list = explode(',', $addrstr);
+ foreach ($list as $address) {
+ $address = trim($address);
+ //Is there a separate name part?
+ if (strpos($address, '<') === false) {
+ //No separate name, just use the whole thing
+ if (static::validateAddress($address)) {
+ $addresses[] = [
+ 'name' => '',
+ 'address' => $address,
+ ];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } else {
+ $parsed = static::parseEmailString($address);
+ $email = $parsed['email'];
+ if (static::validateAddress($email)) {
+ $name = static::decodeHeader($parsed['name'], $charset);
+ $addresses[] = [
+ //Remove any surrounding quotes and spaces from the name
+ 'name' => trim($name, '\'" '),
+ 'address' => $email,
+ ];
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1322,6 +1333,42 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Parse a string containing an email address with an optional name
+ * and divide it into a name and email address.
+ *
+ * @param string $input The email with name.
+ *
+ * @return array{name: string, email: string}
+ */
+ private static function parseEmailString($input)
+ {
+ $input = trim((string)$input);
+
+ if ($input === '') {
+ return ['name' => '', 'email' => ''];
+ }
+
+ $pattern = '/^\s*(?:(?:"([^"]*)"|\'([^\']*)\'|([^<]*?))\s*)?<\s*([^>]+)\s*>\s*$/';
+ if (preg_match($pattern, $input, $matches)) {
+ $name = '';
+ // Double quotes including special scenarios.
+ if (isset($matches[1]) && $matches[1] !== '') {
+ $name = $matches[1];
+ // Single quotes including special scenarios.
+ } elseif (isset($matches[2]) && $matches[2] !== '') {
+ $name = $matches[2];
+ // Simplest scenario, name and email are in the format "Name <email>".
+ } elseif (isset($matches[3])) {
+ $name = trim($matches[3]);
+ }
+
+ return ['name' => $name, 'email' => trim($matches[4])];
+ }
+
+ return ['name' => '', 'email' => $input];
+ }
+
+ /**
</ins><span class="cx" style="display: block; padding: 0 10px"> * Set the From and FromName properties.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $address
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1334,6 +1381,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function setFrom($address, $name = '', $auto = true)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (is_null($name)) {
+ //Helps avoid a deprecation warning in the preg_replace() below
+ $name = '';
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> $address = trim((string)$address);
</span><span class="cx" style="display: block; padding: 0 10px"> $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
</span><span class="cx" style="display: block; padding: 0 10px"> //Don't validate now addresses with IDN. Will be done in send().
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1345,7 +1396,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $error_message = sprintf(
</span><span class="cx" style="display: block; padding: 0 10px"> '%s (From): %s',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->lang('invalid_address'),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ self::lang('invalid_address'),
</ins><span class="cx" style="display: block; padding: 0 10px"> $address
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> $this->setError($error_message);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1601,7 +1652,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> && ini_get('mail.add_x_header') === '1'
</span><span class="cx" style="display: block; padding: 0 10px"> && stripos(PHP_OS, 'WIN') === 0
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- trigger_error($this->lang('buggy_php'), E_USER_WARNING);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ trigger_error(self::lang('buggy_php'), E_USER_WARNING);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1631,7 +1682,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> call_user_func_array([$this, 'addAnAddress'], $params);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (count($this->to) + count($this->cc) + count($this->bcc) < 1) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('provide_address'), self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('provide_address'), self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Validate From, Sender, and ConfirmReadingTo addresses
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1648,7 +1699,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!static::validateAddress($this->{$address_kind})) {
</span><span class="cx" style="display: block; padding: 0 10px"> $error_message = sprintf(
</span><span class="cx" style="display: block; padding: 0 10px"> '%s (%s): %s',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->lang('invalid_address'),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ self::lang('invalid_address'),
</ins><span class="cx" style="display: block; padding: 0 10px"> $address_kind,
</span><span class="cx" style="display: block; padding: 0 10px"> $this->{$address_kind}
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1670,7 +1721,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->setMessageType();
</span><span class="cx" style="display: block; padding: 0 10px"> //Refuse to send an empty message unless we are specifically allowing it
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->AllowEmpty && empty($this->Body)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('empty_message'), self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Trim subject consistently
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1809,8 +1860,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $sendmailFmt = '%s -oi -f%s -t';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } elseif ($this->Mailer === 'qmail') {
+ $sendmailFmt = '%s';
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- //allow sendmail to choose a default envelope sender. It may
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Allow sendmail to choose a default envelope sender. It may
</ins><span class="cx" style="display: block; padding: 0 10px"> //seem preferable to force it to use the From header as with
</span><span class="cx" style="display: block; padding: 0 10px"> //SMTP, but that introduces new problems (see
</span><span class="cx" style="display: block; padding: 0 10px"> //<https://github.com/PHPMailer/PHPMailer/issues/2298>), and
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1828,7 +1881,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->SingleToArray as $toAddr) {
</span><span class="cx" style="display: block; padding: 0 10px"> $mail = @popen($sendmail, 'w');
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$mail) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug("To: {$toAddr}");
</span><span class="cx" style="display: block; padding: 0 10px"> fwrite($mail, 'To: ' . $toAddr . "\n");
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1835,26 +1888,28 @@
</span><span class="cx" style="display: block; padding: 0 10px"> fwrite($mail, $header);
</span><span class="cx" style="display: block; padding: 0 10px"> fwrite($mail, $body);
</span><span class="cx" style="display: block; padding: 0 10px"> $result = pclose($mail);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $addrinfo = static::parseAddresses($toAddr, true, $this->CharSet);
- $this->doCallback(
- ($result === 0),
- [[$addrinfo['address'], $addrinfo['name']]],
- $this->cc,
- $this->bcc,
- $this->Subject,
- $body,
- $this->From,
- []
- );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $addrinfo = static::parseAddresses($toAddr, null, $this->CharSet);
+ foreach ($addrinfo as $addr) {
+ $this->doCallback(
+ ($result === 0),
+ [[$addr['address'], $addr['name']]],
+ $this->cc,
+ $this->bcc,
+ $this->Subject,
+ $body,
+ $this->From,
+ []
+ );
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->edebug("Result: " . ($result === 0 ? 'true' : 'false'));
</span><span class="cx" style="display: block; padding: 0 10px"> if (0 !== $result) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $mail = @popen($sendmail, 'w');
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$mail) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> fwrite($mail, $header);
</span><span class="cx" style="display: block; padding: 0 10px"> fwrite($mail, $body);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1871,7 +1926,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug("Result: " . ($result === 0 ? 'true' : 'false'));
</span><span class="cx" style="display: block; padding: 0 10px"> if (0 !== $result) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2010,17 +2065,19 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->SingleTo && count($toArr) > 1) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($toArr as $toAddr) {
</span><span class="cx" style="display: block; padding: 0 10px"> $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $addrinfo = static::parseAddresses($toAddr, true, $this->CharSet);
- $this->doCallback(
- $result,
- [[$addrinfo['address'], $addrinfo['name']]],
- $this->cc,
- $this->bcc,
- $this->Subject,
- $body,
- $this->From,
- []
- );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $addrinfo = static::parseAddresses($toAddr, null, $this->CharSet);
+ foreach ($addrinfo as $addr) {
+ $this->doCallback(
+ $result,
+ [[$addr['address'], $addr['name']]],
+ $this->cc,
+ $this->bcc,
+ $this->Subject,
+ $body,
+ $this->From,
+ []
+ );
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2030,7 +2087,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> ini_set('sendmail_from', $old_from);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$result) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('instantiate'), self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('instantiate'), self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2116,12 +2173,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $header = static::stripTrailingWSP($header) . static::$LE . static::$LE;
</span><span class="cx" style="display: block; padding: 0 10px"> $bad_rcpt = [];
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->smtpConnect($this->SMTPOptions)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('smtp_connect_failed'), self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> //If we have recipient addresses that need Unicode support,
</span><span class="cx" style="display: block; padding: 0 10px"> //but the server doesn't support it, stop here
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->UseSMTPUTF8 && !$this->smtp->getServerExt('SMTPUTF8')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('no_smtputf8'), self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('no_smtputf8'), self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> //Sender already validated in preSend()
</span><span class="cx" style="display: block; padding: 0 10px"> if ('' === $this->Sender) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2133,7 +2190,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->smtp->xclient($this->SMTPXClient);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->smtp->mail($smtp_from)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->setError(self::lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
</ins><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->ErrorInfo, self::STOP_CRITICAL);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2155,7 +2212,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Only send the DATA command if we have viable recipients
</span><span class="cx" style="display: block; padding: 0 10px"> if ((count($this->all_recipients) > count($bad_rcpt)) && !$this->smtp->data($header . $body)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('data_not_accepted'), self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('data_not_accepted'), self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $smtp_transaction_id = $this->smtp->getLastTransactionID();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2186,7 +2243,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($bad_rcpt as $bad) {
</span><span class="cx" style="display: block; padding: 0 10px"> $errstr .= $bad['to'] . ': ' . $bad['error'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('recipients_failed') . $errstr, self::STOP_CONTINUE);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('recipients_failed') . $errstr, self::STOP_CONTINUE);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2240,7 +2297,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $hostinfo
</span><span class="cx" style="display: block; padding: 0 10px"> )
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->edebug($this->lang('invalid_hostentry') . ' ' . trim($hostentry));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->edebug(self::lang('invalid_hostentry') . ' ' . trim($hostentry));
</ins><span class="cx" style="display: block; padding: 0 10px"> //Not a valid host entry
</span><span class="cx" style="display: block; padding: 0 10px"> continue;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2252,7 +2309,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Check the host name is a valid name or IP address before trying to use it
</span><span class="cx" style="display: block; padding: 0 10px"> if (!static::isValidHost($hostinfo[2])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->edebug($this->lang('invalid_host') . ' ' . $hostinfo[2]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->edebug(self::lang('invalid_host') . ' ' . $hostinfo[2]);
</ins><span class="cx" style="display: block; padding: 0 10px"> continue;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $prefix = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2272,7 +2329,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (static::ENCRYPTION_STARTTLS === $secure || static::ENCRYPTION_SMTPS === $secure) {
</span><span class="cx" style="display: block; padding: 0 10px"> //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$sslext) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('extension_missing') . 'openssl', self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('extension_missing') . 'openssl', self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $host = $hostinfo[2];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2324,7 +2381,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->oauth
</span><span class="cx" style="display: block; padding: 0 10px"> )
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('authenticate'));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('authenticate'));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2374,7 +2431,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @return bool Returns true if the requested language was loaded, false otherwise.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function setLanguage($langcode = 'en', $lang_path = '')
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function setLanguage($langcode = 'en', $lang_path = '')
</ins><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> //Backwards compatibility for renamed language codes
</span><span class="cx" style="display: block; padding: 0 10px"> $renamed_langcodes = [
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2423,6 +2480,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 'smtp_error' => 'SMTP server error: ',
</span><span class="cx" style="display: block; padding: 0 10px"> 'variable_set' => 'Cannot set or reset variable: ',
</span><span class="cx" style="display: block; padding: 0 10px"> 'no_smtputf8' => 'Server does not support SMTPUTF8 needed to send to Unicode addresses',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'imap_recommended' => 'Using simplified address parser is not recommended. ' .
+ 'Install the PHP IMAP extension for full RFC822 parsing.',
+ 'deprecated_argument' => 'Argument $deprecatedArg is deprecated',
</ins><span class="cx" style="display: block; padding: 0 10px"> ];
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($lang_path)) {
</span><span class="cx" style="display: block; padding: 0 10px"> //Calculate an absolute path so it can work if CWD is not here
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2489,7 +2549,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->language = $PHPMAILER_LANG;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ self::$language = $PHPMAILER_LANG;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return $foundlang; //Returns false if language not found
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2501,11 +2561,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function getTranslations()
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (empty($this->language)) {
- $this->setLanguage(); // Set the default language.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (empty(self::$language)) {
+ self::setLanguage(); // Set the default language.
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->language;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return self::$language;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2928,10 +2988,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> //Create unique IDs and preset boundaries
</span><span class="cx" style="display: block; padding: 0 10px"> $this->setBoundaries();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($this->sign_key_file) {
- $body .= $this->getMailMIME() . static::$LE;
- }
-
</del><span class="cx" style="display: block; padding: 0 10px"> $this->setWordWrap();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $bodyEncoding = $this->Encoding;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2963,6 +3019,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (static::ENCODING_BASE64 !== $altBodyEncoding && static::hasLineLongerThanMax($this->AltBody)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ if ($this->sign_key_file) {
+ $this->Encoding = $bodyEncoding;
+ $body .= $this->getMailMIME() . static::$LE;
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> //Use this as a preamble in all multipart message types
</span><span class="cx" style="display: block; padding: 0 10px"> $mimepre = '';
</span><span class="cx" style="display: block; padding: 0 10px"> switch ($this->message_type) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3144,12 +3206,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->isError()) {
</span><span class="cx" style="display: block; padding: 0 10px"> $body = '';
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->exceptions) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('empty_message'), self::STOP_CRITICAL);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ($this->sign_key_file) {
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!defined('PKCS7_TEXT')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('extension_missing') . 'openssl');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('extension_missing') . 'openssl');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $file = tempnam(sys_get_temp_dir(), 'srcsign');
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3187,7 +3249,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $body = $parts[1];
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> @unlink($signed);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('signing') . openssl_error_string());
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('signing') . openssl_error_string());
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } catch (Exception $exc) {
</span><span class="cx" style="display: block; padding: 0 10px"> $body = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3332,7 +3394,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!static::fileIsAccessible($path)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('file_access') . $path, self::STOP_CONTINUE);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //If a MIME type is not specified, try to work it out from the file name
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3345,7 +3407,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $name = $filename;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->validateEncoding($encoding)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('encoding') . $encoding);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('encoding') . $encoding);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $this->attachment[] = [
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3506,11 +3568,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!static::fileIsAccessible($path)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('file_open') . $path, self::STOP_CONTINUE);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $file_buffer = file_get_contents($path);
</span><span class="cx" style="display: block; padding: 0 10px"> if (false === $file_buffer) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('file_open') . $path, self::STOP_CONTINUE);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $file_buffer = $this->encodeString($file_buffer, $encoding);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3563,9 +3625,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $encoded = $this->encodeQP($str);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->setError($this->lang('encoding') . $encoding);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->setError(self::lang('encoding') . $encoding);
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->exceptions) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('encoding') . $encoding);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('encoding') . $encoding);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3672,6 +3734,42 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Decode an RFC2047-encoded header value
+ * Attempts multiple strategies so it works even when the mbstring extension is disabled.
+ *
+ * @param string $value The header value to decode
+ * @param string $charset The target charset to convert to, defaults to ISO-8859-1 for BC
+ *
+ * @return string The decoded header value
+ */
+ public static function decodeHeader($value, $charset = self::CHARSET_ISO88591)
+ {
+ if (!is_string($value) || $value === '') {
+ return '';
+ }
+ // Detect the presence of any RFC2047 encoded-words
+ $hasEncodedWord = (bool) preg_match('/=\?.*\?=/s', $value);
+ if ($hasEncodedWord && defined('MB_CASE_UPPER')) {
+ $origCharset = mb_internal_encoding();
+ // Always decode to UTF-8 to provide a consistent, modern output encoding.
+ mb_internal_encoding($charset);
+ if (PHP_VERSION_ID < 80300) {
+ // Undo any RFC2047-encoded spaces-as-underscores.
+ $value = str_replace('_', '=20', $value);
+ } else {
+ // PHP 8.3+ already interprets underscores as spaces. Remove additional
+ // linear whitespace between adjacent encoded words to avoid double spacing.
+ $value = preg_replace('/(\?=)\s+(=\?)/', '$1$2', $value);
+ }
+ // Decode the header value
+ $value = mb_decode_mimeheader($value);
+ mb_internal_encoding($origCharset);
+ }
+
+ return $value;
+ }
+
+ /**
</ins><span class="cx" style="display: block; padding: 0 10px"> * Check if a string contains multi-byte characters.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $str multi-byte text to wrap encode
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3840,7 +3938,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->validateEncoding($encoding)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('encoding') . $encoding);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('encoding') . $encoding);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Append to $attachment array
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3899,7 +3997,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!static::fileIsAccessible($path)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('file_access') . $path, self::STOP_CONTINUE);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //If a MIME type is not specified, try to work it out from the file name
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3908,7 +4006,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->validateEncoding($encoding)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('encoding') . $encoding);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('encoding') . $encoding);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $filename = (string) static::mb_pathinfo($path, PATHINFO_BASENAME);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3974,7 +4072,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->validateEncoding($encoding)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('encoding') . $encoding);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('encoding') . $encoding);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Append to $attachment array
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4231,7 +4329,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (strpbrk($name . $value, "\r\n") !== false) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->exceptions) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('invalid_header'));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('invalid_header'));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4255,15 +4353,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ('smtp' === $this->Mailer && null !== $this->smtp) {
</span><span class="cx" style="display: block; padding: 0 10px"> $lasterror = $this->smtp->getError();
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($lasterror['error'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $msg .= ' ' . $this->lang('smtp_error') . $lasterror['error'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $msg .= ' ' . self::lang('smtp_error') . $lasterror['error'];
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!empty($lasterror['detail'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $msg .= ' ' . self::lang('smtp_detail') . $lasterror['detail'];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($lasterror['smtp_code'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $msg .= ' ' . $this->lang('smtp_code') . $lasterror['smtp_code'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $msg .= ' ' . self::lang('smtp_code') . $lasterror['smtp_code'];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($lasterror['smtp_code_ex'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $msg .= ' ' . $this->lang('smtp_code_ex') . $lasterror['smtp_code_ex'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $msg .= ' ' . self::lang('smtp_code_ex') . $lasterror['smtp_code_ex'];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4388,21 +4486,21 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @return string
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- protected function lang($key)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ protected static function lang($key)
</ins><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (count($this->language) < 1) {
- $this->setLanguage(); //Set the default language
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (count(self::$language) < 1) {
+ self::setLanguage(); //Set the default language
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (array_key_exists($key, $this->language)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (array_key_exists($key, self::$language)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('smtp_connect_failed' === $key) {
</span><span class="cx" style="display: block; padding: 0 10px"> //Include a link to troubleshooting docs on SMTP connection failure.
</span><span class="cx" style="display: block; padding: 0 10px"> //This is by far the biggest cause of support questions
</span><span class="cx" style="display: block; padding: 0 10px"> //but it's usually not PHPMailer's fault.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return self::$language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->language[$key];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return self::$language[$key];
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Return the key as a fallback
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4417,7 +4515,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> private function getSmtpErrorMessage($base_key)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $message = $this->lang($base_key);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $message = self::lang($base_key);
</ins><span class="cx" style="display: block; padding: 0 10px"> $error = $this->smtp->getError();
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($error['error'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $message .= ' ' . $error['error'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4461,7 +4559,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> //Ensure name is not empty, and that neither name nor value contain line breaks
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($name) || strpbrk($name . $value, "\r\n") !== false) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->exceptions) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('invalid_header'));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('invalid_header'));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4854,7 +4952,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->setError($this->lang('variable_set') . $name);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->setError(self::lang('variable_set') . $name);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4992,7 +5090,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!defined('PKCS7_TEXT')) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->exceptions) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception($this->lang('extension_missing') . 'openssl');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception(self::lang('extension_missing') . 'openssl');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return '';
</span></span></pre></div>
<a id="trunksrcwpincludesPHPMailerPOP3php"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/PHPMailer/POP3.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/PHPMailer/POP3.php 2025-09-29 19:11:01 UTC (rev 60812)
+++ trunk/src/wp-includes/PHPMailer/POP3.php 2025-09-30 12:46:53 UTC (rev 60813)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -46,7 +46,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var string
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- const VERSION = '6.10.0';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const VERSION = '6.11.0';
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * Default POP3 port number.
</span></span></pre></div>
<a id="trunksrcwpincludesPHPMailerSMTPphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/PHPMailer/SMTP.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/PHPMailer/SMTP.php 2025-09-29 19:11:01 UTC (rev 60812)
+++ trunk/src/wp-includes/PHPMailer/SMTP.php 2025-09-30 12:46:53 UTC (rev 60813)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -35,7 +35,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @var string
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- const VERSION = '6.10.0';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const VERSION = '6.11.0';
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px"> * SMTP line break constant.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -205,6 +205,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
</span><span class="cx" style="display: block; padding: 0 10px"> 'ZoneMTA' => '/[\d]{3} Message queued as (.*)/',
</span><span class="cx" style="display: block; padding: 0 10px"> 'Mailjet' => '/[\d]{3} OK queued as (.*)/',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'Gsmtp' => '/[\d]{3} 2\.0\.0 OK (.*) - gsmtp/',
</ins><span class="cx" style="display: block; padding: 0 10px"> ];
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -633,10 +634,41 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $oauth = $OAuth->getOauth64();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- //Start authentication
- if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
- return false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /*
+ * An SMTP command line can have a maximum length of 512 bytes, including the command name,
+ * so the base64-encoded OAUTH token has a maximum length of:
+ * 512 - 13 (AUTH XOAUTH2) - 2 (CRLF) = 497 bytes
+ * If the token is longer than that, the command and the token must be sent separately as described in
+ * https://www.rfc-editor.org/rfc/rfc4954#section-4
+ */
+ if ($oauth === '') {
+ //Sending an empty auth token is legitimate, but it must be encoded as '='
+ //to indicate it's not a 2-part command
+ if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 =', 235)) {
+ return false;
+ }
+ } elseif (strlen($oauth) <= 497) {
+ //Authenticate using a token in the initial-response part
+ if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
+ return false;
+ }
+ } else {
+ //The token is too long, so we need to send it in two parts.
+ //Send the auth command without a token and expect a 334
+ if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2', 334)) {
+ return false;
+ }
+ //Send the token
+ if (!$this->sendCommand('OAuth TOKEN', $oauth, [235, 334])) {
+ return false;
+ }
+ //If the server answers with 334, send an empty line and wait for a 235
+ if (
+ substr($this->last_reply, 0, 3) === '334'
+ && $this->sendCommand('AUTH End', '', 235)
+ ) {
+ return false;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1309,7 +1341,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //stream_select returns false when the `select` system call is interrupted
</span><span class="cx" style="display: block; padding: 0 10px"> //by an incoming signal, try the select again
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (stripos($message, 'interrupted system call') !== false) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (
+ stripos($message, 'interrupted system call') !== false ||
+ (
+ // on applications with a different locale than english, the message above is not found because
+ // it's translated. So we also check for the SOCKET_EINTR constant which is defined under
+ // Windows and UNIX-like platforms (if available on the platform).
+ defined('SOCKET_EINTR') &&
+ stripos($message, 'stream_select(): Unable to select [' . SOCKET_EINTR . ']') !== false
+ )
+ ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->edebug(
</span><span class="cx" style="display: block; padding: 0 10px"> 'SMTP -> get_lines(): retrying stream_select',
</span><span class="cx" style="display: block; padding: 0 10px"> self::DEBUG_LOWLEVEL
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpphpmailerphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-phpmailer.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-phpmailer.php 2025-09-29 19:11:01 UTC (rev 60812)
+++ trunk/src/wp-includes/class-wp-phpmailer.php 2025-09-30 12:46:53 UTC (rev 60813)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -24,7 +24,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function __construct( $exceptions = false ) {
</span><span class="cx" style="display: block; padding: 0 10px"> parent::__construct( $exceptions );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->setLanguage();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ static::setLanguage();
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -36,8 +36,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $lang_path Optional. Unused. Path to the language file directory. Default empty string.
</span><span class="cx" style="display: block; padding: 0 10px"> * @return true Always returns true.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function setLanguage( $langcode = 'en', $lang_path = '' ) {
- $this->language = array(
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function setLanguage( $langcode = 'en', $lang_path = '' ) {
+ static::$language = array(
</ins><span class="cx" style="display: block; padding: 0 10px"> 'authenticate' => __( 'SMTP Error: Could not authenticate.' ),
</span><span class="cx" style="display: block; padding: 0 10px"> 'buggy_php' => sprintf(
</span><span class="cx" style="display: block; padding: 0 10px"> /* translators: 1: mail.add_x_header. 2: php.ini */
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -89,6 +89,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /* translators: There is a space after the colon. */
</span><span class="cx" style="display: block; padding: 0 10px"> 'variable_set' => __( 'Cannot set or reset variable: ' ),
</span><span class="cx" style="display: block; padding: 0 10px"> 'no_smtputf8' => __( 'Server does not support SMTPUTF8 needed to send to Unicode addresses' ),
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'imap_recommended' => __( 'Using simplified address parser is not recommended. Install the PHP IMAP extension for full RFC822 parsing.' ),
+ 'deprecated_argument' => sprintf(
+ /* translators: %s: $deprecatedArg */
+ __( 'Argument %s is deprecated' ),
+ '$deprecatedArg'
+ ),
</ins><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span></span></pre>
</div>
</div>
</body>
</html>