<!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>[60623] trunk/src/wp-includes: External Libraries: Upgrade PHPMailer to version 6.10.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/60623">60623</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/60623","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-08-11 16:16:19 +0000 (Mon, 11 Aug 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.10.0.

This is a feature and maintenance release introducing full support for [https://www.rfc-editor.org/rfc/rfc6531 RFC 6531 SMTPUTF8], meaning that plugin or theme developers are now free to use Unicode characters in email addresses, such as `J{U+00F8}eUser@example.com`, without any complicated encoding schemes. Using this feature requires sending through a mail server that advertises support for SMTPUTF8. For full details see [https://github.com/PHPMailer/PHPMailer/blob/master/SMTPUTF8.md SMTPUTF8.md].

This commit also includes the parts of PHPMailer not previously bundled with core, specifically the DSNConfigurator, OAuth, and POP3 classes, so that plugin developers could use those extended features without including their own versions of the library.

Including the full library aims to make it easier (and faster) for core to update in case of security issues, and to provide more flexibility and security for plugins and (by extension) users of WordPress.

References:
* [https://github.com/PHPMailer/PHPMailer/releases/tag/v6.10.0 PHPMailer 6.10.0 release notes]
* [https://github.com/PHPMailer/PHPMailer/compare/v6.9.3...v6.10.0 Full list of changes in PHPMailer 6.10.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>.

Props agulbra, Ipstenu, JeffMatson, lukecavanagh, dd32, Otto42, JeffMatson, MattyRob, desrosj, SirLouen, SergeyBiryukov.
Fixes <a href="https://core.trac.wordpress.org/ticket/39714">#39714</a>, <a href="https://core.trac.wordpress.org/ticket/63811">#63811</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesPHPMailerPHPMailerphp">trunk/src/wp-includes/PHPMailer/PHPMailer.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>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesPHPMailerDSNConfiguratorphp">trunk/src/wp-includes/PHPMailer/DSNConfigurator.php</a></li>
<li><a href="#trunksrcwpincludesPHPMailerOAuthphp">trunk/src/wp-includes/PHPMailer/OAuth.php</a></li>
<li><a href="#trunksrcwpincludesPHPMailerOAuthTokenProviderphp">trunk/src/wp-includes/PHPMailer/OAuthTokenProvider.php</a></li>
<li><a href="#trunksrcwpincludesPHPMailerPOP3php">trunk/src/wp-includes/PHPMailer/POP3.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesPHPMailerDSNConfiguratorphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/PHPMailer/DSNConfigurator.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/PHPMailer/DSNConfigurator.php                               (rev 0)
+++ trunk/src/wp-includes/PHPMailer/DSNConfigurator.php 2025-08-11 16:16:19 UTC (rev 60623)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,245 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * PHPMailer - PHP email creation and transport class.
+ * PHP Version 5.5.
+ *
+ * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
+ *
+ * @author    Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author    Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ * @author    Brent R. Matzelle (original founder)
+ * @copyright 2012 - 2023 Marcus Bointon
+ * @copyright 2010 - 2012 Jim Jagielski
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license   https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
+ * @note      This program is distributed in the hope that it will be useful - WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+namespace PHPMailer\PHPMailer;
+
+/**
+ * Configure PHPMailer with DSN string.
+ *
+ * @see https://en.wikipedia.org/wiki/Data_source_name
+ *
+ * @author Oleg Voronkovich <oleg-voronkovich@yandex.ru>
+ */
+class DSNConfigurator
+{
+    /**
+     * Create new PHPMailer instance configured by DSN.
+     *
+     * @param string $dsn        DSN
+     * @param bool   $exceptions Should we throw external exceptions?
+     *
+     * @return PHPMailer
+     */
+    public static function mailer($dsn, $exceptions = null)
+    {
+        static $configurator = null;
+
+        if (null === $configurator) {
+            $configurator = new DSNConfigurator();
+        }
+
+        return $configurator->configure(new PHPMailer($exceptions), $dsn);
+    }
+
+    /**
+     * Configure PHPMailer instance with DSN string.
+     *
+     * @param PHPMailer $mailer PHPMailer instance
+     * @param string    $dsn    DSN
+     *
+     * @return PHPMailer
+     */
+    public function configure(PHPMailer $mailer, $dsn)
+    {
+        $config = $this->parseDSN($dsn);
+
+        $this->applyConfig($mailer, $config);
+
+        return $mailer;
+    }
+
+    /**
+     * Parse DSN string.
+     *
+     * @param string $dsn DSN
+     *
+     * @throws Exception If DSN is malformed
+     *
+     * @return array Configuration
+     */
+    private function parseDSN($dsn)
+    {
+        $config = $this->parseUrl($dsn);
+
+        if (false === $config || !isset($config['scheme']) || !isset($config['host'])) {
+            throw new Exception('Malformed DSN');
+        }
+
+        if (isset($config['query'])) {
+            parse_str($config['query'], $config['query']);
+        }
+
+        return $config;
+    }
+
+    /**
+     * Apply configuration to mailer.
+     *
+     * @param PHPMailer $mailer PHPMailer instance
+     * @param array     $config Configuration
+     *
+     * @throws Exception If scheme is invalid
+     */
+    private function applyConfig(PHPMailer $mailer, $config)
+    {
+        switch ($config['scheme']) {
+            case 'mail':
+                $mailer->isMail();
+                break;
+            case 'sendmail':
+                $mailer->isSendmail();
+                break;
+            case 'qmail':
+                $mailer->isQmail();
+                break;
+            case 'smtp':
+            case 'smtps':
+                $mailer->isSMTP();
+                $this->configureSMTP($mailer, $config);
+                break;
+            default:
+                throw new Exception(
+                    sprintf(
+                        'Invalid scheme: "%s". Allowed values: "mail", "sendmail", "qmail", "smtp", "smtps".',
+                        $config['scheme']
+                    )
+                );
+        }
+
+        if (isset($config['query'])) {
+            $this->configureOptions($mailer, $config['query']);
+        }
+    }
+
+    /**
+     * Configure SMTP.
+     *
+     * @param PHPMailer $mailer PHPMailer instance
+     * @param array     $config Configuration
+     */
+    private function configureSMTP($mailer, $config)
+    {
+        $isSMTPS = 'smtps' === $config['scheme'];
+
+        if ($isSMTPS) {
+            $mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
+        }
+
+        $mailer->Host = $config['host'];
+
+        if (isset($config['port'])) {
+            $mailer->Port = $config['port'];
+        } elseif ($isSMTPS) {
+            $mailer->Port = SMTP::DEFAULT_SECURE_PORT;
+        }
+
+        $mailer->SMTPAuth = isset($config['user']) || isset($config['pass']);
+
+        if (isset($config['user'])) {
+            $mailer->Username = $config['user'];
+        }
+
+        if (isset($config['pass'])) {
+            $mailer->Password = $config['pass'];
+        }
+    }
+
+    /**
+     * Configure options.
+     *
+     * @param PHPMailer $mailer  PHPMailer instance
+     * @param array     $options Options
+     *
+     * @throws Exception If option is unknown
+     */
+    private function configureOptions(PHPMailer $mailer, $options)
+    {
+        $allowedOptions = get_object_vars($mailer);
+
+        unset($allowedOptions['Mailer']);
+        unset($allowedOptions['SMTPAuth']);
+        unset($allowedOptions['Username']);
+        unset($allowedOptions['Password']);
+        unset($allowedOptions['Hostname']);
+        unset($allowedOptions['Port']);
+        unset($allowedOptions['ErrorInfo']);
+
+        $allowedOptions = \array_keys($allowedOptions);
+
+        foreach ($options as $key => $value) {
+            if (!in_array($key, $allowedOptions)) {
+                throw new Exception(
+                    sprintf(
+                        'Unknown option: "%s". Allowed values: "%s"',
+                        $key,
+                        implode('", "', $allowedOptions)
+                    )
+                );
+            }
+
+            switch ($key) {
+                case 'AllowEmpty':
+                case 'SMTPAutoTLS':
+                case 'SMTPKeepAlive':
+                case 'SingleTo':
+                case 'UseSendmailOptions':
+                case 'do_verp':
+                case 'DKIM_copyHeaderFields':
+                    $mailer->$key = (bool) $value;
+                    break;
+                case 'Priority':
+                case 'SMTPDebug':
+                case 'WordWrap':
+                    $mailer->$key = (int) $value;
+                    break;
+                default:
+                    $mailer->$key = $value;
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Parse a URL.
+     * Wrapper for the built-in parse_url function to work around a bug in PHP 5.5.
+     *
+     * @param string $url URL
+     *
+     * @return array|false
+     */
+    protected function parseUrl($url)
+    {
+        if (\PHP_VERSION_ID >= 50600 || false === strpos($url, '?')) {
+            return parse_url($url);
+        }
+
+        $chunks = explode('?', $url);
+        if (is_array($chunks)) {
+            $result = parse_url($chunks[0]);
+            if (is_array($result)) {
+                $result['query'] = $chunks[1];
+            }
+            return $result;
+        }
+
+        return false;
+    }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/PHPMailer/DSNConfigurator.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludesPHPMailerOAuthphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/PHPMailer/OAuth.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/PHPMailer/OAuth.php                         (rev 0)
+++ trunk/src/wp-includes/PHPMailer/OAuth.php   2025-08-11 16:16:19 UTC (rev 60623)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,139 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * PHPMailer - PHP email creation and transport class.
+ * PHP Version 5.5.
+ *
+ * @see       https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
+ *
+ * @author    Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author    Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ * @author    Brent R. Matzelle (original founder)
+ * @copyright 2012 - 2020 Marcus Bointon
+ * @copyright 2010 - 2012 Jim Jagielski
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license   https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
+ * @note      This program is distributed in the hope that it will be useful - WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+namespace PHPMailer\PHPMailer;
+
+use League\OAuth2\Client\Grant\RefreshToken;
+use League\OAuth2\Client\Provider\AbstractProvider;
+use League\OAuth2\Client\Token\AccessToken;
+
+/**
+ * OAuth - OAuth2 authentication wrapper class.
+ * Uses the oauth2-client package from the League of Extraordinary Packages.
+ *
+ * @see     https://oauth2-client.thephpleague.com
+ *
+ * @author  Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ */
+class OAuth implements OAuthTokenProvider
+{
+    /**
+     * An instance of the League OAuth Client Provider.
+     *
+     * @var AbstractProvider
+     */
+    protected $provider;
+
+    /**
+     * The current OAuth access token.
+     *
+     * @var AccessToken
+     */
+    protected $oauthToken;
+
+    /**
+     * The user's email address, usually used as the login ID
+     * and also the from address when sending email.
+     *
+     * @var string
+     */
+    protected $oauthUserEmail = '';
+
+    /**
+     * The client secret, generated in the app definition of the service you're connecting to.
+     *
+     * @var string
+     */
+    protected $oauthClientSecret = '';
+
+    /**
+     * The client ID, generated in the app definition of the service you're connecting to.
+     *
+     * @var string
+     */
+    protected $oauthClientId = '';
+
+    /**
+     * The refresh token, used to obtain new AccessTokens.
+     *
+     * @var string
+     */
+    protected $oauthRefreshToken = '';
+
+    /**
+     * OAuth constructor.
+     *
+     * @param array $options Associative array containing
+     *                       `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements
+     */
+    public function __construct($options)
+    {
+        $this->provider = $options['provider'];
+        $this->oauthUserEmail = $options['userName'];
+        $this->oauthClientSecret = $options['clientSecret'];
+        $this->oauthClientId = $options['clientId'];
+        $this->oauthRefreshToken = $options['refreshToken'];
+    }
+
+    /**
+     * Get a new RefreshToken.
+     *
+     * @return RefreshToken
+     */
+    protected function getGrant()
+    {
+        return new RefreshToken();
+    }
+
+    /**
+     * Get a new AccessToken.
+     *
+     * @return AccessToken
+     */
+    protected function getToken()
+    {
+        return $this->provider->getAccessToken(
+            $this->getGrant(),
+            ['refresh_token' => $this->oauthRefreshToken]
+        );
+    }
+
+    /**
+     * Generate a base64-encoded OAuth token.
+     *
+     * @return string
+     */
+    public function getOauth64()
+    {
+        //Get a new token if it's not available or has expired
+        if (null === $this->oauthToken || $this->oauthToken->hasExpired()) {
+            $this->oauthToken = $this->getToken();
+        }
+
+        return base64_encode(
+            'user=' .
+            $this->oauthUserEmail .
+            "\001auth=Bearer " .
+            $this->oauthToken .
+            "\001\001"
+        );
+    }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/PHPMailer/OAuth.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludesPHPMailerOAuthTokenProviderphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/PHPMailer/OAuthTokenProvider.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/PHPMailer/OAuthTokenProvider.php                            (rev 0)
+++ trunk/src/wp-includes/PHPMailer/OAuthTokenProvider.php      2025-08-11 16:16:19 UTC (rev 60623)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,44 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * PHPMailer - PHP email creation and transport class.
+ * PHP Version 5.5.
+ *
+ * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
+ *
+ * @author    Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author    Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ * @author    Brent R. Matzelle (original founder)
+ * @copyright 2012 - 2020 Marcus Bointon
+ * @copyright 2010 - 2012 Jim Jagielski
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license   https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
+ * @note      This program is distributed in the hope that it will be useful - WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+namespace PHPMailer\PHPMailer;
+
+/**
+ * OAuthTokenProvider - OAuth2 token provider interface.
+ * Provides base64 encoded OAuth2 auth strings for SMTP authentication.
+ *
+ * @see     OAuth
+ * @see     SMTP::authenticate()
+ *
+ * @author  Peter Scopes (pdscopes)
+ * @author  Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ */
+interface OAuthTokenProvider
+{
+    /**
+     * Generate a base64-encoded OAuth token ensuring that the access token has not expired.
+     * The string to be base 64 encoded should be in the form:
+     * "user=<user_email_address>\001auth=Bearer <access_token>\001\001"
+     *
+     * @return string
+     */
+    public function getOauth64();
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/PHPMailer/OAuthTokenProvider.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><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-08-10 20:58:31 UTC (rev 60622)
+++ trunk/src/wp-includes/PHPMailer/PHPMailer.php       2025-08-11 16:16:19 UTC (rev 60623)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -580,6 +580,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">      * May be a callable to inject your own validator, but there are several built-in validators.
</span><span class="cx" style="display: block; padding: 0 10px">      * The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option.
</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 CharSet is UTF8, the validator is left at the default value,
+     * and you send to addresses that use non-ASCII local parts, then
+     * PHPMailer automatically changes to the 'eai' validator.
+     *
</ins><span class="cx" style="display: block; padding: 0 10px">      * @see PHPMailer::validateAddress()
</span><span class="cx" style="display: block; padding: 0 10px">      *
</span><span class="cx" style="display: block; padding: 0 10px">      * @var string|callable
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -660,6 +664,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">     protected $ReplyToQueue = [];
</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">+     * Whether the need for SMTPUTF8 has been detected. Set by
+     * preSend() if necessary.
+     *
+     * @var bool
+     */
+    public $UseSMTPUTF8 = false;
+
+    /**
</ins><span class="cx" style="display: block; padding: 0 10px">      * The array of attachments.
</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="lines" style="display: block; padding: 0 10px; color: #888">@@ -756,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.9.3';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    const VERSION = '6.10.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">@@ -1110,19 +1122,22 @@
</span><span class="cx" style="display: block; padding: 0 10px">         $params = [$kind, $address, $name];
</span><span class="cx" style="display: block; padding: 0 10px">         //Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
</span><span class="cx" style="display: block; padding: 0 10px">         //Domain is assumed to be whatever is after the last @ symbol in the address
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) {
-            if ('Reply-To' !== $kind) {
-                if (!array_key_exists($address, $this->RecipientsQueue)) {
-                    $this->RecipientsQueue[$address] = $params;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        if ($this->has8bitChars(substr($address, ++$pos))) {
+            if (static::idnSupported()) {
+                if ('Reply-To' !== $kind) {
+                    if (!array_key_exists($address, $this->RecipientsQueue)) {
+                        $this->RecipientsQueue[$address] = $params;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        return true;
+                    }
+                } elseif (!array_key_exists($address, $this->ReplyToQueue)) {
+                    $this->ReplyToQueue[$address] = $params;
+
</ins><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($address, $this->ReplyToQueue)) {
-                $this->ReplyToQueue[$address] = $params;
-
-                return true;
</del><span class="cx" style="display: block; padding: 0 10px">             }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+            //We have an 8-bit domain, but we are missing the necessary extensions to support it
+            //Or we are already sending to this address
</ins><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">@@ -1160,6 +1175,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">      */
</span><span class="cx" style="display: block; padding: 0 10px">     protected function addAnAddress($kind, $address, $name = '')
</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 (
+            self::$validator === 'php' &&
+            ((bool) preg_match('/[\x80-\xFF]/', $address))
+        ) {
+            //The caller has not altered the validator and is sending to an address
+            //with UTF-8, so assume that they want UTF-8 support instead of failing
+            $this->CharSet = self::CHARSET_UTF8;
+            self::$validator = 'eai';
+        }
</ins><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><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1362,6 +1386,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">      * * `pcre` Use old PCRE implementation;
</span><span class="cx" style="display: block; padding: 0 10px">      * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
</span><span class="cx" style="display: block; padding: 0 10px">      * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+     * * `eai` Use a pattern similar to the HTML5 spec for 'email' and to firefox, extended to support EAI (RFC6530).
</ins><span class="cx" style="display: block; padding: 0 10px">      * * `noregex` Don't use a regex: super fast, really dumb.
</span><span class="cx" style="display: block; padding: 0 10px">      * Alternatively you may pass in a callable to inject your own validator, for example:
</span><span class="cx" style="display: block; padding: 0 10px">      *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1432,6 +1457,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">                     '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
</span><span class="cx" style="display: block; padding: 0 10px">                     $address
</span><span class="cx" style="display: block; padding: 0 10px">                 );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+            case 'eai':
+                /*
+                 * This is the pattern used in the HTML5 spec for validation of 'email' type
+                 * form input elements (as above), modified to accept Unicode email addresses.
+                 * This is also more lenient than Firefox' html5 spec, in order to make the regex faster.
+                 * 'eai' is an acronym for Email Address Internationalization.
+                 * This validator is selected automatically if you attempt to use recipient addresses
+                 * that contain Unicode characters in the local part.
+                 *
+                 * @see https://html.spec.whatwg.org/#e-mail-state-(type=email)
+                 * @see https://en.wikipedia.org/wiki/International_email
+                 */
+                return (bool) preg_match(
+                    '/^[-\p{L}\p{N}\p{M}.!#$%&\'*+\/=?^_`{|}~]+@[\p{L}\p{N}\p{M}](?:[\p{L}\p{N}\p{M}-]{0,61}' .
+                    '[\p{L}\p{N}\p{M}])?(?:\.[\p{L}\p{N}\p{M}]' .
+                    '(?:[-\p{L}\p{N}\p{M}]{0,61}[\p{L}\p{N}\p{M}])?)*$/usD',
+                    $address
+                );
</ins><span class="cx" style="display: block; padding: 0 10px">             case 'php':
</span><span class="cx" style="display: block; padding: 0 10px">             default:
</span><span class="cx" style="display: block; padding: 0 10px">                 return filter_var($address, FILTER_VALIDATE_EMAIL) !== false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1567,9 +1610,26 @@
</span><span class="cx" style="display: block; padding: 0 10px">             $this->error_count = 0; //Reset errors
</span><span class="cx" style="display: block; padding: 0 10px">             $this->mailHeader = '';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+            //The code below tries to support full use of Unicode,
+            //while remaining compatible with legacy SMTP servers to
+            //the greatest degree possible: If the message uses
+            //Unicode in the local parts of any addresses, it is sent
+            //using SMTPUTF8. If not, it it sent using
+            //punycode-encoded domains and plain SMTP.
+            if (
+                static::CHARSET_UTF8 === strtolower($this->CharSet) &&
+                ($this->anyAddressHasUnicodeLocalPart($this->RecipientsQueue) ||
+                 $this->anyAddressHasUnicodeLocalPart(array_keys($this->all_recipients)) ||
+                 $this->anyAddressHasUnicodeLocalPart($this->ReplyToQueue) ||
+                 $this->addressHasUnicodeLocalPart($this->From))
+            ) {
+                $this->UseSMTPUTF8 = true;
+            }
</ins><span class="cx" style="display: block; padding: 0 10px">             //Dequeue recipient and Reply-To addresses with IDN
</span><span class="cx" style="display: block; padding: 0 10px">             foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $params[1] = $this->punyencodeAddress($params[1]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                if (!$this->UseSMTPUTF8) {
+                    $params[1] = $this->punyencodeAddress($params[1]);
+                }
</ins><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><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2060,6 +2120,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">         if (!$this->smtpConnect($this->SMTPOptions)) {
</span><span class="cx" style="display: block; padding: 0 10px">             throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
</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 we have recipient addresses that need Unicode support,
+        //but the server doesn't support it, stop here
+        if ($this->UseSMTPUTF8 && !$this->smtp->getServerExt('SMTPUTF8')) {
+            throw new Exception($this->lang('no_smtputf8'), self::STOP_CRITICAL);
+        }
</ins><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="cx" style="display: block; padding: 0 10px">             $smtp_from = $this->From;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2161,6 +2226,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         $this->smtp->setDebugLevel($this->SMTPDebug);
</span><span class="cx" style="display: block; padding: 0 10px">         $this->smtp->setDebugOutput($this->Debugoutput);
</span><span class="cx" style="display: block; padding: 0 10px">         $this->smtp->setVerp($this->do_verp);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $this->smtp->setSMTPUTF8($this->UseSMTPUTF8);
</ins><span class="cx" style="display: block; padding: 0 10px">         if ($this->Host === null) {
</span><span class="cx" style="display: block; padding: 0 10px">             $this->Host = 'localhost';
</span><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2358,6 +2424,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">             'smtp_detail' => 'Detail: ',
</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><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+            'no_smtputf8' => 'Server does not support SMTPUTF8 needed to send to Unicode addresses',
</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">@@ -2872,7 +2939,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">         $bodyEncoding = $this->Encoding;
</span><span class="cx" style="display: block; padding: 0 10px">         $bodyCharSet = $this->CharSet;
</span><span class="cx" style="display: block; padding: 0 10px">         //Can we do a 7-bit downgrade?
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        if ($this->UseSMTPUTF8) {
+            $bodyEncoding = static::ENCODING_8BIT;
+        } elseif (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) {
</ins><span class="cx" style="display: block; padding: 0 10px">             $bodyEncoding = static::ENCODING_7BIT;
</span><span class="cx" style="display: block; padding: 0 10px">             //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
</span><span class="cx" style="display: block; padding: 0 10px">             $bodyCharSet = static::CHARSET_ASCII;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3509,7 +3578,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">     /**
</span><span class="cx" style="display: block; padding: 0 10px">      * Encode a header value (not including its label) optimally.
</span><span class="cx" style="display: block; padding: 0 10px">      * Picks shortest of Q, B, or none. Result includes folding if needed.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-     * See RFC822 definitions for phrase, comment and text positions.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+     * See RFC822 definitions for phrase, comment and text positions,
+     * and RFC2047 for inline encodings.
</ins><span class="cx" style="display: block; padding: 0 10px">      *
</span><span class="cx" style="display: block; padding: 0 10px">      * @param string $str      The header value to encode
</span><span class="cx" style="display: block; padding: 0 10px">      * @param string $position What context the string will be used in
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3518,6 +3588,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">      */
</span><span class="cx" style="display: block; padding: 0 10px">     public function encodeHeader($str, $position = 'text')
</span><span class="cx" style="display: block; padding: 0 10px">     {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $position = strtolower($position);
+        if ($this->UseSMTPUTF8 && !("comment" === $position)) {
+            return trim(static::normalizeBreaks($str));
+        }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $matchcount = 0;
</span><span class="cx" style="display: block; padding: 0 10px">         switch (strtolower($position)) {
</span><span class="cx" style="display: block; padding: 0 10px">             case 'phrase':
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4182,7 +4257,7 @@
</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 .= ' ' . $this->lang('smtp_error') . $lasterror['error'];
</ins><span class="cx" style="display: block; padding: 0 10px">                 if (!empty($lasterror['detail'])) {
</span><span class="cx" style="display: block; padding: 0 10px">                     $msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail'];
</span><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4270,6 +4345,45 @@
</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">+     * Check whether the supplied address uses Unicode in the local part.
+     *
+     * @return bool
+     */
+    protected function addressHasUnicodeLocalPart($address)
+    {
+        return (bool) preg_match('/[\x80-\xFF].*@/', $address);
+    }
+
+    /**
+     * Check whether any of the supplied addresses use Unicode in the local part.
+     *
+     * @return bool
+     */
+    protected function anyAddressHasUnicodeLocalPart($addresses)
+    {
+        foreach ($addresses as $address) {
+            if (is_array($address)) {
+                $address = $address[0];
+            }
+            if ($this->addressHasUnicodeLocalPart($address)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check whether the message requires SMTPUTF8 based on what's known so far.
+     *
+     * @return bool
+     */
+    public function needsSMTPUTF8()
+    {
+        return $this->UseSMTPUTF8;
+    }
+
+
+    /**
</ins><span class="cx" style="display: block; padding: 0 10px">      * Get an error message in the current language.
</span><span class="cx" style="display: block; padding: 0 10px">      *
</span><span class="cx" style="display: block; padding: 0 10px">      * @param string $key
</span></span></pre></div>
<a id="trunksrcwpincludesPHPMailerPOP3php"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: 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                          (rev 0)
+++ trunk/src/wp-includes/PHPMailer/POP3.php    2025-08-11 16:16:19 UTC (rev 60623)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,469 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+/**
+ * PHPMailer POP-Before-SMTP Authentication Class.
+ * PHP Version 5.5.
+ *
+ * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
+ *
+ * @author    Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author    Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ * @author    Brent R. Matzelle (original founder)
+ * @copyright 2012 - 2020 Marcus Bointon
+ * @copyright 2010 - 2012 Jim Jagielski
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license   https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
+ * @note      This program is distributed in the hope that it will be useful - WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+namespace PHPMailer\PHPMailer;
+
+/**
+ * PHPMailer POP-Before-SMTP Authentication Class.
+ * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
+ * 1) This class does not support APOP authentication.
+ * 2) Opening and closing lots of POP3 connections can be quite slow. If you need
+ *   to send a batch of emails then just perform the authentication once at the start,
+ *   and then loop through your mail sending script. Providing this process doesn't
+ *   take longer than the verification period lasts on your POP3 server, you should be fine.
+ * 3) This is really ancient technology; you should only need to use it to talk to very old systems.
+ * 4) This POP3 class is deliberately lightweight and incomplete, implementing just
+ *   enough to do authentication.
+ *   If you want a more complete class there are other POP3 classes for PHP available.
+ *
+ * @author Richard Davey (original author) <rich@corephp.co.uk>
+ * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
+ * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
+ * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
+ */
+class POP3
+{
+    /**
+     * The POP3 PHPMailer Version number.
+     *
+     * @var string
+     */
+    const VERSION = '6.10.0';
+
+    /**
+     * Default POP3 port number.
+     *
+     * @var int
+     */
+    const DEFAULT_PORT = 110;
+
+    /**
+     * Default timeout in seconds.
+     *
+     * @var int
+     */
+    const DEFAULT_TIMEOUT = 30;
+
+    /**
+     * POP3 class debug output mode.
+     * Debug output level.
+     * Options:
+     * @see POP3::DEBUG_OFF: No output
+     * @see POP3::DEBUG_SERVER: Server messages, connection/server errors
+     * @see POP3::DEBUG_CLIENT: Client and Server messages, connection/server errors
+     *
+     * @var int
+     */
+    public $do_debug = self::DEBUG_OFF;
+
+    /**
+     * POP3 mail server hostname.
+     *
+     * @var string
+     */
+    public $host;
+
+    /**
+     * POP3 port number.
+     *
+     * @var int
+     */
+    public $port;
+
+    /**
+     * POP3 Timeout Value in seconds.
+     *
+     * @var int
+     */
+    public $tval;
+
+    /**
+     * POP3 username.
+     *
+     * @var string
+     */
+    public $username;
+
+    /**
+     * POP3 password.
+     *
+     * @var string
+     */
+    public $password;
+
+    /**
+     * Resource handle for the POP3 connection socket.
+     *
+     * @var resource
+     */
+    protected $pop_conn;
+
+    /**
+     * Are we connected?
+     *
+     * @var bool
+     */
+    protected $connected = false;
+
+    /**
+     * Error container.
+     *
+     * @var array
+     */
+    protected $errors = [];
+
+    /**
+     * Line break constant.
+     */
+    const LE = "\r\n";
+
+    /**
+     * Debug level for no output.
+     *
+     * @var int
+     */
+    const DEBUG_OFF = 0;
+
+    /**
+     * Debug level to show server -> client messages
+     * also shows clients connection errors or errors from server
+     *
+     * @var int
+     */
+    const DEBUG_SERVER = 1;
+
+    /**
+     * Debug level to show client -> server and server -> client messages.
+     *
+     * @var int
+     */
+    const DEBUG_CLIENT = 2;
+
+    /**
+     * Simple static wrapper for all-in-one POP before SMTP.
+     *
+     * @param string   $host        The hostname to connect to
+     * @param int|bool $port        The port number to connect to
+     * @param int|bool $timeout     The timeout value
+     * @param string   $username
+     * @param string   $password
+     * @param int      $debug_level
+     *
+     * @return bool
+     */
+    public static function popBeforeSmtp(
+        $host,
+        $port = false,
+        $timeout = false,
+        $username = '',
+        $password = '',
+        $debug_level = 0
+    ) {
+        $pop = new self();
+
+        return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
+    }
+
+    /**
+     * Authenticate with a POP3 server.
+     * A connect, login, disconnect sequence
+     * appropriate for POP-before SMTP authorisation.
+     *
+     * @param string   $host        The hostname to connect to
+     * @param int|bool $port        The port number to connect to
+     * @param int|bool $timeout     The timeout value
+     * @param string   $username
+     * @param string   $password
+     * @param int      $debug_level
+     *
+     * @return bool
+     */
+    public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
+    {
+        $this->host = $host;
+        //If no port value provided, use default
+        if (false === $port) {
+            $this->port = static::DEFAULT_PORT;
+        } else {
+            $this->port = (int) $port;
+        }
+        //If no timeout value provided, use default
+        if (false === $timeout) {
+            $this->tval = static::DEFAULT_TIMEOUT;
+        } else {
+            $this->tval = (int) $timeout;
+        }
+        $this->do_debug = $debug_level;
+        $this->username = $username;
+        $this->password = $password;
+        //Reset the error log
+        $this->errors = [];
+        //Connect
+        $result = $this->connect($this->host, $this->port, $this->tval);
+        if ($result) {
+            $login_result = $this->login($this->username, $this->password);
+            if ($login_result) {
+                $this->disconnect();
+
+                return true;
+            }
+        }
+        //We need to disconnect regardless of whether the login succeeded
+        $this->disconnect();
+
+        return false;
+    }
+
+    /**
+     * Connect to a POP3 server.
+     *
+     * @param string   $host
+     * @param int|bool $port
+     * @param int      $tval
+     *
+     * @return bool
+     */
+    public function connect($host, $port = false, $tval = 30)
+    {
+        //Are we already connected?
+        if ($this->connected) {
+            return true;
+        }
+
+        //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
+        //Rather than suppress it with @fsockopen, capture it cleanly instead
+        set_error_handler(function () {
+            call_user_func_array([$this, 'catchWarning'], func_get_args());
+        });
+
+        if (false === $port) {
+            $port = static::DEFAULT_PORT;
+        }
+
+        //Connect to the POP3 server
+        $errno = 0;
+        $errstr = '';
+        $this->pop_conn = fsockopen(
+            $host, //POP3 Host
+            $port, //Port #
+            $errno, //Error Number
+            $errstr, //Error Message
+            $tval
+        ); //Timeout (seconds)
+        //Restore the error handler
+        restore_error_handler();
+
+        //Did we connect?
+        if (false === $this->pop_conn) {
+            //It would appear not...
+            $this->setError(
+                "Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr"
+            );
+
+            return false;
+        }
+
+        //Increase the stream time-out
+        stream_set_timeout($this->pop_conn, $tval, 0);
+
+        //Get the POP3 server response
+        $pop3_response = $this->getResponse();
+        //Check for the +OK
+        if ($this->checkResponse($pop3_response)) {
+            //The connection is established and the POP3 server is talking
+            $this->connected = true;
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Log in to the POP3 server.
+     * Does not support APOP (RFC 2828, 4949).
+     *
+     * @param string $username
+     * @param string $password
+     *
+     * @return bool
+     */
+    public function login($username = '', $password = '')
+    {
+        if (!$this->connected) {
+            $this->setError('Not connected to POP3 server');
+            return false;
+        }
+        if (empty($username)) {
+            $username = $this->username;
+        }
+        if (empty($password)) {
+            $password = $this->password;
+        }
+
+        //Send the Username
+        $this->sendString("USER $username" . static::LE);
+        $pop3_response = $this->getResponse();
+        if ($this->checkResponse($pop3_response)) {
+            //Send the Password
+            $this->sendString("PASS $password" . static::LE);
+            $pop3_response = $this->getResponse();
+            if ($this->checkResponse($pop3_response)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Disconnect from the POP3 server.
+     */
+    public function disconnect()
+    {
+        // If could not connect at all, no need to disconnect
+        if ($this->pop_conn === false) {
+            return;
+        }
+
+        $this->sendString('QUIT' . static::LE);
+
+        // RFC 1939 shows POP3 server sending a +OK response to the QUIT command.
+        // Try to get it.  Ignore any failures here.
+        try {
+            $this->getResponse();
+        } catch (Exception $e) {
+            //Do nothing
+        }
+
+        //The QUIT command may cause the daemon to exit, which will kill our connection
+        //So ignore errors here
+        try {
+            @fclose($this->pop_conn);
+        } catch (Exception $e) {
+            //Do nothing
+        }
+
+        // Clean up attributes.
+        $this->connected = false;
+        $this->pop_conn  = false;
+    }
+
+    /**
+     * Get a response from the POP3 server.
+     *
+     * @param int $size The maximum number of bytes to retrieve
+     *
+     * @return string
+     */
+    protected function getResponse($size = 128)
+    {
+        $response = fgets($this->pop_conn, $size);
+        if ($this->do_debug >= self::DEBUG_SERVER) {
+            echo 'Server -> Client: ', $response;
+        }
+
+        return $response;
+    }
+
+    /**
+     * Send raw data to the POP3 server.
+     *
+     * @param string $string
+     *
+     * @return int
+     */
+    protected function sendString($string)
+    {
+        if ($this->pop_conn) {
+            if ($this->do_debug >= self::DEBUG_CLIENT) { //Show client messages when debug >= 2
+                echo 'Client -> Server: ', $string;
+            }
+
+            return fwrite($this->pop_conn, $string, strlen($string));
+        }
+
+        return 0;
+    }
+
+    /**
+     * Checks the POP3 server response.
+     * Looks for for +OK or -ERR.
+     *
+     * @param string $string
+     *
+     * @return bool
+     */
+    protected function checkResponse($string)
+    {
+        if (strpos($string, '+OK') !== 0) {
+            $this->setError("Server reported an error: $string");
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Add an error to the internal error store.
+     * Also display debug output if it's enabled.
+     *
+     * @param string $error
+     */
+    protected function setError($error)
+    {
+        $this->errors[] = $error;
+        if ($this->do_debug >= self::DEBUG_SERVER) {
+            echo '<pre>';
+            foreach ($this->errors as $e) {
+                print_r($e);
+            }
+            echo '</pre>';
+        }
+    }
+
+    /**
+     * Get an array of error messages, if any.
+     *
+     * @return array
+     */
+    public function getErrors()
+    {
+        return $this->errors;
+    }
+
+    /**
+     * POP3 connection error handler.
+     *
+     * @param int    $errno
+     * @param string $errstr
+     * @param string $errfile
+     * @param int    $errline
+     */
+    protected function catchWarning($errno, $errstr, $errfile, $errline)
+    {
+        $this->setError(
+            'Connecting to the POP3 server raised a PHP warning:' .
+            "errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline"
+        );
+    }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/PHPMailer/POP3.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><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-08-10 20:58:31 UTC (rev 60622)
+++ trunk/src/wp-includes/PHPMailer/SMTP.php    2025-08-11 16:16:19 UTC (rev 60623)
</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.9.3';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    const VERSION = '6.10.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">@@ -160,6 +160,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">     public $do_verp = false;
</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">+     * Whether to use SMTPUTF8.
+     *
+     * @see https://www.rfc-editor.org/rfc/rfc6531
+     *
+     * @var bool
+     */
+    public $do_smtputf8 = false;
+
+    /**
</ins><span class="cx" style="display: block; padding: 0 10px">      * The timeout value for connection, in seconds.
</span><span class="cx" style="display: block; padding: 0 10px">      * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
</span><span class="cx" style="display: block; padding: 0 10px">      * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -913,8 +922,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">      * $from. Returns true if successful or false otherwise. If True
</span><span class="cx" style="display: block; padding: 0 10px">      * the mail transaction is started and then one or more recipient
</span><span class="cx" style="display: block; padding: 0 10px">      * commands may be called followed by a data command.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-     * Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF>.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+     * Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF> and
+     * two extensions, namely XVERP and SMTPUTF8.
</ins><span class="cx" style="display: block; padding: 0 10px">      *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+     * The server's EHLO response is not checked. If use of either
+     * extensions is enabled even though the server does not support
+     * that, mail submission will fail.
+     *
+     * XVERP is documented at https://www.postfix.org/VERP_README.html
+     * and SMTPUTF8 is specified in RFC 6531.
+     *
</ins><span class="cx" style="display: block; padding: 0 10px">      * @param string $from Source address of this message
</span><span class="cx" style="display: block; padding: 0 10px">      *
</span><span class="cx" style="display: block; padding: 0 10px">      * @return bool
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -922,10 +939,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">     public function mail($from)
</span><span class="cx" style="display: block; padding: 0 10px">     {
</span><span class="cx" style="display: block; padding: 0 10px">         $useVerp = ($this->do_verp ? ' XVERP' : '');
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $useSmtputf8 = ($this->do_smtputf8 ? ' SMTPUTF8' : '');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">         return $this->sendCommand(
</span><span class="cx" style="display: block; padding: 0 10px">             'MAIL FROM',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-            'MAIL FROM:<' . $from . '>' . $useVerp,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+            'MAIL FROM:<' . $from . '>' . $useSmtputf8 . $useVerp,
</ins><span class="cx" style="display: block; padding: 0 10px">             250
</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">@@ -1365,6 +1383,26 @@
</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">+     * Enable or disable use of SMTPUTF8.
+     *
+     * @param bool $enabled
+     */
+    public function setSMTPUTF8($enabled = false)
+    {
+        $this->do_smtputf8 = $enabled;
+    }
+
+    /**
+     * Get SMTPUTF8 use.
+     *
+     * @return bool
+     */
+    public function getSMTPUTF8()
+    {
+        return $this->do_smtputf8;
+    }
+
+    /**
</ins><span class="cx" style="display: block; padding: 0 10px">      * Set error messages and codes.
</span><span class="cx" style="display: block; padding: 0 10px">      *
</span><span class="cx" style="display: block; padding: 0 10px">      * @param string $message      The error message
</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-08-10 20:58:31 UTC (rev 60622)
+++ trunk/src/wp-includes/class-wp-phpmailer.php        2025-08-11 16:16:19 UTC (rev 60623)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -88,6 +88,7 @@
</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">                        /* 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><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        'no_smtputf8'          => __( 'Server does not support SMTPUTF8 needed to send to Unicode addresses' ),
</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>