Changeset 46097
- Timestamp:
- 09/12/2019 02:36:42 PM (5 years ago)
- Location:
- trunk/src/wp-includes
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-phpmailer.php
r39759 r46097 32 32 * @var string 33 33 */ 34 public $Version = '5.2.2 2';34 public $Version = '5.2.27'; 35 35 36 36 /** … … 441 441 * Parameters: 442 442 * boolean $result result of the send action 443 * string $to email address of the recipient444 * string$cc cc email addresses445 * string$bcc bcc email addresses443 * array $to email addresses of the recipients 444 * array $cc cc email addresses 445 * array $bcc bcc email addresses 446 446 * string $subject the subject 447 447 * string $body the email body … … 660 660 $this->exceptions = (boolean)$exceptions; 661 661 } 662 //Pick an appropriate debug output format automatically 663 $this->Debugoutput = (strpos(PHP_SAPI, 'cli') !== false ? 'echo' : 'html'); 662 664 } 663 665 … … 1295 1297 // Sign with DKIM if enabled 1296 1298 if (!empty($this->DKIM_domain) 1297 && !empty($this->DKIM_selector) 1298 && (!empty($this->DKIM_private_string) 1299 || (!empty($this->DKIM_private) && file_exists($this->DKIM_private)) 1299 and !empty($this->DKIM_selector) 1300 and (!empty($this->DKIM_private_string) 1301 or (!empty($this->DKIM_private) 1302 and self::isPermittedPath($this->DKIM_private) 1303 and file_exists($this->DKIM_private) 1304 ) 1300 1305 ) 1301 1306 ) { … … 1463 1468 1464 1469 /** 1470 * Check whether a file path is of a permitted type. 1471 * Used to reject URLs and phar files from functions that access local file paths, 1472 * such as addAttachment. 1473 * @param string $path A relative or absolute path to a file. 1474 * @return bool 1475 */ 1476 protected static function isPermittedPath($path) 1477 { 1478 return !preg_match('#^[a-z]+://#i', $path); 1479 } 1480 1481 /** 1465 1482 * Send mail using the PHP mail() function. 1466 1483 * @param string $header The message headers … … 1624 1641 foreach ($hosts as $hostentry) { 1625 1642 $hostinfo = array(); 1626 if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) { 1643 if (!preg_match( 1644 '/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*|\[[a-fA-F0-9:]+\]):?([0-9]*)$/', 1645 trim($hostentry), 1646 $hostinfo 1647 )) { 1627 1648 // Not a valid host entry 1649 $this->edebug('Ignoring invalid host: ' . $hostentry); 1628 1650 continue; 1629 1651 } … … 1744 1766 'no' => 'nb', 1745 1767 'se' => 'sv', 1768 'sr' => 'rs' 1746 1769 ); 1747 1770 … … 1785 1808 if ($langcode != 'en') { 1786 1809 // Make sure language file path is readable 1787 if (! is_readable($lang_file)) {1810 if (!self::isPermittedPath($lang_file) or !is_readable($lang_file)) { 1788 1811 $foundlang = false; 1789 1812 } else { … … 2026 2049 $result = ''; 2027 2050 2028 if ($this->MessageDate == '') { 2029 $this->MessageDate = self::rfcDate(); 2030 } 2031 $result .= $this->headerLine('Date', $this->MessageDate); 2051 $result .= $this->headerLine('Date', $this->MessageDate == '' ? self::rfcDate() : $this->MessageDate); 2032 2052 2033 2053 // To be created automatically by mail() … … 2496 2516 * Never use a user-supplied path to a file! 2497 2517 * Returns false if the file could not be found or read. 2518 * Explicitly *does not* support passing URLs; PHPMailer is not an HTTP client. 2519 * If you need to do that, fetch the resource yourself and pass it in via a local file or string. 2498 2520 * @param string $path Path to the attachment. 2499 2521 * @param string $name Overrides the attachment name. … … 2507 2529 { 2508 2530 try { 2509 if (! @is_file($path)) {2531 if (!self::isPermittedPath($path) or !@is_file($path)) { 2510 2532 throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE); 2511 2533 } … … 2688 2710 { 2689 2711 try { 2690 if (! is_readable($path)) {2712 if (!self::isPermittedPath($path) or !file_exists($path)) { 2691 2713 throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE); 2692 2714 } … … 3032 3054 public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline') 3033 3055 { 3034 if (! @is_file($path)) {3056 if (!self::isPermittedPath($path) or !@is_file($path)) { 3035 3057 $this->setError($this->lang('file_access') . $path); 3036 3058 return false; … … 4035 4057 public function errorMessage() 4036 4058 { 4037 $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";4059 $errorMsg = '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n"; 4038 4060 return $errorMsg; 4039 4061 } -
trunk/src/wp-includes/class-smtp.php
r44894 r46097 31 31 * @var string 32 32 */ 33 const VERSION = '5.2.2 2';33 const VERSION = '5.2.27'; 34 34 35 35 /** … … 82 82 * @see SMTP::VERSION 83 83 */ 84 public $Version = '5.2.2 2';84 public $Version = '5.2.27'; 85 85 86 86 /** … … 151 151 public $Timelimit = 300; 152 152 153 /** 154 * @var array patterns to extract smtp transaction id from smtp reply 155 * Only first capture group will be use, use non-capturing group to deal with it 156 * Extend this class to override this property to fulfil your needs. 157 */ 158 protected $smtp_transaction_id_patterns = array( 159 'exim' => '/[0-9]{3} OK id=(.*)/', 160 'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/', 161 'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/' 162 ); 153 /** 154 * @var array Patterns to extract an SMTP transaction id from reply to a DATA command. 155 * The first capture group in each regex will be used as the ID. 156 */ 157 protected $smtp_transaction_id_patterns = array( 158 'exim' => '/[0-9]{3} OK id=(.*)/', 159 'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/', 160 'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/' 161 ); 162 163 /** 164 * @var string The last transaction ID issued in response to a DATA command, 165 * if one was detected 166 */ 167 protected $last_smtp_transaction_id; 163 168 164 169 /** … … 228 233 case 'html': 229 234 //Cleans up output a bit for a better looking, HTML-safe output 230 echo htmlentities(235 echo gmdate('Y-m-d H:i:s') . ' ' . htmlentities( 231 236 preg_replace('/[\r\n]+/', '', $str), 232 237 ENT_QUOTES, 233 238 'UTF-8' 234 ) 235 . "<br>\n"; 239 ) . "<br>\n"; 236 240 break; 237 241 case 'echo': … … 243 247 "\n \t ", 244 248 trim($str) 245 ) ."\n";249 ) . "\n"; 246 250 } 247 251 } … … 277 281 // Connect to the SMTP server 278 282 $this->edebug( 279 "Connection: opening to $host:$port, timeout=$timeout, options=".var_export($options, true), 283 "Connection: opening to $host:$port, timeout=$timeout, options=" . 284 var_export($options, true), 280 285 self::DEBUG_CONNECTION 281 286 ); … … 363 368 364 369 // Begin encrypted connection 365 if (!stream_socket_enable_crypto( 370 set_error_handler(array($this, 'errorHandler')); 371 $crypto_ok = stream_socket_enable_crypto( 366 372 $this->smtp_conn, 367 373 true, 368 374 $crypto_method 369 )) { 370 return false; 371 } 372 return true; 375 ); 376 restore_error_handler(); 377 return $crypto_ok; 373 378 } 374 379 … … 399 404 400 405 if (array_key_exists('EHLO', $this->server_caps)) { 401 // SMTP extensions are available. Let's try to find a proper authentication method 402 406 // SMTP extensions are available; try to find a proper authentication method 403 407 if (!array_key_exists('AUTH', $this->server_caps)) { 404 408 $this->setError('Authentication is not allowed at this stage'); … … 425 429 return false; 426 430 } 427 self::edebug('Auth method selected: ' .$authtype, self::DEBUG_LOWLEVEL);431 self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL); 428 432 } 429 433 … … 488 492 * in case that function is not available 489 493 * @param string $data The data to hash 490 * @param string $key 494 * @param string $key The key to hash with 491 495 * @access protected 492 496 * @return string … … 565 569 * Send an SMTP DATA command. 566 570 * Issues a data command and sends the msg_data to the server, 567 * fin alizing the mail transaction. $msg_data is the message571 * finializing the mail transaction. $msg_data is the message 568 572 * that is to be send with the headers. Each header needs to be 569 573 * on a single line followed by a <CRLF> with the message headers 570 * and the message body being separated by an additional <CRLF>.574 * and the message body being separated by and additional <CRLF>. 571 575 * Implements rfc 821: DATA <CRLF> 572 576 * @param string $msg_data Message data to send … … 648 652 $this->Timelimit = $this->Timelimit * 2; 649 653 $result = $this->sendCommand('DATA END', '.', 250); 654 $this->recordLastTransactionID(); 650 655 //Restore timelimit 651 656 $this->Timelimit = $savetimelimit; … … 831 836 // Cut off error code from each response line 832 837 $detail = preg_replace( 833 "/{$code}[ -]".($code_ex ? str_replace('.', '\\.', $code_ex).' ' : '')."/m", 838 "/{$code}[ -]" . 839 ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . "/m", 834 840 '', 835 841 $this->last_reply … … 927 933 { 928 934 $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT); 929 return fwrite($this->smtp_conn, $data); 935 set_error_handler(array($this, 'errorHandler')); 936 $result = fwrite($this->smtp_conn, $data); 937 restore_error_handler(); 938 return $result; 930 939 } 931 940 … … 1027 1036 $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL); 1028 1037 $data .= $str; 1029 // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen 1030 if ((isset($str[3]) and $str[3] == ' ')) { 1038 // If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled), 1039 // or 4th character is a space, we are done reading, break the loop, 1040 // string array access is a micro-optimisation over strlen 1041 if (!isset($str[3]) or (isset($str[3]) and $str[3] == ' ')) { 1031 1042 break; 1032 1043 } … … 1043 1054 if ($endtime and time() > $endtime) { 1044 1055 $this->edebug( 1045 'SMTP -> get_lines(): timelimit reached (' .1056 'SMTP -> get_lines(): timelimit reached (' . 1046 1057 $this->Timelimit . ' sec)', 1047 1058 self::DEBUG_LOWLEVEL … … 1146 1157 * @param integer $errno The error number returned by PHP. 1147 1158 * @param string $errmsg The error message returned by PHP. 1148 */ 1149 protected function errorHandler($errno, $errmsg) 1150 { 1151 $notice = 'Connection: Failed to connect to server.'; 1159 * @param string $errfile The file the error occurred in 1160 * @param integer $errline The line number the error occurred on 1161 */ 1162 protected function errorHandler($errno, $errmsg, $errfile = '', $errline = 0) 1163 { 1164 $notice = 'Connection failed.'; 1152 1165 $this->setError( 1153 1166 $notice, … … 1156 1169 ); 1157 1170 $this->edebug( 1158 $notice . ' Error number ' . $errno . '. "Error notice: ' . $errmsg,1171 $notice . ' Error #' . $errno . ': ' . $errmsg . " [$errfile line $errline]", 1159 1172 self::DEBUG_CONNECTION 1160 1173 ); 1161 1174 } 1162 1175 1163 /** 1164 * Will return the ID of the last smtp transaction based on a list of patterns provided 1165 * in SMTP::$smtp_transaction_id_patterns. 1166 * If no reply has been received yet, it will return null. 1167 * If no pattern has been matched, it will return false. 1168 * @return bool|null|string 1169 */ 1170 public function getLastTransactionID() 1171 { 1172 $reply = $this->getLastReply(); 1173 1174 if (empty($reply)) { 1175 return null; 1176 } 1177 1178 foreach($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) { 1179 if(preg_match($smtp_transaction_id_pattern, $reply, $matches)) { 1180 return $matches[1]; 1181 } 1182 } 1183 1184 return false; 1176 /** 1177 * Extract and return the ID of the last SMTP transaction based on 1178 * a list of patterns provided in SMTP::$smtp_transaction_id_patterns. 1179 * Relies on the host providing the ID in response to a DATA command. 1180 * If no reply has been received yet, it will return null. 1181 * If no pattern was matched, it will return false. 1182 * @return bool|null|string 1183 */ 1184 protected function recordLastTransactionID() 1185 { 1186 $reply = $this->getLastReply(); 1187 1188 if (empty($reply)) { 1189 $this->last_smtp_transaction_id = null; 1190 } else { 1191 $this->last_smtp_transaction_id = false; 1192 foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) { 1193 if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) { 1194 $this->last_smtp_transaction_id = $matches[1]; 1195 } 1196 } 1197 } 1198 1199 return $this->last_smtp_transaction_id; 1200 } 1201 1202 /** 1203 * Get the queue/transaction ID of the last SMTP transaction 1204 * If no reply has been received yet, it will return null. 1205 * If no pattern was matched, it will return false. 1206 * @return bool|null|string 1207 * @see recordLastTransactionID() 1208 */ 1209 public function getLastTransactionID() 1210 { 1211 return $this->last_smtp_transaction_id; 1185 1212 } 1186 1213 }
Note: See TracChangeset
for help on using the changeset viewer.