mirror of
https://github.com/egulias/EmailValidator.git
synced 2026-09-02 05:27:52 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ac0be80b3 | |||
| c38e9600fb | |||
| 777864f79e | |||
| ecbcdcef05 | |||
| b28de87213 | |||
| 6d6a87e5d9 | |||
| 0170967656 | |||
| 4c72190f32 | |||
| 413b263617 | |||
| 18b9e5b572 | |||
| 1ca313dfcd | |||
| cf5908bb1a | |||
| b241b54919 | |||
| 74d2f16d9d | |||
| f88dcf4b14 | |||
| e3c1f426e5 |
+1
-1
@@ -3,7 +3,7 @@ imports:
|
|||||||
|
|
||||||
build:
|
build:
|
||||||
environment:
|
environment:
|
||||||
php: '7.4'
|
php: '7.3'
|
||||||
tests:
|
tests:
|
||||||
override:
|
override:
|
||||||
-
|
-
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ language: php
|
|||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- php: 7.3
|
||||||
|
env:
|
||||||
|
- psalm=yes
|
||||||
|
dist: bionic
|
||||||
- php: 7.4
|
- php: 7.4
|
||||||
dist: bionic
|
dist: bionic
|
||||||
env:
|
env:
|
||||||
@@ -11,6 +15,11 @@ matrix:
|
|||||||
- psalm=yes
|
- psalm=yes
|
||||||
dist: bionic
|
dist: bionic
|
||||||
#ppc64le support code
|
#ppc64le support code
|
||||||
|
- php: 7.3
|
||||||
|
arch: ppc64le
|
||||||
|
env:
|
||||||
|
- psalm=yes
|
||||||
|
dist: bionic
|
||||||
- php: 7.4
|
- php: 7.4
|
||||||
arch: ppc64le
|
arch: ppc64le
|
||||||
env:
|
env:
|
||||||
|
|||||||
Generated
+232
-286
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<psalm
|
<psalm
|
||||||
|
totallyTyped="false"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns="https://getpsalm.org/schema/config"
|
xmlns="https://getpsalm.org/schema/config"
|
||||||
xsi:schemaLocation="https://getpsalm.org/schema/config ./vendor/vimeo/psalm/config.xsd"
|
xsi:schemaLocation="https://getpsalm.org/schema/config ./vendor/vimeo/psalm/config.xsd"
|
||||||
|
|||||||
+1
-1
@@ -151,7 +151,7 @@ class EmailLexer extends AbstractLexer
|
|||||||
/**
|
/**
|
||||||
* The next token in the input.
|
* The next token in the input.
|
||||||
*
|
*
|
||||||
* @var array{position: int, type: int|null|string, value: int|string}|null
|
* @var array|null
|
||||||
*/
|
*/
|
||||||
public $lookahead;
|
public $lookahead;
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class DomainLiteral extends PartParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->lexer->isNextTokenAny(
|
if ($this->lexer->isNextTokenAny(
|
||||||
array(EmailLexer::S_HTAB, EmailLexer::S_SP, EmailLexer::CRLF)
|
array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF)
|
||||||
)) {
|
)) {
|
||||||
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
|
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
|
||||||
$this->parseFWS();
|
$this->parseFWS();
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Egulias\EmailValidator\Validation;
|
namespace Egulias\EmailValidator\Validation;
|
||||||
|
|
||||||
use Egulias\EmailValidator\Validation\DNSGetRecordWrapper;
|
|
||||||
use Egulias\EmailValidator\EmailLexer;
|
use Egulias\EmailValidator\EmailLexer;
|
||||||
use Egulias\EmailValidator\Result\InvalidEmail;
|
use Egulias\EmailValidator\Result\InvalidEmail;
|
||||||
use Egulias\EmailValidator\Result\Reason\DomainAcceptsNoMail;
|
use Egulias\EmailValidator\Result\Reason\DomainAcceptsNoMail;
|
||||||
@@ -56,22 +55,11 @@ class DNSCheckValidation implements EmailValidation
|
|||||||
*/
|
*/
|
||||||
private $mxRecords = [];
|
private $mxRecords = [];
|
||||||
|
|
||||||
/**
|
public function __construct()
|
||||||
* @var DNSGetRecordWrapper
|
|
||||||
*/
|
|
||||||
private $dnsGetRecord;
|
|
||||||
|
|
||||||
public function __construct(DNSGetRecordWrapper $dnsGetRecord = null)
|
|
||||||
{
|
{
|
||||||
if (!function_exists('idn_to_ascii')) {
|
if (!function_exists('idn_to_ascii')) {
|
||||||
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
|
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($dnsGetRecord == null) {
|
|
||||||
$dnsGetRecord = new DNSGetRecordWrapper();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->dnsGetRecord = $dnsGetRecord;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isValid(string $email, EmailLexer $emailLexer) : bool
|
public function isValid(string $email, EmailLexer $emailLexer) : bool
|
||||||
@@ -133,17 +121,27 @@ class DNSCheckValidation implements EmailValidation
|
|||||||
*/
|
*/
|
||||||
private function validateDnsRecords($host) : bool
|
private function validateDnsRecords($host) : bool
|
||||||
{
|
{
|
||||||
$dnsRecordsResult = $this->dnsGetRecord->getRecords($host, static::DNS_RECORD_TYPES_TO_CHECK);
|
// A workaround to fix https://bugs.php.net/bug.php?id=73149
|
||||||
|
/** @psalm-suppress InvalidArgument */
|
||||||
|
set_error_handler(
|
||||||
|
static function (int $errorLevel, string $errorMessage): ?bool {
|
||||||
|
throw new \RuntimeException("Unable to get DNS record for the host: $errorMessage");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if ($dnsRecordsResult->withError()) {
|
try {
|
||||||
|
// Get all MX, A and AAAA DNS records for host
|
||||||
|
$dnsRecords = dns_get_record($host, static::DNS_RECORD_TYPES_TO_CHECK);
|
||||||
|
} catch (\RuntimeException $exception) {
|
||||||
$this->error = new InvalidEmail(new UnableToGetDNSRecord(), '');
|
$this->error = new InvalidEmail(new UnableToGetDNSRecord(), '');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
restore_error_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
$dnsRecords = $dnsRecordsResult->getRecords();
|
|
||||||
|
|
||||||
// No MX, A or AAAA DNS records
|
// No MX, A or AAAA DNS records
|
||||||
if ($dnsRecords === []) {
|
if ($dnsRecords === [] || $dnsRecords === false) {
|
||||||
$this->error = new InvalidEmail(new ReasonNoDNSRecord(), '');
|
$this->error = new InvalidEmail(new ReasonNoDNSRecord(), '');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -170,11 +168,6 @@ class DNSCheckValidation implements EmailValidation
|
|||||||
*/
|
*/
|
||||||
private function validateMxRecord($dnsRecord) : bool
|
private function validateMxRecord($dnsRecord) : bool
|
||||||
{
|
{
|
||||||
if (!isset($dnsRecord['type'])) {
|
|
||||||
$this->error = new InvalidEmail(new ReasonNoDNSRecord(), '');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($dnsRecord['type'] !== 'MX') {
|
if ($dnsRecord['type'] !== 'MX') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Egulias\EmailValidator\Validation;
|
|
||||||
|
|
||||||
class DNSGetRecordWrapper
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param string $host
|
|
||||||
* @param int $type
|
|
||||||
*/
|
|
||||||
public function getRecords(string $host, int $type) : DNSRecords
|
|
||||||
{
|
|
||||||
// A workaround to fix https://bugs.php.net/bug.php?id=73149
|
|
||||||
/** @psalm-suppress InvalidArgument */
|
|
||||||
set_error_handler(
|
|
||||||
static function (int $errorLevel, string $errorMessage): ?bool {
|
|
||||||
throw new \RuntimeException("Unable to get DNS record for the host: $errorMessage");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
// Get all MX, A and AAAA DNS records for host
|
|
||||||
return new DNSRecords(dns_get_record($host, $type));
|
|
||||||
} catch (\RuntimeException $exception) {
|
|
||||||
return new DNSRecords([], true);
|
|
||||||
} finally {
|
|
||||||
restore_error_handler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Egulias\EmailValidator\Validation;
|
|
||||||
|
|
||||||
class DNSRecords
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array $records
|
|
||||||
*/
|
|
||||||
private $records = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool $error
|
|
||||||
*/
|
|
||||||
private $error = false;
|
|
||||||
|
|
||||||
public function __construct(array $records, bool $error = false)
|
|
||||||
{
|
|
||||||
$this->records = $records;
|
|
||||||
$this->error = $error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRecords() : array
|
|
||||||
{
|
|
||||||
return $this->records;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function withError() : bool
|
|
||||||
{
|
|
||||||
return $this->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,8 +9,6 @@ use Egulias\EmailValidator\Result\Reason\LocalOrReservedDomain;
|
|||||||
use Egulias\EmailValidator\Result\Reason\NoDNSRecord;
|
use Egulias\EmailValidator\Result\Reason\NoDNSRecord;
|
||||||
use Egulias\EmailValidator\Result\Reason\UnableToGetDNSRecord;
|
use Egulias\EmailValidator\Result\Reason\UnableToGetDNSRecord;
|
||||||
use Egulias\EmailValidator\Validation\DNSCheckValidation;
|
use Egulias\EmailValidator\Validation\DNSCheckValidation;
|
||||||
use Egulias\EmailValidator\Validation\DNSGetRecordWrapper;
|
|
||||||
use Egulias\EmailValidator\Validation\DNSRecords;
|
|
||||||
use Egulias\EmailValidator\Warning\NoDNSMXRecord;
|
use Egulias\EmailValidator\Warning\NoDNSMXRecord;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
@@ -118,35 +116,13 @@ class DNSCheckValidationTest extends TestCase
|
|||||||
error_reporting(\E_ALL);
|
error_reporting(\E_ALL);
|
||||||
|
|
||||||
// UnableToGetDNSRecord raises on network errors (e.g. timeout) that we can‘t emulate in tests (for sure),
|
// UnableToGetDNSRecord raises on network errors (e.g. timeout) that we can‘t emulate in tests (for sure),
|
||||||
// but we can simulate with the wrapper helper
|
// but we can try to get timeout error by trying to fetch all DNS records
|
||||||
|
$validation = new class extends DNSCheckValidation {
|
||||||
$wrapper = new class extends DNSGetRecordWrapper {
|
protected const DNS_RECORD_TYPES_TO_CHECK = \DNS_ALL;
|
||||||
public function getRecords(string $host, int $type) : DNSRecords
|
|
||||||
{
|
|
||||||
return new DNSRecords([], true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$validation = new DNSCheckValidation($wrapper);
|
|
||||||
$expectedError = new InvalidEmail(new UnableToGetDNSRecord(), '');
|
$expectedError = new InvalidEmail(new UnableToGetDNSRecord(), '');
|
||||||
|
|
||||||
$validation->isValid('example@invalid.example.com', new EmailLexer());
|
$validation->isValid('example@invalid.example.com', new EmailLexer());
|
||||||
$this->assertEquals($expectedError, $validation->getError());
|
$this->assertEquals($expectedError, $validation->getError());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public function testMissingTypeKey()
|
|
||||||
{
|
|
||||||
$wrapper = new class extends DNSGetRecordWrapper {
|
|
||||||
public function getRecords(string $host, int $type): DNSRecords
|
|
||||||
{
|
|
||||||
return new DNSRecords(['host' => 'test']);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$validation = new DNSCheckValidation($wrapper);
|
|
||||||
$expectedError = new InvalidEmail(new NoDNSRecord(), '');
|
|
||||||
|
|
||||||
$validation->isValid('example@invalid.example.com', new EmailLexer());
|
|
||||||
$this->assertEquals($expectedError, $validation->getError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user