<!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>[50397] trunk/src/wp-includes/PHPMailer: External Libraries: Upgrade PHPMailer to version 6.3.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/50397">50397</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/50397","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>2021-02-21 09:32:41 +0000 (Sun, 21 Feb 2021)</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.3.0.
This is a maintenance release. Changes include:
* Handle early connection errors such as 421 during connection and EHLO states.
* Make the `mail()` and sendmail transports set the envelope sender the same way as SMTP does, i.e. use whatever `From` is set to, only falling back to the `sendmail_from` php.ini setting if `From` is unset. This avoids errors from the `mail()` function if `Sender` is not set explicitly and php.ini is not configured. This is a minor functionality change, so bumps the minor version number.
* Extend `parseAddresses` to decode encoded names.
Release notes: https://github.com/PHPMailer/PHPMailer/releases/tag/v6.3.0
For a full list of changes in this update, see the PHPMailer GitHub:
https://github.com/PHPMailer/PHPMailer/compare/v6.2.0...v6.3.0
Props ayeshrajans.
Fixes <a href="https://core.trac.wordpress.org/ticket/52577">#52577</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>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<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 2021-02-20 17:43:55 UTC (rev 50396)
+++ trunk/src/wp-includes/PHPMailer/PHPMailer.php 2021-02-21 09:32:41 UTC (rev 50397)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -748,7 +748,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.2.0';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const VERSION = '6.3.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">@@ -862,18 +862,25 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $subject = $this->encodeHeader($this->secureHeader($subject));
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> //Calling mail() with null params breaks
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->edebug('Sending with mail()');
+ $this->edebug('Sendmail path: ' . ini_get('sendmail_path'));
+ $this->edebug("Envelope sender: {$this->Sender}");
+ $this->edebug("To: {$to}");
+ $this->edebug("Subject: {$subject}");
+ $this->edebug("Headers: {$header}");
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!$this->UseSendmailOptions || null === $params) {
</span><span class="cx" style="display: block; padding: 0 10px"> $result = @mail($to, $subject, $body, $header);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->edebug("Additional params: {$params}");
</ins><span class="cx" style="display: block; padding: 0 10px"> $result = @mail($to, $subject, $body, $header, $params);
</span><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">+ $this->edebug('Result: ' . ($result ? 'true' : 'false'));
</ins><span class="cx" style="display: block; padding: 0 10px"> return $result;
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Output debugging info via user-defined method.
- * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug).
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Output debugging info via a user-defined method.
+ * Only generates output if debug output is enabled.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @see PHPMailer::$Debugoutput
</span><span class="cx" style="display: block; padding: 0 10px"> * @see PHPMailer::$SMTPDebug
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1070,7 +1077,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
</span><span class="cx" style="display: block; padding: 0 10px"> $pos = strrpos($address, '@');
</span><span class="cx" style="display: block; padding: 0 10px"> if (false === $pos) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // At-sign is missing.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //At-sign is missing.
</ins><span class="cx" style="display: block; padding: 0 10px"> $error_message = sprintf(
</span><span class="cx" style="display: block; padding: 0 10px"> '%s (%s): %s',
</span><span class="cx" style="display: block; padding: 0 10px"> $this->lang('invalid_address'),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1086,7 +1093,7 @@
</span><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"> $params = [$kind, $address, $name];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
</ins><span class="cx" style="display: block; padding: 0 10px"> if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ('Reply-To' !== $kind) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!array_key_exists($address, $this->RecipientsQueue)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1103,7 +1110,7 @@
</span><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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Immediately add standard addresses without IDN.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Immediately add standard addresses without IDN.
</ins><span class="cx" style="display: block; padding: 0 10px"> return 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">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1191,6 +1198,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $address->mailbox . '@' . $address->host
</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">+ //Decode the name part if it's present and encoded
+ if (property_exists($address, 'personal') && preg_match('/^=\?.*\?=$/', $address->personal)) {
+ $address->personal = mb_decode_mimeheader($address->personal);
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> $addresses[] = [
</span><span class="cx" style="display: block; padding: 0 10px"> 'name' => (property_exists($address, 'personal') ? $address->personal : ''),
</span><span class="cx" style="display: block; padding: 0 10px"> 'address' => $address->mailbox . '@' . $address->host,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1214,9 +1226,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> list($name, $email) = explode('<', $address);
</span><span class="cx" style="display: block; padding: 0 10px"> $email = trim(str_replace('>', '', $email));
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $name = trim($name);
</ins><span class="cx" style="display: block; padding: 0 10px"> if (static::validateAddress($email)) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If this name is encoded, decode it
+ if (preg_match('/^=\?.*\?=$/', $name)) {
+ $name = mb_decode_mimeheader($name);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> $addresses[] = [
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'name' => trim(str_replace(['"', "'"], '', $name)),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Remove any surrounding quotes and spaces from the name
+ 'name' => trim($name, '\'" '),
</ins><span class="cx" style="display: block; padding: 0 10px"> 'address' => $email,
</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">@@ -1242,7 +1260,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> $address = trim($address);
</span><span class="cx" style="display: block; padding: 0 10px"> $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Don't validate now addresses with IDN. Will be done in send().
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Don't validate now addresses with IDN. Will be done in send().
</ins><span class="cx" style="display: block; padding: 0 10px"> $pos = strrpos($address, '@');
</span><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="cx" style="display: block; padding: 0 10px"> (false === $pos)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1395,7 +1413,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function punyencodeAddress($address)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Verify we have required functions, CharSet, and at-sign.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Verify we have required functions, CharSet, and at-sign.
</ins><span class="cx" style="display: block; padding: 0 10px"> $pos = strrpos($address, '@');
</span><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="cx" style="display: block; padding: 0 10px"> !empty($this->CharSet) &&
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1403,17 +1421,21 @@
</span><span class="cx" style="display: block; padding: 0 10px"> static::idnSupported()
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $domain = substr($address, ++$pos);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Verify CharSet string is a valid one, and domain properly encoded in this CharSet.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Verify CharSet string is a valid one, and domain properly encoded in this CharSet.
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->has8bitChars($domain) && @mb_check_encoding($domain, $this->CharSet)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Convert the domain from whatever charset it's in to UTF-8
+ $domain = mb_convert_encoding($domain, self::CHARSET_UTF8, $this->CharSet);
</ins><span class="cx" style="display: block; padding: 0 10px"> //Ignore IDE complaints about this line - method signature changed in PHP 5.4
</span><span class="cx" style="display: block; padding: 0 10px"> $errorcode = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> if (defined('INTL_IDNA_VARIANT_UTS46')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_UTS46);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Use the current punycode standard (appeared in PHP 7.2)
+ $punycode = idn_to_ascii($domain, $errorcode, \INTL_IDNA_VARIANT_UTS46);
</ins><span class="cx" style="display: block; padding: 0 10px"> } elseif (defined('INTL_IDNA_VARIANT_2003')) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Fall back to this old, deprecated/removed encoding
</ins><span class="cx" style="display: block; padding: 0 10px"> // phpcs:ignore PHPCompatibility.Constants.RemovedConstants.intl_idna_variant_2003Deprecated
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_2003);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $punycode = idn_to_ascii($domain, $errorcode, \INTL_IDNA_VARIANT_2003);
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Fall back to a default we don't know about
</ins><span class="cx" style="display: block; padding: 0 10px"> // phpcs:ignore PHPCompatibility.ParameterValues.NewIDNVariantDefault.NotSet
</span><span class="cx" style="display: block; padding: 0 10px"> $punycode = idn_to_ascii($domain, $errorcode);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1464,7 +1486,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="cx" style="display: block; padding: 0 10px"> 'smtp' === $this->Mailer
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- || ('mail' === $this->Mailer && (PHP_VERSION_ID >= 80000 || stripos(PHP_OS, 'WIN') === 0))
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ || ('mail' === $this->Mailer && (\PHP_VERSION_ID >= 80000 || stripos(PHP_OS, 'WIN') === 0))
</ins><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="cx" style="display: block; padding: 0 10px"> //SMTP mandates RFC-compliant line endings
</span><span class="cx" style="display: block; padding: 0 10px"> //and it's also used with mail() on Windows
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1476,8 +1498,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> //Check for buggy PHP versions that add a header with an incorrect line break
</span><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="cx" style="display: block; padding: 0 10px"> 'mail' === $this->Mailer
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- && ((PHP_VERSION_ID >= 70000 && PHP_VERSION_ID < 70017)
- || (PHP_VERSION_ID >= 70100 && PHP_VERSION_ID < 70103))
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ && ((\PHP_VERSION_ID >= 70000 && \PHP_VERSION_ID < 70017)
+ || (\PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70103))
</ins><span class="cx" style="display: block; padding: 0 10px"> && ini_get('mail.add_x_header') === '1'
</span><span class="cx" style="display: block; padding: 0 10px"> && stripos(PHP_OS, 'WIN') === 0
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1490,10 +1512,10 @@
</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"> try {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->error_count = 0; // Reset errors
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error_count = 0; //Reset errors
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->mailHeader = '';
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Dequeue recipient and Reply-To addresses with IDN
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Dequeue recipient and Reply-To addresses with IDN
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
</span><span class="cx" style="display: block; padding: 0 10px"> $params[1] = $this->punyencodeAddress($params[1]);
</span><span class="cx" style="display: block; padding: 0 10px"> call_user_func_array([$this, 'addAnAddress'], $params);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1502,7 +1524,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('provide_address'), self::STOP_CRITICAL);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Validate From, Sender, and ConfirmReadingTo addresses
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Validate From, Sender, and ConfirmReadingTo addresses
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->$address_kind = trim($this->$address_kind);
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($this->$address_kind)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1526,13 +1548,13 @@
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Set whether the message is multipart/alternative
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Set whether the message is multipart/alternative
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->alternativeExists()) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->ContentType = static::CONTENT_TYPE_MULTIPART_ALTERNATIVE;
</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"> $this->setMessageType();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Refuse to send an empty message unless we are specifically allowing it
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Refuse to send an empty message unless we are specifically allowing it
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!$this->AllowEmpty && empty($this->Body)) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1539,16 +1561,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Trim subject consistently
</span><span class="cx" style="display: block; padding: 0 10px"> $this->Subject = trim($this->Subject);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Create body before headers in case body makes changes to headers (e.g. altering transfer encoding)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Create body before headers in case body makes changes to headers (e.g. altering transfer encoding)
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->MIMEHeader = '';
</span><span class="cx" style="display: block; padding: 0 10px"> $this->MIMEBody = $this->createBody();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // createBody may have added some headers, so retain them
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //createBody may have added some headers, so retain them
</ins><span class="cx" style="display: block; padding: 0 10px"> $tempheaders = $this->MIMEHeader;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->MIMEHeader = $this->createHeader();
</span><span class="cx" style="display: block; padding: 0 10px"> $this->MIMEHeader .= $tempheaders;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // To capture the complete message when using mail(), create
- // an extra header list which createHeader() doesn't fold in
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //To capture the complete message when using mail(), create
+ //an extra header list which createHeader() doesn't fold in
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('mail' === $this->Mailer) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (count($this->to) > 0) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->mailHeader .= $this->addrAppend('To', $this->to);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1561,7 +1583,7 @@
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Sign with DKIM if enabled
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Sign with DKIM if enabled
</ins><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="cx" style="display: block; padding: 0 10px"> !empty($this->DKIM_domain)
</span><span class="cx" style="display: block; padding: 0 10px"> && !empty($this->DKIM_selector)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1602,7 +1624,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> public function postSend()
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Choose the mailer and send through it
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Choose the mailer and send through it
</ins><span class="cx" style="display: block; padding: 0 10px"> switch ($this->Mailer) {
</span><span class="cx" style="display: block; padding: 0 10px"> case 'sendmail':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'qmail':
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1647,22 +1669,45 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> protected function sendmailSend($header, $body)
</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 ($this->Mailer === 'qmail') {
+ $this->edebug('Sending with qmail');
+ } else {
+ $this->edebug('Sending with sendmail');
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> $header = static::stripTrailingWSP($header) . static::$LE . static::$LE;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
- if (!empty($this->Sender) && self::isShellSafe($this->Sender)) {
- if ('qmail' === $this->Mailer) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
+ //A space after `-f` is optional, but there is a long history of its presence
+ //causing problems, so we don't use one
+ //Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
+ //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html
+ //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html
+ //Example problem: https://www.drupal.org/node/1057954
+ //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
+ if ('' === $this->Sender) {
+ $this->Sender = $this->From;
+ }
+ if (empty($this->Sender) && !empty(ini_get('sendmail_from'))) {
+ //PHP config has a sender address we can use
+ $this->Sender = ini_get('sendmail_from');
+ }
+ //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
+ //But sendmail requires this param, so fail without it
+ if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) {
+ if ($this->Mailer === 'qmail') {
</ins><span class="cx" style="display: block; padding: 0 10px"> $sendmailFmt = '%s -f%s';
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $sendmailFmt = '%s -oi -f%s -t';
</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 ('qmail' === $this->Mailer) {
- $sendmailFmt = '%s';
</del><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $sendmailFmt = '%s -oi -t';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->edebug('Sender address unusable or missing: ' . $this->Sender);
+ return false;
</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"> $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->edebug('Sendmail path: ' . $this->Sendmail);
+ $this->edebug('Sendmail command: ' . $sendmail);
+ $this->edebug('Envelope sender: ' . $this->Sender);
+ $this->edebug("Headers: {$header}");
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->SingleTo) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->SingleToArray as $toAddr) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1670,6 +1715,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$mail) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('execute') . $this->Sendmail, 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">+ $this->edebug("To: {$toAddr}");
</ins><span class="cx" style="display: block; padding: 0 10px"> fwrite($mail, 'To: ' . $toAddr . "\n");
</span><span class="cx" style="display: block; padding: 0 10px"> fwrite($mail, $header);
</span><span class="cx" style="display: block; padding: 0 10px"> fwrite($mail, $body);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1684,6 +1730,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->From,
</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">+ $this->edebug("Result: " . ($result === 0 ? 'true' : 'false'));
</ins><span class="cx" style="display: block; padding: 0 10px"> if (0 !== $result) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1706,6 +1753,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->From,
</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">+ $this->edebug("Result: " . ($result === 0 ? 'true' : 'false'));
</ins><span class="cx" style="display: block; padding: 0 10px"> if (0 !== $result) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1726,7 +1774,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> protected static function isShellSafe($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">- // Future-proof
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Future-proof
</ins><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="cx" style="display: block; padding: 0 10px"> escapeshellcmd($string) !== $string
</span><span class="cx" style="display: block; padding: 0 10px"> || !in_array(escapeshellarg($string), ["'$string'", "\"$string\""])
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1739,9 +1787,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> for ($i = 0; $i < $length; ++$i) {
</span><span class="cx" style="display: block; padding: 0 10px"> $c = $string[$i];
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // All other characters have a special meaning in at least one common shell, including = and +.
- // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
- // Note that this does permit non-Latin alphanumeric characters based on the current locale.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //All other characters have a special meaning in at least one common shell, including = and +.
+ //Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
+ //Note that this does permit non-Latin alphanumeric characters based on the current locale.
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!ctype_alnum($c) && strpos('@_-.', $c) === false) {
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1811,11 +1859,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html
</span><span class="cx" style="display: block; padding: 0 10px"> //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html
</span><span class="cx" style="display: block; padding: 0 10px"> //Example problem: https://www.drupal.org/node/1057954
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
- if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) {
- $params = sprintf('-f%s', $this->Sender);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
+ if ('' === $this->Sender) {
+ $this->Sender = $this->From;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (empty($this->Sender) && !empty(ini_get('sendmail_from'))) {
+ //PHP config has a sender address we can use
+ $this->Sender = ini_get('sendmail_from');
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!empty($this->Sender) && static::validateAddress($this->Sender)) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (self::isShellSafe($this->Sender)) {
+ $params = sprintf('-f%s', $this->Sender);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> $old_from = ini_get('sendmail_from');
</span><span class="cx" style="display: block; padding: 0 10px"> ini_set('sendmail_from', $this->Sender);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1901,7 +1956,7 @@
</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"> $callbacks = [];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Attempt to send to all recipients
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Attempt to send to all recipients
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ([$this->to, $this->cc, $this->bcc] as $togroup) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($togroup as $to) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->smtp->recipient($to[0], $this->dsn)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1916,7 +1971,7 @@
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Only send the DATA command if we have viable recipients
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Only send the DATA command if we have viable recipients
</ins><span class="cx" style="display: block; padding: 0 10px"> if ((count($this->all_recipients) > count($bad_rcpt)) && !$this->smtp->data($header . $body)) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('data_not_accepted'), self::STOP_CRITICAL);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1978,7 +2033,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $options = $this->SMTPOptions;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Already connected?
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Already connected?
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->smtp->connected()) {
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2000,14 +2055,14 @@
</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"> $this->edebug($this->lang('invalid_hostentry') . ' ' . trim($hostentry));
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Not a valid host entry
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Not a valid host entry
</ins><span class="cx" style="display: block; padding: 0 10px"> continue;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // $hostinfo[1]: optional ssl or tls prefix
- // $hostinfo[2]: the hostname
- // $hostinfo[3]: optional port number
- // The host string prefix can temporarily override the current setting for SMTPSecure
- // If it's not specified, the default value is used
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //$hostinfo[1]: optional ssl or tls prefix
+ //$hostinfo[2]: the hostname
+ //$hostinfo[3]: optional port number
+ //The host string prefix can temporarily override the current setting for SMTPSecure
+ //If it's not specified, the default value is used
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Check the host name is a valid name or IP address before trying to use it
</span><span class="cx" style="display: block; padding: 0 10px"> if (!static::isValidHost($hostinfo[2])) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2019,11 +2074,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $tls = (static::ENCRYPTION_STARTTLS === $this->SMTPSecure);
</span><span class="cx" style="display: block; padding: 0 10px"> if ('ssl' === $hostinfo[1] || ('' === $hostinfo[1] && static::ENCRYPTION_SMTPS === $this->SMTPSecure)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $prefix = 'ssl://';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $tls = false; // Can't have SSL and TLS at the same time
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $tls = false; //Can't have SSL and TLS at the same time
</ins><span class="cx" style="display: block; padding: 0 10px"> $secure = static::ENCRYPTION_SMTPS;
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ('tls' === $hostinfo[1]) {
</span><span class="cx" style="display: block; padding: 0 10px"> $tls = true;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // tls doesn't use a prefix
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //TLS doesn't use a prefix
</ins><span class="cx" style="display: block; padding: 0 10px"> $secure = static::ENCRYPTION_STARTTLS;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> //Do we need the OpenSSL extension?
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2053,10 +2108,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $this->smtp->hello($hello);
</span><span class="cx" style="display: block; padding: 0 10px"> //Automatically enable TLS encryption if:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // * it's not disabled
- // * we have openssl extension
- // * we are not already using SSL
- // * the server offers STARTTLS
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //* it's not disabled
+ //* we have openssl extension
+ //* we are not already using SSL
+ //* the server offers STARTTLS
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->SMTPAutoTLS && $sslext && 'ssl' !== $secure && $this->smtp->getServerExt('STARTTLS')) {
</span><span class="cx" style="display: block; padding: 0 10px"> $tls = true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2064,7 +2119,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->smtp->startTLS()) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('connect_host'));
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // We must resend EHLO after TLS negotiation
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //We must resend EHLO after TLS negotiation
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->smtp->hello($hello);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2082,14 +2137,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } catch (Exception $exc) {
</span><span class="cx" style="display: block; padding: 0 10px"> $lastexception = $exc;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug($exc->getMessage());
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // We must have connected, but then failed TLS or Auth, so close connection nicely
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //We must have connected, but then failed TLS or Auth, so close connection nicely
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->smtp->quit();
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If we get here, all connection attempts have failed, so close connection hard
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If we get here, all connection attempts have failed, so close connection hard
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->smtp->close();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // As we've caught all exceptions, just report whatever the last one was
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //As we've caught all exceptions, just report whatever the last one was
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->exceptions && null !== $lastexception) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw $lastexception;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2120,7 +2175,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function setLanguage($langcode = 'en', $lang_path = '')
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Backwards compatibility for renamed language codes
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Backwards compatibility for renamed language codes
</ins><span class="cx" style="display: block; padding: 0 10px"> $renamed_langcodes = [
</span><span class="cx" style="display: block; padding: 0 10px"> 'br' => 'pt_br',
</span><span class="cx" style="display: block; padding: 0 10px"> 'cz' => 'cs',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2136,7 +2191,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $langcode = $renamed_langcodes[$langcode];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Define full set of translatable strings in English
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Define full set of translatable strings in English
</ins><span class="cx" style="display: block; padding: 0 10px"> $PHPMAILER_LANG = [
</span><span class="cx" style="display: block; padding: 0 10px"> 'authenticate' => 'SMTP Error: Could not authenticate.',
</span><span class="cx" style="display: block; padding: 0 10px"> 'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2161,7 +2216,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 'extension_missing' => 'Extension missing: ',
</span><span class="cx" style="display: block; padding: 0 10px"> ];
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($lang_path)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Calculate an absolute path so it can work if CWD is not here
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Calculate an absolute path so it can work if CWD is not here
</ins><span class="cx" style="display: block; padding: 0 10px"> $lang_path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> //Validate $langcode
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2170,20 +2225,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $foundlang = true;
</span><span class="cx" style="display: block; padding: 0 10px"> $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // There is no English translation file
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //There is no English translation file
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('en' !== $langcode) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Make sure language file path is readable
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Make sure language file path is readable
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!static::fileIsAccessible($lang_file)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $foundlang = false;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Overwrite language-specific strings.
- // This way we'll never have missing translation keys.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Overwrite language-specific strings.
+ //This way we'll never have missing translation keys.
</ins><span class="cx" style="display: block; padding: 0 10px"> $foundlang = include $lang_file;
</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"> $this->language = $PHPMAILER_LANG;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return (bool) $foundlang; // Returns false if language not found
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return (bool) $foundlang; //Returns false if language not found
</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"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2227,7 +2282,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function addrFormat($addr)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (empty($addr[1])) { // No name provided
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (empty($addr[1])) { //No name provided
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->secureHeader($addr[0]);
</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">@@ -2254,8 +2309,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $soft_break = static::$LE;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If utf-8 encoding is used, we will need to make sure we don't
- // split multibyte characters when we wrap
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If utf-8 encoding is used, we will need to make sure we don't
+ //split multibyte characters when we wrap
</ins><span class="cx" style="display: block; padding: 0 10px"> $is_utf8 = static::CHARSET_UTF8 === strtolower($this->CharSet);
</span><span class="cx" style="display: block; padding: 0 10px"> $lelen = strlen(static::$LE);
</span><span class="cx" style="display: block; padding: 0 10px"> $crlflen = strlen(static::$LE);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2355,29 +2410,29 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
</span><span class="cx" style="display: block; padding: 0 10px"> $encodedCharPos = strpos($lastChunk, '=');
</span><span class="cx" style="display: block; padding: 0 10px"> if (false !== $encodedCharPos) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Found start of encoded character byte within $lookBack block.
- // Check the encoded byte value (the 2 chars after the '=')
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Found start of encoded character byte within $lookBack block.
+ //Check the encoded byte value (the 2 chars after the '=')
</ins><span class="cx" style="display: block; padding: 0 10px"> $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
</span><span class="cx" style="display: block; padding: 0 10px"> $dec = hexdec($hex);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($dec < 128) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Single byte character.
- // If the encoded char was found at pos 0, it will fit
- // otherwise reduce maxLength to start of the encoded char
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Single byte character.
+ //If the encoded char was found at pos 0, it will fit
+ //otherwise reduce maxLength to start of the encoded char
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($encodedCharPos > 0) {
</span><span class="cx" style="display: block; padding: 0 10px"> $maxLength -= $lookBack - $encodedCharPos;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $foundSplitPos = true;
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ($dec >= 192) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // First byte of a multi byte character
- // Reduce maxLength to split at start of character
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //First byte of a multi byte character
+ //Reduce maxLength to split at start of character
</ins><span class="cx" style="display: block; padding: 0 10px"> $maxLength -= $lookBack - $encodedCharPos;
</span><span class="cx" style="display: block; padding: 0 10px"> $foundSplitPos = true;
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ($dec < 192) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Middle byte of a multi byte character, look further back
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Middle byte of a multi byte character, look further back
</ins><span class="cx" style="display: block; padding: 0 10px"> $lookBack += 3;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // No encoded character found
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //No encoded character found
</ins><span class="cx" style="display: block; padding: 0 10px"> $foundSplitPos = true;
</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">@@ -2421,7 +2476,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->headerLine('Date', '' === $this->MessageDate ? self::rfcDate() : $this->MessageDate);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // The To header is created automatically by mail(), so needs to be omitted here
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //The To header is created automatically by mail(), so needs to be omitted here
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('mail' !== $this->Mailer) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->SingleTo) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->to as $toaddr) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2435,12 +2490,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->addrAppend('From', [[trim($this->From), $this->FromName]]);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // sendmail and mail() extract Cc from the header before sending
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //sendmail and mail() extract Cc from the header before sending
</ins><span class="cx" style="display: block; padding: 0 10px"> if (count($this->cc) > 0) {
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->addrAppend('Cc', $this->cc);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // sendmail and mail() extract Bcc from the header before sending
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //sendmail and mail() extract Bcc from the header before sending
</ins><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="cx" style="display: block; padding: 0 10px"> (
</span><span class="cx" style="display: block; padding: 0 10px"> 'sendmail' === $this->Mailer || 'qmail' === $this->Mailer || 'mail' === $this->Mailer
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2454,13 +2509,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->addrAppend('Reply-To', $this->ReplyTo);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // mail() sets the subject itself
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //mail() sets the subject itself
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('mail' !== $this->Mailer) {
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
- // https://tools.ietf.org/html/rfc5322#section-3.6.4
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
+ //https://tools.ietf.org/html/rfc5322#section-3.6.4
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('' !== $this->MessageID && preg_match('/^<.*@.*>$/', $this->MessageID)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->lastMessageID = $this->MessageID;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2486,7 +2541,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>');
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Add custom headers
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Add custom headers
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->CustomHeader as $header) {
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->headerLine(
</span><span class="cx" style="display: block; padding: 0 10px"> trim($header[0]),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2528,28 +2583,24 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"');
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Catches case 'plain': and case '':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Catches case 'plain': and case '':
</ins><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
</span><span class="cx" style="display: block; padding: 0 10px"> $ismultipart = false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // RFC1341 part 5 says 7bit is assumed if not specified
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //RFC1341 part 5 says 7bit is assumed if not specified
</ins><span class="cx" style="display: block; padding: 0 10px"> if (static::ENCODING_7BIT !== $this->Encoding) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($ismultipart) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (static::ENCODING_8BIT === $this->Encoding) {
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->headerLine('Content-Transfer-Encoding', static::ENCODING_8BIT);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ('mail' !== $this->Mailer) {
-// $result .= static::$LE;
- }
-
</del><span class="cx" style="display: block; padding: 0 10px"> return $result;
</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">@@ -2818,7 +2869,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $body .= $this->attachAll('attachment', $this->boundary[1]);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types
</ins><span class="cx" style="display: block; padding: 0 10px"> //Reset the `Encoding` property in case we changed it for line length reasons
</span><span class="cx" style="display: block; padding: 0 10px"> $this->Encoding = $bodyEncoding;
</span><span class="cx" style="display: block; padding: 0 10px"> $body .= $this->encodeString($this->Body, $this->Encoding);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2909,7 +2960,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->textLine('--' . $boundary);
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet);
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= static::$LE;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // RFC1341 part 5 says 7bit is assumed if not specified
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //RFC1341 part 5 says 7bit is assumed if not specified
</ins><span class="cx" style="display: block; padding: 0 10px"> if (static::ENCODING_7BIT !== $encoding) {
</span><span class="cx" style="display: block; padding: 0 10px"> $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3007,7 +3058,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If a MIME type is not specified, try to work it out from the file name
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If a MIME type is not specified, try to work it out from the file name
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('' === $type) {
</span><span class="cx" style="display: block; padding: 0 10px"> $type = static::filenameToType($path);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3026,7 +3077,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 2 => $name,
</span><span class="cx" style="display: block; padding: 0 10px"> 3 => $encoding,
</span><span class="cx" style="display: block; padding: 0 10px"> 4 => $type,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 5 => false, // isStringAttachment
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 5 => false, //isStringAttachment
</ins><span class="cx" style="display: block; padding: 0 10px"> 6 => $disposition,
</span><span class="cx" style="display: block; padding: 0 10px"> 7 => $name,
</span><span class="cx" style="display: block; padding: 0 10px"> ];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3066,16 +3117,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> protected function attachAll($disposition_type, $boundary)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Return text of body
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Return text of body
</ins><span class="cx" style="display: block; padding: 0 10px"> $mime = [];
</span><span class="cx" style="display: block; padding: 0 10px"> $cidUniq = [];
</span><span class="cx" style="display: block; padding: 0 10px"> $incl = [];
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Add all attachments
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Add all attachments
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->attachment as $attachment) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Check if it is a valid disposition_filter
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Check if it is a valid disposition_filter
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($attachment[6] === $disposition_type) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Check for string attachment
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Check for string attachment
</ins><span class="cx" style="display: block; padding: 0 10px"> $string = '';
</span><span class="cx" style="display: block; padding: 0 10px"> $path = '';
</span><span class="cx" style="display: block; padding: 0 10px"> $bString = $attachment[5];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3116,7 +3167,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> static::$LE
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // RFC1341 part 5 says 7bit is assumed if not specified
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //RFC1341 part 5 says 7bit is assumed if not specified
</ins><span class="cx" style="display: block; padding: 0 10px"> if (static::ENCODING_7BIT !== $encoding) {
</span><span class="cx" style="display: block; padding: 0 10px"> $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, static::$LE);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3126,7 +3177,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $mime[] = 'Content-ID: <' . $this->encodeHeader($this->secureHeader($cid)) . '>' . static::$LE;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Allow for bypassing the Content-Disposition header
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Allow for bypassing the Content-Disposition header
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!empty($disposition)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $encoded_name = $this->encodeHeader($this->secureHeader($name));
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($encoded_name)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3147,7 +3198,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $mime[] = static::$LE;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Encode as string attachment
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Encode as string attachment
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($bString) {
</span><span class="cx" style="display: block; padding: 0 10px"> $mime[] = $this->encodeString($string, $encoding);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3223,7 +3274,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> case static::ENCODING_7BIT:
</span><span class="cx" style="display: block; padding: 0 10px"> case static::ENCODING_8BIT:
</span><span class="cx" style="display: block; padding: 0 10px"> $encoded = static::normalizeBreaks($str);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Make sure it ends with a line break
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Make sure it ends with a line break
</ins><span class="cx" style="display: block; padding: 0 10px"> if (substr($encoded, -(strlen(static::$LE))) !== static::$LE) {
</span><span class="cx" style="display: block; padding: 0 10px"> $encoded .= static::$LE;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3261,7 +3312,7 @@
</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="cx" style="display: block; padding: 0 10px"> if (!preg_match('/[\200-\377]/', $str)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Can't use addslashes as we don't know the value of magic_quotes_sybase
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Can't use addslashes as we don't know the value of magic_quotes_sybase
</ins><span class="cx" style="display: block; padding: 0 10px"> $encoded = addcslashes($str, "\0..\37\177\\\"");
</span><span class="cx" style="display: block; padding: 0 10px"> if (($str === $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
</span><span class="cx" style="display: block; padding: 0 10px"> return $encoded;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3287,7 +3338,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $charset = static::CHARSET_ASCII;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Q/B encoding adds 8 chars and the charset ("` =?<charset>?[QB]?<content>?=`").
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Q/B encoding adds 8 chars and the charset ("` =?<charset>?[QB]?<content>?=`").
</ins><span class="cx" style="display: block; padding: 0 10px"> $overhead = 8 + strlen($charset);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ('mail' === $this->Mailer) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3296,18 +3347,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $maxlen = static::MAX_LINE_LENGTH - $overhead;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Select the encoding that produces the shortest output and/or prevents corruption.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Select the encoding that produces the shortest output and/or prevents corruption.
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($matchcount > strlen($str) / 3) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // More than 1/3 of the content needs encoding, use B-encode.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //More than 1/3 of the content needs encoding, use B-encode.
</ins><span class="cx" style="display: block; padding: 0 10px"> $encoding = 'B';
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ($matchcount > 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Less than 1/3 of the content needs encoding, use Q-encode.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Less than 1/3 of the content needs encoding, use Q-encode.
</ins><span class="cx" style="display: block; padding: 0 10px"> $encoding = 'Q';
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (strlen($str) > $maxlen) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // No encoding needed, but value exceeds max line length, use Q-encode to prevent corruption.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //No encoding needed, but value exceeds max line length, use Q-encode to prevent corruption.
</ins><span class="cx" style="display: block; padding: 0 10px"> $encoding = 'Q';
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // No reformatting needed
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //No reformatting needed
</ins><span class="cx" style="display: block; padding: 0 10px"> $encoding = 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">@@ -3314,8 +3365,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> switch ($encoding) {
</span><span class="cx" style="display: block; padding: 0 10px"> case 'B':
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->hasMultiBytes($str)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Use a custom function which correctly encodes and wraps long
- // multibyte strings without breaking lines within a character
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Use a custom function which correctly encodes and wraps long
+ //multibyte strings without breaking lines within a character
</ins><span class="cx" style="display: block; padding: 0 10px"> $encoded = $this->base64EncodeWrapMB($str, "\n");
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $encoded = base64_encode($str);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3350,7 +3401,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return strlen($str) > mb_strlen($str, $this->CharSet);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Assume no multibytes (we can't handle without mbstring functions anyway)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Assume no multibytes (we can't handle without mbstring functions anyway)
</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">@@ -3388,11 +3439,11 @@
</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"> $mb_length = mb_strlen($str, $this->CharSet);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Each line must have length <= 75, including $start and $end
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Each line must have length <= 75, including $start and $end
</ins><span class="cx" style="display: block; padding: 0 10px"> $length = 75 - strlen($start) - strlen($end);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Average multi-byte ratio
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Average multi-byte ratio
</ins><span class="cx" style="display: block; padding: 0 10px"> $ratio = $mb_length / strlen($str);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Base64 has a 4:3 ratio
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Base64 has a 4:3 ratio
</ins><span class="cx" style="display: block; padding: 0 10px"> $avgLength = floor($length * $ratio * .75);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $offset = 0;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3407,7 +3458,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $encoded .= $chunk . $linebreak;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Chomp the last linefeed
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Chomp the last linefeed
</ins><span class="cx" style="display: block; padding: 0 10px"> return substr($encoded, 0, -strlen($linebreak));
</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">@@ -3436,12 +3487,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function encodeQ($str, $position = 'text')
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // There should not be any EOL in the string
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //There should not be any EOL in the string
</ins><span class="cx" style="display: block; padding: 0 10px"> $pattern = '';
</span><span class="cx" style="display: block; padding: 0 10px"> $encoded = str_replace(["\r", "\n"], '', $str);
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // RFC 2047 section 5.3
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //RFC 2047 section 5.3
</ins><span class="cx" style="display: block; padding: 0 10px"> $pattern = '^A-Za-z0-9!*+\/ -';
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> /*
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3454,15 +3505,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /* Intentional fall through */
</span><span class="cx" style="display: block; padding: 0 10px"> case 'text':
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // RFC 2047 section 5.1
- // Replace every high ascii, control, =, ? and _ characters
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //RFC 2047 section 5.1
+ //Replace every high ascii, control, =, ? and _ characters
</ins><span class="cx" style="display: block; padding: 0 10px"> $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $matches = [];
</span><span class="cx" style="display: block; padding: 0 10px"> if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If the string contains an '=', make sure it's the first thing we replace
- // so as to avoid double-encoding
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If the string contains an '=', make sure it's the first thing we replace
+ //so as to avoid double-encoding
</ins><span class="cx" style="display: block; padding: 0 10px"> $eqkey = array_search('=', $matches[0], true);
</span><span class="cx" style="display: block; padding: 0 10px"> if (false !== $eqkey) {
</span><span class="cx" style="display: block; padding: 0 10px"> unset($matches[0][$eqkey]);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3472,8 +3523,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Replace spaces with _ (more readable than =20)
- // RFC 2047 section 4.2(2)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Replace spaces with _ (more readable than =20)
+ //RFC 2047 section 4.2(2)
</ins><span class="cx" style="display: block; padding: 0 10px"> return str_replace(' ', '_', $encoded);
</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">@@ -3500,7 +3551,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $disposition = 'attachment'
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If a MIME type is not specified, try to work it out from the file name
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If a MIME type is not specified, try to work it out from the file name
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('' === $type) {
</span><span class="cx" style="display: block; padding: 0 10px"> $type = static::filenameToType($filename);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3509,7 +3560,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('encoding') . $encoding);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Append to $attachment array
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Append to $attachment array
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->attachment[] = [
</span><span class="cx" style="display: block; padding: 0 10px"> 0 => $string,
</span><span class="cx" style="display: block; padding: 0 10px"> 1 => $filename,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3516,7 +3567,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 2 => static::mb_pathinfo($filename, PATHINFO_BASENAME),
</span><span class="cx" style="display: block; padding: 0 10px"> 3 => $encoding,
</span><span class="cx" style="display: block; padding: 0 10px"> 4 => $type,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 5 => true, // isStringAttachment
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 5 => true, //isStringAttachment
</ins><span class="cx" style="display: block; padding: 0 10px"> 6 => $disposition,
</span><span class="cx" style="display: block; padding: 0 10px"> 7 => 0,
</span><span class="cx" style="display: block; padding: 0 10px"> ];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3567,7 +3618,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If a MIME type is not specified, try to work it out from the file name
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If a MIME type is not specified, try to work it out from the file name
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('' === $type) {
</span><span class="cx" style="display: block; padding: 0 10px"> $type = static::filenameToType($path);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3581,7 +3632,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $name = $filename;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Append to $attachment array
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Append to $attachment array
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->attachment[] = [
</span><span class="cx" style="display: block; padding: 0 10px"> 0 => $path,
</span><span class="cx" style="display: block; padding: 0 10px"> 1 => $filename,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3588,7 +3639,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 2 => $name,
</span><span class="cx" style="display: block; padding: 0 10px"> 3 => $encoding,
</span><span class="cx" style="display: block; padding: 0 10px"> 4 => $type,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 5 => false, // isStringAttachment
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 5 => false, //isStringAttachment
</ins><span class="cx" style="display: block; padding: 0 10px"> 6 => $disposition,
</span><span class="cx" style="display: block; padding: 0 10px"> 7 => $cid,
</span><span class="cx" style="display: block; padding: 0 10px"> ];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3633,7 +3684,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $disposition = 'inline'
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If a MIME type is not specified, try to work it out from the name
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If a MIME type is not specified, try to work it out from the name
</ins><span class="cx" style="display: block; padding: 0 10px"> if ('' === $type && !empty($name)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $type = static::filenameToType($name);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3642,7 +3693,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> throw new Exception($this->lang('encoding') . $encoding);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Append to $attachment array
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Append to $attachment array
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->attachment[] = [
</span><span class="cx" style="display: block; padding: 0 10px"> 0 => $string,
</span><span class="cx" style="display: block; padding: 0 10px"> 1 => $name,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3649,7 +3700,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 2 => $name,
</span><span class="cx" style="display: block; padding: 0 10px"> 3 => $encoding,
</span><span class="cx" style="display: block; padding: 0 10px"> 4 => $type,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 5 => true, // isStringAttachment
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 5 => true, //isStringAttachment
</ins><span class="cx" style="display: block; padding: 0 10px"> 6 => $disposition,
</span><span class="cx" style="display: block; padding: 0 10px"> 7 => $cid,
</span><span class="cx" style="display: block; padding: 0 10px"> ];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3869,8 +3920,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public static function rfcDate()
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Set the time zone to whatever the default is to avoid 500 errors
- // Will default to UTC if it's not set properly in php.ini
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Set the time zone to whatever the default is to avoid 500 errors
+ //Will default to UTC if it's not set properly in php.ini
</ins><span class="cx" style="display: block; padding: 0 10px"> date_default_timezone_set(@date_default_timezone_get());
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return date('D, j M Y H:i:s O');
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3948,13 +3999,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> protected function lang($key)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> if (count($this->language) < 1) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->setLanguage(); // set the default language
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->setLanguage(); //Set the default language
</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"> if (array_key_exists($key, $this->language)) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ('smtp_connect_failed' === $key) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- //Include a link to troubleshooting docs on SMTP connection failure
- //this is by far the biggest cause of support questions
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Include a link to troubleshooting docs on SMTP connection failure.
+ //This is by far the biggest cause of support questions
</ins><span class="cx" style="display: block; padding: 0 10px"> //but it's usually not PHPMailer's fault.
</span><span class="cx" style="display: block; padding: 0 10px"> return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3989,7 +4040,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> public function addCustomHeader($name, $value = null)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> if (null === $value && strpos($name, ':') !== false) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Value passed in as name:value
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Value passed in as name:value
</ins><span class="cx" style="display: block; padding: 0 10px"> list($name, $value) = explode(':', $name, 2);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $name = trim($name);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4043,11 +4094,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> preg_match_all('/(?<!-)(src|background)=["\'](.*)["\']/Ui', $message, $images);
</span><span class="cx" style="display: block; padding: 0 10px"> if (array_key_exists(2, $images)) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (strlen($basedir) > 1 && '/' !== substr($basedir, -1)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Ensure $basedir has a trailing /
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Ensure $basedir has a trailing /
</ins><span class="cx" style="display: block; padding: 0 10px"> $basedir .= '/';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($images[2] as $imgindex => $url) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Convert data URIs into embedded images
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Convert data URIs into embedded images
</ins><span class="cx" style="display: block; padding: 0 10px"> //e.g. "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
</span><span class="cx" style="display: block; padding: 0 10px"> $match = [];
</span><span class="cx" style="display: block; padding: 0 10px"> if (preg_match('#^data:(image/(?:jpe?g|gif|png));?(base64)?,(.+)#', $url, $match)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4061,7 +4112,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> //Hash the decoded data, not the URL, so that the same data-URI image used in multiple places
</span><span class="cx" style="display: block; padding: 0 10px"> //will only be embedded once, even if it used a different encoding
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cid = substr(hash('sha256', $data), 0, 32) . '@phpmailer.0'; // RFC2392 S 2
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $cid = substr(hash('sha256', $data), 0, 32) . '@phpmailer.0'; //RFC2392 S 2
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->cidExists($cid)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->addStringEmbeddedImage(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4080,13 +4131,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> continue;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Only process relative URLs if a basedir is provided (i.e. no absolute local paths)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Only process relative URLs if a basedir is provided (i.e. no absolute local paths)
</ins><span class="cx" style="display: block; padding: 0 10px"> !empty($basedir)
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Ignore URLs containing parent dir traversal (..)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Ignore URLs containing parent dir traversal (..)
</ins><span class="cx" style="display: block; padding: 0 10px"> && (strpos($url, '..') === false)
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Do not change urls that are already inline images
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Do not change urls that are already inline images
</ins><span class="cx" style="display: block; padding: 0 10px"> && 0 !== strpos($url, 'cid:')
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Do not change absolute URLs, including anonymous protocol
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Do not change absolute URLs, including anonymous protocol
</ins><span class="cx" style="display: block; padding: 0 10px"> && !preg_match('#^[a-z][a-z0-9+.-]*:?//#i', $url)
</span><span class="cx" style="display: block; padding: 0 10px"> ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $filename = static::mb_pathinfo($url, PATHINFO_BASENAME);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4094,7 +4145,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ('.' === $directory) {
</span><span class="cx" style="display: block; padding: 0 10px"> $directory = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // RFC2392 S 2
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //RFC2392 S 2
</ins><span class="cx" style="display: block; padding: 0 10px"> $cid = substr(hash('sha256', $url), 0, 32) . '@phpmailer.0';
</span><span class="cx" style="display: block; padding: 0 10px"> if (strlen($basedir) > 1 && '/' !== substr($basedir, -1)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $basedir .= '/';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4121,7 +4172,7 @@
</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"> $this->isHTML();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Convert all message body line breaks to LE, makes quoted-printable encoding work much better
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Convert all message body line breaks to LE, makes quoted-printable encoding work much better
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->Body = static::normalizeBreaks($message);
</span><span class="cx" style="display: block; padding: 0 10px"> $this->AltBody = static::normalizeBreaks($this->html2text($message, $advanced));
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->alternativeExists()) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4140,9 +4191,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Example usage:
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * ```php
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * // Use default conversion
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * //Use default conversion
</ins><span class="cx" style="display: block; padding: 0 10px"> * $plain = $mail->html2text($html);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * // Use your own custom converter
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * //Use your own custom converter
</ins><span class="cx" style="display: block; padding: 0 10px"> * $plain = $mail->html2text($html, function($html) {
</span><span class="cx" style="display: block; padding: 0 10px"> * $converter = new MyHtml2text($html);
</span><span class="cx" style="display: block; padding: 0 10px"> * return $converter->get_text();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4309,7 +4360,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public static function filenameToType($filename)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // In case the path is a URL, strip any query string before getting extension
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //In case the path is a URL, strip any query string before getting extension
</ins><span class="cx" style="display: block; padding: 0 10px"> $qpos = strpos($filename, '?');
</span><span class="cx" style="display: block; padding: 0 10px"> if (false !== $qpos) {
</span><span class="cx" style="display: block; padding: 0 10px"> $filename = substr($filename, 0, $qpos);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4420,9 +4471,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (null === $breaktype) {
</span><span class="cx" style="display: block; padding: 0 10px"> $breaktype = static::$LE;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Normalise to \n
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Normalise to \n
</ins><span class="cx" style="display: block; padding: 0 10px"> $text = str_replace([self::CRLF, "\r"], "\n", $text);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Now convert LE as needed
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Now convert LE as needed
</ins><span class="cx" style="display: block; padding: 0 10px"> if ("\n" !== $breaktype) {
</span><span class="cx" style="display: block; padding: 0 10px"> $text = str_replace("\n", $breaktype, $text);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4528,13 +4579,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $privKey = openssl_pkey_get_private($privKeyStr);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (PHP_MAJOR_VERSION < 8) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (\PHP_MAJOR_VERSION < 8) {
</ins><span class="cx" style="display: block; padding: 0 10px"> openssl_pkey_free($privKey);
</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"> return base64_encode($signature);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (PHP_MAJOR_VERSION < 8) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (\PHP_MAJOR_VERSION < 8) {
</ins><span class="cx" style="display: block; padding: 0 10px"> openssl_pkey_free($privKey);
</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">@@ -4601,7 +4652,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($body)) {
</span><span class="cx" style="display: block; padding: 0 10px"> return self::CRLF;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Normalize line endings to CRLF
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Normalize line endings to CRLF
</ins><span class="cx" style="display: block; padding: 0 10px"> $body = static::normalizeBreaks($body, self::CRLF);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Reduce multiple trailing line breaks to a single one
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4621,9 +4672,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function DKIM_Add($headers_line, $subject, $body)
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $DKIMsignatureType = 'rsa-sha256'; // Signature & hash algorithms
- $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization methods of header & body
- $DKIMquery = 'dns/txt'; // Query method
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $DKIMsignatureType = 'rsa-sha256'; //Signature & hash algorithms
+ $DKIMcanonicalization = 'relaxed/simple'; //Canonicalization methods of header & body
+ $DKIMquery = 'dns/txt'; //Query method
</ins><span class="cx" style="display: block; padding: 0 10px"> $DKIMtime = time();
</span><span class="cx" style="display: block; padding: 0 10px"> //Always sign these headers without being asked
</span><span class="cx" style="display: block; padding: 0 10px"> //Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4724,7 +4775,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $headerKeys = ' h=' . implode(':', $headersToSignKeys) . ';' . static::$LE;
</span><span class="cx" style="display: block; padding: 0 10px"> $headerValues = implode(static::$LE, $headersToSign);
</span><span class="cx" style="display: block; padding: 0 10px"> $body = $this->DKIM_BodyC($body);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Base64 of packed binary SHA-256 hash of body
+ $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body)));
</ins><span class="cx" style="display: block; padding: 0 10px"> $ident = '';
</span><span class="cx" style="display: block; padding: 0 10px"> if ('' !== $this->DKIM_identity) {
</span><span class="cx" style="display: block; padding: 0 10px"> $ident = ' i=' . $this->DKIM_identity . ';' . static::$LE;
</span></span></pre></div>
<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 2021-02-20 17:43:55 UTC (rev 50396)
+++ trunk/src/wp-includes/PHPMailer/SMTP.php 2021-02-21 09:32:41 UTC (rev 50397)
</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.2.0';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const VERSION = '6.3.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">@@ -312,11 +312,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function connect($host, $port = null, $timeout = 30, $options = [])
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Clear errors to avoid confusion
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Clear errors to avoid confusion
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->setError('');
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Make sure we are __not__ connected
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Make sure we are __not__ connected
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->connected()) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Already connected, generate error
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Already connected, generate error
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->setError('Already connected to a server');
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -324,7 +324,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($port)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $port = self::DEFAULT_PORT;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Connect to the SMTP server
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Connect to the SMTP server
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->edebug(
</span><span class="cx" style="display: block; padding: 0 10px"> "Connection: opening to $host:$port, timeout=$timeout, options=" .
</span><span class="cx" style="display: block; padding: 0 10px"> (count($options) > 0 ? var_export($options, true) : 'array()'),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -340,11 +340,23 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Get any announcement
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Get any announcement
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->last_reply = $this->get_lines();
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- return true;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $responseCode = (int)substr($this->last_reply, 0, 3);
+ if ($responseCode === 220) {
+ return true;
+ }
+ //Anything other than a 220 response means something went wrong
+ //RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error
+ //https://tools.ietf.org/html/rfc5321#section-3.1
+ if ($responseCode === 554) {
+ $this->quit();
+ }
+ //This will handle 421 responses which may not wait for a QUIT (e.g. if the server is being shut down)
+ $this->edebug('Connection: closing due to error', self::DEBUG_CONNECTION);
+ $this->close();
+ return false;
</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"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -397,7 +409,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> restore_error_handler();
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Verify we connected properly
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Verify we connected properly
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!is_resource($connection)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->setError(
</span><span class="cx" style="display: block; padding: 0 10px"> 'Failed to connect to server',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -414,11 +426,11 @@
</span><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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // SMTP server can take longer to respond, give longer timeout for first read
- // Windows does not have support for this timeout function
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //SMTP server can take longer to respond, give longer timeout for first read
+ //Windows does not have support for this timeout function
</ins><span class="cx" style="display: block; padding: 0 10px"> if (strpos(PHP_OS, 'WIN') !== 0) {
</span><span class="cx" style="display: block; padding: 0 10px"> $max = (int)ini_get('max_execution_time');
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Don't bother if unlimited, or if set_time_limit is disabled
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Don't bother if unlimited, or if set_time_limit is disabled
</ins><span class="cx" style="display: block; padding: 0 10px"> if (0 !== $max && $timeout > $max && strpos(ini_get('disable_functions'), 'set_time_limit') === false) {
</span><span class="cx" style="display: block; padding: 0 10px"> @set_time_limit($timeout);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -449,7 +461,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Begin encrypted connection
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Begin encrypted connection
</ins><span class="cx" style="display: block; padding: 0 10px"> set_error_handler([$this, 'errorHandler']);
</span><span class="cx" style="display: block; padding: 0 10px"> $crypto_ok = stream_socket_enable_crypto(
</span><span class="cx" style="display: block; padding: 0 10px"> $this->smtp_conn,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -487,11 +499,11 @@
</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"> if (array_key_exists('EHLO', $this->server_caps)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // SMTP extensions are available; try to find a proper authentication method
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //SMTP extensions are available; try to find a proper authentication method
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!array_key_exists('AUTH', $this->server_caps)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->setError('Authentication is not allowed at this stage');
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // 'at this stage' means that auth may be allowed after the stage changes
- // e.g. after STARTTLS
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //'at this stage' means that auth may be allowed after the stage changes
+ //e.g. after STARTTLS
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -535,11 +547,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> switch ($authtype) {
</span><span class="cx" style="display: block; padding: 0 10px"> case 'PLAIN':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Start authentication
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Start authentication
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Send encoded username and password
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Send encoded username and password
</ins><span class="cx" style="display: block; padding: 0 10px"> if (
</span><span class="cx" style="display: block; padding: 0 10px"> !$this->sendCommand(
</span><span class="cx" style="display: block; padding: 0 10px"> 'User & Password',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -551,7 +563,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> case 'LOGIN':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Start authentication
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Start authentication
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -563,17 +575,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> case 'CRAM-MD5':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Start authentication
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Start authentication
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Get the challenge
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Get the challenge
</ins><span class="cx" style="display: block; padding: 0 10px"> $challenge = base64_decode(substr($this->last_reply, 4));
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Build the response
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Build the response
</ins><span class="cx" style="display: block; padding: 0 10px"> $response = $username . ' ' . $this->hmac($challenge, $password);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // send encoded credentials
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //send encoded credentials
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->sendCommand('Username', base64_encode($response), 235);
</span><span class="cx" style="display: block; padding: 0 10px"> case 'XOAUTH2':
</span><span class="cx" style="display: block; padding: 0 10px"> //The OAuth instance must be set up prior to requesting auth.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -582,7 +594,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $oauth = $OAuth->getOauth64();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Start authentication
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Start authentication
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -612,15 +624,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return hash_hmac('md5', $data, $key);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // The following borrowed from
- // http://php.net/manual/en/function.mhash.php#27225
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //The following borrowed from
+ //http://php.net/manual/en/function.mhash.php#27225
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // RFC 2104 HMAC implementation for php.
- // Creates an md5 HMAC.
- // Eliminates the need to install mhash to compute a HMAC
- // by Lance Rushing
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //RFC 2104 HMAC implementation for php.
+ //Creates an md5 HMAC.
+ //Eliminates the need to install mhash to compute a HMAC
+ //by Lance Rushing
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $bytelen = 64; // byte length for md5
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $bytelen = 64; //byte length for md5
</ins><span class="cx" style="display: block; padding: 0 10px"> if (strlen($key) > $bytelen) {
</span><span class="cx" style="display: block; padding: 0 10px"> $key = pack('H*', md5($key));
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -643,7 +655,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (is_resource($this->smtp_conn)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $sock_status = stream_get_meta_data($this->smtp_conn);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($sock_status['eof']) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // The socket is valid but we are not connected
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //The socket is valid but we are not connected
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->edebug(
</span><span class="cx" style="display: block; padding: 0 10px"> 'SMTP NOTICE: EOF caught while checking if connected',
</span><span class="cx" style="display: block; padding: 0 10px"> self::DEBUG_CLIENT
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -653,7 +665,7 @@
</span><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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return true; // everything looks good
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return true; //everything looks good
</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 false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -671,7 +683,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->server_caps = null;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->helo_rply = null;
</span><span class="cx" style="display: block; padding: 0 10px"> if (is_resource($this->smtp_conn)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // close the connection and cleanup
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Close the connection and cleanup
</ins><span class="cx" style="display: block; padding: 0 10px"> fclose($this->smtp_conn);
</span><span class="cx" style="display: block; padding: 0 10px"> $this->smtp_conn = null; //Makes for cleaner serialization
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -706,7 +718,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * NOTE: this does not count towards line-length limit.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Normalize line breaks before exploding
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Normalize line breaks before exploding
</ins><span class="cx" style="display: block; padding: 0 10px"> $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data));
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -752,7 +764,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //Send the lines to the server
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($lines_out as $line_out) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- //RFC2821 section 4.5.2
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Dot-stuffing as per RFC5321 section 4.5.2
+ //https://tools.ietf.org/html/rfc5321#section-4.5.2
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!empty($line_out) && $line_out[0] === '.') {
</span><span class="cx" style="display: block; padding: 0 10px"> $line_out = '.' . $line_out;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -786,7 +799,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> public function hello($host = '')
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><span class="cx" style="display: block; padding: 0 10px"> //Try extended hello first (RFC 2821)
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($this->sendHello('EHLO', $host)) {
+ return true;
+ }
+
+ //Some servers shut down the SMTP service here (RFC 5321)
+ if (substr($this->helo_rply, 0, 3) == '421') {
+ return false;
+ }
+
+ return $this->sendHello('HELO', $host);
</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"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -976,12 +998,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->client_send($commandstring . static::LE, $command);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $this->last_reply = $this->get_lines();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Fetch SMTP code and possible error code explanation
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Fetch SMTP code and possible error code explanation
</ins><span class="cx" style="display: block; padding: 0 10px"> $matches = [];
</span><span class="cx" style="display: block; padding: 0 10px"> if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $code = (int) $matches[1];
</span><span class="cx" style="display: block; padding: 0 10px"> $code_ex = (count($matches) > 2 ? $matches[2] : null);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Cut off error code from each response line
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Cut off error code from each response line
</ins><span class="cx" style="display: block; padding: 0 10px"> $detail = preg_replace(
</span><span class="cx" style="display: block; padding: 0 10px"> "/{$code}[ -]" .
</span><span class="cx" style="display: block; padding: 0 10px"> ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . '/m',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -989,7 +1011,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->last_reply
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Fall back to simple parsing if regex fails
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Fall back to simple parsing if regex fails
</ins><span class="cx" style="display: block; padding: 0 10px"> $code = (int) substr($this->last_reply, 0, 3);
</span><span class="cx" style="display: block; padding: 0 10px"> $code_ex = null;
</span><span class="cx" style="display: block; padding: 0 10px"> $detail = substr($this->last_reply, 4);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1184,7 +1206,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> protected function get_lines()
</span><span class="cx" style="display: block; padding: 0 10px"> {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If the connection is bad, give up straight away
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If the connection is bad, give up straight away
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!is_resource($this->smtp_conn)) {
</span><span class="cx" style="display: block; padding: 0 10px"> return '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1237,13 +1259,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH);
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL);
</span><span class="cx" style="display: block; padding: 0 10px"> $data .= $str;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
- // or 4th character is a space or a line break char, we are done reading, break the loop.
- // String array access is a significant micro-optimisation over strlen
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
+ //or 4th character is a space or a line break char, we are done reading, break the loop.
+ //String array access is a significant micro-optimisation over strlen
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") {
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Timed-out? Log and break
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Timed-out? Log and break
</ins><span class="cx" style="display: block; padding: 0 10px"> $info = stream_get_meta_data($this->smtp_conn);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['timed_out']) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1252,7 +1274,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Now check if reads took too long
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //Now check if reads took too long
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($endtime && time() > $endtime) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->edebug(
</span><span class="cx" style="display: block; padding: 0 10px"> 'SMTP -> get_lines(): timelimit reached (' .
</span></span></pre>
</div>
</div>
</body>
</html>