Compare commits
25 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
ebf1655bd5 | |
|
|
b938991866 | |
|
|
7e3f24386f | |
|
|
1a0004b51b | |
|
|
a969e57c06 | |
|
|
28caa24930 | |
|
|
5f710689e5 | |
|
|
827e170f50 | |
|
|
0d4c5ee8da | |
|
|
14e1efe293 | |
|
|
dca8e03946 | |
|
|
84097ce614 | |
|
|
7ff3620f50 | |
|
|
85df414ab4 | |
|
|
d04efe78e1 | |
|
|
2b240b44e9 | |
|
|
4c06f874c9 | |
|
|
4e8292f43c | |
|
|
8d27fb6b7c | |
|
|
34b209f864 | |
|
|
31e3d491aa | |
|
|
96d82b913a | |
|
|
8ff00047a8 | |
|
|
a767d446c2 | |
|
|
b6729d7bd2 |
|
|
@ -8,7 +8,8 @@ updates:
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "cron"
|
||||||
|
cronjob: "10 22 5,20 * *" # At 22:10, every 5th and 20th day of the month.
|
||||||
open-pull-requests-limit: 5
|
open-pull-requests-limit: 5
|
||||||
commit-message:
|
commit-message:
|
||||||
prefix: "GH Actions:"
|
prefix: "GH Actions:"
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@ jobs:
|
||||||
if: github.repository == 'PHPMailer/PHPMailer'
|
if: github.repository == 'PHPMailer/PHPMailer'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Build Docs
|
- name: Build Docs
|
||||||
uses: ./.github/actions/build-docs
|
uses: ./.github/actions/build-docs
|
||||||
- name: Publish Docs to gh-pages
|
- name: Publish Docs to gh-pages
|
||||||
uses: JamesIves/github-pages-deploy-action@4a3abc783e1a24aeb44c16e869ad83caf6b4cc23 # v4.7.4
|
uses: JamesIves/github-pages-deploy-action@9d877eea73427180ae43cf98e8914934fe157a1a # v4.7.6
|
||||||
with:
|
with:
|
||||||
branch: gh-pages
|
branch: gh-pages
|
||||||
folder: docs
|
folder: docs
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ jobs:
|
||||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||||
# format to the repository Actions tab.
|
# format to the repository Actions tab.
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
|
|
@ -56,6 +56,6 @@ jobs:
|
||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
|
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,12 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up PHP
|
- name: Set up PHP
|
||||||
uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # 2.35.5
|
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
|
||||||
with:
|
with:
|
||||||
php-version: 'latest'
|
php-version: 'latest'
|
||||||
coverage: none
|
coverage: none
|
||||||
|
|
@ -64,12 +64,12 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Install PHP
|
- name: Install PHP
|
||||||
uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # 2.35.5
|
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php }}
|
php-version: ${{ matrix.php }}
|
||||||
ini-values: error_reporting=-1, display_errors=On, display_startup_errors=On
|
ini-values: error_reporting=-1, display_errors=On, display_startup_errors=On
|
||||||
|
|
@ -139,7 +139,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
|
|
@ -171,7 +171,7 @@ jobs:
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Set up PHP
|
- name: Set up PHP
|
||||||
uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # 2.35.5
|
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php }}
|
php-version: ${{ matrix.php }}
|
||||||
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
|
||||||
|
|
@ -228,7 +228,7 @@ jobs:
|
||||||
|
|
||||||
- name: Send coverage report to Codecov
|
- name: Send coverage report to Codecov
|
||||||
if: ${{ success() && matrix.coverage == true && github.event.repository.fork == false }}
|
if: ${{ success() && matrix.coverage == true && github.event.repository.fork == false }}
|
||||||
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
|
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||||
env:
|
env:
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
# PHPMailer Change Log
|
# PHPMailer Change Log
|
||||||
|
|
||||||
|
## Version 7.0.2 (January 9th, 2026)
|
||||||
|
* Fixes for sendmail parameter problems in WordPress, thanks to @SirLouen
|
||||||
|
* Reduce memory consumption when sending large attachments by @RobinvanderVliet
|
||||||
|
|
||||||
## Version 7.0.1 (November 25th, 2025)
|
## Version 7.0.1 (November 25th, 2025)
|
||||||
* Use From domain when generating CIDs in msgHTML.
|
* Use From domain when generating CIDs in msgHTML.
|
||||||
* Update to PHPCompatibility 10, resolve numerous PHPCS issues in PHP 8.5.
|
* Update to PHPCompatibility 10, resolve numerous PHPCS issues in PHP 8.5.
|
||||||
|
|
|
||||||
|
|
@ -768,7 +768,7 @@ class PHPMailer
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const VERSION = '7.0.1';
|
const VERSION = '7.0.2';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error severity: message only, continue processing.
|
* Error severity: message only, continue processing.
|
||||||
|
|
@ -988,6 +988,54 @@ class PHPMailer
|
||||||
$this->Mailer = 'mail';
|
$this->Mailer = 'mail';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract sendmail path and parse to deal with known parameters.
|
||||||
|
*
|
||||||
|
* @param string $sendmailPath The sendmail path as set in php.ini
|
||||||
|
*
|
||||||
|
* @return string The sendmail path without the known parameters
|
||||||
|
*/
|
||||||
|
private function parseSendmailPath($sendmailPath)
|
||||||
|
{
|
||||||
|
$sendmailPath = trim((string)$sendmailPath);
|
||||||
|
if ($sendmailPath === '') {
|
||||||
|
return $sendmailPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = preg_split('/\s+/', $sendmailPath);
|
||||||
|
if (empty($parts)) {
|
||||||
|
return $sendmailPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
$command = array_shift($parts);
|
||||||
|
$remainder = [];
|
||||||
|
|
||||||
|
// Parse only -t, -i, -oi and -f parameters.
|
||||||
|
for ($i = 0; $i < count($parts); ++$i) {
|
||||||
|
$part = $parts[$i];
|
||||||
|
if (preg_match('/^-(i|oi|t)$/', $part, $matches)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (preg_match('/^-f(.*)$/', $part, $matches)) {
|
||||||
|
$address = $matches[1];
|
||||||
|
if ($address === '' && isset($parts[$i + 1]) && strpos($parts[$i + 1], '-') !== 0) {
|
||||||
|
$address = $parts[++$i];
|
||||||
|
}
|
||||||
|
$this->Sender = $address;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$remainder[] = $part;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The params that are not parsed are added back to the command.
|
||||||
|
if (!empty($remainder)) {
|
||||||
|
$command .= ' ' . implode(' ', $remainder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $command;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send messages using $Sendmail.
|
* Send messages using $Sendmail.
|
||||||
*/
|
*/
|
||||||
|
|
@ -996,10 +1044,9 @@ class PHPMailer
|
||||||
$ini_sendmail_path = ini_get('sendmail_path');
|
$ini_sendmail_path = ini_get('sendmail_path');
|
||||||
|
|
||||||
if (false === stripos($ini_sendmail_path, 'sendmail')) {
|
if (false === stripos($ini_sendmail_path, 'sendmail')) {
|
||||||
$this->Sendmail = '/usr/sbin/sendmail';
|
$ini_sendmail_path = '/usr/sbin/sendmail';
|
||||||
} else {
|
|
||||||
$this->Sendmail = $ini_sendmail_path;
|
|
||||||
}
|
}
|
||||||
|
$this->Sendmail = $this->parseSendmailPath($ini_sendmail_path);
|
||||||
$this->Mailer = 'sendmail';
|
$this->Mailer = 'sendmail';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1011,10 +1058,9 @@ class PHPMailer
|
||||||
$ini_sendmail_path = ini_get('sendmail_path');
|
$ini_sendmail_path = ini_get('sendmail_path');
|
||||||
|
|
||||||
if (false === stripos($ini_sendmail_path, 'qmail')) {
|
if (false === stripos($ini_sendmail_path, 'qmail')) {
|
||||||
$this->Sendmail = '/var/qmail/bin/qmail-inject';
|
$ini_sendmail_path = '/var/qmail/bin/qmail-inject';
|
||||||
} else {
|
|
||||||
$this->Sendmail = $ini_sendmail_path;
|
|
||||||
}
|
}
|
||||||
|
$this->Sendmail = $this->parseSendmailPath($ini_sendmail_path);
|
||||||
$this->Mailer = 'qmail';
|
$this->Mailer = 'qmail';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1860,25 +1906,27 @@ class PHPMailer
|
||||||
//PHP config has a sender address we can use
|
//PHP config has a sender address we can use
|
||||||
$this->Sender = ini_get('sendmail_from');
|
$this->Sender = ini_get('sendmail_from');
|
||||||
}
|
}
|
||||||
//CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
|
|
||||||
|
$sendmailArgs = [];
|
||||||
|
|
||||||
|
// CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
|
||||||
|
// Also don't add the -f automatically unless it has been set either via Sender
|
||||||
|
// or sendmail_path. Otherwise it can introduce new problems.
|
||||||
|
// @see http://github.com/PHPMailer/PHPMailer/issues/2298
|
||||||
if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) {
|
if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) {
|
||||||
if ($this->Mailer === 'qmail') {
|
$sendmailArgs[] = '-f' . $this->Sender;
|
||||||
$sendmailFmt = '%s -f%s';
|
|
||||||
} else {
|
|
||||||
$sendmailFmt = '%s -oi -f%s -t';
|
|
||||||
}
|
|
||||||
} elseif ($this->Mailer === 'qmail') {
|
|
||||||
$sendmailFmt = '%s';
|
|
||||||
} else {
|
|
||||||
//Allow sendmail to choose a default envelope sender. It may
|
|
||||||
//seem preferable to force it to use the From header as with
|
|
||||||
//SMTP, but that introduces new problems (see
|
|
||||||
//<https://github.com/PHPMailer/PHPMailer/issues/2298>), and
|
|
||||||
//it has historically worked this way.
|
|
||||||
$sendmailFmt = '%s -oi -t';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender);
|
// Qmail doesn't accept all the sendmail parameters
|
||||||
|
// @see https://github.com/PHPMailer/PHPMailer/issues/3189
|
||||||
|
if ($this->Mailer !== 'qmail') {
|
||||||
|
$sendmailArgs[] = '-i';
|
||||||
|
$sendmailArgs[] = '-t';
|
||||||
|
}
|
||||||
|
|
||||||
|
$resultArgs = (empty($sendmailArgs) ? '' : ' ' . implode(' ', $sendmailArgs));
|
||||||
|
|
||||||
|
$sendmail = trim(escapeshellcmd($this->Sendmail) . $resultArgs);
|
||||||
$this->edebug('Sendmail path: ' . $this->Sendmail);
|
$this->edebug('Sendmail path: ' . $this->Sendmail);
|
||||||
$this->edebug('Sendmail command: ' . $sendmail);
|
$this->edebug('Sendmail command: ' . $sendmail);
|
||||||
$this->edebug('Envelope sender: ' . $this->Sender);
|
$this->edebug('Envelope sender: ' . $this->Sender);
|
||||||
|
|
@ -2062,7 +2110,8 @@ class PHPMailer
|
||||||
$this->Sender = ini_get('sendmail_from');
|
$this->Sender = ini_get('sendmail_from');
|
||||||
}
|
}
|
||||||
if (!empty($this->Sender) && static::validateAddress($this->Sender)) {
|
if (!empty($this->Sender) && static::validateAddress($this->Sender)) {
|
||||||
if (self::isShellSafe($this->Sender)) {
|
$phpmailer_path = ini_get('sendmail_path');
|
||||||
|
if (self::isShellSafe($this->Sender) && strpos($phpmailer_path, ' -f') === false) {
|
||||||
$params = sprintf('-f%s', $this->Sender);
|
$params = sprintf('-f%s', $this->Sender);
|
||||||
}
|
}
|
||||||
$old_from = ini_get('sendmail_from');
|
$old_from = ini_get('sendmail_from');
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ class POP3
|
||||||
* @var string
|
* @var string
|
||||||
* @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead.
|
* @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead.
|
||||||
*/
|
*/
|
||||||
const VERSION = '7.0.1';
|
const VERSION = '7.0.2';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default POP3 port number.
|
* Default POP3 port number.
|
||||||
|
|
|
||||||
28
src/SMTP.php
28
src/SMTP.php
|
|
@ -36,7 +36,7 @@ class SMTP
|
||||||
* @var string
|
* @var string
|
||||||
* @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead.
|
* @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead.
|
||||||
*/
|
*/
|
||||||
const VERSION = '7.0.1';
|
const VERSION = '7.0.2';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SMTP line break constant.
|
* SMTP line break constant.
|
||||||
|
|
@ -770,6 +770,25 @@ class SMTP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function iterateLines($s)
|
||||||
|
{
|
||||||
|
$start = 0;
|
||||||
|
$length = strlen($s);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $length; $i++) {
|
||||||
|
$c = $s[$i];
|
||||||
|
if ($c === "\n" || $c === "\r") {
|
||||||
|
yield substr($s, $start, $i - $start);
|
||||||
|
if ($c === "\r" && $i + 1 < $length && $s[$i + 1] === "\n") {
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$start = $i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield substr($s, $start);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an SMTP DATA command.
|
* Send an SMTP DATA command.
|
||||||
* Issues a data command and sends the msg_data to the server,
|
* Issues a data command and sends the msg_data to the server,
|
||||||
|
|
@ -798,15 +817,16 @@ class SMTP
|
||||||
* NOTE: this does not count towards line-length limit.
|
* NOTE: this does not count towards line-length limit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Normalize line breaks before exploding
|
//Iterate over lines with normalized line breaks
|
||||||
$lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data));
|
$lines = $this->iterateLines($msg_data);
|
||||||
|
|
||||||
/* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
|
/* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
|
||||||
* of the first line (':' separated) does not contain a space then it _should_ be a header, and we will
|
* of the first line (':' separated) does not contain a space then it _should_ be a header, and we will
|
||||||
* process all lines before a blank line as headers.
|
* process all lines before a blank line as headers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$field = substr($lines[0], 0, strpos($lines[0], ':'));
|
$first_line = $lines->current();
|
||||||
|
$field = substr($first_line, 0, strpos($first_line, ':'));
|
||||||
$in_headers = false;
|
$in_headers = false;
|
||||||
if (!empty($field) && strpos($field, ' ') === false) {
|
if (!empty($field) && strpos($field, ' ') === false) {
|
||||||
$in_headers = true;
|
$in_headers = true;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,23 @@ use PHPMailer\Test\SendTestCase;
|
||||||
*/
|
*/
|
||||||
final class MailTransportTest extends SendTestCase
|
final class MailTransportTest extends SendTestCase
|
||||||
{
|
{
|
||||||
|
/** @var string */
|
||||||
|
private $originalSendmailFrom = '';
|
||||||
|
|
||||||
|
protected function set_up()
|
||||||
|
{
|
||||||
|
parent::set_up();
|
||||||
|
|
||||||
|
$from = ini_get('sendmail_from');
|
||||||
|
$this->originalSendmailFrom = $from === false ? '' : $from;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tear_down()
|
||||||
|
{
|
||||||
|
ini_set('sendmail_from', $this->originalSendmailFrom);
|
||||||
|
parent::tear_down();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test sending using SendMail.
|
* Test sending using SendMail.
|
||||||
*
|
*
|
||||||
|
|
@ -65,12 +82,6 @@ final class MailTransportTest extends SendTestCase
|
||||||
*/
|
*/
|
||||||
public function testMailSend()
|
public function testMailSend()
|
||||||
{
|
{
|
||||||
$sendmail = ini_get('sendmail_path');
|
|
||||||
// No path in sendmail_path.
|
|
||||||
if (strpos($sendmail, '/') === false) {
|
|
||||||
ini_set('sendmail_path', '/usr/sbin/sendmail -t -i ');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Mail->Body = 'Sending via mail()';
|
$this->Mail->Body = 'Sending via mail()';
|
||||||
$this->buildBody();
|
$this->buildBody();
|
||||||
$this->Mail->Subject = $this->Mail->Subject . ': mail()';
|
$this->Mail->Subject = $this->Mail->Subject . ': mail()';
|
||||||
|
|
@ -105,4 +116,146 @@ final class MailTransportTest extends SendTestCase
|
||||||
$msg = $this->Mail->getSentMIMEMessage();
|
$msg = $this->Mail->getSentMIMEMessage();
|
||||||
self::assertStringNotContainsString("\r\n\r\nMIME-Version:", $msg, 'Incorrect MIME headers');
|
self::assertStringNotContainsString("\r\n\r\nMIME-Version:", $msg, 'Incorrect MIME headers');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test sending using PHP mail() function with Sender address
|
||||||
|
* and explicit sendmail_from ini set.
|
||||||
|
* Test running required with:
|
||||||
|
* php -d sendmail_path="/usr/sbin/sendmail -t -i -frpath@example.org" ./vendor/bin/phpunit
|
||||||
|
*
|
||||||
|
* @group sendmailparams
|
||||||
|
* @covers \PHPMailer\PHPMailer\PHPMailer::isMail
|
||||||
|
*/
|
||||||
|
public function testMailSendWithSendmailParams()
|
||||||
|
{
|
||||||
|
$sender = 'rpath@example.org';
|
||||||
|
|
||||||
|
if (strpos(ini_get('sendmail_path'), $sender) === false) {
|
||||||
|
self::markTestSkipped('Custom Sendmail php.ini not available');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->Mail->Body = 'Sending via mail()';
|
||||||
|
$this->buildBody();
|
||||||
|
$this->Mail->Subject = $this->Mail->Subject . ': mail()';
|
||||||
|
$this->Mail->clearAddresses();
|
||||||
|
$this->setAddress('testmailsend@example.com', 'totest');
|
||||||
|
|
||||||
|
ini_set('sendmail_from', $sender);
|
||||||
|
$this->Mail->createHeader();
|
||||||
|
$this->Mail->isMail();
|
||||||
|
|
||||||
|
self::assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test sending using SendMail with Sender address
|
||||||
|
* and explicit sendmail_from ini set.
|
||||||
|
* Test running required with:
|
||||||
|
* php -d sendmail_path="/usr/sbin/sendmail -t -i -frpath@example.org" ./vendor/bin/phpunit
|
||||||
|
*
|
||||||
|
* @group sendmailparams
|
||||||
|
* @covers \PHPMailer\PHPMailer\PHPMailer::isSendmail
|
||||||
|
*/
|
||||||
|
public function testSendmailSendWithSendmailParams()
|
||||||
|
{
|
||||||
|
$sender = 'rpath@example.org';
|
||||||
|
|
||||||
|
if (strpos(ini_get('sendmail_path'), $sender) === false) {
|
||||||
|
self::markTestSkipped('Custom Sendmail php.ini not available');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->Mail->Body = 'Sending via sendmail';
|
||||||
|
$this->buildBody();
|
||||||
|
$subject = $this->Mail->Subject;
|
||||||
|
|
||||||
|
$this->Mail->Subject = $subject . ': sendmail';
|
||||||
|
ini_set('sendmail_from', $sender);
|
||||||
|
$this->Mail->isSendmail();
|
||||||
|
|
||||||
|
self::assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test parsing of sendmail path and with certain parameters.
|
||||||
|
*
|
||||||
|
* @group sendmailparams
|
||||||
|
* @covers \PHPMailer\PHPMailer\PHPMailer::parseSendmailPath
|
||||||
|
* @dataProvider sendmailPathProvider
|
||||||
|
*
|
||||||
|
* @param string $sendmailPath The sendmail path to parse.
|
||||||
|
* @param string $expectedCommand The expected command after parsing.
|
||||||
|
* @param string $expectedSender The expected Sender (-f parameter) after parsing.
|
||||||
|
*/
|
||||||
|
public function testParseSendmailPath($sendmailPath, $expectedCommand, $expectedSender)
|
||||||
|
{
|
||||||
|
$mailer = $this->Mail;
|
||||||
|
|
||||||
|
$parseSendmailPath = \Closure::bind(
|
||||||
|
function ($path) {
|
||||||
|
return $this->{'parseSendmailPath'}($path);
|
||||||
|
},
|
||||||
|
$mailer,
|
||||||
|
\PHPMailer\PHPMailer\PHPMailer::class
|
||||||
|
);
|
||||||
|
$command = $parseSendmailPath($sendmailPath);
|
||||||
|
|
||||||
|
self::assertSame($expectedCommand, $command, 'Sendmail command not parsed correctly');
|
||||||
|
self::assertSame($expectedSender, $mailer->Sender, 'Sender property not set correctly');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testParseSendmailPath.
|
||||||
|
*
|
||||||
|
* @return array{
|
||||||
|
* 0: string, // The sendmail path to parse.
|
||||||
|
* 1: string, // The expected command after parsing.
|
||||||
|
* 2: string // The expected Sender (-f parameter) after parsing.
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function sendmailPathProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'path only' => [
|
||||||
|
'/usr/sbin/sendmail',
|
||||||
|
'/usr/sbin/sendmail',
|
||||||
|
''
|
||||||
|
],
|
||||||
|
'with i and t' => [
|
||||||
|
'/usr/sbin/sendmail -i -t',
|
||||||
|
'/usr/sbin/sendmail',
|
||||||
|
''
|
||||||
|
],
|
||||||
|
'with f concatenated' => [
|
||||||
|
'/usr/sbin/sendmail -frpath@example.org -i',
|
||||||
|
'/usr/sbin/sendmail',
|
||||||
|
'rpath@example.org'
|
||||||
|
],
|
||||||
|
'with f separated' => [
|
||||||
|
'/usr/sbin/sendmail -f rpath@example.org -t',
|
||||||
|
'/usr/sbin/sendmail',
|
||||||
|
'rpath@example.org',
|
||||||
|
],
|
||||||
|
'with extra flags preserved' => [
|
||||||
|
'/opt/sendmail -x -y -fuser@example.org',
|
||||||
|
'/opt/sendmail -x -y',
|
||||||
|
'user@example.org',
|
||||||
|
],
|
||||||
|
"extra flags with values preserved" => [
|
||||||
|
'/opt/sendmail -X /path/to/logfile -fuser@example.org',
|
||||||
|
'/opt/sendmail -X /path/to/logfile',
|
||||||
|
'user@example.org',
|
||||||
|
],
|
||||||
|
"extra flags concatenated preserved" => [
|
||||||
|
'/opt/sendmail -X/path/to/logfile -t -i',
|
||||||
|
'/opt/sendmail -X/path/to/logfile',
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
"option values with regular parameters" => [
|
||||||
|
'/opt/sendmail -oi -t',
|
||||||
|
'/opt/sendmail',
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue