diff --git a/phpcompat.xml.dist b/phpcompat.xml.dist
index 5af8e2a503..2eedf7851b 100644
a
|
b
|
|
40 | 40 | --> |
41 | 41 | <exclude-pattern>/vendor/*</exclude-pattern> |
42 | 42 | |
| 43 | <!-- Exclude PHPMailer library from checks --> |
| 44 | <exclude-pattern>/src/wp-includes/PHPMailer/*</exclude-pattern> |
| 45 | |
43 | 46 | <!-- |
44 | 47 | PHPCompatibilityParagonieSodiumCompat prevents false positives in `sodium_compat`. |
45 | 48 | However, because these files are included in a non-standard path, false positives are triggered in WordPress Core. |
diff --git a/src/wp-includes/PHPMailer/PHPMailer.php b/src/wp-includes/PHPMailer/PHPMailer.php
index 27af1a937b..2d4156f4e8 100644
a
|
b
|
class PHPMailer |
441 | 441 | * Only supported in `mail` and `sendmail` transports, not in SMTP. |
442 | 442 | * |
443 | 443 | * @var bool |
| 444 | * |
| 445 | * @deprecated 6.0.0 PHPMailer isn't a mailing list manager! |
444 | 446 | */ |
445 | 447 | public $SingleTo = false; |
446 | 448 | |
… |
… |
class PHPMailer |
745 | 747 | * |
746 | 748 | * @var string |
747 | 749 | */ |
748 | | const VERSION = '6.1.6'; |
| 750 | const VERSION = '6.1.7'; |
749 | 751 | |
750 | 752 | /** |
751 | 753 | * Error severity: message only, continue processing. |
… |
… |
public function __destruct() |
853 | 855 | private function mailPassthru($to, $subject, $body, $header, $params) |
854 | 856 | { |
855 | 857 | //Check overloading of mail function to avoid double-encoding |
856 | | if (ini_get('mbstring.func_overload') & 1) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated |
| 858 | if (ini_get('mbstring.func_overload') & 1) { |
857 | 859 | $subject = $this->secureHeader($subject); |
858 | 860 | } else { |
859 | 861 | $subject = $this->encodeHeader($this->secureHeader($subject)); |
… |
… |
public static function validateAddress($address, $patternselect = null) |
1307 | 1309 | $patternselect = static::$validator; |
1308 | 1310 | } |
1309 | 1311 | if (is_callable($patternselect)) { |
1310 | | return $patternselect($address); |
| 1312 | return call_user_func($patternselect, $address); |
1311 | 1313 | } |
1312 | 1314 | //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321 |
1313 | 1315 | if (strpos($address, "\n") !== false || strpos($address, "\r") !== false) { |
… |
… |
public function punyencodeAddress($address) |
1401 | 1403 | //Ignore IDE complaints about this line - method signature changed in PHP 5.4 |
1402 | 1404 | $errorcode = 0; |
1403 | 1405 | if (defined('INTL_IDNA_VARIANT_UTS46')) { |
1404 | | // phpcs:ignore PHPCompatibility.ParameterValues.NewIDNVariantDefault.NotSet |
1405 | 1406 | $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_UTS46); |
1406 | 1407 | } elseif (defined('INTL_IDNA_VARIANT_2003')) { |
1407 | | // phpcs:ignore PHPCompatibility.Constants.RemovedConstants.intl_idna_variant_2003Deprecated |
1408 | 1408 | $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_2003); |
1409 | 1409 | } else { |
1410 | | // phpcs:ignore PHPCompatibility.ParameterValues.NewIDNVariantDefault.NotSet |
1411 | 1410 | $punycode = idn_to_ascii($domain, $errorcode); |
1412 | 1411 | } |
1413 | 1412 | if (false !== $punycode) { |
… |
… |
public function addAttachment( |
2978 | 2977 | if ('' === $name) { |
2979 | 2978 | $name = $filename; |
2980 | 2979 | } |
2981 | | |
2982 | 2980 | if (!$this->validateEncoding($encoding)) { |
2983 | 2981 | throw new Exception($this->lang('encoding') . $encoding); |
2984 | 2982 | } |
… |
… |
public function getCustomHeaders() |
3993 | 3991 | * @param string $message HTML message string |
3994 | 3992 | * @param string $basedir Absolute path to a base directory to prepend to relative paths to images |
3995 | 3993 | * @param bool|callable $advanced Whether to use the internal HTML to text converter |
3996 | | * or your own custom converter @return string $message The transformed message Body |
| 3994 | * or your own custom converter |
| 3995 | * @return string The transformed message body |
3997 | 3996 | * |
3998 | 3997 | * @throws Exception |
3999 | 3998 | * |
… |
… |
public function msgHTML($message, $basedir = '', $advanced = false) |
4117 | 4116 | public function html2text($html, $advanced = false) |
4118 | 4117 | { |
4119 | 4118 | if (is_callable($advanced)) { |
4120 | | return $advanced($html); |
| 4119 | return call_user_func($advanced, $html); |
4121 | 4120 | } |
4122 | 4121 | |
4123 | 4122 | return html_entity_decode( |
diff --git a/src/wp-includes/PHPMailer/SMTP.php b/src/wp-includes/PHPMailer/SMTP.php
index aa5555149a..6b0b73ddd9 100644
a
|
b
|
class SMTP |
34 | 34 | * |
35 | 35 | * @var string |
36 | 36 | */ |
37 | | const VERSION = '6.1.6'; |
| 37 | const VERSION = '6.1.7'; |
38 | 38 | |
39 | 39 | /** |
40 | 40 | * SMTP line break constant. |
… |
… |
protected function edebug($str, $level = 0) |
311 | 311 | */ |
312 | 312 | public function connect($host, $port = null, $timeout = 30, $options = []) |
313 | 313 | { |
314 | | static $streamok; |
315 | | //This is enabled by default since 5.0.0 but some providers disable it |
316 | | //Check this once and cache the result |
317 | | if (null === $streamok) { |
318 | | $streamok = function_exists('stream_socket_client'); |
319 | | } |
320 | 314 | // Clear errors to avoid confusion |
321 | 315 | $this->setError(''); |
322 | 316 | // Make sure we are __not__ connected |
… |
… |
public function connect($host, $port = null, $timeout = 30, $options = []) |
335 | 329 | (count($options) > 0 ? var_export($options, true) : 'array()'), |
336 | 330 | self::DEBUG_CONNECTION |
337 | 331 | ); |
| 332 | |
| 333 | $this->smtp_conn = $this->getSMTPConnection($host, $port, $timeout, $options); |
| 334 | |
| 335 | if ($this->smtp_conn === false) { |
| 336 | //Error info already set inside `getSMTPConnection()` |
| 337 | return false; |
| 338 | } |
| 339 | |
| 340 | $this->edebug('Connection: opened', self::DEBUG_CONNECTION); |
| 341 | |
| 342 | // Get any announcement |
| 343 | $this->last_reply = $this->get_lines(); |
| 344 | $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); |
| 345 | |
| 346 | return true; |
| 347 | } |
| 348 | |
| 349 | /** |
| 350 | * Create connection to the SMTP server. |
| 351 | * |
| 352 | * @param string $host SMTP server IP or host name |
| 353 | * @param int $port The port number to connect to |
| 354 | * @param int $timeout How long to wait for the connection to open |
| 355 | * @param array $options An array of options for stream_context_create() |
| 356 | * |
| 357 | * @return false|resource |
| 358 | */ |
| 359 | protected function getSMTPConnection($host, $port = null, $timeout = 30, $options = []) |
| 360 | { |
| 361 | static $streamok; |
| 362 | //This is enabled by default since 5.0.0 but some providers disable it |
| 363 | //Check this once and cache the result |
| 364 | if (null === $streamok) { |
| 365 | $streamok = function_exists('stream_socket_client'); |
| 366 | } |
| 367 | |
338 | 368 | $errno = 0; |
339 | 369 | $errstr = ''; |
340 | 370 | if ($streamok) { |
341 | 371 | $socket_context = stream_context_create($options); |
342 | 372 | set_error_handler([$this, 'errorHandler']); |
343 | | $this->smtp_conn = stream_socket_client( |
| 373 | $connection = stream_socket_client( |
344 | 374 | $host . ':' . $port, |
345 | 375 | $errno, |
346 | 376 | $errstr, |
… |
… |
public function connect($host, $port = null, $timeout = 30, $options = []) |
356 | 386 | self::DEBUG_CONNECTION |
357 | 387 | ); |
358 | 388 | set_error_handler([$this, 'errorHandler']); |
359 | | $this->smtp_conn = fsockopen( |
| 389 | $connection = fsockopen( |
360 | 390 | $host, |
361 | 391 | $port, |
362 | 392 | $errno, |
… |
… |
public function connect($host, $port = null, $timeout = 30, $options = []) |
365 | 395 | ); |
366 | 396 | restore_error_handler(); |
367 | 397 | } |
| 398 | |
368 | 399 | // Verify we connected properly |
369 | | if (!is_resource($this->smtp_conn)) { |
| 400 | if (!is_resource($connection)) { |
370 | 401 | $this->setError( |
371 | 402 | 'Failed to connect to server', |
372 | 403 | '', |
… |
… |
public function connect($host, $port = null, $timeout = 30, $options = []) |
381 | 412 | |
382 | 413 | return false; |
383 | 414 | } |
384 | | $this->edebug('Connection: opened', self::DEBUG_CONNECTION); |
| 415 | |
385 | 416 | // SMTP server can take longer to respond, give longer timeout for first read |
386 | 417 | // Windows does not have support for this timeout function |
387 | 418 | if (strpos(PHP_OS, 'WIN') !== 0) { |
388 | | $max = (int) ini_get('max_execution_time'); |
| 419 | $max = (int)ini_get('max_execution_time'); |
389 | 420 | // Don't bother if unlimited |
390 | 421 | if (0 !== $max && $timeout > $max) { |
391 | 422 | @set_time_limit($timeout); |
392 | 423 | } |
393 | | stream_set_timeout($this->smtp_conn, $timeout, 0); |
| 424 | stream_set_timeout($connection, $timeout, 0); |
394 | 425 | } |
395 | | // Get any announcement |
396 | | $announce = $this->get_lines(); |
397 | | $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER); |
398 | 426 | |
399 | | return true; |
| 427 | return $connection; |
400 | 428 | } |
401 | 429 | |
402 | 430 | /** |
… |
… |
protected function get_lines() |
1166 | 1194 | $selW = null; |
1167 | 1195 | while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { |
1168 | 1196 | //Must pass vars in here as params are by reference |
1169 | | if (!stream_select($selR, $selW, $selW, $this->Timelimit)) { |
| 1197 | //solution for signals inspired by https://github.com/symfony/symfony/pull/6540 |
| 1198 | set_error_handler([$this, 'errorHandler']); |
| 1199 | $n = stream_select($selR, $selW, $selW, $this->Timelimit); |
| 1200 | restore_error_handler(); |
| 1201 | |
| 1202 | if ($n === false) { |
| 1203 | $message = $this->getError()['detail']; |
| 1204 | |
| 1205 | $this->edebug( |
| 1206 | 'SMTP -> get_lines(): select failed (' . $message . ')', |
| 1207 | self::DEBUG_LOWLEVEL |
| 1208 | ); |
| 1209 | |
| 1210 | //stream_select returns false when the `select` system call is interrupted by an incoming signal, try the select again |
| 1211 | if (stripos($message, 'interrupted system call') !== false) { |
| 1212 | $this->edebug( |
| 1213 | 'SMTP -> get_lines(): retrying stream_select', |
| 1214 | self::DEBUG_LOWLEVEL |
| 1215 | ); |
| 1216 | $this->setError(''); |
| 1217 | continue; |
| 1218 | } |
| 1219 | |
| 1220 | break; |
| 1221 | } |
| 1222 | |
| 1223 | if (!$n) { |
1170 | 1224 | $this->edebug( |
1171 | 1225 | 'SMTP -> get_lines(): select timed-out in (' . $this->Timelimit . ' sec)', |
1172 | 1226 | self::DEBUG_LOWLEVEL |
1173 | 1227 | ); |
1174 | 1228 | break; |
1175 | 1229 | } |
| 1230 | |
1176 | 1231 | //Deliberate noise suppression - errors are handled afterwards |
1177 | 1232 | $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH); |
1178 | 1233 | $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL); |