* Update dependencies

* dns_get_record wrapper for testing of the function's behaviour

* remove unused classes

* Fix Psalm errors

* Increase PHP Version
This commit is contained in:
Eduardo Gulias Davis
2022-05-29 00:19:18 +02:00
committed by GitHub
parent 312b65911f
commit a5ed8d58ed
10 changed files with 626 additions and 432 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ imports:
build:
environment:
php: '7.3'
php: '7.4'
tests:
override:
-
-9
View File
@@ -2,10 +2,6 @@ language: php
matrix:
include:
- php: 7.3
env:
- psalm=yes
dist: bionic
- php: 7.4
dist: bionic
env:
@@ -15,11 +11,6 @@ matrix:
- psalm=yes
dist: bionic
#ppc64le support code
- php: 7.3
arch: ppc64le
env:
- psalm=yes
dist: bionic
- php: 7.4
arch: ppc64le
env:
Generated
+509 -399
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1,6 +1,5 @@
<?xml version="1.0"?>
<psalm
totallyTyped="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config ./vendor/vimeo/psalm/config.xsd"
+1 -1
View File
@@ -151,7 +151,7 @@ class EmailLexer extends AbstractLexer
/**
* The next token in the input.
*
* @var array|null
* @var array{position: int, type: int|null|string, value: int|string}|null
*/
public $lookahead;
+1 -1
View File
@@ -50,7 +50,7 @@ class DomainLiteral extends PartParser
}
if ($this->lexer->isNextTokenAny(
array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF)
array(EmailLexer::S_HTAB, EmailLexer::S_SP, EmailLexer::CRLF)
)) {
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
$this->parseFWS();
+23 -16
View File
@@ -2,6 +2,7 @@
namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\Validation\DNSGetRecordWrapper;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Result\Reason\DomainAcceptsNoMail;
@@ -55,11 +56,22 @@ class DNSCheckValidation implements EmailValidation
*/
private $mxRecords = [];
public function __construct()
/**
* @var DNSGetRecordWrapper
*/
private $dnsGetRecord;
public function __construct(DNSGetRecordWrapper $dnsGetRecord = null)
{
if (!function_exists('idn_to_ascii')) {
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
@@ -121,27 +133,17 @@ class DNSCheckValidation implements EmailValidation
*/
private function validateDnsRecords($host) : bool
{
// 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");
}
);
$dnsRecordsResult = $this->dnsGetRecord->getRecords($host, static::DNS_RECORD_TYPES_TO_CHECK);
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) {
if ($dnsRecordsResult->withError()) {
$this->error = new InvalidEmail(new UnableToGetDNSRecord(), '');
return false;
} finally {
restore_error_handler();
}
$dnsRecords = $dnsRecordsResult->getRecords();
// No MX, A or AAAA DNS records
if ($dnsRecords === [] || $dnsRecords === false) {
if ($dnsRecords === []) {
$this->error = new InvalidEmail(new ReasonNoDNSRecord(), '');
return false;
}
@@ -168,6 +170,11 @@ class DNSCheckValidation implements EmailValidation
*/
private function validateMxRecord($dnsRecord) : bool
{
if (!isset($dnsRecord['type'])) {
$this->error = new InvalidEmail(new ReasonNoDNSRecord(), '');
return false;
}
if ($dnsRecord['type'] !== 'MX') {
return true;
}
+28
View File
@@ -0,0 +1,28 @@
<?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();
}
}
}
+35
View File
@@ -0,0 +1,35 @@
<?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,6 +9,8 @@ use Egulias\EmailValidator\Result\Reason\LocalOrReservedDomain;
use Egulias\EmailValidator\Result\Reason\NoDNSRecord;
use Egulias\EmailValidator\Result\Reason\UnableToGetDNSRecord;
use Egulias\EmailValidator\Validation\DNSCheckValidation;
use Egulias\EmailValidator\Validation\DNSGetRecordWrapper;
use Egulias\EmailValidator\Validation\DNSRecords;
use Egulias\EmailValidator\Warning\NoDNSMXRecord;
use PHPUnit\Framework\TestCase;
@@ -116,13 +118,35 @@ class DNSCheckValidationTest extends TestCase
error_reporting(\E_ALL);
// UnableToGetDNSRecord raises on network errors (e.g. timeout) that we cant emulate in tests (for sure),
// but we can try to get timeout error by trying to fetch all DNS records
$validation = new class extends DNSCheckValidation {
protected const DNS_RECORD_TYPES_TO_CHECK = \DNS_ALL;
// but we can simulate with the wrapper helper
$wrapper = new class extends DNSGetRecordWrapper {
public function getRecords(string $host, int $type) : DNSRecords
{
return new DNSRecords([], true);
}
};
$validation = new DNSCheckValidation($wrapper);
$expectedError = new InvalidEmail(new UnableToGetDNSRecord(), '');
$validation->isValid('example@invalid.example.com', new EmailLexer());
$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());
}
}