|
|
@@ -350,8 +350,8 @@ class PHPMailer
|
|
|
public $Password = '';
|
|
|
|
|
|
/**
|
|
|
- * SMTP auth type.
|
|
|
- * Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2, attempted in that order if not specified.
|
|
|
+ * SMTP authentication type. Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2.
|
|
|
+ * If not specified, the first one from that list that the server supports will be selected.
|
|
|
*
|
|
|
* @var string
|
|
|
*/
|
|
|
@@ -750,7 +750,7 @@ class PHPMailer
|
|
|
*
|
|
|
* @var string
|
|
|
*/
|
|
|
- const VERSION = '6.6.0';
|
|
|
+ const VERSION = '6.8.0';
|
|
|
|
|
|
/**
|
|
|
* Error severity: message only, continue processing.
|
|
|
@@ -858,7 +858,7 @@ class PHPMailer
|
|
|
private function mailPassthru($to, $subject, $body, $header, $params)
|
|
|
{
|
|
|
//Check overloading of mail function to avoid double-encoding
|
|
|
- if (ini_get('mbstring.func_overload') & 1) {
|
|
|
+ if ((int)ini_get('mbstring.func_overload') & 1) {
|
|
|
$subject = $this->secureHeader($subject);
|
|
|
} else {
|
|
|
$subject = $this->encodeHeader($this->secureHeader($subject));
|
|
|
@@ -1066,8 +1066,8 @@ class PHPMailer
|
|
|
* Addresses that have been added already return false, but do not throw exceptions.
|
|
|
*
|
|
|
* @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
|
|
|
- * @param string $address The email address to send, resp. to reply to
|
|
|
- * @param string $name
|
|
|
+ * @param string $address The email address
|
|
|
+ * @param string $name An optional username associated with the address
|
|
|
*
|
|
|
* @throws Exception
|
|
|
*
|
|
|
@@ -1075,9 +1075,11 @@ class PHPMailer
|
|
|
*/
|
|
|
protected function addOrEnqueueAnAddress($kind, $address, $name)
|
|
|
{
|
|
|
- $address = trim($address);
|
|
|
- $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
|
|
|
- $pos = strrpos($address, '@');
|
|
|
+ $pos = false;
|
|
|
+ if ($address !== null) {
|
|
|
+ $address = trim($address);
|
|
|
+ $pos = strrpos($address, '@');
|
|
|
+ }
|
|
|
if (false === $pos) {
|
|
|
//At-sign is missing.
|
|
|
$error_message = sprintf(
|
|
|
@@ -1094,8 +1096,14 @@ class PHPMailer
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
+ if ($name !== null && is_string($name)) {
|
|
|
+ $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
|
|
|
+ } else {
|
|
|
+ $name = '';
|
|
|
+ }
|
|
|
$params = [$kind, $address, $name];
|
|
|
//Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
|
|
|
+ //Domain is assumed to be whatever is after the last @ symbol in the address
|
|
|
if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) {
|
|
|
if ('Reply-To' !== $kind) {
|
|
|
if (!array_key_exists($address, $this->RecipientsQueue)) {
|
|
|
@@ -1116,6 +1124,22 @@ class PHPMailer
|
|
|
return call_user_func_array([$this, 'addAnAddress'], $params);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Set the boundaries to use for delimiting MIME parts.
|
|
|
+ * If you override this, ensure you set all 3 boundaries to unique values.
|
|
|
+ * The default boundaries include a "=_" sequence which cannot occur in quoted-printable bodies,
|
|
|
+ * as suggested by https://www.rfc-editor.org/rfc/rfc2045#section-6.7
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function setBoundaries()
|
|
|
+ {
|
|
|
+ $this->uniqueid = $this->generateId();
|
|
|
+ $this->boundary[1] = 'b1=_' . $this->uniqueid;
|
|
|
+ $this->boundary[2] = 'b2=_' . $this->uniqueid;
|
|
|
+ $this->boundary[3] = 'b3=_' . $this->uniqueid;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Add an address to one of the recipient arrays or to the ReplyTo array.
|
|
|
* Addresses that have been added already return false, but do not throw exceptions.
|
|
|
@@ -1280,7 +1304,7 @@ class PHPMailer
|
|
|
*/
|
|
|
public function setFrom($address, $name = '', $auto = true)
|
|
|
{
|
|
|
- $address = trim($address);
|
|
|
+ $address = trim((string)$address);
|
|
|
$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
|
|
|
//Don't validate now addresses with IDN. Will be done in send().
|
|
|
$pos = strrpos($address, '@');
|
|
|
@@ -1547,17 +1571,17 @@ class PHPMailer
|
|
|
|
|
|
//Validate From, Sender, and ConfirmReadingTo addresses
|
|
|
foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
|
|
|
- $this->$address_kind = trim($this->$address_kind);
|
|
|
- if (empty($this->$address_kind)) {
|
|
|
+ $this->{$address_kind} = trim($this->{$address_kind});
|
|
|
+ if (empty($this->{$address_kind})) {
|
|
|
continue;
|
|
|
}
|
|
|
- $this->$address_kind = $this->punyencodeAddress($this->$address_kind);
|
|
|
- if (!static::validateAddress($this->$address_kind)) {
|
|
|
+ $this->{$address_kind} = $this->punyencodeAddress($this->{$address_kind});
|
|
|
+ if (!static::validateAddress($this->{$address_kind})) {
|
|
|
$error_message = sprintf(
|
|
|
'%s (%s): %s',
|
|
|
$this->lang('invalid_address'),
|
|
|
$address_kind,
|
|
|
- $this->$address_kind
|
|
|
+ $this->{$address_kind}
|
|
|
);
|
|
|
$this->setError($error_message);
|
|
|
$this->edebug($error_message);
|
|
|
@@ -1657,17 +1681,17 @@ class PHPMailer
|
|
|
default:
|
|
|
$sendMethod = $this->Mailer . 'Send';
|
|
|
if (method_exists($this, $sendMethod)) {
|
|
|
- return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
|
|
|
+ return $this->{$sendMethod}($this->MIMEHeader, $this->MIMEBody);
|
|
|
}
|
|
|
|
|
|
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
|
|
|
}
|
|
|
} catch (Exception $exc) {
|
|
|
- if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true) {
|
|
|
- $this->smtp->reset();
|
|
|
- }
|
|
|
$this->setError($exc->getMessage());
|
|
|
$this->edebug($exc->getMessage());
|
|
|
+ if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) {
|
|
|
+ $this->smtp->reset();
|
|
|
+ }
|
|
|
if ($this->exceptions) {
|
|
|
throw $exc;
|
|
|
}
|
|
|
@@ -1855,7 +1879,7 @@ class PHPMailer
|
|
|
if (!static::isPermittedPath($path)) {
|
|
|
return false;
|
|
|
}
|
|
|
- $readable = file_exists($path);
|
|
|
+ $readable = is_file($path);
|
|
|
//If not a UNC path (expected to start with \\), check read permission, see #2069
|
|
|
if (strpos($path, '\\\\') !== 0) {
|
|
|
$readable = $readable && is_readable($path);
|
|
|
@@ -1883,7 +1907,14 @@ class PHPMailer
|
|
|
foreach ($this->to as $toaddr) {
|
|
|
$toArr[] = $this->addrFormat($toaddr);
|
|
|
}
|
|
|
- $to = implode(', ', $toArr);
|
|
|
+ $to = trim(implode(', ', $toArr));
|
|
|
+
|
|
|
+ //If there are no To-addresses (e.g. when sending only to BCC-addresses)
|
|
|
+ //the following should be added to get a correct DKIM-signature.
|
|
|
+ //Compare with $this->preSend()
|
|
|
+ if ($to === '') {
|
|
|
+ $to = 'undisclosed-recipients:;';
|
|
|
+ }
|
|
|
|
|
|
$params = null;
|
|
|
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
|
|
|
@@ -2086,6 +2117,9 @@ class PHPMailer
|
|
|
$this->smtp->setDebugLevel($this->SMTPDebug);
|
|
|
$this->smtp->setDebugOutput($this->Debugoutput);
|
|
|
$this->smtp->setVerp($this->do_verp);
|
|
|
+ if ($this->Host === null) {
|
|
|
+ $this->Host = 'localhost';
|
|
|
+ }
|
|
|
$hosts = explode(';', $this->Host);
|
|
|
$lastexception = null;
|
|
|
|
|
|
@@ -2192,7 +2226,8 @@ class PHPMailer
|
|
|
//As we've caught all exceptions, just report whatever the last one was
|
|
|
if ($this->exceptions && null !== $lastexception) {
|
|
|
throw $lastexception;
|
|
|
- } elseif ($this->exceptions) {
|
|
|
+ }
|
|
|
+ if ($this->exceptions) {
|
|
|
// no exception was thrown, likely $this->smtp->connect() failed
|
|
|
$message = $this->getSmtpErrorMessage('connect_host');
|
|
|
throw new Exception($message);
|
|
|
@@ -2388,7 +2423,7 @@ class PHPMailer
|
|
|
*/
|
|
|
public function addrFormat($addr)
|
|
|
{
|
|
|
- if (empty($addr[1])) { //No name provided
|
|
|
+ if (!isset($addr[1]) || ($addr[1] === '')) { //No name provided
|
|
|
return $this->secureHeader($addr[0]);
|
|
|
}
|
|
|
|
|
|
@@ -2775,10 +2810,7 @@ class PHPMailer
|
|
|
{
|
|
|
$body = '';
|
|
|
//Create unique IDs and preset boundaries
|
|
|
- $this->uniqueid = $this->generateId();
|
|
|
- $this->boundary[1] = 'b1_' . $this->uniqueid;
|
|
|
- $this->boundary[2] = 'b2_' . $this->uniqueid;
|
|
|
- $this->boundary[3] = 'b3_' . $this->uniqueid;
|
|
|
+ $this->setBoundaries();
|
|
|
|
|
|
if ($this->sign_key_file) {
|
|
|
$body .= $this->getMailMIME() . static::$LE;
|
|
|
@@ -2814,7 +2846,7 @@ class PHPMailer
|
|
|
$altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
|
|
|
}
|
|
|
//Use this as a preamble in all multipart message types
|
|
|
- $mimepre = 'This is a multi-part message in MIME format.' . static::$LE . static::$LE;
|
|
|
+ $mimepre = '';
|
|
|
switch ($this->message_type) {
|
|
|
case 'inline':
|
|
|
$body .= $mimepre;
|
|
|
@@ -3050,6 +3082,18 @@ class PHPMailer
|
|
|
return $body;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Get the boundaries that this message will use
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public function getBoundaries()
|
|
|
+ {
|
|
|
+ if (empty($this->boundary)) {
|
|
|
+ $this->setBoundaries();
|
|
|
+ }
|
|
|
+ return $this->boundary;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Return the start of a message boundary.
|
|
|
*
|
|
|
@@ -3705,20 +3749,21 @@ class PHPMailer
|
|
|
* These differ from 'regular' attachments in that they are intended to be
|
|
|
* displayed inline with the message, not just attached for download.
|
|
|
* This is used in HTML messages that embed the images
|
|
|
- * the HTML refers to using the $cid value.
|
|
|
+ * the HTML refers to using the `$cid` value in `img` tags, for example `<img src="cid:mylogo">`.
|
|
|
* Never use a user-supplied path to a file!
|
|
|
*
|
|
|
* @param string $path Path to the attachment
|
|
|
* @param string $cid Content ID of the attachment; Use this to reference
|
|
|
* the content when using an embedded image in HTML
|
|
|
- * @param string $name Overrides the attachment name
|
|
|
- * @param string $encoding File encoding (see $Encoding)
|
|
|
- * @param string $type File MIME type
|
|
|
- * @param string $disposition Disposition to use
|
|
|
+ * @param string $name Overrides the attachment filename
|
|
|
+ * @param string $encoding File encoding (see $Encoding) defaults to `base64`
|
|
|
+ * @param string $type File MIME type (by default mapped from the `$path` filename's extension)
|
|
|
+ * @param string $disposition Disposition to use: `inline` (default) or `attachment`
|
|
|
+ * (unlikely you want this – {@see `addAttachment()`} instead)
|
|
|
*
|
|
|
+ * @return bool True on successfully adding an attachment
|
|
|
* @throws Exception
|
|
|
*
|
|
|
- * @return bool True on successfully adding an attachment
|
|
|
*/
|
|
|
public function addEmbeddedImage(
|
|
|
$path,
|
|
|
@@ -4096,12 +4141,8 @@ class PHPMailer
|
|
|
//Is it a valid IPv4 address?
|
|
|
return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
|
|
|
}
|
|
|
- if (filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false) {
|
|
|
- //Is it a syntactically valid hostname?
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
+ //Is it a syntactically valid hostname (when embeded in a URL)?
|
|
|
+ return filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -4170,6 +4211,7 @@ class PHPMailer
|
|
|
* @param string $name Custom header name
|
|
|
* @param string|null $value Header value
|
|
|
*
|
|
|
+ * @return bool True if a header was set successfully
|
|
|
* @throws Exception
|
|
|
*/
|
|
|
public function addCustomHeader($name, $value = null)
|
|
|
@@ -4464,6 +4506,7 @@ class PHPMailer
|
|
|
'ics' => 'text/calendar',
|
|
|
'xml' => 'text/xml',
|
|
|
'xsl' => 'text/xml',
|
|
|
+ 'csv' => 'text/csv',
|
|
|
'wmv' => 'video/x-ms-wmv',
|
|
|
'mpeg' => 'video/mpeg',
|
|
|
'mpe' => 'video/mpeg',
|
|
|
@@ -4571,7 +4614,7 @@ class PHPMailer
|
|
|
public function set($name, $value = '')
|
|
|
{
|
|
|
if (property_exists($this, $name)) {
|
|
|
- $this->$name = $value;
|
|
|
+ $this->{$name} = $value;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
@@ -4618,17 +4661,29 @@ class PHPMailer
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Remove trailing breaks from a string.
|
|
|
+ * Remove trailing whitespace from a string.
|
|
|
*
|
|
|
* @param string $text
|
|
|
*
|
|
|
- * @return string The text to remove breaks from
|
|
|
+ * @return string The text to remove whitespace from
|
|
|
*/
|
|
|
public static function stripTrailingWSP($text)
|
|
|
{
|
|
|
return rtrim($text, " \r\n\t");
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Strip trailing line breaks from a string.
|
|
|
+ *
|
|
|
+ * @param string $text
|
|
|
+ *
|
|
|
+ * @return string The text to remove breaks from
|
|
|
+ */
|
|
|
+ public static function stripTrailingBreaks($text)
|
|
|
+ {
|
|
|
+ return rtrim($text, "\r\n");
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Return the current line break format string.
|
|
|
*
|
|
|
@@ -4792,7 +4847,7 @@ class PHPMailer
|
|
|
$body = static::normalizeBreaks($body, self::CRLF);
|
|
|
|
|
|
//Reduce multiple trailing line breaks to a single one
|
|
|
- return static::stripTrailingWSP($body) . self::CRLF;
|
|
|
+ return static::stripTrailingBreaks($body) . self::CRLF;
|
|
|
}
|
|
|
|
|
|
/**
|