Skip to content

Commit 653b644

Browse files
External Libraries: Upgrade PHPMailer to version 6.9.1.
This is a maintenance and feature release, adding support for the official release of PHP 8.3, methods for removing and replacing custom headers, XCLIENT support, and links to a new way of implementing XOAUTH2 authentication. The only change likely to have any impact on existing code is that PHPMailer previously attempted to use opportunistic STARTTLS encryption when connecting to `localhost`, which was unlikely to work. The workaround required setting `SMTPAutoTLS = false`, but that's no longer required. You may still need to use this setting when connecting to literal IPs. References: * [https://github.com/PHPMailer/PHPMailer/releases/tag/v6.9.1 PHPMailer 6.9.1 release notes] * [PHPMailer/PHPMailer@v6.8.1...v6.9.1 Full list of changes in PHPMailer 6.9.1] Follow-up to [50628], [50799], [51169], [51634], [51635], [52252], [52749], [52811], [53500], [53535], [53917], [54427], [54937], [55557], [56484]. Props jrf, Synchro. Fixes #59966. git-svn-id: https://develop.svn.wordpress.org/trunk@57137 602fd350-edb4-49c9-b593-d223f7449a82
1 parent bc4eb46 commit 653b644

2 files changed

Lines changed: 160 additions & 3 deletions

File tree

src/wp-includes/PHPMailer/PHPMailer.php

Lines changed: 128 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,13 @@ class PHPMailer
357357
*/
358358
public $AuthType = '';
359359

360+
/**
361+
* SMTP SMTPXClient command attibutes
362+
*
363+
* @var array
364+
*/
365+
protected $SMTPXClient = [];
366+
360367
/**
361368
* An implementation of the PHPMailer OAuthTokenProvider interface.
362369
*
@@ -750,7 +757,7 @@ class PHPMailer
750757
*
751758
* @var string
752759
*/
753-
const VERSION = '6.8.1';
760+
const VERSION = '6.9.1';
754761

755762
/**
756763
* Error severity: message only, continue processing.
@@ -1573,6 +1580,10 @@ public function preSend()
15731580

15741581
//Validate From, Sender, and ConfirmReadingTo addresses
15751582
foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
1583+
if ($this->{$address_kind} === null) {
1584+
$this->{$address_kind} = '';
1585+
continue;
1586+
}
15761587
$this->{$address_kind} = trim($this->{$address_kind});
15771588
if (empty($this->{$address_kind})) {
15781589
continue;
@@ -1999,6 +2010,38 @@ public function setSMTPInstance(SMTP $smtp)
19992010
return $this->smtp;
20002011
}
20012012

2013+
/**
2014+
* Provide SMTP XCLIENT attributes
2015+
*
2016+
* @param string $name Attribute name
2017+
* @param ?string $value Attribute value
2018+
*
2019+
* @return bool
2020+
*/
2021+
public function setSMTPXclientAttribute($name, $value)
2022+
{
2023+
if (!in_array($name, SMTP::$xclient_allowed_attributes)) {
2024+
return false;
2025+
}
2026+
if (isset($this->SMTPXClient[$name]) && $value === null) {
2027+
unset($this->SMTPXClient[$name]);
2028+
} elseif ($value !== null) {
2029+
$this->SMTPXClient[$name] = $value;
2030+
}
2031+
2032+
return true;
2033+
}
2034+
2035+
/**
2036+
* Get SMTP XCLIENT attributes
2037+
*
2038+
* @return array
2039+
*/
2040+
public function getSMTPXclientAttributes()
2041+
{
2042+
return $this->SMTPXClient;
2043+
}
2044+
20022045
/**
20032046
* Send mail via SMTP.
20042047
* Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
@@ -2027,6 +2070,9 @@ protected function smtpSend($header, $body)
20272070
} else {
20282071
$smtp_from = $this->Sender;
20292072
}
2073+
if (count($this->SMTPXClient)) {
2074+
$this->smtp->xclient($this->SMTPXClient);
2075+
}
20302076
if (!$this->smtp->mail($smtp_from)) {
20312077
$this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
20322078
throw new Exception($this->ErrorInfo, self::STOP_CRITICAL);
@@ -2189,10 +2235,17 @@ public function smtpConnect($options = null)
21892235
$this->smtp->hello($hello);
21902236
//Automatically enable TLS encryption if:
21912237
//* it's not disabled
2238+
//* we are not connecting to localhost
21922239
//* we have openssl extension
21932240
//* we are not already using SSL
21942241
//* the server offers STARTTLS
2195-
if ($this->SMTPAutoTLS && $sslext && 'ssl' !== $secure && $this->smtp->getServerExt('STARTTLS')) {
2242+
if (
2243+
$this->SMTPAutoTLS &&
2244+
$this->Host !== 'localhost' &&
2245+
$sslext &&
2246+
$secure !== 'ssl' &&
2247+
$this->smtp->getServerExt('STARTTLS')
2248+
) {
21962249
$tls = true;
21972250
}
21982251
if ($tls) {
@@ -4049,6 +4102,79 @@ public function clearCustomHeaders()
40494102
$this->CustomHeader = [];
40504103
}
40514104

4105+
/**
4106+
* Clear a specific custom header by name or name and value.
4107+
* $name value can be overloaded to contain
4108+
* both header name and value (name:value).
4109+
*
4110+
* @param string $name Custom header name
4111+
* @param string|null $value Header value
4112+
*
4113+
* @return bool True if a header was replaced successfully
4114+
*/
4115+
public function clearCustomHeader($name, $value = null)
4116+
{
4117+
if (null === $value && strpos($name, ':') !== false) {
4118+
//Value passed in as name:value
4119+
list($name, $value) = explode(':', $name, 2);
4120+
}
4121+
$name = trim($name);
4122+
$value = (null === $value) ? null : trim($value);
4123+
4124+
foreach ($this->CustomHeader as $k => $pair) {
4125+
if ($pair[0] == $name) {
4126+
// We remove the header if the value is not provided or it matches.
4127+
if (null === $value || $pair[1] == $value) {
4128+
unset($this->CustomHeader[$k]);
4129+
}
4130+
}
4131+
}
4132+
4133+
return true;
4134+
}
4135+
4136+
/**
4137+
* Replace a custom header.
4138+
* $name value can be overloaded to contain
4139+
* both header name and value (name:value).
4140+
*
4141+
* @param string $name Custom header name
4142+
* @param string|null $value Header value
4143+
*
4144+
* @return bool True if a header was replaced successfully
4145+
* @throws Exception
4146+
*/
4147+
public function replaceCustomHeader($name, $value = null)
4148+
{
4149+
if (null === $value && strpos($name, ':') !== false) {
4150+
//Value passed in as name:value
4151+
list($name, $value) = explode(':', $name, 2);
4152+
}
4153+
$name = trim($name);
4154+
$value = (null === $value) ? '' : trim($value);
4155+
4156+
$replaced = false;
4157+
foreach ($this->CustomHeader as $k => $pair) {
4158+
if ($pair[0] == $name) {
4159+
if ($replaced) {
4160+
unset($this->CustomHeader[$k]);
4161+
continue;
4162+
}
4163+
if (strpbrk($name . $value, "\r\n") !== false) {
4164+
if ($this->exceptions) {
4165+
throw new Exception($this->lang('invalid_header'));
4166+
}
4167+
4168+
return false;
4169+
}
4170+
$this->CustomHeader[$k] = [$name, $value];
4171+
$replaced = true;
4172+
}
4173+
}
4174+
4175+
return true;
4176+
}
4177+
40524178
/**
40534179
* Add an error message to the error container.
40544180
*

src/wp-includes/PHPMailer/SMTP.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class SMTP
3535
*
3636
* @var string
3737
*/
38-
const VERSION = '6.8.1';
38+
const VERSION = '6.9.1';
3939

4040
/**
4141
* SMTP line break constant.
@@ -198,6 +198,18 @@ class SMTP
198198
'Mailjet' => '/[\d]{3} OK queued as (.*)/',
199199
];
200200

201+
/**
202+
* Allowed SMTP XCLIENT attributes.
203+
* Must be allowed by the SMTP server. EHLO response is not checked.
204+
*
205+
* @see https://www.postfix.org/XCLIENT_README.html
206+
*
207+
* @var array
208+
*/
209+
public static $xclient_allowed_attributes = [
210+
'NAME', 'ADDR', 'PORT', 'PROTO', 'HELO', 'LOGIN', 'DESTADDR', 'DESTPORT'
211+
];
212+
201213
/**
202214
* The last transaction ID issued in response to a DATA command,
203215
* if one was detected.
@@ -971,6 +983,25 @@ public function recipient($address, $dsn = '')
971983
);
972984
}
973985

986+
/**
987+
* Send SMTP XCLIENT command to server and check its return code.
988+
*
989+
* @return bool True on success
990+
*/
991+
public function xclient(array $vars)
992+
{
993+
$xclient_options = "";
994+
foreach ($vars as $key => $value) {
995+
if (in_array($key, SMTP::$xclient_allowed_attributes)) {
996+
$xclient_options .= " {$key}={$value}";
997+
}
998+
}
999+
if (!$xclient_options) {
1000+
return true;
1001+
}
1002+
return $this->sendCommand('XCLIENT', 'XCLIENT' . $xclient_options, 250);
1003+
}
1004+
9741005
/**
9751006
* Send an SMTP RSET command.
9761007
* Abort any transaction that is currently in progress.

0 commit comments

Comments
 (0)