PHPMailer/test/PHPMailer/ValidateAddressCustomValida...

117 lines
3.5 KiB
PHP

<?php
/**
* PHPMailer - PHP email transport unit tests.
* PHP version 5.5.
*
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
* @author Andy Prevost
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
*/
namespace PHPMailer\Test\PHPMailer;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\Test\TestCase;
/**
* Test email address validation using a custom validator.
*
* @covers \PHPMailer\PHPMailer\PHPMailer::validateAddress
*/
final class ValidateAddressCustomValidatorTest extends TestCase
{
/**
* Test injecting a one-off custom validator.
*/
public function testOneOffCustomValidator()
{
$callback = static function ($address) {
return strpos($address, '@') !== false;
};
self::assertTrue(
PHPMailer::validateAddress('user@example.com', $callback),
'Custom validator false negative'
);
self::assertFalse(
PHPMailer::validateAddress('userexample.com', $callback),
'Custom validator false positive'
);
}
/**
* Test setting the default validator to an injected function.
*/
public function testSetDefaultValidatorToCustom()
{
// Set the default validator to an injected function.
PHPMailer::$validator = static function ($address) {
return 'user@example.com' === $address;
};
self::assertTrue(
$this->Mail->addAddress('user@example.com'),
'Custom default validator false negative'
);
// Need to pick a failing value which would pass all other validators
// to be sure we're using our custom one.
self::assertFalse(
$this->Mail->addAddress('bananas@example.com'),
'Custom default validator false positive'
);
// Set validator back to default
PHPMailer::$validator = 'php';
// This is a valid address that FILTER_VALIDATE_EMAIL thinks is invalid.
self::assertFalse(
$this->Mail->addAddress('first.last@example.123'),
'PHP validator not behaving as expected'
);
}
/**
* Test denying function name callables as validators.
*
* See SECURITY.md and CVE-2021-3603.
*
* @dataProvider dataRejectCallables
*
* @param string $callback Callback function name.
* @param string $message Message to display if the test would fail.
*/
public function testRejectCallables($callback, $message)
{
require_once \PHPMAILER_INCLUDE_DIR . '/test/validators.php';
self::assertTrue(PHPMailer::validateAddress('test@example.com', $callback), $message);
}
/**
* Data provider.
*
* @return array
*/
public function dataRejectCallables()
{
return [
// If a `php` function defined in validators.php successfully overrides this built-in validator name,
// this would return false - and we don't want to allow that.
'php' => [
'callback' => 'php',
'message' => 'Build-in php validator overridden',
],
// Check that a non-existent validator name falls back to a built-in validator
// and does not call a global function with that name.
'phpx' => [
'callback' => 'phpx',
'message' => 'Global function called instead of default validator',
],
];
}
}