Changeset 60623 for trunk/src/wp-includes/PHPMailer/PHPMailer.php
- Timestamp:
- 08/11/2025 04:16:19 PM (3 months ago)
- File:
-
- 1 edited
-
trunk/src/wp-includes/PHPMailer/PHPMailer.php (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/PHPMailer/PHPMailer.php
r59481 r60623 581 581 * The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option. 582 582 * 583 * If CharSet is UTF8, the validator is left at the default value, 584 * and you send to addresses that use non-ASCII local parts, then 585 * PHPMailer automatically changes to the 'eai' validator. 586 * 583 587 * @see PHPMailer::validateAddress() 584 588 * … … 661 665 662 666 /** 667 * Whether the need for SMTPUTF8 has been detected. Set by 668 * preSend() if necessary. 669 * 670 * @var bool 671 */ 672 public $UseSMTPUTF8 = false; 673 674 /** 663 675 * The array of attachments. 664 676 * … … 757 769 * @var string 758 770 */ 759 const VERSION = '6. 9.3';771 const VERSION = '6.10.0'; 760 772 761 773 /** … … 1111 1123 //Enqueue addresses with IDN until we know the PHPMailer::$CharSet. 1112 1124 //Domain is assumed to be whatever is after the last @ symbol in the address 1113 if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) { 1114 if ('Reply-To' !== $kind) { 1115 if (!array_key_exists($address, $this->RecipientsQueue)) { 1116 $this->RecipientsQueue[$address] = $params; 1125 if ($this->has8bitChars(substr($address, ++$pos))) { 1126 if (static::idnSupported()) { 1127 if ('Reply-To' !== $kind) { 1128 if (!array_key_exists($address, $this->RecipientsQueue)) { 1129 $this->RecipientsQueue[$address] = $params; 1130 1131 return true; 1132 } 1133 } elseif (!array_key_exists($address, $this->ReplyToQueue)) { 1134 $this->ReplyToQueue[$address] = $params; 1117 1135 1118 1136 return true; 1119 1137 } 1120 } elseif (!array_key_exists($address, $this->ReplyToQueue)) { 1121 $this->ReplyToQueue[$address] = $params; 1122 1123 return true; 1124 } 1125 1138 } 1139 //We have an 8-bit domain, but we are missing the necessary extensions to support it 1140 //Or we are already sending to this address 1126 1141 return false; 1127 1142 } … … 1161 1176 protected function addAnAddress($kind, $address, $name = '') 1162 1177 { 1178 if ( 1179 self::$validator === 'php' && 1180 ((bool) preg_match('/[\x80-\xFF]/', $address)) 1181 ) { 1182 //The caller has not altered the validator and is sending to an address 1183 //with UTF-8, so assume that they want UTF-8 support instead of failing 1184 $this->CharSet = self::CHARSET_UTF8; 1185 self::$validator = 'eai'; 1186 } 1163 1187 if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) { 1164 1188 $error_message = sprintf( … … 1363 1387 * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; 1364 1388 * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. 1389 * * `eai` Use a pattern similar to the HTML5 spec for 'email' and to firefox, extended to support EAI (RFC6530). 1365 1390 * * `noregex` Don't use a regex: super fast, really dumb. 1366 1391 * Alternatively you may pass in a callable to inject your own validator, for example: … … 1433 1458 $address 1434 1459 ); 1460 case 'eai': 1461 /* 1462 * This is the pattern used in the HTML5 spec for validation of 'email' type 1463 * form input elements (as above), modified to accept Unicode email addresses. 1464 * This is also more lenient than Firefox' html5 spec, in order to make the regex faster. 1465 * 'eai' is an acronym for Email Address Internationalization. 1466 * This validator is selected automatically if you attempt to use recipient addresses 1467 * that contain Unicode characters in the local part. 1468 * 1469 * @see https://html.spec.whatwg.org/#e-mail-state-(type=email) 1470 * @see https://en.wikipedia.org/wiki/International_email 1471 */ 1472 return (bool) preg_match( 1473 '/^[-\p{L}\p{N}\p{M}.!#$%&\'*+\/=?^_`{|}~]+@[\p{L}\p{N}\p{M}](?:[\p{L}\p{N}\p{M}-]{0,61}' . 1474 '[\p{L}\p{N}\p{M}])?(?:\.[\p{L}\p{N}\p{M}]' . 1475 '(?:[-\p{L}\p{N}\p{M}]{0,61}[\p{L}\p{N}\p{M}])?)*$/usD', 1476 $address 1477 ); 1435 1478 case 'php': 1436 1479 default: … … 1568 1611 $this->mailHeader = ''; 1569 1612 1613 //The code below tries to support full use of Unicode, 1614 //while remaining compatible with legacy SMTP servers to 1615 //the greatest degree possible: If the message uses 1616 //Unicode in the local parts of any addresses, it is sent 1617 //using SMTPUTF8. If not, it it sent using 1618 //punycode-encoded domains and plain SMTP. 1619 if ( 1620 static::CHARSET_UTF8 === strtolower($this->CharSet) && 1621 ($this->anyAddressHasUnicodeLocalPart($this->RecipientsQueue) || 1622 $this->anyAddressHasUnicodeLocalPart(array_keys($this->all_recipients)) || 1623 $this->anyAddressHasUnicodeLocalPart($this->ReplyToQueue) || 1624 $this->addressHasUnicodeLocalPart($this->From)) 1625 ) { 1626 $this->UseSMTPUTF8 = true; 1627 } 1570 1628 //Dequeue recipient and Reply-To addresses with IDN 1571 1629 foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) { 1572 $params[1] = $this->punyencodeAddress($params[1]); 1630 if (!$this->UseSMTPUTF8) { 1631 $params[1] = $this->punyencodeAddress($params[1]); 1632 } 1573 1633 call_user_func_array([$this, 'addAnAddress'], $params); 1574 1634 } … … 2061 2121 throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); 2062 2122 } 2123 //If we have recipient addresses that need Unicode support, 2124 //but the server doesn't support it, stop here 2125 if ($this->UseSMTPUTF8 && !$this->smtp->getServerExt('SMTPUTF8')) { 2126 throw new Exception($this->lang('no_smtputf8'), self::STOP_CRITICAL); 2127 } 2063 2128 //Sender already validated in preSend() 2064 2129 if ('' === $this->Sender) { … … 2162 2227 $this->smtp->setDebugOutput($this->Debugoutput); 2163 2228 $this->smtp->setVerp($this->do_verp); 2229 $this->smtp->setSMTPUTF8($this->UseSMTPUTF8); 2164 2230 if ($this->Host === null) { 2165 2231 $this->Host = 'localhost'; … … 2359 2425 'smtp_error' => 'SMTP server error: ', 2360 2426 'variable_set' => 'Cannot set or reset variable: ', 2427 'no_smtputf8' => 'Server does not support SMTPUTF8 needed to send to Unicode addresses', 2361 2428 ]; 2362 2429 if (empty($lang_path)) { … … 2873 2940 $bodyCharSet = $this->CharSet; 2874 2941 //Can we do a 7-bit downgrade? 2875 if (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) { 2942 if ($this->UseSMTPUTF8) { 2943 $bodyEncoding = static::ENCODING_8BIT; 2944 } elseif (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) { 2876 2945 $bodyEncoding = static::ENCODING_7BIT; 2877 2946 //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit … … 3510 3579 * Encode a header value (not including its label) optimally. 3511 3580 * Picks shortest of Q, B, or none. Result includes folding if needed. 3512 * See RFC822 definitions for phrase, comment and text positions. 3581 * See RFC822 definitions for phrase, comment and text positions, 3582 * and RFC2047 for inline encodings. 3513 3583 * 3514 3584 * @param string $str The header value to encode … … 3519 3589 public function encodeHeader($str, $position = 'text') 3520 3590 { 3591 $position = strtolower($position); 3592 if ($this->UseSMTPUTF8 && !("comment" === $position)) { 3593 return trim(static::normalizeBreaks($str)); 3594 } 3595 3521 3596 $matchcount = 0; 3522 3597 switch (strtolower($position)) { … … 4183 4258 $lasterror = $this->smtp->getError(); 4184 4259 if (!empty($lasterror['error'])) { 4185 $msg .= $this->lang('smtp_error') . $lasterror['error'];4260 $msg .= ' ' . $this->lang('smtp_error') . $lasterror['error']; 4186 4261 if (!empty($lasterror['detail'])) { 4187 4262 $msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail']; … … 4269 4344 return filter_var('https://' . $host, FILTER_VALIDATE_URL) !== false; 4270 4345 } 4346 4347 /** 4348 * Check whether the supplied address uses Unicode in the local part. 4349 * 4350 * @return bool 4351 */ 4352 protected function addressHasUnicodeLocalPart($address) 4353 { 4354 return (bool) preg_match('/[\x80-\xFF].*@/', $address); 4355 } 4356 4357 /** 4358 * Check whether any of the supplied addresses use Unicode in the local part. 4359 * 4360 * @return bool 4361 */ 4362 protected function anyAddressHasUnicodeLocalPart($addresses) 4363 { 4364 foreach ($addresses as $address) { 4365 if (is_array($address)) { 4366 $address = $address[0]; 4367 } 4368 if ($this->addressHasUnicodeLocalPart($address)) { 4369 return true; 4370 } 4371 } 4372 return false; 4373 } 4374 4375 /** 4376 * Check whether the message requires SMTPUTF8 based on what's known so far. 4377 * 4378 * @return bool 4379 */ 4380 public function needsSMTPUTF8() 4381 { 4382 return $this->UseSMTPUTF8; 4383 } 4384 4271 4385 4272 4386 /**
Note: See TracChangeset
for help on using the changeset viewer.