Compare commits

..

No commits in common. "master" and "v6.9.2" have entirely different histories.

48 changed files with 684 additions and 1632 deletions

1
.gitattributes vendored
View File

@ -1,7 +1,6 @@
* text=auto
/.codecov.yml export-ignore
/.editorconfig export-ignore
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore

View File

@ -8,14 +8,7 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "cron"
cronjob: "10 22 5,20 * *" # At 22:10, every 5th and 20th day of the month.
interval: "weekly"
open-pull-requests-limit: 5
commit-message:
prefix: "GH Actions:"
groups:
action-runners:
applies-to: version-updates
update-types:
- "minor"
- "patch"

View File

@ -14,14 +14,13 @@ jobs:
if: github.repository == 'PHPMailer/PHPMailer'
steps:
- name: Checkout sources
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@v4
with:
fetch-depth: 1
persist-credentials: false
- name: Build Docs
uses: ./.github/actions/build-docs
- name: Publish Docs to gh-pages
uses: JamesIves/github-pages-deploy-action@9d877eea73427180ae43cf98e8914934fe157a1a # v4.7.6
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: docs

View File

@ -7,29 +7,30 @@ on:
push:
branches: [ "master" ]
permissions: {}
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
# Don't run the cron job on forks.
if: ${{ github.event_name != 'schedule' || github.event.repository.fork == false }}
name: Scorecards analysis
runs-on: ubuntu-latest
permissions:
# Required when publishing results (badge / API / code scanning)
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Used to receive a badge. (Upcoming feature)
id-token: write
# Needs for private repositories.
contents: read
actions: read
steps:
- name: "Checkout code"
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@v4
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46
with:
results_file: results.sarif
results_format: sarif
@ -48,7 +49,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@v4
with:
name: SARIF file
path: results.sarif
@ -56,6 +57,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif

View File

@ -6,7 +6,8 @@ on:
# Allow manually triggering the workflow.
workflow_dispatch:
permissions: {}
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
@ -14,17 +15,12 @@ jobs:
runs-on: ubuntu-22.04
name: Coding standards
permissions:
contents: read # to fetch code (actions/checkout)
steps:
- name: Check out code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Set up PHP
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
uses: shivammathur/setup-php@v2
with:
php-version: 'latest'
coverage: none
@ -33,7 +29,7 @@ jobs:
# Install dependencies and handle caching in one go.
# @link https://github.com/marketplace/actions/install-php-dependencies-with-composer
- name: Install Composer dependencies
uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # 3.1.1
uses: "ramsey/composer-install@v3"
with:
# Bust the cache at least once a month - output format: YYYY-MM.
custom-cache-suffix: $(date -u "+%Y-%m")
@ -50,46 +46,40 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
php: ['5.5', '7.2', '8.0', '8.5']
php: ['5.5', '7.2', '8.0', '8.1', '8.2', '8.3']
experimental: [false]
include:
- php: 'nightly'
- php: '8.4'
experimental: true
name: "Lint: PHP ${{ matrix.php }}"
continue-on-error: ${{ matrix.experimental }}
permissions:
contents: read # to fetch code (actions/checkout)
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Install PHP
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
ini-values: error_reporting=-1, display_errors=On, display_startup_errors=On
coverage: none
tools: cs2pr
# Install dependencies and handle caching in one go.
# @link https://github.com/marketplace/actions/install-php-dependencies-with-composer
- name: Install Composer dependencies
uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # 3.1.1
uses: "ramsey/composer-install@v3"
with:
# Bust the cache at least once a month - output format: YYYY-MM.
custom-cache-suffix: $(date -u "+%Y-%m")
- name: Lint against parse errors
if: ${{ matrix.php != 'nightly' }}
if: ${{ matrix.php != '8.4' }}
run: composer lint -- --checkstyle | cs2pr
- name: Lint against future parse errors (PHP nightly)
if: ${{ matrix.php == 'nightly' }}
- name: Lint against future parse errors (PHP 8.4)
if: ${{ matrix.php == '8.4' }}
run: composer lint
test:
@ -97,7 +87,7 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
extensions: ['optimal', 'minimal']
coverage: [false]
experimental: [false]
@ -111,21 +101,21 @@ jobs:
extensions: 'minimal'
coverage: true
experimental: false
- php: '8.5'
- php: '8.3'
extensions: 'optimal'
coverage: true
experimental: false
- php: '8.5'
- php: '8.3'
extensions: 'minimal'
coverage: true
experimental: false
# Experimental builds. These are allowed to fail.
- php: '8.6'
- php: '8.4'
extensions: 'optimal'
coverage: false
experimental: true
- php: '8.6'
- php: '8.4'
extensions: 'minimal'
coverage: false
experimental: true
@ -134,14 +124,9 @@ jobs:
continue-on-error: ${{ matrix.experimental }}
permissions:
contents: read # to fetch code (actions/checkout)
steps:
- name: Check out code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
uses: actions/checkout@v4
# About the "extensions":
#
@ -171,26 +156,26 @@ jobs:
fi
- name: Set up PHP
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }}
ini-values: sendmail_path=/usr/sbin/sendmail -t -i, error_reporting=-1, display_errors=On, display_startup_errors=On
ini-values: sendmail_path=/usr/sbin/sendmail -t -i, error_reporting=E_ALL, display_errors=On
extensions: ${{ steps.set_extensions.outputs.EXT }}
# Install dependencies and handle caching in one go.
# @link https://github.com/marketplace/actions/install-php-dependencies-with-composer
- name: Install PHP packages - normal
if: ${{ matrix.php != '8.6' }}
uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # 3.1.1
if: ${{ matrix.php != '8.4' }}
uses: "ramsey/composer-install@v3"
with:
composer-options: ${{ steps.set_extensions.outputs.COMPOSER_OPTIONS }}
# Bust the cache at least once a month - output format: YYYY-MM.
custom-cache-suffix: $(date -u "+%Y-%m")
- name: Install PHP packages - ignore-platform-reqs
if: ${{ matrix.php == '8.6' }}
uses: "ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520" # 3.1.1
if: ${{ matrix.php == '8.4' }}
uses: "ramsey/composer-install@v3"
with:
composer-options: --ignore-platform-reqs ${{ steps.set_extensions.outputs.COMPOSER_OPTIONS }}
# Bust the cache at least once a month - output format: YYYY-MM.
@ -199,7 +184,7 @@ jobs:
# Install postfix and automatically retry if the install failed, which happens reguarly.
# @link https://github.com/marketplace/actions/retry-step
- name: Install postfix
uses: nick-invision/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
uses: nick-invision/retry@v3
with:
timeout_minutes: 2
max_attempts: 3
@ -227,8 +212,8 @@ jobs:
run: vendor/bin/phpunit
- name: Send coverage report to Codecov
if: ${{ success() && matrix.coverage == true && github.event.repository.fork == false }}
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
if: ${{ success() && matrix.coverage == true }}
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:

View File

@ -20,26 +20,25 @@
- Multipart/alternative emails for mail clients that do not read HTML email
- Add attachments, including inline
- Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings
- Full UTF-8 support when using servers that support `SMTPUTF8`.
- Support for iCal events in multiparts and attachments
- SMTP authentication with `LOGIN`, `PLAIN`, `CRAM-MD5`, and `XOAUTH2` mechanisms over SMTPS and SMTP+STARTTLS transports
- SMTP authentication with LOGIN, PLAIN, CRAM-MD5, and XOAUTH2 mechanisms over SMTPS and SMTP+STARTTLS transports
- Validates email addresses automatically
- Protects against header injection attacks
- Error messages in over 50 languages!
- DKIM and S/MIME signing support
- Compatible with PHP 5.5 and later, including PHP 8.5
- Compatible with PHP 5.5 and later, including PHP 8.2
- Namespaced to prevent name clashes
- Much more!
## Why you might need it
Many PHP developers need to send email from their code. The only PHP function that supports this directly is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as authentication, HTML messages, and attachments.
Many PHP developers need to send email from their code. The only PHP function that supports this directly is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as encryption, authentication, HTML messages, and attachments.
Formatting email correctly is surprisingly difficult. There are myriad overlapping (and conflicting) standards, requiring tight adherence to horribly complicated formatting and encoding rules the vast majority of code that you'll find online that uses the `mail()` function directly is just plain wrong, if not unsafe!
The PHP `mail()` function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD, and macOS platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP client allows email sending on all platforms without needing a local mail server. Be aware though, that the `mail()` function should be avoided when possible; it's both faster and [safer](https://exploitbox.io/paper/Pwning-PHP-Mail-Function-For-Fun-And-RCE.html) to use SMTP to localhost.
*Please* don't be tempted to do it yourself if you don't use PHPMailer, there are many other excellent libraries that
you should look at before rolling your own. Try [Symfony Mailer](https://symfony.com/doc/current/mailer.html), [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc.
you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/)
, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc.
## License
This software is distributed under the [LGPL 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
@ -48,7 +47,7 @@ This software is distributed under the [LGPL 2.1](https://www.gnu.org/licenses/o
PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file:
```json
"phpmailer/phpmailer": "^7.0.0"
"phpmailer/phpmailer": "^6.9.2"
```
or run
@ -75,7 +74,7 @@ require 'path/to/PHPMailer/src/PHPMailer.php';
require 'path/to/PHPMailer/src/SMTP.php';
```
If you're not using the `SMTP` class explicitly (you're probably not), you don't need a `use` line for it. Even if you're not using exceptions, you do still need to load the `Exception` class as it is used internally.
If you're not using the `SMTP` class explicitly (you're probably not), you don't need a `use` line for the SMTP class. Even if you're not using exceptions, you do still need to load the `Exception` class as it is used internally.
## Legacy versions
PHPMailer 5.2 (which is compatible with PHP 5.0 — 7.0) is no longer supported, even for security updates. You will find the latest version of 5.2 in the [5.2-stable branch](https://github.com/PHPMailer/PHPMailer/tree/5.2-stable). If you're using PHP 5.5 or later (which you should be), switch to the 6.x releases.
@ -96,7 +95,7 @@ use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
//Load Composer's autoloader (created by composer, not included with PHPMailer)
//Load Composer's autoloader
require 'vendor/autoload.php';
//Create an instance; passing `true` enables exceptions
@ -163,7 +162,7 @@ To reduce PHPMailer's deployed code footprint, examples are not included if you
Complete generated API documentation is [available online](https://phpmailer.github.io/PHPMailer/).
You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](https://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailer/PHPMailerTest.php) a good reference for how to do various operations such as encryption.
You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](https://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailerTest.php) a good reference for how to do various operations such as encryption.
If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](https://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting).

View File

@ -1,48 +0,0 @@
# A short history of UTF-8 in email
## Background
For most of its existence, SMTP has been a 7-bit channel, only supporting US-ASCII characters. This has been a problem for many languages, especially those that use non-Latin scripts, and has led to the development of various workarounds.
The first major improvement, introduced in 1994 in [RFC 1652](https://www.rfc-editor.org/rfc/rfc1652) and extended in 2011 in [RFC 6152](https://www.rfc-editor.org/rfc/rfc6152), was the addition of the `8BITMIME` SMTP extension, which allowed raw 8-bit data to be included in message bodies sent over SMTP.
This allowed the message *contents* to contain 8-bit data, including things like UTF-8 text, even though the SMTP protocol itself was still firmly 7-bit. This worked by having the server switch to 8-bit after the headers, and then back to 7-bit after the completion of a `DATA` command.
From 1996, messages could support [RFC 2047 encoding](https://www.rfc-editor.org/rfc/rfc2047), which permitted inserting characters from any character set into header *values* (but not names), but only by encoding them in somewhat unreadable ways to allow them to survive passage through a 7-bit channel. An example with a subject of "Schrödinger's cat" would be:
```
Subject: =?utf-8?Q=Schr=C3=B6dinger=92s_Cat?=
```
Here the accented `ö` is encoded as `=C3=B6`, which is the UTF-8 encoding of the 2-byte character, and the whole thing is wrapped in `=?utf-8?Q?` to indicate that it uses the UTF-8 charset and `quoted-printable` encoding. This is a bit of a hack, and not very human-friendly, but it works.
Similarly, 8-bit message bodies could be encoded using the same `quoted-printable` and `base64` content transfer encoding (CTE) schemes, which preserved the 8-bit content while encoding it in a format that could survive transmission through a 7-bit channel.
Domain names were originally also stuck in a 7-bit world, actually even more constrained to only a subset of the US-ASCII character set. But of course, many people want to have domains in their own language/script. Internationalized domain name (IDN) permitted this, using yet another complex encoding scheme called punycode, defined for domain names in 2003 in [RFC 3492](https://www.rfc-editor.org/rfc/rfc3492). This finally allowed the domain part (after the `@`) of email addresses to contain UTF-8, though it was actually an illusion preserved by email client applications. For example, an address of
`user@café.example.com` translates to
`user@xn--caf-dma.example.com` in punycode, rendering it mostly unreadable, but 7-bit friendly, and remaining compatible with email clients that don't know about IDN.
The one remaining part of email that could not handle UTF-8 is the local part of email addresses (the part before the `@`).
I've only mentioned UTF-8 here, but most of these approaches also allowed other character sets that were popular, such as [the ISO-8859 family](https://en.wikipedia.org/wiki/ISO/IEC_8859). However, UTF-8 solves so many problems that these other character sets are gradually falling out of favour, as UTF-8 can support all languages.
This patchwork of overlapping approaches has served us well, but we have to admit that it's a mess.
## SMTPUTF8
`SMTPUTF8` is another SMTP extension, defined in [RFC 6531](https://www.rfc-editor.org/rfc/rfc6531) in 2012. This essentially solves the whole problem, allowing the entire SMTP conversation — commands, headers, and message bodies — to be sent in raw, unencoded UTF-8.
But there's a problem with this approach: adoption. If you send a UTF-8 message to a recipient whose mail server doesn't support this format, the sender has to somehow downgrade the message to make it survive a transition to 7-bit. This is a hard problem to solve, especially since there is no way to make a 7-bit system support UTF-8 in the local parts of addresses. This downgrade problem is what held up the adoption of `SMTPUTF8` in PHPMailer for many years, but in that time the *de facto* approach has become to simply fail in that situation, and tell the recipient it's time they upgraded their mail server 😅.
The vast majority of large email providers (gmail, Yahoo, Microsoft, etc), mail servers (postfix, exim, IIS, etc), and mail clients (Apple Mail, Outlook, Thunderbird, etc) now all support SMTPUTF8, so the need for backward compatibility is no longer what it was.
## SMTPUTF8 in PHPMailer
Several other PHP email libraries have implemented a halfway solution to `SMTPUTF8`, adding only the ability to support UTF-8 in email addresses, not elsewhere in the protocol. I wanted PHPMailer to do it "the right way", and this has taken much longer. PHPMailer now supports UTF-8 everywhere, and does not need to use transfer or header encodings for UTF-8 text when connecting to an `SMTPUTF8`-capable mail server.
This support is handled automatically: if you add an email address that requires UTF-8, PHPMailer will use UTF-8 for everything. If not, it will fall back to 7-bit and encode the message as necessary.
The one place you will need to be careful is in the selection of the address validator. By default, PHPMailer uses PHP's built-in `filter_var` validator, which does not allow UTF-8 email addresses. When PHPMailer spots that you have submitted a UTF-8 address, but have not altered the default validator, it will automatically switch to using a UTF-8-compatible validator. As soon as you do this, any SMTP connection you make will *require* that the server you connect to supports `SMTPUTF8`. You can select this validator explicitly by setting `PHPMailer::$validator = 'eai'` (an acronym for Email Address Internationalization).
### Postfix gotcha
Postfix has supported `SMTPUTF8` for a long time, but it has a peculiarity that it does not always advertise that it does so. However, rather surprisingly, if you use UTF-8 in the conversation, it will work anyway.

View File

@ -1 +1 @@
7.0.2
6.9.2

View File

@ -1,54 +1,5 @@
# 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)
* Use From domain when generating CIDs in msgHTML.
* Update to PHPCompatibility 10, resolve numerous PHPCS issues in PHP 8.5.
* Revise GitHub actions for PHP 8.5 and experimental 8.6 tests.
* Switch gmail example from the deprecated IMAP extension to use `directorytree/imapengine` for IMAP uploads.
* Set `htmlspecialchars()` flags explicitly and consistently.
* Convert XOAUTH2 token exceptions into PHPMailer Exceptions. The original exception is available as an inner exception.
* Deprecate VERSION constants in POP3 and SMTP classes.
* Remove dependency on `roave/security-advisories`; it's now built into composer 2.9.
* Update Dutch, Esperanto, and Norwegian translations.
## Version 7.0.0 (October 15th, 2025)
This is exactly the same as 6.11.1 but bumps the major version number to indicate the presence of a BC break in child classes. Specifically, `lang()`, `setLanguage()`, and `$language` are now static, and should be called statically.
## Version 6.12.0 (October 15th, 2025)
This is exactly the same as 6.10.0, reverting all the changes in 6.11.0 and 6.11.1, which inadvertently introduced a BC break affecting child classes. 6.11.1 has been re-released as 7.0.0.
## Version 6.11.1 (September 30th, 2025)
* Avoid function signature problems with the deprecation of `$useimap` in `parseAddresses`.
## Version 6.11.0 (September 29th, 2025)
* Add support for [RFC4954](https://www.rfc-editor.org/rfc/rfc4954#section-4) two-part authentication for large XOAUTH2 tokens.
* Also support empty tokens.
* Avoid bogus static analyser deprecation warnings in `setFrom`.
* Make language loading entirely static, thanks to @SirLouen.
* Emit warnings when `parseAddresses()` is used without the IMAP extension.
* Handle `mb_decode_mimeheader` changes from PHP 8.3+.
* Deprecate the charset param to parseAddresses.
* Fix PHP 8.5 linting issue.
* Don't use `-t` switch when calling qmail.
* Checking for interrupted system calls now works in languages other than English.
* Add support for extracting gmail transaction IDs after sending.
* For consistency, the protected `ReplyTo` property has been changed to match the format used for other address arrays.
* Fix line length issues when using S/MIME signing.
* Pin action runners to exact versions to avoid unexpected upstream changes.
## Version 6.10.0 (April 24th, 2025)
* Add support for [RFC 6530 SMTPUTF8](https://www.rfc-editor.org/rfc/rfc6530), permitting use of UTF-8 Unicode characters everywhere, thanks to @arnt and ICANN. See `SMTPUTF8.md` for details.
* More reliable checking for multibyte support.
## Version 6.9.3 (November 22nd, 2024)
* Add support for the release version of PHP 8.4
* Add experimental support for PHP 8.5
* Use rfc-editor.org for all RFC docs links
## Version 6.9.2 (October 9th, 2024)
* Escape dots in SMTP transaction ID patterns
* Add link to [aboutmy.email](https://aboutmy.email) testing service in docs
@ -276,7 +227,7 @@ Many thanks to @jrfnl for all her work.
## Version 6.1.0 (September 27th 2019)
* Multiple bug fixes for folding of long header lines, thanks to @caugner
* Add support for [RFC2387 child element content-type hint](https://www.rfc-editor.org/rfc/rfc2387#section-3.1) in `multipart/related` structures.
* Add support for [RFC2387 child element content-type hint](https://tools.ietf.org/html/rfc2387#section-3.1) in `multipart/related` structures.
* Support for Ical event methods other than `REQUEST`, thanks to @puhr-mde
* Change header folding and param separation to use spaces instead of tabs
* Use ; to separate multiple MIME header params

View File

@ -42,25 +42,22 @@
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^10.0.0@dev",
"squizlabs/php_codesniffer": "^3.13.5",
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7.2",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"ext-imap": "Needed to support advanced email address parsing according to RFC822",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication",
"directorytree/imapengine": "For uploading sent messages via IMAP, see gmail example"
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"PHPMailer\\PHPMailer\\": "src/"
@ -74,7 +71,6 @@
"license": "LGPL-2.1-only",
"scripts": {
"check": "./vendor/bin/phpcs",
"style": "./vendor/bin/phpcbf",
"test": "./vendor/bin/phpunit --no-coverage",
"coverage": "./vendor/bin/phpunit",
"lint": [

View File

@ -10,7 +10,7 @@
<div align="center">
<a href="https://github.com/PHPMailer/PHPMailer/"><img src="images/phpmailer.png" height="90" width="340" alt="PHPMailer rocks"></a>
</div>
<p>This example uses <strong>HTML</strong> with the UTF-8 Unicode charset.</p>
<p>This example uses <strong>HTML</strong> with the UTF-8 unicode charset.</p>
<p>Chinese text: 郵件內容為空</p>
<p>Russian text: Пустое тело сообщения</p>
<p>Armenian text: Հաղորդագրությունը դատարկ է</p>

View File

@ -83,24 +83,26 @@ if (!$mail->send()) {
echo 'Message sent!';
//Section 2: IMAP
//Uncomment these to save your message in the 'Sent Mail' folder.
#save_mail($mail->getSentMIMEMessage());
#if (save_mail($mail)) {
# echo "Message saved!";
#}
}
//Section 2: IMAP
//This example uses the directorytree/imapengine IMAP library: https://imapengine.com
//Earlier versions of this code used the deprecated PHP imap_* functions.
function save_mail($message)
//IMAP commands requires the PHP IMAP Extension, found at: https://php.net/manual/en/imap.setup.php
//Function to call which uses the PHP imap_*() functions to save messages: https://php.net/manual/en/book.imap.php
//You can use imap_getmailboxes($imapStream, '/imap/ssl', '*' ) to get a list of available folders or labels, this can
//be useful if you are trying to get this working on a non-Gmail IMAP server.
function save_mail($mail)
{
$mailbox = new \DirectoryTree\ImapEngine\Mailbox([
'host' => 'imap.gmail.com',
'port' => 993,
'encryption' => 'ssl',
'username' => 'user@example.com',
'password' => 'password',
]);
//You can change 'Sent Mail' to any other folder or tag
$path = '{imap.gmail.com:993/imap/ssl}[Gmail]/Sent Mail';
// Find the "sent" messages folder yours may have a different name.
$folder = $mailbox->folders()->find('Sent Mail');
//Tell your server to open an IMAP connection using the same username and password as you used for SMTP
$imapStream = imap_open($path, $mail->Username, $mail->Password);
$folder->messages()->append($message);
$result = imap_append($imapStream, $path, $mail->getSentMIMEMessage());
imap_close($imapStream);
return $result;
}

View File

@ -8,7 +8,7 @@
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
error_reporting(E_ALL);
error_reporting(E_STRICT | E_ALL);
date_default_timezone_set('Etc/UTC');
@ -51,10 +51,7 @@ foreach ($result as $row) {
try {
$mail->addAddress($row['email'], $row['full_name']);
} catch (Exception $e) {
printf(
'Invalid address skipped: %s<br>',
htmlspecialchars($row['email'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401)
);
echo 'Invalid address skipped: ' . htmlspecialchars($row['email']) . '<br>';
continue;
}
if (!empty($row['photo'])) {
@ -69,11 +66,8 @@ foreach ($result as $row) {
try {
$mail->send();
printf(
'Message sent to : %s (%s)<br>',
htmlspecialchars($row['full_name'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401),
htmlspecialchars($row['email'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401)
);
echo 'Message sent to :' . htmlspecialchars($row['full_name']) . ' (' .
htmlspecialchars($row['email']) . ')<br>';
//Mark it as sent in the DB
mysqli_query(
$mysql,
@ -81,11 +75,7 @@ foreach ($result as $row) {
mysqli_real_escape_string($mysql, $row['email']) . "'"
);
} catch (Exception $e) {
printf(
'Mailer Error (%s) %s<br>',
htmlspecialchars($row['email'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401),
$mail->ErrorInfo
);
echo 'Mailer Error (' . htmlspecialchars($row['email']) . ') ' . $mail->ErrorInfo . '<br>';
//Reset the connection to abort sending this message
//The loop will continue trying to send to the rest of the list
$mail->getSMTPInstance()->reset();

View File

@ -54,7 +54,7 @@ if (array_key_exists('userfile', $_FILES)) {
<input type="submit" value="Send File">
</form>
<?php } else {
echo htmlspecialchars($msg, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
echo htmlspecialchars($msg);
} ?>
</body>
</html>

View File

@ -54,7 +54,7 @@ if (array_key_exists('userfile', $_FILES)) {
<input type="submit" value="Send Files">
</form>
<?php } else {
echo htmlspecialchars($msg, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
echo htmlspecialchars($msg);
} ?>
</body>
</html>

View File

@ -10,7 +10,7 @@ use PHPMailer\PHPMailer\PHPMailer;
require '../vendor/autoload.php';
if (array_key_exists('email', $_POST)) {
if (array_key_exists('to', $_POST)) {
$err = false;
$msg = '';
$email = '';
@ -45,7 +45,7 @@ if (array_key_exists('email', $_POST)) {
$to = 'support@example.com';
}
//Make sure the address they provided is valid before trying to use it
if (PHPMailer::validateAddress($_POST['email'])) {
if (array_key_exists('email', $_POST) && PHPMailer::validateAddress($_POST['email'])) {
$email = $_POST['email'];
} else {
$msg .= 'Error: invalid email address provided';
@ -99,4 +99,4 @@ if (array_key_exists('email', $_POST)) {
echo $msg;
} ?>
</body>
</html>
</html>

View File

@ -178,5 +178,5 @@ if (!isset($_GET['code'])) {
);
//Use this to interact with an API on the users behalf
//Use this to get a new access token if the old one expires
echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken(), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken());
}

View File

@ -34,6 +34,3 @@ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.';
$PHPMAILER_LANG['smtp_detail'] = 'Detalje: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: ';
$PHPMAILER_LANG['variable_set'] = 'Kunne ikke definere eller nulstille variablen: ';
$PHPMAILER_LANG['no_smtputf8'] = 'Serveren understøtter ikke SMTPUTF8 som påkrævet for at sende til Unicode adresser';
$PHPMAILER_LANG['imap_recommended'] = 'Brug af forenklet adresseparser anbefales ikke. Installer PHP IMAP udvidelsen for fuld RFC822 parsing.';
$PHPMAILER_LANG['deprecated_argument'] = 'Udfaset argument: ';

View File

@ -3,35 +3,24 @@
/**
* Esperanto PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Robin van der Vliet <info@robinvandervliet.com>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP-eraro: Ne eblis aŭtentigi.';
$PHPMAILER_LANG['buggy_php'] = 'Via versio de PHP estas trafita de cimo, kiu povas kaŭzi difektitajn mesaĝojn. Por ripari tion, ŝanĝu al sendado per SMTP, malŝaltu la opcion mail.add_x_header en via php.ini, ŝanĝu al MacOS aŭ Linux, aŭ ĝisdatigu vian PHP al versio 7.0.17+ aŭ 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'SMTP-eraro: Ne eblis konektiĝi al la SMTP-gastiganto.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-eraro: Datumoj ne akceptitaj.';
$PHPMAILER_LANG['empty_message'] = 'Mesaĝokorpo malplena';
$PHPMAILER_LANG['authenticate'] = 'Eraro de servilo SMTP : aŭtentigo malsukcesis.';
$PHPMAILER_LANG['connect_host'] = 'Eraro de servilo SMTP : konektado al servilo malsukcesis.';
$PHPMAILER_LANG['data_not_accepted'] = 'Eraro de servilo SMTP : neĝustaj datumoj.';
$PHPMAILER_LANG['empty_message'] = 'Teksto de mesaĝo mankas.';
$PHPMAILER_LANG['encoding'] = 'Nekonata kodoprezento: ';
$PHPMAILER_LANG['execute'] = 'Ne eblis plenumi: ';
$PHPMAILER_LANG['extension_missing'] = 'Kromprogramo mankas: ';
$PHPMAILER_LANG['file_access'] = 'Ne eblis aliri la dosieron: ';
$PHPMAILER_LANG['file_open'] = 'Dosiera eraro: Ne eblis malfermi la dosieron: ';
$PHPMAILER_LANG['from_failed'] = 'La sekva(j) sendinto(j) malsukcesis: ';
$PHPMAILER_LANG['instantiate'] = 'Ne eblis funkciigi la retpoŝtan funkcion.';
$PHPMAILER_LANG['invalid_address'] = 'Nevalida adreso: ';
$PHPMAILER_LANG['invalid_header'] = 'Nevalida kaplinia nomo aŭ valoro';
$PHPMAILER_LANG['invalid_hostentry'] = 'Nevalida enigo de gastiganto: ';
$PHPMAILER_LANG['invalid_host'] = 'Nevalida gastiganto: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' retpoŝtilo ne estas subtenata.';
$PHPMAILER_LANG['provide_address'] = 'Vi devas provizi almenaŭ unu retpoŝtadreson de ricevonto.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP-eraro: La sekva(j) ricevonto(j) malsukcesis: ';
$PHPMAILER_LANG['signing'] = 'Subskriba eraro: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP-kodo: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Pliaj SMTP-informoj: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'La SMTP-konektiĝo malsukcesis.';
$PHPMAILER_LANG['smtp_detail'] = 'Informoj: ';
$PHPMAILER_LANG['smtp_error'] = 'Eraro de SMTP-servilo: ';
$PHPMAILER_LANG['variable_set'] = 'Ne eblas agordi aŭ reagordi la variablon: ';
$PHPMAILER_LANG['no_smtputf8'] = 'La servilo ne subtenas SMTPUTF8, kiu estas bezonata por sendi al Unicode-adresoj.';
$PHPMAILER_LANG['imap_recommended'] = 'Uzado de la simpligita adresanalizilo ne estas rekomendita. Instalu la IMAP-kromprogramon por PHP por plena RFC822-analizado.';
$PHPMAILER_LANG['deprecated_argument'] = 'Malrekomendita argumento: ';
$PHPMAILER_LANG['execute'] = 'Lanĉi rulumadon ne eblis: ';
$PHPMAILER_LANG['file_access'] = 'Aliro al dosiero ne sukcesis: ';
$PHPMAILER_LANG['file_open'] = 'Eraro de dosiero: malfermo neeblas: ';
$PHPMAILER_LANG['from_failed'] = 'Jena adreso de sendinto malsukcesis: ';
$PHPMAILER_LANG['instantiate'] = 'Genero de retmesaĝa funkcio neeblis.';
$PHPMAILER_LANG['invalid_address'] = 'Retadreso ne validas: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mesaĝilo ne subtenata.';
$PHPMAILER_LANG['provide_address'] = 'Vi devas tajpi almenaŭ unu recevontan retadreson.';
$PHPMAILER_LANG['recipients_failed'] = 'Eraro de servilo SMTP : la jenaj poŝtrecivuloj kaŭzis eraron: ';
$PHPMAILER_LANG['signing'] = 'Eraro de subskribo: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP konektado malsukcesis.';
$PHPMAILER_LANG['smtp_error'] = 'Eraro de servilo SMTP : ';
$PHPMAILER_LANG['variable_set'] = 'Variablo ne pravalorizeblas aŭ ne repravalorizeblas: ';
$PHPMAILER_LANG['extension_missing'] = 'Mankas etendo: ';

View File

@ -9,7 +9,7 @@
*/
$PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.';
$PHPMAILER_LANG['buggy_php'] = 'Tu versión de PHP ha sido afectada por un bug que puede resultar en mensajes corruptos. Para arreglarlo, cambia a enviar usando SMTP, deshabilita la opción mail.add_x_header en tu php.ini, cambia a MacOS o Linux, o actualiza tu PHP a la versión 7.0.17+ o 7.1.3+.';
$PHPMAILER_LANG['buggy_php'] = 'Tu versión de PHP está afectada por un bug que puede resultar en mensajes corruptos. Para arreglarlo, cambia a enviar usando SMTP, deshabilita la opción mail.add_x_header en tu php.ini, cambia a MacOS o Linux, o actualiza tu PHP a la versión 7.0.17+ o 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Error SMTP: Imposible conectar al servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.';
$PHPMAILER_LANG['empty_message'] = 'El cuerpo del mensaje está vacío.';
@ -18,7 +18,7 @@ $PHPMAILER_LANG['execute'] = 'Imposible ejecutar: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
$PHPMAILER_LANG['file_access'] = 'Imposible acceder al archivo: ';
$PHPMAILER_LANG['file_open'] = 'Error de Archivo: Imposible abrir el archivo: ';
$PHPMAILER_LANG['from_failed'] = 'La siguiente dirección de remitente falló: ';
$PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
$PHPMAILER_LANG['instantiate'] = 'Imposible crear una instancia de la función Mail.';
$PHPMAILER_LANG['invalid_address'] = 'Imposible enviar: dirección de email inválido: ';
$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido';
@ -34,5 +34,3 @@ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
$PHPMAILER_LANG['smtp_detail'] = 'Detalle: ';
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';
$PHPMAILER_LANG['imap_recommended'] = 'No se recomienda usar el analizador de direcciones simplificado. Instala la extensión IMAP de PHP para un análisis RFC822 más completo.';
$PHPMAILER_LANG['deprecated_argument'] = 'Argumento obsoleto: ';

View File

@ -3,21 +3,20 @@
/**
* Norwegian Bokmål PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Wera AS <wordpress@wera.no>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP-feil: Kunne ikke autentisere.';
$PHPMAILER_LANG['buggy_php'] = 'Din versjon av PHP er påvirket av en feil som kan føre til ødelagte meldinger. For å løse problemet kan du bytte til sending via SMTP, deaktivere mail.add_x_header-alternativet i php.ini, bytte til MacOS eller Linux, eller oppgradere PHP til versjon 7.0.17+ eller 7.1.3+.';
$PHPMAILER_LANG['authenticate'] = 'SMTP-feil: Kunne ikke autentiseres.';
$PHPMAILER_LANG['buggy_php'] = 'Din versjon av PHP er berørt av en feil som kan føre til ødelagte meldinger. For å løse problemet kan du bytte til SMTP, deaktivere alternativet mail.add_x_header i php.ini, bytte til MacOS eller Linux eller oppgradere PHP til versjon 7.0.17+ eller 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'SMTP-feil: Kunne ikke koble til SMTP-vert.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-feil: data ikke akseptert.';
$PHPMAILER_LANG['empty_message'] = 'Meldingsinnholdet er tomt';
$PHPMAILER_LANG['empty_message'] = 'Meldingstekst mangler';
$PHPMAILER_LANG['encoding'] = 'Ukjent koding: ';
$PHPMAILER_LANG['execute'] = 'Kunne ikke utføres: ';
$PHPMAILER_LANG['extension_missing'] = 'Utvidelse mangler: ';
$PHPMAILER_LANG['file_access'] = 'Kunne ikke få tilgang til filen: ';
$PHPMAILER_LANG['file_open'] = 'Feil i fil: Kunne ikke åpne filen: ';
$PHPMAILER_LANG['from_failed'] = 'Følgende avsenderadresse mislyktes: ';
$PHPMAILER_LANG['instantiate'] = 'Kunne ikke starte e-postfunksjonen.';
$PHPMAILER_LANG['from_failed'] = 'Følgende Fra-adresse mislyktes: ';
$PHPMAILER_LANG['instantiate'] = 'Kunne ikke instansiere e-postfunksjonen.';
$PHPMAILER_LANG['invalid_address'] = 'Ugyldig adresse: ';
$PHPMAILER_LANG['invalid_header'] = 'Ugyldig headernavn eller verdi';
$PHPMAILER_LANG['invalid_hostentry'] = 'Ugyldig vertsinngang: ';
@ -32,6 +31,3 @@
$PHPMAILER_LANG['smtp_detail'] = 'Detaljer: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfeil: ';
$PHPMAILER_LANG['variable_set'] = 'Kan ikke angi eller tilbakestille variabel: ';
$PHPMAILER_LANG['no_smtputf8'] = 'Serveren støtter ikke SMTPUTF8, som er nødvendig for å sende til Unicode-adresser.';
$PHPMAILER_LANG['imap_recommended'] = 'Det anbefales ikke å bruke forenklet adresseanalyse. Installer PHP IMAP-utvidelsen for full RFC822-analyse.';
$PHPMAILER_LANG['deprecated_argument'] = 'Avviklet argument: ';

View File

@ -4,11 +4,10 @@
* Dutch PHPMailer language file: refer to PHPMailer.php for definitive list.
* @package PHPMailer
* @author Tuxion <team@tuxion.nl>
* @author Robin van der Vliet <info@robinvandervliet.com>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP-fout: authenticatie mislukt.';
$PHPMAILER_LANG['buggy_php'] = 'PHP-versie gedetecteerd die onderhevig is aan een bug die kan resulteren in gecorrumpeerde berichten. Om dit te voorkomen, gebruik SMTP voor het verzenden van berichten, zet de optie mail.add_x_header in uw php.ini uit, gebruik MacOS of Linux, of pas de gebruikte PHP-versie aan naar versie 7.0.17+ or 7.1.3+.';
$PHPMAILER_LANG['buggy_php'] = 'PHP versie gededecteerd die onderhavig is aan een bug die kan resulteren in gecorrumpeerde berichten. Om dit te voorkomen, gebruik SMTP voor het verzenden van berichten, zet de mail.add_x_header optie in uw php.ini file uit, gebruik MacOS of Linux, of pas de gebruikte PHP versie aan naar versie 7.0.17+ or 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'SMTP-fout: kon niet verbinden met SMTP-host.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-fout: data niet geaccepteerd.';
$PHPMAILER_LANG['empty_message'] = 'Berichttekst is leeg';
@ -17,22 +16,19 @@ $PHPMAILER_LANG['execute'] = 'Kon niet uitvoeren: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensie afwezig: ';
$PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: ';
$PHPMAILER_LANG['file_open'] = 'Bestandsfout: kon bestand niet openen: ';
$PHPMAILER_LANG['from_failed'] = 'Het volgende afzenderadres is mislukt: ';
$PHPMAILER_LANG['from_failed'] = 'Het volgende afzendersadres is mislukt: ';
$PHPMAILER_LANG['instantiate'] = 'Kon mailfunctie niet initialiseren.';
$PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres: ';
$PHPMAILER_LANG['invalid_header'] = 'Ongeldige headernaam of -waarde';
$PHPMAILER_LANG['invalid_header'] = 'Ongeldige header naam of waarde';
$PHPMAILER_LANG['invalid_hostentry'] = 'Ongeldige hostentry: ';
$PHPMAILER_LANG['invalid_host'] = 'Ongeldige host: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';
$PHPMAILER_LANG['provide_address'] = 'Er moet minstens één ontvanger worden opgegeven.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP-fout: de volgende ontvangers zijn mislukt: ';
$PHPMAILER_LANG['signing'] = 'Signeerfout: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP-code: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Aanvullende SMTP-informatie: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP-verbinding mislukt.';
$PHPMAILER_LANG['smtp_code'] = 'SMTP code: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Aanvullende SMTP informatie: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Verbinding mislukt.';
$PHPMAILER_LANG['smtp_detail'] = 'Detail: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfout: ';
$PHPMAILER_LANG['variable_set'] = 'Kan de volgende variabele niet instellen of herstellen: ';
$PHPMAILER_LANG['no_smtputf8'] = 'De server ondersteunt geen SMTPUTF8 dat nodig is om naar Unicode-adressen te sturen.';
$PHPMAILER_LANG['imap_recommended'] = 'Het gebruik van de vereenvoudigde adresparser is niet aanbevolen. Installeer de IMAP-extensie voor PHP voor volledige RFC822-ondersteuning.';
$PHPMAILER_LANG['deprecated_argument'] = 'Verouderd argument: ';
$PHPMAILER_LANG['variable_set'] = 'Kan de volgende variabele niet instellen of resetten: ';

View File

@ -5,29 +5,29 @@
* @package PHPMailer
*/
$PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: nie udało się przeprowadzić uwierzytelnienia.';
$PHPMAILER_LANG['buggy_php'] = 'Używana wersja PHP zawiera błąd, który może powodować uszkodzenie wiadomości. Aby temu zapobiec, użyj wysyłki przez SMTP, wyłącz opcję mail.add_x_header w php.ini, przejdź na macOS lub Linux, lub zaktualizuj PHP do wersji 7.0.17+ albo 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: nie udało się połączyć z serwerem (hostem).';
$PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: dane wiadomości nie zostały przyjęte przez serwer.';
$PHPMAILER_LANG['empty_message'] = 'Nie można wysłać pustej wiadomości.';
$PHPMAILER_LANG['encoding'] = 'Nieobsługiwane kodowanie znaków: ';
$PHPMAILER_LANG['execute'] = 'Nie udało się uruchomić polecenia: ';
$PHPMAILER_LANG['extension_missing'] = 'Brak wymaganego rozszerzenia PHP: ';
$PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzić uwierzytelnienia.';
$PHPMAILER_LANG['buggy_php'] = 'Twoja wersja PHP zawiera błąd, który może powodować uszkodzenie wiadomości. Aby go naprawić, przełącz się na wysyłanie za pomocą SMTP, wyłącz opcję mail.add_x_header w php.ini, przełącz się na MacOS lub Linux lub zaktualizuj PHP do wersji 7.0.17+ lub 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
$PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.';
$PHPMAILER_LANG['empty_message'] = 'Wiadomość jest pusta.';
$PHPMAILER_LANG['encoding'] = 'Błędny sposób kodowania znaków: ';
$PHPMAILER_LANG['execute'] = 'Nie można uruchomić: ';
$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';
$PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: ';
$PHPMAILER_LANG['file_open'] = 'Nie udało się otworzyć pliku: ';
$PHPMAILER_LANG['from_failed'] = 'Nieprawidłowy adres nadawcy: ';
$PHPMAILER_LANG['instantiate'] = 'Nie można zainicjować funkcji mail(). Sprawdź konfigurację serwera.';
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości. Nieprawidłowy adres odbiorcy: ';
$PHPMAILER_LANG['invalid_header'] = 'Nieprawidłowa nazwa lub wartość nagłówka.';
$PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: ';
$PHPMAILER_LANG['from_failed'] = 'Następujący adres nadawcy jest nieprawidłowy lub nie istnieje: ';
$PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' . 'następujący adres odbiorcy jest nieprawidłowy lub nie istnieje: ';
$PHPMAILER_LANG['invalid_header'] = 'Nieprawidłowa nazwa lub wartość nagłówka';
$PHPMAILER_LANG['invalid_hostentry'] = 'Nieprawidłowy wpis hosta: ';
$PHPMAILER_LANG['invalid_host'] = 'Nieprawidłowa nazwa hosta: ';
$PHPMAILER_LANG['provide_address'] = 'Musisz podać co najmniej jeden prawidłowy adres e-mail odbiorcy.';
$PHPMAILER_LANG['invalid_host'] = 'Nieprawidłowy host: ';
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email odbiorcy.';
$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: nie udało się wysłać do następujących odbiorców: ';
$PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości cyfrowo: ';
$PHPMAILER_LANG['smtp_code'] = 'Kod odpowiedzi SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Dodatkowe informacje serwera SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Nie udało się nawiązać połączenia za pomocą SMTP Connect().';
$PHPMAILER_LANG['smtp_detail'] = 'Szczegóły błędu: ';
$PHPMAILER_LANG['smtp_error'] = 'Błąd serwera SMTP: ';
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi lub nie istnieją: ';
$PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: ';
$PHPMAILER_LANG['smtp_code'] = 'Kod SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Dodatkowe informacje SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Wywołanie funkcji SMTP Connect() zostało zakończone niepowodzeniem.';
$PHPMAILER_LANG['smtp_detail'] = 'Szczegóły: ';
$PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';

View File

@ -3,32 +3,25 @@
/**
* Portuguese (European) PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author João Vieira <mail@joaovieira.eu>
* @author Jonadabe <jonadabe@hotmail.com>
*/
$PHPMAILER_LANG['authenticate'] = 'Erro SMTP: Falha na autenticação.';
$PHPMAILER_LANG['buggy_php'] = 'A sua versão do PHP tem um bug que pode causar mensagens corrompidas. Para resolver, utilize o envio por SMTP, desative a opção mail.add_x_header no ficheiro php.ini, mude para MacOS ou Linux, ou atualize o PHP para a versão 7.0.17+ ou 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Erro SMTP: Não foi possível ligar ao servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erro SMTP: Dados não aceites.';
$PHPMAILER_LANG['empty_message'] = 'A mensagem de e-mail está vazia.';
$PHPMAILER_LANG['authenticate'] = 'Erro do SMTP: Não foi possível realizar a autenticação.';
$PHPMAILER_LANG['connect_host'] = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erro do SMTP: Os dados foram rejeitados.';
$PHPMAILER_LANG['empty_message'] = 'A mensagem no e-mail está vazia.';
$PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: ';
$PHPMAILER_LANG['execute'] = 'Não foi possível executar: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensão em falta: ';
$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder ao ficheiro: ';
$PHPMAILER_LANG['file_open'] = 'Erro ao abrir o ficheiro: ';
$PHPMAILER_LANG['from_failed'] = 'O envio falhou para o seguinte endereço do remetente: ';
$PHPMAILER_LANG['instantiate'] = 'Não foi possível instanciar a função mail.';
$PHPMAILER_LANG['invalid_address'] = 'Endereço de e-mail inválido: ';
$PHPMAILER_LANG['invalid_header'] = 'Nome ou valor do cabeçalho inválido.';
$PHPMAILER_LANG['invalid_hostentry'] = 'Entrada de host inválida: ';
$PHPMAILER_LANG['invalid_host'] = 'Host inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = 'O cliente de e-mail não é suportado.';
$PHPMAILER_LANG['provide_address'] = 'Deve fornecer pelo menos um endereço de destinatário.';
$PHPMAILER_LANG['recipients_failed'] = 'Erro SMTP: Falha no envio para os seguintes destinatários: ';
$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder o ficheiro: ';
$PHPMAILER_LANG['file_open'] = 'Abertura do ficheiro: Não foi possível abrir o ficheiro: ';
$PHPMAILER_LANG['from_failed'] = 'Ocorreram falhas nos endereços dos seguintes remententes: ';
$PHPMAILER_LANG['instantiate'] = 'Não foi possível iniciar uma instância da função mail.';
$PHPMAILER_LANG['invalid_address'] = 'Não foi enviado nenhum e-mail para o endereço de e-mail inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';
$PHPMAILER_LANG['provide_address'] = 'Tem de fornecer pelo menos um endereço como destinatário do e-mail.';
$PHPMAILER_LANG['recipients_failed'] = 'Erro do SMTP: O endereço do seguinte destinatário falhou: ';
$PHPMAILER_LANG['signing'] = 'Erro ao assinar: ';
$PHPMAILER_LANG['smtp_code'] = 'Código SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Informações adicionais SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Falha na função SMTP connect().';
$PHPMAILER_LANG['smtp_detail'] = 'Detalhes: ';
$PHPMAILER_LANG['smtp_error'] = 'Erro do servidor SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.';
$PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensão em falta: ';

View File

@ -27,26 +27,16 @@
<exclude name="PSR2.Methods.MethodDeclaration.Underscore"/>
<exclude name="PSR12.Properties.ConstantVisibility.NotFound"/>
</rule>
<rule ref="PHPCompatibility"/>
<!--
#############################################################################
SELECTIVE EXCLUSIONS
Exclude specific files for specific sniffs and/or exclude sub-groups in sniffs.
#############################################################################
-->
<rule ref="PHPCompatibility">
<exclude name="PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_1_clientFound"/>
<exclude name="PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_2_clientFound"/>
<exclude name="PHPCompatibility.Constants.RemovedConstants.intl_idna_variant_2003Deprecated"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.random_bytesFound"/>
<exclude name="PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated"/>
<exclude name="PHPCompatibility.ParameterValues.NewIDNVariantDefault.NotSet"/>
</rule>
<rule ref="Generic.Files.LineLength.TooLong">
<exclude-pattern>*/language/phpmailer\.lang*\.php$</exclude-pattern>
</rule>
<!-- Excludes related to linting ignore comment for one specific test file. -->
<rule ref="PSR12.Files.OpenTag.NotAlone">
<exclude-pattern>*/test/Fixtures/LocalizationTest/phpmailer.lang-yz\.php</exclude-pattern>
</rule>
<rule ref="PSR12.Files.FileHeader.SpacingAfterBlock">
<exclude-pattern>*/test/Fixtures/LocalizationTest/phpmailer.lang-yz\.php</exclude-pattern>
</rule>
</ruleset>

File diff suppressed because it is too large Load Diff

View File

@ -45,9 +45,8 @@ class POP3
* The POP3 PHPMailer Version number.
*
* @var string
* @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead.
*/
const VERSION = '7.0.2';
const VERSION = '6.9.2';
/**
* Default POP3 port number.

View File

@ -34,9 +34,8 @@ class SMTP
* The PHPMailer SMTP version number.
*
* @var string
* @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead.
*/
const VERSION = '7.0.2';
const VERSION = '6.9.2';
/**
* SMTP line break constant.
@ -63,7 +62,7 @@ class SMTP
* The maximum line length allowed by RFC 5321 section 4.5.3.1.6,
* *excluding* a trailing CRLF break.
*
* @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.6
* @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.6
*
* @var int
*/
@ -73,7 +72,7 @@ class SMTP
* The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5,
* *including* a trailing CRLF line break.
*
* @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.5
* @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.5
*
* @var int
*/
@ -160,15 +159,6 @@ class SMTP
*/
public $do_verp = false;
/**
* Whether to use SMTPUTF8.
*
* @see https://www.rfc-editor.org/rfc/rfc6531
*
* @var bool
*/
public $do_smtputf8 = false;
/**
* The timeout value for connection, in seconds.
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
@ -206,7 +196,6 @@ class SMTP
'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
'ZoneMTA' => '/[\d]{3} Message queued as (.*)/',
'Mailjet' => '/[\d]{3} OK queued as (.*)/',
'Gsmtp' => '/[\d]{3} 2\.0\.0 OK (.*) - gsmtp/',
];
/**
@ -384,7 +373,7 @@ class SMTP
}
//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://www.rfc-editor.org/rfc/rfc5321#section-3.1
//https://tools.ietf.org/html/rfc5321#section-3.1
if ($responseCode === 554) {
$this->quit();
}
@ -495,9 +484,7 @@ class SMTP
//PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
//so add them back in manually if we can
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
// phpcs:ignore PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_2_clientFound
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
// phpcs:ignore PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_1_clientFound
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
}
@ -595,7 +582,7 @@ class SMTP
}
//Send encoded username and password
if (
//Format from https://www.rfc-editor.org/rfc/rfc4616#section-2
//Format from https://tools.ietf.org/html/rfc4616#section-2
//We skip the first field (it's forgery), so the string starts with a null byte
!$this->sendCommand(
'User & Password',
@ -636,48 +623,11 @@ class SMTP
if (null === $OAuth) {
return false;
}
try {
$oauth = $OAuth->getOauth64();
} catch (\Exception $e) {
// We catch all exceptions and convert them to PHPMailer exceptions to be able to
// handle them correctly later
throw new Exception("SMTP authentication error", 0, $e);
}
/*
* An SMTP command line can have a maximum length of 512 bytes, including the command name,
* so the base64-encoded OAUTH token has a maximum length of:
* 512 - 13 (AUTH XOAUTH2) - 2 (CRLF) = 497 bytes
* If the token is longer than that, the command and the token must be sent separately as described in
* https://www.rfc-editor.org/rfc/rfc4954#section-4
*/
if ($oauth === '') {
//Sending an empty auth token is legitimate, but it must be encoded as '='
//to indicate it's not a 2-part command
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 =', 235)) {
return false;
}
} elseif (strlen($oauth) <= 497) {
//Authenticate using a token in the initial-response part
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
return false;
}
} else {
//The token is too long, so we need to send it in two parts.
//Send the auth command without a token and expect a 334
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2', 334)) {
return false;
}
//Send the token
if (!$this->sendCommand('OAuth TOKEN', $oauth, [235, 334])) {
return false;
}
//If the server answers with 334, send an empty line and wait for a 235
if (
substr($this->last_reply, 0, 3) === '334'
&& $this->sendCommand('AUTH End', '', 235)
) {
return false;
}
$oauth = $OAuth->getOauth64();
//Start authentication
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
return false;
}
break;
default:
@ -770,25 +720,6 @@ 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.
* Issues a data command and sends the msg_data to the server,
@ -817,16 +748,15 @@ class SMTP
* NOTE: this does not count towards line-length limit.
*/
//Iterate over lines with normalized line breaks
$lines = $this->iterateLines($msg_data);
//Normalize line breaks before exploding
$lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data));
/* 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
* process all lines before a blank line as headers.
*/
$first_line = $lines->current();
$field = substr($first_line, 0, strpos($first_line, ':'));
$field = substr($lines[0], 0, strpos($lines[0], ':'));
$in_headers = false;
if (!empty($field) && strpos($field, ' ') === false) {
$in_headers = true;
@ -865,7 +795,7 @@ class SMTP
//Send the lines to the server
foreach ($lines_out as $line_out) {
//Dot-stuffing as per RFC5321 section 4.5.2
//https://www.rfc-editor.org/rfc/rfc5321#section-4.5.2
//https://tools.ietf.org/html/rfc5321#section-4.5.2
if (!empty($line_out) && $line_out[0] === '.') {
$line_out = '.' . $line_out;
}
@ -983,15 +913,7 @@ class SMTP
* $from. Returns true if successful or false otherwise. If True
* the mail transaction is started and then one or more recipient
* commands may be called followed by a data command.
* Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF> and
* two extensions, namely XVERP and SMTPUTF8.
*
* The server's EHLO response is not checked. If use of either
* extensions is enabled even though the server does not support
* that, mail submission will fail.
*
* XVERP is documented at https://www.postfix.org/VERP_README.html
* and SMTPUTF8 is specified in RFC 6531.
* Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF>.
*
* @param string $from Source address of this message
*
@ -1000,11 +922,10 @@ class SMTP
public function mail($from)
{
$useVerp = ($this->do_verp ? ' XVERP' : '');
$useSmtputf8 = ($this->do_smtputf8 ? ' SMTPUTF8' : '');
return $this->sendCommand(
'MAIL FROM',
'MAIL FROM:<' . $from . '>' . $useSmtputf8 . $useVerp,
'MAIL FROM:<' . $from . '>' . $useVerp,
250
);
}
@ -1370,16 +1291,7 @@ class SMTP
//stream_select returns false when the `select` system call is interrupted
//by an incoming signal, try the select again
if (
stripos($message, 'interrupted system call') !== false ||
(
// on applications with a different locale than english, the message above is not found because
// it's translated. So we also check for the SOCKET_EINTR constant which is defined under
// Windows and UNIX-like platforms (if available on the platform).
defined('SOCKET_EINTR') &&
stripos($message, 'stream_select(): Unable to select [' . SOCKET_EINTR . ']') !== false
)
) {
if (stripos($message, 'interrupted system call') !== false) {
$this->edebug(
'SMTP -> get_lines(): retrying stream_select',
self::DEBUG_LOWLEVEL
@ -1452,26 +1364,6 @@ class SMTP
return $this->do_verp;
}
/**
* Enable or disable use of SMTPUTF8.
*
* @param bool $enabled
*/
public function setSMTPUTF8($enabled = false)
{
$this->do_smtputf8 = $enabled;
}
/**
* Get SMTPUTF8 use.
*
* @return bool
*/
public function getSMTPUTF8()
{
return $this->do_smtputf8;
}
/**
* Set error messages and codes.
*

View File

@ -1,31 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIUPVCD/ME/tR7lrcNY0eLMignHqywwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNTA5MTExOTI4MDdaFw0zNTA5
MDkxOTI4MDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQDHDtSUM73CqVfUt5hhBIbz56ENE746CqgqCqYpKypQ
frCDbcaRWagg9JOy4k9BChB4/B8wZilF9vsmfFoIa0H+LmQWQLN1pVx2tuSWI9rw
CdmTm6cXFZCxleOQMFxzmzV53gK9y2YRxAYL/hm6mcWp6Rblv0SqyxBz+GPJLLrr
cVRIgkktEia7ENA56DWpLoi49xYUwnDN3o+PwtrPGEzwsH/25zhEyS1LlcfRM3pY
W9UGX8HtU1LB94dWoVWNvISFvjicCWhVsuNw1Z0tIko499iEQG+zezbmh++n9a2G
bkCaI6dFZL5pHakmKOTYKyZ1sprE4799KDSTd8hlPfHboC4ClWqIiI6ou3kEpJln
sdsNZP5vPHrDgjuW/oE+zsQjmkaJiWaZphpthyYkR32Xu7HPvtQT4MHfkrs/SFE0
43ml8CqrGSa+IjSjI+HXMwsf0mRmEtK7PcqVLhdSWAGjMNPjJ+er/O+PX3ZAWrbl
GzJfYU5LAk1ES/8uKpB+TjAXDL8xyM0+aP0axEeU57SyTNqbVfimrA250KZ+Q3hk
dpTWlTEjCXhxGHXdiJJwFPyanCNstFuKgNHTbmdRTMKIQ+Wmu5EgUSH2GcRZg9oO
t2veQP3EIc9dIxzijUFETWuBqzi80D6rKJJ1KowJE0rdh7owI/SCHNOYgjSN5a0G
XQIDAQABo1MwUTAdBgNVHQ4EFgQUzSwRCSiJnYQsy99FkcsdWzHJjIwwHwYDVR0j
BBgwFoAUzSwRCSiJnYQsy99FkcsdWzHJjIwwDwYDVR0TAQH/BAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAgEAVZApbeRypzpwv2d8B/kPcIRcq5Kot0HhTDr9CNvGqU0G
TwQrVyIVAzi0uX+Ki7flj3+bo1br9xR/ocKbnTbEA3ofCxEbf0KGEjiwvB7tAg22
UeFBxdAZG2IJcwwmY779IHKmjmFgrWGbXTirrN2a3i5TYU/nrTp7yY3GFQFujt5q
hQXBnkEvubS3n9ImdA0ByWCgmYiS08v8HGgsgGs9xVe1idkDkD+5I1imCADvUh7I
0ZksoB/XpdHRaqTRF0h6G2EUXznOG7x04uG4tiHkim1W4IkBBVTLxp6iul9n8GAe
QoZadHGaPIeytwl7A986Qo78WIltxZC+SBjJeQJG7/qHt/MvB8dBXZ49zg1SmHeV
ZtBWdtC0LBGcLoImm9m7DCyA9xMqSKSoOqmzXTlWcKQnPi3MeI5dqfWzuvk9LyLg
71hXXF4EnTgZpHw1ZWJBI47jEfsH2G0c7X46HPYjD4XcDCChNG81d0xQpZMbq5J7
jy6PSbE/iGghEOuiF1NpQsrAnlf0UAzA27bUPyX0NFOmQmAejc8b6NqIljSQE/Xm
MOZlE4RpIa63EzzDo1fas8hhUhtz3loYysHN+nmw4N0BRjVenxatJXiunIbsDkzJ
VeBTrddQlqszd0qOlGCpJM0uhHuVDPntHKmFLo7O32aH2TgvYakpp54Xd+4xIqM=
-----END CERTIFICATE-----

View File

@ -1,52 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQDHDtSUM73CqVfU
t5hhBIbz56ENE746CqgqCqYpKypQfrCDbcaRWagg9JOy4k9BChB4/B8wZilF9vsm
fFoIa0H+LmQWQLN1pVx2tuSWI9rwCdmTm6cXFZCxleOQMFxzmzV53gK9y2YRxAYL
/hm6mcWp6Rblv0SqyxBz+GPJLLrrcVRIgkktEia7ENA56DWpLoi49xYUwnDN3o+P
wtrPGEzwsH/25zhEyS1LlcfRM3pYW9UGX8HtU1LB94dWoVWNvISFvjicCWhVsuNw
1Z0tIko499iEQG+zezbmh++n9a2GbkCaI6dFZL5pHakmKOTYKyZ1sprE4799KDST
d8hlPfHboC4ClWqIiI6ou3kEpJlnsdsNZP5vPHrDgjuW/oE+zsQjmkaJiWaZphpt
hyYkR32Xu7HPvtQT4MHfkrs/SFE043ml8CqrGSa+IjSjI+HXMwsf0mRmEtK7PcqV
LhdSWAGjMNPjJ+er/O+PX3ZAWrblGzJfYU5LAk1ES/8uKpB+TjAXDL8xyM0+aP0a
xEeU57SyTNqbVfimrA250KZ+Q3hkdpTWlTEjCXhxGHXdiJJwFPyanCNstFuKgNHT
bmdRTMKIQ+Wmu5EgUSH2GcRZg9oOt2veQP3EIc9dIxzijUFETWuBqzi80D6rKJJ1
KowJE0rdh7owI/SCHNOYgjSN5a0GXQIDAQABAoIB/3KwmMrLBQqjh3eIUMOVWCwv
yRs/xNqsSTfv6szNkhPO6uTO2xnkDnrucCshOYi/w73xhgbc1er54rrJ6xXutpc9
I22u2bdvD1dXCV14Sy0Cf9oMVLl4M2Yedn8dXic9xhHxWKMCDk0uJE3Emg5pivna
0taM3YOKfHBVLSk8HHaLVYRxjLfrPWWKym6S3Fgd96iatJ5Bab0z/oNWQbwQxEPp
bdFUZ5c6Ul66beabQmKmhpallZan64bWl6PSUPjZJYHpl7RPt02pRGI+sdDPcPRh
2N5aQgGnfHpW2D5tzw0leRNWd4oEAbGO5WaXKUNjmUU3IvVOQ4ZZI/HTkiLDDhX3
DATtfJg5aUXxy/MmlEebHrG0onidu3YZPel8Yj6JY0P7j1lSUcGiXvm6zgpNWk3p
wpWD1KFIc8lJdeSsWtGs1f1SEUkzbjZu/TwHMJfVxY2GWqVsHtiTiDitsbgWhxVX
Th8Vd12yq7DfjxhHO0ZkobUDaOPem32FrnjVyWf/ZEDAOLTZpeycXnCQWEqU2R7T
G78e/o1rwdclRo/kElQ5ksRs2y9mKUpwYSAqMZFFMSh6sXSbuydE7FPd0njX9ypS
+3OgeIntFG1RMspltJTMtJgPhExTkB2yf78jUFrtV7wGCZDDkKDkB+aLkGH0eygT
M+doZSJgFy2fvdYxmzMCggEBAPuQzgO6ab7zfGcaHhlbhXpHl9twMQefYGdH/DVx
yS91Ef1ygUsEgAICNIYAX6bvaBBL6akTf9kMbixo8j47KM6o6uR2ogze9z4nnKUk
Xxsj+CIJz6ImlGdDzMziCwB9wK3duwsxovZBWh2oSgKgvU52kgurI+AW0kKFn1rH
axwlVHoCG+XhiwlUZGD4tD8L0qjzWIn+T/0T4kKAEAvTleG/KZNkCRbOS3mycwrM
ouJGGkdapt5Fh/cmnv+lO5wh5QbkYaJS/kpUkYGljy1/s3HTlvDsw955dADeH1+0
+/2nwfK54dgoB8m037AyIqrwKY6dhGDES7cTUZ5AqiAtJ7MCggEBAMqRFV9YbyBg
Ktgni4Q/vXLCqsaZN7JVnKxjiCqbpJ8UZuGv4Ifalq8npwo0634Hfi10p/54TKxy
gJrUKFwYqffovj7N4mYn0YpRSic5WouN93IIt83ugZ12pU1lL2vp/MX5sWqpGvb/
GyWZ8yfKkJY5dW937j38i9iUeDhW+YksK1RNNrz9crUP5H9zk42EE2h/AHItPMvx
lAktAzB4KuvIrCRMedSO6m+bYpq5P89Vbq2Ovl7fwJWvYDAEUUe7hhkrUDDOxHu/
w1zkdf62YVZ0BAfY1uGEAPr+pJE9Uyy1lW5C0qLRZrOiEXDd7i9Q9rIyZwPBD76+
csaWPGYkEa8CggEBAN3zjrBfYjklXlchBflddFDEpcjoHXoaNdYp/u2wbM7APZUd
19E2MTKUe37XCY2hoHDwaUHRgHUhsHriRQh+7awYANZ9jNBKUF24WU6i3n51p9Fw
Uo8/9qN9gE4sCYTvbnZ4MTTZIGygkD+mYVYcN6nol0ZQQqDNwckLV+OiGnCExxm2
jqKt8hvTJ5UfGPifF8gUm8N0a2JgjroZfw7QKWc5YBc4pYRHkvPWbAXVMsjtDPZz
ltJ5ClMW8iWfxQ4mIYmJKlMrYkx2fMKkLcT47Hu7MWtzmgTJp320fH3WkpXj0wyy
z/4Eo4plWQ59zXR/3EqF02wFBMCL/PDhILiu3l0CggEADdmnrXI9fug0Zb0mc+9r
w6n9xUB6p23lHYBcshUcR2g8tJey8XcHsIg0iqUdqOtYPEFqryKIk43srylsbQee
r32xbFflb/ivAhcWy+HHCB232oswDhuNrzeKi+UsPeOszdiJwfI4DsVYlNSW5JSc
GDlrhyibGI/o+/EC209PFor3l3cEFB38NtcUV4aOgzGRpiZw4F2pd4RYC9yRCEJf
JOn+oyi7d8Yhz2m/bzbVXxbHT4SgDZqc718jY4UYDaCLxbLJc9zfYFq3P+W7D6Rm
uWOLVwIDhz3gV0kL9YZM5pSv1+8nucw5inS9Xos+GuwdQgfiNUaBDhi1flCNZqp2
rwKCAQA6mdcJJJxo7LAAKXKxxWOiTm3rX+6Q0s56/N61cxl1PRGktqKACSXOrizj
DhcKYAVW8taffpEHHWbTTMvB7ypU4b8yTmF9jZlexH9hgM3tGcY+bou44nDiHtsc
ilDjEQgPBagR0LJKz3LOjt3lPQBAxaBydtlPSfBp2YqIwJSl6m3hDt7Q5bCiMh2O
KWHX09Oj4wg/Q82MA4T/t2qOqC5AzJE4diHRHGm1ey+NiXfPY9YdeoeX5CqkfvB+
HNAVmWbSXoNt6Unp1WjLZTaNcBm4+XE7sxM4eDy4ATLEXHIFiCs7Q+axtvILDeSo
ujKpHkhiv0V4kA8yZpxQDcXp84JE
-----END PRIVATE KEY-----

View File

@ -12,5 +12,6 @@ echo $composer;
$PHPMAILER_LANG['extension_missing'] = 'Confirming that test fixture was loaded correctly (yy).';
$PHPMAILER_LANG['empty_message'] = $composer;
$PHPMAILER_LANG['encoding'] = `ls -l`;
$PHPMAILER_LANG['execute'] = exec('some harmful command');
$PHPMAILER_LANG['signing'] = "Double quoted but not interpolated $composer";

View File

@ -1,16 +0,0 @@
<?php // lint < 8.5.
/**
* Test fixture.
*
* Used in the `PHPMailer\LocalizationTest` to test that arbitrary code in translation files is disregarded.
*
* Note: this test fixture uses a syntax (backticks) which has been deprecated in PHP 8.5 and
* is slated for removal in PHP 9.0.
* For that reason, the file is excluded from the linting check on PHP 8.5 and above.
*
* @phpcs:disable PHPCompatibility.LanguageConstructs.RemovedLanguageConstructs.t_backtickDeprecated
*/
$PHPMAILER_LANG['extension_missing'] = 'Confirming that test fixture was loaded correctly (yz).';
$PHPMAILER_LANG['encoding'] = `ls -l`;

View File

@ -36,7 +36,7 @@ final class OAuthTest extends TestCase
$PHPMailer = new PHPMailer(true);
$reflection = new \ReflectionClass($PHPMailer);
$property = $reflection->getProperty('oauth');
(\PHP_VERSION_ID < 80100) && $property->setAccessible(true);
$property->setAccessible(true);
$property->setValue($PHPMailer, true);
self::assertTrue($PHPMailer->getOAuth(), 'Initial value of oauth property is not true');

View File

@ -14,6 +14,7 @@
namespace PHPMailer\Test\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\Test\SendTestCase;
/**
@ -47,13 +48,13 @@ final class DKIMTest extends SendTestCase
/**
* DKIM body canonicalization tests.
*
* @link https://www.rfc-editor.org/rfc/rfc6376.html#section-3.4.4
* @link https://tools.ietf.org/html/rfc6376#section-3.4.4
*
* @covers \PHPMailer\PHPMailer\PHPMailer::DKIM_BodyC
*/
public function testDKIMBodyCanonicalization()
{
// Example from https://www.rfc-editor.org/rfc/rfc6376.html#section-3.4.5.
// Example from https://tools.ietf.org/html/rfc6376#section-3.4.5.
$prebody = " C \r\nD \t E\r\n\r\n\r\n";
$postbody = " C \r\nD \t E\r\n";
@ -82,13 +83,13 @@ final class DKIMTest extends SendTestCase
/**
* DKIM header canonicalization tests.
*
* @link https://www.rfc-editor.org/rfc/rfc6376.html#section-3.4.2
* @link https://tools.ietf.org/html/rfc6376#section-3.4.2
*
* @covers \PHPMailer\PHPMailer\PHPMailer::DKIM_HeaderC
*/
public function testDKIMHeaderCanonicalization()
{
// Example from https://www.rfc-editor.org/rfc/rfc6376.html#section-3.4.5.
// Example from https://tools.ietf.org/html/rfc6376#section-3.4.5.
$preheaders = "A: X\r\nB : Y\t\r\n\tZ \r\n";
$postheaders = "a:X\r\nb:Y Z\r\n";
self::assertSame(
@ -115,7 +116,7 @@ final class DKIMTest extends SendTestCase
/**
* DKIM copied header fields tests.
*
* @link https://www.rfc-editor.org/rfc/rfc6376.html#section-3.5
* @link https://tools.ietf.org/html/rfc6376#section-3.5
*
* @requires extension openssl
*
@ -134,7 +135,7 @@ final class DKIMTest extends SendTestCase
openssl_pkey_export_to_file($pk, self::PRIVATE_KEY_FILE);
$this->Mail->DKIM_private = self::PRIVATE_KEY_FILE;
// Example from https://www.rfc-editor.org/rfc/rfc6376.html#section-3.5.
// Example from https://tools.ietf.org/html/rfc6376#section-3.5.
$from = 'from@example.com';
$to = 'to@example.com';
$date = 'date';
@ -178,7 +179,7 @@ final class DKIMTest extends SendTestCase
openssl_pkey_export_to_file($pk, self::PRIVATE_KEY_FILE);
$this->Mail->DKIM_private = self::PRIVATE_KEY_FILE;
// Example from https://www.rfc-editor.org/rfc/rfc6376.html#section-3.5.
// Example from https://tools.ietf.org/html/rfc6376#section-3.5.
$from = 'from@example.com';
$to = 'to@example.com';
$date = 'date';
@ -247,7 +248,7 @@ final class DKIMTest extends SendTestCase
public function testDKIMSignOpenSSLNotAvailableException()
{
if (extension_loaded('openssl')) {
self::markTestSkipped('Test requires OpenSSL *not* to be available');
$this->markTestSkipped('Test requires OpenSSL *not* to be available');
}
$this->expectException(Exception::class);

View File

@ -13,6 +13,7 @@
namespace PHPMailer\Test\PHPMailer;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\Test\TestCase;
/**
@ -37,7 +38,7 @@ final class DKIMWithoutExceptionsTest extends TestCase
public function testDKIMSignOpenSSLNotAvailable()
{
if (extension_loaded('openssl')) {
self::markTestSkipped('Test requires OpenSSL *not* to be available');
$this->markTestSkipped('Test requires OpenSSL *not* to be available');
}
$signature = $this->Mail->DKIM_Sign('foo');

View File

@ -39,9 +39,9 @@ final class FileIsAccessibleTest extends TestCase
public function testFileIsAccessible($input, $expected)
{
$reflMethod = new ReflectionMethod(PHPMailer::class, 'fileIsAccessible');
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(true);
$reflMethod->setAccessible(true);
$result = $reflMethod->invoke(null, $input);
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(false);
$reflMethod->setAccessible(false);
self::assertSame($expected, $result);
}
@ -83,7 +83,7 @@ final class FileIsAccessibleTest extends TestCase
{
if (\DIRECTORY_SEPARATOR === '\\') {
// Windows does not respect chmod permissions.
self::markTestSkipped('This test requires a non-Windows OS.');
$this->markTestSkipped('This test requires a non-Windows OS.');
}
$path = dirname(__DIR__) . '/Fixtures/FileIsAccessibleTest/';
@ -91,9 +91,9 @@ final class FileIsAccessibleTest extends TestCase
chmod($file, octdec('0'));
$reflMethod = new ReflectionMethod(PHPMailer::class, 'fileIsAccessible');
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(true);
$reflMethod->setAccessible(true);
$result = $reflMethod->invoke(null, $file);
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(false);
$reflMethod->setAccessible(false);
// Reset to the default for git files before running assertions.
chmod($file, octdec('644'));

View File

@ -56,46 +56,6 @@ final class HasLineLongerThanMaxTest extends PreSendTestCase
);
}
/**
* Test constructing a SMIME signed message that contains lines that are too long for RFC compliance.
*
* @covers \PHPMailer\PHPMailer\PHPMailer::hasLineLongerThanMax
*/
public function testLongBodySmime()
{
$oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::getLE(), 2);
// Use +2 to ensure line length is over limit - LE may only be 1 char.
$badlen = str_repeat(str_repeat('1', PHPMailer::MAX_LINE_LENGTH + 2) . PHPMailer::getLE(), 2);
$this->Mail->Body = 'This message contains lines that are too long.' .
PHPMailer::getLE() . $oklen . $badlen . $oklen;
self::assertTrue(
PHPMailer::hasLineLongerThanMax($this->Mail->Body),
'Test content does not contain long lines!'
);
$this->Mail->isHTML();
$this->buildBody();
#$this->Mail->AltBody = $this->Mail->Body;
$this->Mail->Encoding = '8bit';
$this->Mail->sign(
__DIR__ . '/../Fixtures/HasLineLongerThanMaxTest/cert.pem',
__DIR__ . '/../Fixtures/HasLineLongerThanMaxTest/key.pem',
null
);
$this->Mail->preSend();
$message = $this->Mail->getSentMIMEMessage();
self::assertFalse(
PHPMailer::hasLineLongerThanMax($message),
'Long line not corrected (Max: ' . (PHPMailer::MAX_LINE_LENGTH + strlen(PHPMailer::getLE())) . ' chars)'
);
self::assertStringContainsString(
'Content-Transfer-Encoding: quoted-printable',
$message,
'Long line did not cause transfer encoding switch.'
);
}
/**
* Test constructing a message that does NOT contain lines that are too long for RFC compliance.
*

View File

@ -35,9 +35,9 @@ final class IsPermittedPathTest extends TestCase
public function testIsPermittedPath($input, $expected)
{
$reflMethod = new ReflectionMethod(PHPMailer::class, 'isPermittedPath');
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(true);
$reflMethod->setAccessible(true);
$result = $reflMethod->invoke(null, $input);
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(false);
$reflMethod->setAccessible(false);
self::assertSame($expected, $result);
}

View File

@ -15,7 +15,6 @@ namespace PHPMailer\Test\PHPMailer;
use ReflectionMethod;
use PHPMailer\Test\TestCase;
use PHPMailer\PHPMailer\PHPMailer;
/**
* Test localized error message functionality.
@ -306,6 +305,13 @@ final class LocalizationTest extends TestCase
'The "empty_message" translation is not as expected'
);
self::assertArrayHasKey('encoding', $lang, 'The "encoding" translation key was not found');
self::assertSame(
'Unknown encoding: ',
$lang['encoding'],
'The "encoding" translation is not as expected'
);
self::assertArrayHasKey('execute', $lang, 'The "execute" translation key was not found');
self::assertSame(
'Could not execute: ',
@ -321,37 +327,6 @@ final class LocalizationTest extends TestCase
);
}
/**
* Test that arbitrary code in a language file does not get executed.
*/
public function testSetLanguageDoesNotExecuteCodeWithBackticksInLangFile()
{
$result = $this->Mail->setLanguage(
'yz', // Unassigned lang code.
dirname(__DIR__) . '/Fixtures/LocalizationTest/'
);
$lang = $this->Mail->getTranslations();
self::assertTrue($result, 'Setting the language failed. Translations set to: ' . var_export($lang, true));
self::assertIsArray($lang, 'Translations is not an array');
// Verify that the fixture file was loaded.
self::assertArrayHasKey('extension_missing', $lang, 'The "extension_missing" translation key was not found');
self::assertSame(
'Confirming that test fixture was loaded correctly (yz).',
$lang['extension_missing'],
'The "extension_missing" translation is not as expected'
);
// Verify that arbitrary code in a translation file does not get processed.
self::assertArrayHasKey('encoding', $lang, 'The "encoding" translation key was not found');
self::assertSame(
'Unknown encoding: ',
$lang['encoding'],
'The "encoding" translation is not as expected'
);
}
/**
* Test that text strings passed in from a language file for arbitrary keys do not get processed.
*/
@ -444,13 +419,13 @@ final class LocalizationTest extends TestCase
public function testLang($input, $expected, $langCode = null)
{
if (isset($langCode)) {
PHPMailer::setLanguage($langCode);
$this->Mail->setLanguage($langCode);
}
$reflMethod = new ReflectionMethod(PHPMailer::class, 'lang');
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(true);
$result = $reflMethod->invoke(null, $input);
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(false);
$reflMethod = new ReflectionMethod($this->Mail, 'lang');
$reflMethod->setAccessible(true);
$result = $reflMethod->invoke($this->Mail, $input);
$reflMethod->setAccessible(false);
self::assertSame($expected, $result);
}

View File

@ -20,23 +20,6 @@ use PHPMailer\Test\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.
*
@ -82,6 +65,12 @@ final class MailTransportTest extends SendTestCase
*/
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->buildBody();
$this->Mail->Subject = $this->Mail->Subject . ': mail()';
@ -116,146 +105,4 @@ final class MailTransportTest extends SendTestCase
$msg = $this->Mail->getSentMIMEMessage();
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',
'',
],
];
}
}

View File

@ -253,7 +253,7 @@ EOT;
$PHPMailer = new PHPMailer();
$reflection = new \ReflectionClass($PHPMailer);
$property = $reflection->getProperty('message_type');
(\PHP_VERSION_ID < 80100) && $property->setAccessible(true);
$property->setAccessible(true);
$property->setValue($PHPMailer, 'inline');
self::assertIsString($PHPMailer->createBody());
@ -278,8 +278,6 @@ EOT;
/**
* Send a message containing ISO-8859-1 text.
*
* @requires extension mbstring
*/
public function testHtmlIso8859()
{
@ -597,7 +595,6 @@ EOT;
*/
public function testEmbeddedImage()
{
$this->Mail->From = '';
$this->Mail->msgHTML('<!DOCTYPE html>
<html lang="en">
<head>
@ -616,32 +613,6 @@ EOT;
);
}
/**
* An embedded attachment test with custom cid domain.
*/
public function testEmbeddedImageCustomCidDomain()
{
$result = $this->Mail->setFrom('test@example.com');
self::assertTrue($result, 'setFrom failed');
$this->Mail->msgHTML('<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>E-Mail Inline Image Test</title>
</head>
<body>
<p><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="></p>
</body>
</html>', '', false);
$this->Mail->preSend();
self::assertStringContainsString(
'Content-ID: <bb229a48bee31f5d54ca12dc9bd960c6@example.com>',
$this->Mail->getSentMIMEMessage(),
'Embedded image header encoding incorrect.'
);
}
/**
* An embedded attachment test.
*/
@ -1150,13 +1121,12 @@ EOT;
public function testConvertEncoding()
{
if (!PHPMailer::idnSupported()) {
self::markTestSkipped('Both intl and mbstring extensions are required.');
self::markTestSkipped('intl and/or mbstring extensions are not available');
}
$this->Mail->clearAllRecipients();
//This file is UTF-8 encoded so we have to take a roundabout route
//to make a domain using an ISO-8859-1 character.
//This file is UTF-8 encoded. Create a domain encoded in "iso-8859-1".
$letter = html_entity_decode('&ccedil;', ENT_COMPAT, PHPMailer::CHARSET_ISO88591);
$domain = '@' . 'fran' . $letter . 'ois.ch';
$this->Mail->addAddress('test' . $domain);
@ -1195,7 +1165,7 @@ EOT;
public function testDuplicateIDNRemoved()
{
if (!PHPMailer::idnSupported()) {
self::markTestSkipped('Both intl and mbstring extensions are required.');
self::markTestSkipped('intl and/or mbstring extensions are not available');
}
$this->Mail->clearAllRecipients();
@ -1221,90 +1191,6 @@ EOT;
);
}
/**
* Test that validation doesn't accidentally succeed.
*/
public function testUnsupportedSmtpUTF8()
{
self::assertFalse(PHPMailer::validateAddress('spın̈altap@example.com', 'html5'));
self::assertTrue(PHPMailer::validateAddress('spın̈altap@example.com', 'eai'));
}
/**
* The eai regex is complex and warrants a few extra tests.
*/
public function testStrangeUnicodeEmailAddresses()
{
PHPMailer::$validator = 'eai';
self::assertTrue(PHPMailer::validateAddress('spın̈altap@example.com'));
self::assertTrue(PHPMailer::validateAddress('spın̈altap@spın̈altap.com'));
self::assertTrue(PHPMailer::validateAddress('दूकान@मेरी.दूकान.भारत'));
self::assertTrue(PHPMailer::validateAddress('慕田峪长城@慕田峪长城.网址'));
self::assertFalse(PHPMailer::validateAddress('慕田峪长城@慕田峪长城。网址'));
}
/**
* Test that SMTPUTF8 is allowed unless the caller has made a conscious choice against it.
*/
public function testAutomaticEaiValidation()
{
$this->Mail = new PHPMailer(true);
PHPMailer::$validator = 'php';
$this->Mail->Body = 'Test';
$this->Mail->isSMTP();
self::assertTrue($this->Mail->addAddress('spın̈altap@example.com', ''));
$this->Mail->preSend();
self::assertTrue($this->Mail->needsSMTPUTF8());
}
/**
* Test SMTPUTF8 usage, including when it is not to be used.
*/
public function testSmtpUTF8()
{
PHPMailer::$validator = 'php';
$this->Mail = new PHPMailer(true);
$this->Mail->Body = 'Test';
$this->Mail->isSMTP();
$this->Mail->addAddress('foo@example.com', '');
$this->Mail->preSend();
self::assertFalse($this->Mail->needsSMTPUTF8());
//Beyond this point we need UTF-8 support
if (!PHPMailer::idnSupported()) {
self::markTestSkipped('Both intl and mbstring extensions are required.');
}
//Using a punycodable domain does not need SMTPUTF8
self::assertFalse($this->Mail->needsSMTPUTF8());
$this->Mail->addAddress('foo@spın̈altap.example', '');
$this->Mail->preSend();
self::assertFalse($this->Mail->needsSMTPUTF8());
//Need to use SMTPUTF8, and can.
self::assertTrue($this->Mail->addAddress('spın̈altap@example.com', ''));
$this->Mail->preSend();
self::assertTrue($this->Mail->needsSMTPUTF8());
//If using SMTPUTF8, then the To header should contain
//Unicode@Unicode, for better rendering by clients like Mac
//Outlook.
$this->Mail->addAddress('spın̈altap@spın̈altap.invalid', '');
$this->Mail->preSend();
self::assertStringContainsString('spın̈altap@spın̈altap.invalid', $this->Mail->createHeader());
//Sending unencoded UTF8 is legal when SMTPUTF8 is used,
//except that body parts have to be encoded if they
//accidentally contain any lines that match the MIME boundary
//lines. It also looks good, so let's do it.
$this->Mail->Subject = 'Spın̈al Tap';
self::assertStringContainsString('Spın̈al', $this->Mail->createHeader());
$this->Mail->Body = 'Spın̈al Tap';
$this->Mail->preSend();
self::assertStringContainsString('Spın̈al', $this->Mail->createBody());
}
/**
* Test SMTP Xclient options
*/

View File

@ -14,14 +14,147 @@
namespace PHPMailer\Test\PHPMailer;
use PHPMailer\PHPMailer\PHPMailer;
use ReflectionMethod;
use Yoast\PHPUnitPolyfills\TestCases\TestCase;
/**
* Test RFC822 address splitting.
*
* @todo Additional tests need to be added to verify the correct handling of inputs which
* include a different encoding than UTF8 or even mixed encoding. For more information
* on what these test cases should look like and should test, please see
* {@link https://github.com/PHPMailer/PHPMailer/pull/2449} for context.
*
* @covers \PHPMailer\PHPMailer\PHPMailer::parseAddresses
*/
final class ParseAddressesTest extends TestCase
{
/**
* Test RFC822 address splitting using the PHPMailer native implementation
* with the Mbstring extension available.
*
* @requires extension mbstring
*
* @dataProvider dataAddressSplitting
*
* @param string $addrstr The address list string.
* @param array $expected The expected function output.
* @param string $charset Optional. The charset to use.
*/
public function testAddressSplittingNative($addrstr, $expected, $charset = null)
{
if (isset($charset)) {
$parsed = PHPMailer::parseAddresses($addrstr, false, $charset);
} else {
$parsed = PHPMailer::parseAddresses($addrstr, false);
}
$expectedOutput = $expected['default'];
if (empty($expected['native+mbstring']) === false) {
$expectedOutput = $expected['native+mbstring'];
} elseif (empty($expected['native']) === false) {
$expectedOutput = $expected['native'];
}
$this->verifyExpectations($parsed, $expectedOutput);
}
/**
* Test RFC822 address splitting using the IMAP implementation
* with the Mbstring extension available.
*
* @requires extension imap
* @requires extension mbstring
*
* @dataProvider dataAddressSplitting
*
* @param string $addrstr The address list string.
* @param array $expected The expected function output.
* @param string $charset Optional. The charset to use.
*/
public function testAddressSplittingImap($addrstr, $expected, $charset = null)
{
if (isset($charset)) {
$parsed = PHPMailer::parseAddresses($addrstr, true, $charset);
} else {
$parsed = PHPMailer::parseAddresses($addrstr, true);
}
$expectedOutput = $expected['default'];
if (empty($expected['imap+mbstring']) === false) {
$expectedOutput = $expected['imap+mbstring'];
} elseif (empty($expected['imap']) === false) {
$expectedOutput = $expected['imap'];
}
$this->verifyExpectations($parsed, $expectedOutput);
}
/**
* Test RFC822 address splitting using the PHPMailer native implementation
* without the Mbstring extension.
*
* @dataProvider dataAddressSplitting
*
* @param string $addrstr The address list string.
* @param array $expected The expected function output.
* @param string $charset Optional. The charset to use.
*/
public function testAddressSplittingNativeNoMbstring($addrstr, $expected, $charset = null)
{
if (extension_loaded('mbstring')) {
$this->markTestSkipped('Test requires MbString *not* to be available');
}
if (isset($charset)) {
$parsed = PHPMailer::parseAddresses($addrstr, false, $charset);
} else {
$parsed = PHPMailer::parseAddresses($addrstr, false);
}
$expectedOutput = $expected['default'];
if (empty($expected['native--mbstring']) === false) {
$expectedOutput = $expected['native--mbstring'];
} elseif (empty($expected['native']) === false) {
$expectedOutput = $expected['native'];
}
$this->verifyExpectations($parsed, $expectedOutput);
}
/**
* Test RFC822 address splitting using the IMAP implementation
* without the Mbstring extension.
*
* @requires extension imap
*
* @dataProvider dataAddressSplitting
*
* @param string $addrstr The address list string.
* @param array $expected The expected function output.
* @param string $charset Optional. The charset to use.
*/
public function testAddressSplittingImapNoMbstring($addrstr, $expected, $charset = null)
{
if (extension_loaded('mbstring')) {
$this->markTestSkipped('Test requires MbString *not* to be available');
}
if (isset($charset)) {
$parsed = PHPMailer::parseAddresses($addrstr, true, $charset);
} else {
$parsed = PHPMailer::parseAddresses($addrstr, true);
}
$expectedOutput = $expected['default'];
if (empty($expected['imap--mbstring']) === false) {
$expectedOutput = $expected['imap--mbstring'];
} elseif (empty($expected['imap']) === false) {
$expectedOutput = $expected['imap'];
}
$this->verifyExpectations($parsed, $expectedOutput);
}
/**
* Verify the expectations.
*
@ -40,135 +173,19 @@ final class ParseAddressesTest extends TestCase
);
}
/**
* Test RFC822 address splitting using the native implementation
*
* @dataProvider dataAddressSplittingNative
* @covers \PHPMailer\PHPMailer\PHPMailer::parseSimplerAddresses
*
* @param string $addrstr The address list string.
* @param array $expected The expected function output.
* @param string $charset Optional.The charset to use.
*/
public function testAddressSplittingNative($addrstr, $expected, $charset = PHPMailer::CHARSET_ISO88591)
{
set_error_handler(static function ($errno, $errstr) {
throw new \Exception($errstr, $errno);
}, E_USER_NOTICE);
try {
$this->expectException(\Exception::class);
$reflMethod = new ReflectionMethod(PHPMailer::class, 'parseSimplerAddresses');
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(true);
$parsed = $reflMethod->invoke(null, $addrstr, $charset);
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(false);
$this->verifyExpectations($parsed, $expected);
} finally {
restore_error_handler();
}
}
/**
* Data provider for testAddressSplittingNative.
*
* @return array
* addrstr: string,
* expected: array{name: string, address: string}[]
* charset: string
*/
public function dataAddressSplittingNative()
{
return [
'Valid address: single address without name' => [
'addrstr' => 'joe@example.com',
'expected' => [
['name' => '', 'address' => 'joe@example.com'],
],
],
'Valid address: two addresses with names' => [
'addrstr' => 'Joe User <joe@example.com>, Jill User <jill@example.net>',
'expected' => [
['name' => 'Joe User', 'address' => 'joe@example.com'],
['name' => 'Jill User', 'address' => 'jill@example.net'],
],
],
];
}
/**
* Test if email addresses are parsed and split into a name and address.
*
* @dataProvider dataParseEmailString
* @covers \PHPMailer\PHPMailer\PHPMailer::parseEmailString
* @param mixed $addrstr
* @param mixed $expected
*/
public function testParseEmailString($addrstr, $expected)
{
$reflMethod = new ReflectionMethod(PHPMailer::class, 'parseEmailString');
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(true);
$parsed = $reflMethod->invoke(null, $addrstr);
(\PHP_VERSION_ID < 80100) && $reflMethod->setAccessible(false);
$this->assertEquals($parsed, $expected);
}
/**
* Data provider for testParseEmailString.
*
* @return array The array is expected to have an `addrstr` and an `expected` key.
*/
public function dataParseEmailString()
{
return [
'Valid address: simple address' => [
'addrstr' => 'Joe User <joe@example.com>',
'expected' => ['name' => 'Joe User', 'email' => 'joe@example.com'],
],
'Valid address: simple address with double quotes' => [
'addrstr' => '"Joe User" <joe@example.com>',
'expected' => ['name' => 'Joe User', 'email' => 'joe@example.com'],
],
'Valid address: simple address with single quotes' => [
'addrstr' => '\'Joe User\' <joe@example.com>',
'expected' => ['name' => 'Joe User', 'email' => 'joe@example.com'],
],
'Valid address: complex address with single quotes' => [
'addrstr' => '\'Joe<User\' <joe@example.com>',
'expected' => ['name' => 'Joe<User', 'email' => 'joe@example.com'],
],
'Valid address: complex address with triangle bracket' => [
'addrstr' => '"test<stage" <test@example.com>',
'expected' => ['name' => 'test<stage', 'email' => 'test@example.com'],
],
];
}
/**
* Test RFC822 address splitting using the PHPMailer implementation
*
* @dataProvider dataAddressSplitting
* @covers \PHPMailer\PHPMailer\PHPMailer::parseAddresses
*
* @requires extension imap
* @requires extension mbstring
*
* @param string $addrstr The address list string.
* @param array $expected The expected function output.
* @param string $charset Optional. The charset to use.
*/
public function testAddressSplitting($addrstr, $expected)
{
$parsed = PHPMailer::parseAddresses($addrstr, null, PHPMailer::CHARSET_UTF8);
$this->verifyExpectations($parsed, $expected);
}
/**
* Data provider.
*
* @return array The array is expected to have an `addrstr` and an `expected` key.
* The `expected` key should - as a minimum.
* The `expected` key should - as a minimum - have a `default` key.
* Optionally, the following extra keys are supported:
* - `native` Expected output from the native implementation with or without Mbstring.
* - `native+mbstring` Expected output from the native implementation with Mbstring.
* - `native--mbstring` Expected output from the native implementation without Mbstring.
* - `imap` Expected output from the IMAP implementation with or without Mbstring.
* - `imap+mbstring` Expected output from the IMAP implementation with Mbstring.
* - `imap--mbstring` Expected output from the IMAP implementation without Mbstring.
* Also optionally, an additional `charset` key can be passed,
*/
public function dataAddressSplitting()
{
@ -177,39 +194,54 @@ final class ParseAddressesTest extends TestCase
'Valid address: single address without name' => [
'addrstr' => 'joe@example.com',
'expected' => [
'default' => [
['name' => '', 'address' => 'joe@example.com'],
],
],
],
'Valid address: single address with name' => [
'addrstr' => 'Joe User <joe@example.com>',
'expected' => [
['name' => 'Joe User', 'address' => 'joe@example.com'],
'default' => [
['name' => 'Joe User', 'address' => 'joe@example.com'],
],
],
],
'Valid address: single RFC2047 address folded onto multiple lines' => [
'addrstr' => "=?ISO-8859-1?Q?J=F6rg?=\r\n" .
' =?ISO-8859-1?Q?_M=FCller?= <xyz@example.com>',
'addrstr' => "=?iso-8859-1?B?QWJjZGVmZ2ggSWprbG3DsSDmnIPorbDlrqTpoJDntITn?=\r\n" .
' =?iso-8859-1?B?s7vntbE=?= <xyz@example.com>',
'expected' => [
['name' => 'Jörg Müller', 'address' => 'xyz@example.com'],
'default' => [
['name' => 'Abcdefgh Ijklmñ 會議室預約系統', 'address' => 'xyz@example.com'],
],
],
],
'Valid address: single RFC2047 address with space encoded as _' => [
'addrstr' => '=?iso-8859-1?Q?Abcdefgh_ijklm=F1?= <xyz@example.com>',
'addrstr' => '=?iso-8859-1?Q?Abcdefgh_ijklm=C3=B1?= <xyz@example.com>',
'expected' => [
['name' => 'Abcdefgh ijklmñ', 'address' => 'xyz@example.com'],
'default' => [
['name' => 'Abcdefgh ijklmñ', 'address' => 'xyz@example.com'],
],
],
],
'Valid address: single address, quotes within name' => [
'addrstr' => 'Tim "The Book" O\'Reilly <foo@example.com>',
'expected' => [
['name' => 'Tim The Book O\'Reilly', 'address' => 'foo@example.com'],
'default' => [
['name' => 'Tim "The Book" O\'Reilly', 'address' => 'foo@example.com'],
],
'imap' => [
['name' => 'Tim The Book O\'Reilly', 'address' => 'foo@example.com'],
],
],
],
'Valid address: two addresses with names' => [
'addrstr' => 'Joe User <joe@example.com>, Jill User <jill@example.net>',
'expected' => [
['name' => 'Joe User', 'address' => 'joe@example.com'],
['name' => 'Jill User', 'address' => 'jill@example.net'],
'default' => [
['name' => 'Joe User', 'address' => 'joe@example.com'],
['name' => 'Jill User', 'address' => 'jill@example.net'],
],
],
],
'Valid address: two addresses with names, one without' => [
@ -217,104 +249,106 @@ final class ParseAddressesTest extends TestCase
. 'Jill User <jill@example.net>,'
. 'frank@example.com,',
'expected' => [
['name' => 'Joe User', 'address' => 'joe@example.com'],
['name' => 'Jill User', 'address' => 'jill@example.net'],
['name' => '', 'address' => 'frank@example.com'],
'default' => [
['name' => 'Joe User', 'address' => 'joe@example.com'],
['name' => 'Jill User', 'address' => 'jill@example.net'],
['name' => '', 'address' => 'frank@example.com'],
],
],
],
'Valid address: multiple address, various formats, including one utf8-encoded names' => [
'Valid address: multiple address, various formats, including one utf8-encoded name' => [
'addrstr' => 'joe@example.com, <me@example.com>, Joe Doe <doe@example.com>,' .
' "John O\'Groats" <johnog@example.net>,' .
' =?utf-8?B?0J3QsNC30LLQsNC90LjQtSDRgtC10YHRgtCw?= <encoded@example.org>,' .
' =?UTF-8?Q?Welcome_to_our_caf=C3=A9!?= =?ISO-8859-1?Q?_Willkommen_in_unserem_Caf=E9!?=' .
' =?KOI8-R?Q?_=F0=D2=C9=D7=C5=D4_=D7_=CE=C1=DB=C5_=CB=C1=C6=C5!?= <encoded3@example.org>',
' =?utf-8?B?0J3QsNC30LLQsNC90LjQtSDRgtC10YHRgtCw?= <encoded@example.org>',
'expected' => [
['name' => '', 'address' => 'joe@example.com'],
['name' => '', 'address' => 'me@example.com'],
['name' => 'Joe Doe', 'address' => 'doe@example.com'],
['name' => "John O'Groats", 'address' => 'johnog@example.net'],
['name' => 'Название теста', 'address' => 'encoded@example.org'],
[
'name' => 'Welcome to our café! Willkommen in unserem Café! Привет в наше кафе!',
'address' => 'encoded3@example.org'
'default' => [
[
'name' => '',
'address' => 'joe@example.com',
],
[
'name' => '',
'address' => 'me@example.com',
],
[
'name' => 'Joe Doe',
'address' => 'doe@example.com',
],
[
'name' => "John O'Groats",
'address' => 'johnog@example.net',
],
[
'name' => 'Название теста',
'address' => 'encoded@example.org',
],
],
]
'native--mbstring' => [
[
'name' => '',
'address' => 'joe@example.com',
],
[
'name' => '',
'address' => 'me@example.com',
],
[
'name' => 'Joe Doe',
'address' => 'doe@example.com',
],
[
'name' => "John O'Groats",
'address' => 'johnog@example.net',
],
[
'name' => '=?utf-8?B?0J3QsNC30LLQsNC90LjQtSDRgtC10YHRgtCw?=',
'address' => 'encoded@example.org',
],
],
'imap--mbstring' => [
[
'name' => '',
'address' => 'joe@example.com',
],
[
'name' => '',
'address' => 'me@example.com',
],
[
'name' => 'Joe Doe',
'address' => 'doe@example.com',
],
[
'name' => "John O'Groats",
'address' => 'johnog@example.net',
],
[
'name' => '=?utf-8?B?0J3QsNC30LLQsNC90LjQtSDRgtC10YHRgtCw?=',
'address' => 'encoded@example.org',
],
],
],
'charset' => PHPMailer::CHARSET_UTF8,
],
// Test cases with invalid addresses.
'Invalid address: single address, incomplete email' => [
'addrstr' => 'Jill User <doug@>',
'expected' => [],
'expected' => [
'default' => [],
],
],
'Invalid address: single address, invalid characters in email' => [
'addrstr' => 'Joe User <{^c\@**Dog^}@cartoon.com>',
'expected' => [],
'expected' => [
'default' => [],
],
],
'Invalid address: multiple addresses, invalid periods' => [
'addrstr' => 'Joe User <joe@example.com.>, Jill User <jill.@example.net>',
'expected' => [],
],
];
}
/**
* Test decodeHeader using the PHPMailer
* with the Mbstring extension available.
*
* @dataProvider dataDecodeHeader
* @covers \PHPMailer\PHPMailer\PHPMailer::decodeHeader
*
* @requires extension mbstring
*
* @param string $addrstr The header string.
* @param array $expected The expected function output.
*/
public function testDecodeHeader($str, $expected)
{
$parsed = PHPMailer::decodeHeader($str, PHPMailer::CHARSET_UTF8);
$this->assertEquals($parsed, $expected);
}
/**
* Data provider for decodeHeader.
*
* @return array The array is expected to have an `addrstr` and an `expected` key.
* The `expected` key should - as a minimum - have a single value.
*/
public function dataDecodeHeader()
{
return [
'UTF-8 B-encoded' => [
'name' => '=?utf-8?B?0J3QsNC30LLQsNC90LjQtSDRgtC10YHRgtCw?=',
'expected' => 'Название теста',
],
'UTF-8 Q-encoded' => [
'name' => '=?UTF-8?Q?=D0=9D=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8?=' .
' =?UTF-8?Q?=D0=B5_=D1=82=D0=B5=D1=81=D1=82=D0=B0?=',
'expected' => 'Название теста',
],
'UTF-8 Q-encoded with multiple wrong labels and space encoded as _' => [
'name' => '=?UTF-8?Q?Welcome_to_our_caf=C3=A9!?= =?ISO-8859-1?Q?_Willkommen_in_unserem_Caf=E9!?=' .
' =?KOI8-R?Q?_=F0=D2=C9=D7=C5=D4_=D7_=CE=C1=DB=C5_=CB=C1=C6=C5!?=',
'expected' => 'Welcome to our café! Willkommen in unserem Café! Привет в наше кафе!',
],
'ISO-8859-1 Q-encoded' => [
'name' => '=?ISO-8859-1?Q?Willkommen_in_unserem_Caf=E9!?=',
'expected' => 'Willkommen in unserem Café!',
],
'Valid but wrongly labeled UTF-8 as ISO-8859-1' => [
'name' => '=?iso-8859-1?B?5pyD6K2w5a6k?=',
'expected' => "æ\xC2\x9C\xC2\x83議室",
],
'SMTPUTF8 encoded' => [
'name' => '=?UTF-8?B?SGVsbG8g8J+MjSDkuJbnlYwgY2Fmw6k=?=',
'expected' => 'Hello 🌍 世界 café',
],
'Multiple lines' => [
'name' => '=?UTF-8?B?0YLQtdGB0YIg0YLQtdGB0YIg0YLQtdGB0YIg0YLQtdGB0YIg0YLQtdGB0YIg?='
. "\n =?UTF-8?B?0YLQtdGB0YIg0YLQtdGB0YI=?=",
'expected' => 'тест тест тест тест тест тест тест',
'expected' => [
'default' => [],
],
],
];
}

View File

@ -48,6 +48,7 @@ final class ReplyToGetSetClearTest extends PreSendTestCase
if (isset($expected) === false) {
$expected = [
'key' => $address,
'address' => $address,
'name' => $name,
];
@ -61,19 +62,25 @@ final class ReplyToGetSetClearTest extends PreSendTestCase
self::assertIsArray($retrieved, 'ReplyTo property is not an array');
self::assertCount(1, $retrieved, 'ReplyTo property does not contain exactly one address');
$key = $expected['key'];
self::assertArrayHasKey(
$key,
$retrieved,
'ReplyTo property does not contain an entry with this address as the key'
);
self::assertCount(
2,
$retrieved[0],
$retrieved[$key],
'ReplyTo array for this address does not contain exactly two array items'
);
self::assertSame(
$expected['address'],
$retrieved[0][0],
$retrieved[$key][0],
'ReplyTo array for this address does not contain added address'
);
self::assertSame(
$expected['name'],
$retrieved[0][1],
$retrieved[$key][1],
'ReplyTo array for this address does not contain added name'
);
}
@ -93,6 +100,7 @@ final class ReplyToGetSetClearTest extends PreSendTestCase
'address' => " \tMiXeD@Example.Com \r\n",
'name' => null,
'expected' => [
'key' => 'mixed@example.com',
'address' => 'MiXeD@Example.Com',
'name' => '',
],
@ -105,6 +113,7 @@ final class ReplyToGetSetClearTest extends PreSendTestCase
'address' => 'a@example.com',
'name' => "\t\t ReplyTo\r\nname ",
'expected' => [
'key' => 'a@example.com',
'address' => 'a@example.com',
'name' => 'ReplyToname',
],
@ -283,11 +292,9 @@ final class ReplyToGetSetClearTest extends PreSendTestCase
// Addresses with IDN are returned by get*Addresses() after preSend() call.
$domain = $this->Mail->punyencodeAddress($domain);
$expected = array('test+replyto' . $domain, '');
$retrieved = $this->Mail->getReplyToAddresses();
self::assertSame(
$expected,
$retrieved[0],
['test+replyto' . $domain => ['test+replyto' . $domain, '']],
$this->Mail->getReplyToAddresses(),
'Bad "reply-to" addresses'
);
}
@ -370,24 +377,24 @@ final class ReplyToGetSetClearTest extends PreSendTestCase
self::assertCount(1, $retrieved, 'Stored addresses after preSend() is not 1');
// Verify that the registered reply-to address is the initially added lowercase punycode one.
self::assertSame(
self::assertArrayHasKey(
$expectedAddress,
$retrieved[0][0],
$retrieved,
'ReplyTo property does not contain an entry with this address as the key'
);
self::assertCount(
2,
$retrieved[0],
$retrieved[$expectedAddress],
'ReplyTo array for this address does not contain exactly two array items'
);
self::assertSame(
$expectedAddress,
$retrieved[0][0],
$retrieved[$expectedAddress][0],
'ReplyTo array for this address does not contain added address'
);
self::assertSame(
'',
$retrieved[0][1],
$retrieved[$expectedAddress][1],
'ReplyTo array for this address does not contain added name'
);
}
@ -401,8 +408,8 @@ final class ReplyToGetSetClearTest extends PreSendTestCase
*/
public function testAddReplyToFailsOn8BitCharInDomainWithoutOptionalExtensions()
{
if (PHPMailer::idnSupported()) {
self::markTestSkipped('Test requires MbString and/or Intl *not* to be available');
if (extension_loaded('mbstring') && function_exists('idn_to_ascii')) {
$this->markTestSkipped('Test requires MbString and/or Intl *not* to be available');
}
self::assertFalse($this->Mail->addReplyTo('test@françois.ch'));

View File

@ -111,7 +111,7 @@ final class SetErrorTest extends TestCase
'smtp_code' => '',
'smtp_code_ex' => '',
],
'expected' => 'Cannot set or reset variable: nonexistentproperty SMTP server error: Fake error',
'expected' => 'Cannot set or reset variable: nonexistentpropertySMTP server error: Fake error',
],
'SMTP error, full details' => [
'mockReturn' => [
@ -120,7 +120,7 @@ final class SetErrorTest extends TestCase
'smtp_code' => 'Fake code',
'smtp_code_ex' => 'Fake code ex',
],
'expected' => 'Cannot set or reset variable: nonexistentproperty SMTP server error: '
'expected' => 'Cannot set or reset variable: nonexistentpropertySMTP server error: '
. 'Fake error Detail: Fake detail SMTP code: Fake code Additional SMTP info: Fake code ex',
],
];

View File

@ -194,7 +194,7 @@ final class SetFromTest extends TestCase
public function testSetFromFailsOn8BitCharInDomainWithoutOptionalExtensions()
{
if (extension_loaded('mbstring') && function_exists('idn_to_ascii')) {
self::markTestSkipped('Test requires MbString and/or Intl *not* to be available');
$this->markTestSkipped('Test requires MbString and/or Intl *not* to be available');
}
$this->testSetFromFail("8bit@ex\x80mple.com");

View File

@ -438,7 +438,7 @@ final class ValidateAddressTest extends TestCase
'first.last@phplíst.com',
];
return $this->arrayToNamedDataProvider($unicodeaddresses, 'Invalid Unicode: ');
return $this->arrayToNamedDataProvider($unicodeaddresses, 'Invalid unicode: ');
}
/**

View File

@ -52,7 +52,7 @@ final class PopBeforeSmtpTest extends TestCase
protected function set_up()
{
if (DIRECTORY_SEPARATOR === '\\') {
self::markTestSkipped('This test needs a non-Windows OS to run');
$this->markTestSkipped('This test needs a non-Windows OS to run');
}
// Chdir to test directory as runfakepopserver.sh runs fakepopserver.sh

View File

@ -119,7 +119,6 @@ abstract class TestCase extends PolyfillTestCase
private $PHPMailerStaticProps = [
'LE' => PHPMailer::CRLF,
'validator' => 'php',
'language' => [],
];
/**