Compare commits

..

20 Commits

Author SHA1 Message Date
Eduardo Gulias Davis 9d48c27245 Test for #317 2024-12-27 01:51:44 +01:00
Eduardo Gulias Davis b115554301 Fix Readme style 2024-12-27 01:36:43 +01:00
Eduardo Gulias Davis c67e8e655f Fix Readme style 2024-12-27 01:27:39 +01:00
Eduardo Gulias Davis 2647beedf3 Removed stale changelog 2024-12-27 01:17:25 +01:00
Eduardo Gulias Davis e25ccf7e74 Add depandabot 2024-12-27 00:36:05 +01:00
Eduardo Gulias Davis d379dc240b Update readme 2024-12-27 00:31:08 +01:00
Eduardo Gulias Davis 621d46003b Fix github action (#396)
* Fix github action

* PHP8.4 is too new

* Revert log storage
2024-12-27 00:28:29 +01:00
chris 87db43e4ff docs: fix build status in README.md (#392) 2024-10-16 23:10:38 +02:00
chris c118cc7666 ci: fix deprecation for github actions (#391) 2024-10-08 19:20:25 +02:00
Arnt Gulbrandsen b4a1a0e5a6 Regularise a test. (#389)
The validEmailsProvider contained n-1 valid email addresses and 1 domain;
this replaces the domain with two valid email addresses in that domain, so
that all entries match the name.
2024-09-15 22:03:00 +02:00
Danny van der Sluijs 92c1ab0cc1 Update GitHub Actions to V4 (#383)
* Update tests.yml using actions/checkout@v4

* Update static-analysis.yml usingactions/checkout@v4
2024-05-01 15:20:12 +02:00
Daniel 8775776563 chore: replace scalar with more precise type specification (#369)
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
2023-10-22 23:56:40 +02:00
Andrew Ivchenkov 87b8b8506e Used the most strict psalm level and fixed all psalm errors (#377) 2023-10-15 23:39:26 +02:00
Christian Rishøj ebaaf5be6c perform AAAA check separately (fixes #301) (#376) 2023-10-06 08:47:41 +02:00
chris d11195e117 chore: add tests for php 8.3 (#373)
authored-by: Christopher Georg <christopher.georg@sr-travel.de>
2023-08-28 18:30:37 +02:00
chris 36233f5918 chore: update phpunit 9 = 10 and psalm 4 = 5 (#368)
Co-authored-by: Christopher Georg <christopher.georg@sr-travel.de>
2023-07-28 20:33:18 +02:00
Márk Magyar 27be0e7157 code refactor (#364)
* use spread syntax instead of array_merge()

* use type cast instead of function cast

* removed redundant returns

* removed redundant phpdoc - type is already inferred

* removed invalid phpdoc - type is already inferred

The PHPDoc return type hint was incomplete, it should have been `InvalidEmail|null`, however, it can be removed altogether as the return type is already inferred from the code.

* changed warnEscaping()'s return value from bool to void

This is not a breaking change as the method is private,  and it's only used at one place, where the return value was not used anyway.

* made private class property local

`private $parser` was used in only one place, hence it can be local, there is no reason to put it into the class' scope.

* removed unnecessary type casting

Concatenation already casts `static::CODE` from `int` to `string`, no reason to do it explicitly.

* removed redundant initializers - constructor overwrites them immediately

* removed redundant else block

* simplified if-else statement

* wrapped if body in brackets to comply with PSR12

* fixed README formatting

- fixed numbering at the `Available validations` section
- fixed overall formatting

* Revert "removed redundant phpdoc - type is already inferred"

This reverts commit 68a9ae20bd.

* don't wrap long lines

* make properties typed

Also using constructor property promotion, see more info about it [here](https://php.watch/versions/8.0/constructor-property-promotion).
2023-06-07 16:47:52 +02:00
Eduardo Gulias Davis 97c28cd611 Badges and Scrutinezr config (#366)
* Codacy badges and removing Scrutinizr config
2023-05-23 22:25:38 +02:00
Eduardo Gulias Davis 178d148438 Codacy GitHub action (#365)
* README for v4

* badges update

* license year

* Adding codacy reporter action

* plain text secret for testing

* using bash

* downloading artifact

* all in one

* path to coverage

* removing extra job and adding sending coverage report only once
2023-05-23 17:55:24 +02:00
Grégoire Pineau c4f65a68ee Fixed typo in CHANGELOG.md (#363) 2023-05-22 16:53:31 +02:00
40 changed files with 207 additions and 249 deletions
-1
View File
@@ -3,5 +3,4 @@
/.* export-ignore /.* export-ignore
/phpunit.xml.dist export-ignore /phpunit.xml.dist export-ignore
/psalm.xml export-ignore /psalm.xml export-ignore
/psalm.baseline.xml export-ignore
/README.md export-ignore /README.md export-ignore
+6
View File
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "weekly"
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Setup PHP - name: Setup PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
+14 -6
View File
@@ -1,4 +1,4 @@
name: tests name: build
on: on:
push: push:
@@ -16,7 +16,7 @@ jobs:
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
php: ['8.1', '8.2'] php: ['8.1', '8.2', '8.3']
deps: [highest] deps: [highest]
include: include:
@@ -27,7 +27,7 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Setup PHP - name: Setup PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@@ -38,7 +38,7 @@ jobs:
coverage: xdebug coverage: xdebug
- name: Install dependencies - name: Install dependencies
uses: ramsey/composer-install@v2 uses: ramsey/composer-install@v3
with: with:
dependency-versions: ${{ matrix.deps }} dependency-versions: ${{ matrix.deps }}
@@ -48,8 +48,16 @@ jobs:
- name: Execute tests - name: Execute tests
run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml --exclude-group flaky run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml --exclude-group flaky
- name: Coverage
if: ${{ matrix.php == '8.1' && matrix.deps == 'lowest' }}
shell: bash
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
run: bash <(curl -Ls https://coverage.codacy.com/get.sh) report -r build/logs/clover.xml
- name: Store artifacts - name: Store artifacts
uses: actions/upload-artifact@v3 if: ${{ matrix.php == '8.1' && matrix.deps == 'lowest' }}
uses: actions/upload-artifact@v4
with: with:
name: logs name: clover.xml
path: build/logs path: build/logs
-13
View File
@@ -1,13 +0,0 @@
imports:
- php
build:
environment:
php: "8.1"
tests:
override:
- command: "vendor/bin/phpunit --coverage-clover=clover.xml --exclude-group flaky"
coverage:
file: "build/logs/clover.xml"
format: "clover"
- php-scrutinizer-run
-33
View File
@@ -1,33 +0,0 @@
# EmailValidator v3 Changelog
## New Features
* Access to local part and domain part from EmailParser
* Validations outside of the scope of the RFC will be considered "extra" validations, thus opening the door for adding new; will live in their own folder "extra" (as requested in #248, #195, #183).
## Breaking changes
* PHP version upgraded to match Symfony's (as of 12/2020).
* DNSCheckValidation now fails for missing MX records. While the RFC argues that the existence of only A records to be valid, starting in v3 they will be considered invalid.
* Emails domain part are now intenteded to be RFC 1035 compliant, rendering previous valid emails (e.g example@examp&) invalid.
## PHP versions upgrade policy
PHP version upgrade requirement will happen via MINOR (3.x) version upgrades of the library, following the adoption level by major frameworks.
## Changes
* #235
* #215
* #130
* #258
* #188
* #181
* #217
* #214
* #249
* #236
* #257
* #210
## Thanks
To contributors, be it with PRs, reporting issues or supporting otherwise.
+69 -47
View File
@@ -1,43 +1,48 @@
# EmailValidator # EmailValidator
[![Build Status](https://github.com/egulias/EmailValidator/workflows/tests/badge.svg?branch=4.x)](https://github.com/egulias/EmailValidator/actions) [![Build Status](https://github.com/egulias/EmailValidator/actions/workflows/tests.yml/badge.svg)](https://github.com/egulias/EmailValidator/actions/workflows/tests.yml)
[![Code Quality](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/quality-score.png?b=3.x)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=4.x) [![Quality Badge](https://app.codacy.com/project/badge/Grade/55d44898c7e44ebdb4e457523563ad63)](https://app.codacy.com/gh/egulias/EmailValidator/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Test Coverage](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/coverage.png?b=3.x)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=4.x) [![Test Coverage](https://app.codacy.com/project/badge/Coverage/55d44898c7e44ebdb4e457523563ad63)](https://app.codacy.com/gh/egulias/EmailValidator/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)
![Latest Release](https://img.shields.io/github/v/release/egulias/EmailValidator)
A library for validating emails against several RFC. A library for validating emails against several RFC.
## Supported RFCs ## ## Supported RFCs
This library aims to support RFCs: This library aims to support RFCs:
* [5321](https://tools.ietf.org/html/rfc5321), * [5321](https://tools.ietf.org/html/rfc5321),
* [5322](https://tools.ietf.org/html/rfc5322), * [5322](https://tools.ietf.org/html/rfc5322),
* [6530](https://tools.ietf.org/html/rfc6530), * [6530](https://tools.ietf.org/html/rfc6530),
* [6531](https://tools.ietf.org/html/rfc6531), * [6531](https://tools.ietf.org/html/rfc6531),
* [6532](https://tools.ietf.org/html/rfc6532), * [6532](https://tools.ietf.org/html/rfc6532),
* [1035](https://tools.ietf.org/html/rfc1035) * [1035](https://tools.ietf.org/html/rfc1035)
## Supported versions ## Supported versions
**Current major version with full support is v3** | Version | Released | EOL | Only critical bug fixes | Full |
|:-------:|:----------:|:---:|:-----------------------:|:----:|
|**v4.x** |**2023/01/07** | - | **X** |**X** |
| v3.x | 2020/12/29 | YES | | |
| v2.1.x | 2016/05/16 | YES | | |
| v1.2 | 2013/19/05 | YES | | |
| Version | Released | EOL | Only critical bug fixes | Full | ## Requirements
| :-----: | :--------: | :---: | :---------------------: | :---: |
| v4.x | 2023/01/07 | - | X | X |
| v3.x | 2020/12/29 | - | X | |
| v2.1.x | 2016/05/16 | YES | | |
| v1.2 | 2013/19/05 | YES | | |
* PHP 8.1
* [Composer](https://getcomposer.org) is required for installation
* [Spoofchecking](/src/Validation/Extra/SpoofCheckValidation.php) and
[DNSCheckValidation](/src/Validation/DNSCheckValidation.php) validation
requires that your PHP system has the
[PHP Internationalization Libraries](https://php.net/manual/en/book.intl.php)
(also known as PHP Intl)
## Requirements ## **Note**: `PHP version upgrades will happen to accomodate to the pace of major
frameworks. Minor versions bumps will go via minor versions of this library
(i.e: PHP7.3 -> v3.x+1). Major versions will go with major versions
of the library`
* PHP 8.1 ## Installation
* [Composer](https://getcomposer.org) is required for installation
* [Spoofchecking](/src/Validation/Extra/SpoofCheckValidation.php) and [DNSCheckValidation](/src/Validation/DNSCheckValidation.php) validation requires that your PHP system has the [PHP Internationalization Libraries](https://php.net/manual/en/book.intl.php) (also known as PHP Intl)
**Note**: `PHP version upgrades will happen to accomodate to the pace of major frameworks. Minor versions bumps will go via minor versions of this library (i.e: PHP7.3 -> v3.x+1). Major versions will go with major versions of the library`
## Installation ##
Run the command below to install via Composer Run the command below to install via Composer
@@ -45,11 +50,14 @@ Run the command below to install via Composer
composer require egulias/email-validator composer require egulias/email-validator
``` ```
## Getting Started ## ## Getting Started
`EmailValidator` requires you to decide which (or combination of them) validation/s strategy/ies you'd like to follow for each [validation](#available-validations). `EmailValidator` requires you to decide which (or combination of them)
validation/s strategy/ies you'd like to follow for each
[validation](#available-validations).
A basic example with the RFC validation A basic example with the RFC validation
```php ```php
<?php <?php
@@ -60,17 +68,22 @@ $validator = new EmailValidator();
$validator->isValid("example@example.com", new RFCValidation()); //true $validator->isValid("example@example.com", new RFCValidation()); //true
``` ```
### Available validations
### Available validations ###
1. [RFCValidation](/src/Validation/RFCValidation.php): Standard RFC-like email validation. 1. [RFCValidation](/src/Validation/RFCValidation.php): Standard RFC-like email validation.
2. [NoRFCWarningsValidation](/src/Validation/NoRFCWarningsValidation.php): RFC-like validation that will fail when warnings* are found. 2. [NoRFCWarningsValidation](/src/Validation/NoRFCWarningsValidation.php):
3. [DNSCheckValidation](/src/Validation/DNSCheckValidation.php): Will check if there are DNS records that signal that the server accepts emails. This does not entail that the email exists. RFC-like validation that will fail when warnings* are found.
5. [MultipleValidationWithAnd](/src/Validation/MultipleValidationWithAnd.php): It is a validation that operates over other validations performing a logical and (&&) over the result of each validation. 3. [DNSCheckValidation](/src/Validation/DNSCheckValidation.php):
6. [MessageIDValidation](/src/Validation/MessageIDValidation.php): Follows [RFC2822 for message-id](https://tools.ietf.org/html/rfc2822#section-3.6.4) to validate that field, that has some differences in the domain part. Will check if there are DNS records that signal that the server accepts emails. This does not entail that the email exists.
7. [Your own validation](#how-to-extend): You can extend the library behaviour by implementing your own validations. 4. [MultipleValidationWithAnd](/src/Validation/MultipleValidationWithAnd.php):
It is a validation that operates over other validations performing a logical and (&&) over the result of each validation.
5. [MessageIDValidation](/src/Validation/MessageIDValidation.php):
Follows [RFC2822 for message-id](https://tools.ietf.org/html/rfc2822#section-3.6.4) to validate that field, that has some differences in the domain part.
6. [Your own validation](#how-to-extend): You can extend the library behaviour
by implementing your own validations.
*warnings: Warnings are deviations from the RFC that in a broader interpretation are accepted. *warnings: Warnings are deviations from the RFC that in a broader interpretation
are accepted.
```php ```php
<?php <?php
@@ -89,30 +102,39 @@ $multipleValidations = new MultipleValidationWithAnd([
$validator->isValid("example@ietf.org", $multipleValidations); //true $validator->isValid("example@ietf.org", $multipleValidations); //true
``` ```
#### Additional validations #### #### Additional validations
Validations not present in the RFCs
1. [SpoofCheckValidation](/src/Validation/Extra/SpoofCheckValidation.php): Will check for multi-utf-8 chars that can signal an erroneous email name. Validations not present in the RFCs
1. [SpoofCheckValidation](/src/Validation/Extra/SpoofCheckValidation.php):
Will check for multi-utf-8 chars that can signal an erroneous email name.
### How to extend ### ### How to extend
It's easy! You just need to implement [EmailValidation](/src/Validation/EmailValidation.php) and you can use your own validation. It's easy! You just need to implement
[EmailValidation](/src/Validation/EmailValidation.php) and you can use your own
validation.
## Contributing ## ## Contributing
Please follow the [Contribution guide](CONTRIBUTING.md). Is short and simple and will help a lot. Please follow the [Contribution guide](CONTRIBUTING.md).
Is short and simple and will help a lot.
## Other Contributors ## ## Other Contributors
(You can find current contributors [here](https://github.com/egulias/EmailValidator/graphs/contributors)) (You can find current contributors
[here](https://github.com/egulias/EmailValidator/graphs/contributors))
As this is a port from another library and work, here are other people related to the previous one: As this is a port from another library and work, here are other people related to the previous one:
* Ricard Clau [@ricardclau](https://github.com/ricardclau): Performance against PHP built-in filter_var (v2 and earlier) * Ricard Clau [@ricardclau](https://github.com/ricardclau):
* Josepf Bielawski [@stloyd](https://github.com/stloyd): For its first re-work of Dominic's lib Performance against PHP built-in filter_var (v2 and earlier)
* Dominic Sayers [@dominicsayers](https://github.com/dominicsayers): The original isemail function * Josepf Bielawski [@stloyd](https://github.com/stloyd):
For its first re-work of Dominic's lib
* Dominic Sayers [@dominicsayers](https://github.com/dominicsayers):
The original `isemail` function
## License ## ## License
Released under the MIT License attached with this code. Released under the MIT License attached with this code.
+2 -2
View File
@@ -18,8 +18,8 @@
"symfony/polyfill-intl-idn": "^1.26" "symfony/polyfill-intl-idn": "^1.26"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.5.27", "phpunit/phpunit": "^10.2",
"vimeo/psalm": "^4.30" "vimeo/psalm": "^5.12"
}, },
"suggest": { "suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
+19 -9
View File
@@ -1,17 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" backupStaticAttributes="false" bootstrap="vendor/autoload.php" colors="true" convertDeprecationsToExceptions="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" executionOrder="defects" processIsolation="false" stopOnFailure="false"> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<coverage> xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
<include> bootstrap="vendor/autoload.php"
<directory>./src/</directory> colors="true"
</include> executionOrder="defects"
<exclude> cacheDirectory=".phpunit.cache"
<directory suffix=".php">./src/Result/Reason</directory> >
</exclude> <coverage/>
</coverage>
<testsuites> <testsuites>
<testsuite name="EmailValidator Test Suite"> <testsuite name="EmailValidator Test Suite">
<directory>./tests/EmailValidator</directory> <directory>./tests/EmailValidator</directory>
<exclude>./vendor/</exclude> <exclude>./vendor/</exclude>
</testsuite> </testsuite>
</testsuites> </testsuites>
<source>
<include>
<directory>./src/</directory>
</include>
<exclude>
<directory suffix=".php">./src/Result/Reason</directory>
</exclude>
</source>
</phpunit> </phpunit>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.4.0@62db5d4f6a7ae0a20f7cc5a4952d730272fc0863">
<file src="src/Parser/DomainPart.php">
<RedundantConditionGivenDocblockType occurrences="1">
<code>null !== $this-&gt;lexer-&gt;token['type']</code>
</RedundantConditionGivenDocblockType>
</file>
</files>
+5 -10
View File
@@ -3,7 +3,11 @@
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"
errorBaseline="psalm.baseline.xml" errorLevel="1"
findUnusedCode="false"
findUnusedPsalmSuppress="true"
disableSuppressAll="true"
findUnusedVariablesAndParams="true"
> >
<projectFiles> <projectFiles>
<directory name="src" /> <directory name="src" />
@@ -11,13 +15,4 @@
<directory name="vendor" /> <directory name="vendor" />
</ignoreFiles> </ignoreFiles>
</projectFiles> </projectFiles>
<issueHandlers>
<DeprecatedMethod>
<errorLevel type="suppress">
<!-- This issue needs to be resolved before upgrading to Lexer 3 -->
<referencedMethod name="Doctrine\Common\Lexer\Token::offsetGet"/>
</errorLevel>
</DeprecatedMethod>
</issueHandlers>
</psalm> </psalm>
+1 -2
View File
@@ -61,7 +61,7 @@ class EmailLexer extends AbstractLexer
/** /**
* US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3) * US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3)
* *
* @var array * @var array<string, int>
*/ */
protected $charValue = [ protected $charValue = [
'{' => self::S_OPENCURLYBRACES, '{' => self::S_OPENCURLYBRACES,
@@ -177,7 +177,6 @@ class EmailLexer extends AbstractLexer
* @throws \UnexpectedValueException * @throws \UnexpectedValueException
* @return boolean * @return boolean
* *
* @psalm-suppress InvalidScalarArgument
*/ */
public function find($type): bool public function find($type): bool
{ {
+2 -2
View File
@@ -56,7 +56,7 @@ class EmailParser extends Parser
$localPartParser = new LocalPart($this->lexer); $localPartParser = new LocalPart($this->lexer);
$localPartResult = $localPartParser->parse(); $localPartResult = $localPartParser->parse();
$this->localPart = $localPartParser->localPart(); $this->localPart = $localPartParser->localPart();
$this->warnings = array_merge($localPartParser->getWarnings(), $this->warnings); $this->warnings = [...$localPartParser->getWarnings(), ...$this->warnings];
return $localPartResult; return $localPartResult;
} }
@@ -66,7 +66,7 @@ class EmailParser extends Parser
$domainPartParser = new DomainPart($this->lexer); $domainPartParser = new DomainPart($this->lexer);
$domainPartResult = $domainPartParser->parse(); $domainPartResult = $domainPartParser->parse();
$this->domainPart = $domainPartParser->domainPart(); $this->domainPart = $domainPartParser->domainPart();
$this->warnings = array_merge($domainPartParser->getWarnings(), $this->warnings); $this->warnings = [...$domainPartParser->getWarnings(), ...$this->warnings];
return $domainPartResult; return $domainPartResult;
} }
+2 -2
View File
@@ -57,7 +57,7 @@ class MessageIDParser extends Parser
$localPartParser = new IDLeftPart($this->lexer); $localPartParser = new IDLeftPart($this->lexer);
$localPartResult = $localPartParser->parse(); $localPartResult = $localPartParser->parse();
$this->idLeft = $localPartParser->localPart(); $this->idLeft = $localPartParser->localPart();
$this->warnings = array_merge($localPartParser->getWarnings(), $this->warnings); $this->warnings = [...$localPartParser->getWarnings(), ...$this->warnings];
return $localPartResult; return $localPartResult;
} }
@@ -67,7 +67,7 @@ class MessageIDParser extends Parser
$domainPartParser = new IDRightPart($this->lexer); $domainPartParser = new IDRightPart($this->lexer);
$domainPartResult = $domainPartParser->parse(); $domainPartResult = $domainPartParser->parse();
$this->idRight = $domainPartParser->domainPart(); $this->idRight = $domainPartParser->domainPart();
$this->warnings = array_merge($domainPartParser->getWarnings(), $this->warnings); $this->warnings = [...$domainPartParser->getWarnings(), ...$this->warnings];
return $domainPartResult; return $domainPartResult;
} }
+5 -6
View File
@@ -66,29 +66,28 @@ class Comment extends PartParser
$finalValidations = $this->commentStrategy->endOfLoopValidations($this->lexer); $finalValidations = $this->commentStrategy->endOfLoopValidations($this->lexer);
$this->warnings = array_merge($this->warnings, $this->commentStrategy->getWarnings()); $this->warnings = [...$this->warnings, ...$this->commentStrategy->getWarnings()];
return $finalValidations; return $finalValidations;
} }
/** /**
* @return bool * @return void
*/ */
private function warnEscaping(): bool private function warnEscaping(): void
{ {
//Backslash found //Backslash found
if (!$this->lexer->current->isA(EmailLexer::S_BACKSLASH)) { if (!$this->lexer->current->isA(EmailLexer::S_BACKSLASH)) {
return false; return;
} }
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) { if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) {
return false; return;
} }
$this->warnings[QuotedPart::CODE] = $this->warnings[QuotedPart::CODE] =
new QuotedPart($this->lexer->getPrevious()->type, $this->lexer->current->type); new QuotedPart($this->lexer->getPrevious()->type, $this->lexer->current->type);
return true;
} }
private function noClosingParenthesis(): bool private function noClosingParenthesis(): bool
+1 -5
View File
@@ -12,11 +12,7 @@ class DomainComment implements CommentStrategy
{ {
public function exitCondition(EmailLexer $lexer, int $openedParenthesis): bool public function exitCondition(EmailLexer $lexer, int $openedParenthesis): bool
{ {
if (($openedParenthesis === 0 && $lexer->isNextToken(EmailLexer::S_DOT))) { // || !$internalLexer->moveNext()) { return !($openedParenthesis === 0 && $lexer->isNextToken(EmailLexer::S_DOT));
return false;
}
return true;
} }
public function endOfLoopValidations(EmailLexer $lexer): Result public function endOfLoopValidations(EmailLexer $lexer): Result
+2 -1
View File
@@ -8,11 +8,12 @@ use Egulias\EmailValidator\Result\ValidEmail;
use Egulias\EmailValidator\Warning\CFWSNearAt; use Egulias\EmailValidator\Warning\CFWSNearAt;
use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Result\Reason\ExpectingATEXT; use Egulias\EmailValidator\Result\Reason\ExpectingATEXT;
use Egulias\EmailValidator\Warning\Warning;
class LocalComment implements CommentStrategy class LocalComment implements CommentStrategy
{ {
/** /**
* @var array * @var array<int, Warning>
*/ */
private $warnings = []; private $warnings = [];
+2 -2
View File
@@ -82,10 +82,10 @@ class DomainLiteral extends PartParser
if (!$isAddressLiteralIPv4) { if (!$isAddressLiteralIPv4) {
return new ValidEmail(); return new ValidEmail();
} else {
$addressLiteral = $this->convertIPv4ToIPv6($addressLiteral);
} }
$addressLiteral = $this->convertIPv4ToIPv6($addressLiteral);
if (!$IPv6TAG) { if (!$IPv6TAG) {
$this->warnings[WarningDomainLiteral::CODE] = new WarningDomainLiteral(); $this->warnings[WarningDomainLiteral::CODE] = new WarningDomainLiteral();
return new ValidEmail(); return new ValidEmail();
+7 -6
View File
@@ -137,7 +137,7 @@ class DomainPart extends PartParser
{ {
$commentParser = new Comment($this->lexer, new DomainComment()); $commentParser = new Comment($this->lexer, new DomainComment());
$result = $commentParser->parse(); $result = $commentParser->parse();
$this->warnings = array_merge($this->warnings, $commentParser->getWarnings()); $this->warnings = [...$this->warnings, ...$commentParser->getWarnings()];
return $result; return $result;
} }
@@ -213,9 +213,9 @@ class DomainPart extends PartParser
return new ValidEmail(); return new ValidEmail();
} }
/** /**
* @param Token<int, string> $token * @param Token<int, string> $token
* *
* @return Result * @return Result
*/ */
private function checkNotAllowedChars(Token $token): Result private function checkNotAllowedChars(Token $token): Result
@@ -240,14 +240,14 @@ class DomainPart extends PartParser
$domainLiteralParser = new DomainLiteralParser($this->lexer); $domainLiteralParser = new DomainLiteralParser($this->lexer);
$result = $domainLiteralParser->parse(); $result = $domainLiteralParser->parse();
$this->warnings = array_merge($this->warnings, $domainLiteralParser->getWarnings()); $this->warnings = [...$this->warnings, ...$domainLiteralParser->getWarnings()];
return $result; return $result;
} }
/** /**
* @param Token<int, string> $prev * @param Token<int, string> $prev
* @param bool $hasComments * @param bool $hasComments
* *
* @return Result * @return Result
*/ */
protected function checkDomainPartExceptions(Token $prev, bool $hasComments): Result protected function checkDomainPartExceptions(Token $prev, bool $hasComments): Result
@@ -307,6 +307,7 @@ class DomainPart extends PartParser
{ {
if (preg_match('/[^\x00-\x7F]/', $label)) { if (preg_match('/[^\x00-\x7F]/', $label)) {
idn_to_ascii($label, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $idnaInfo); idn_to_ascii($label, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $idnaInfo);
/** @psalm-var array{errors: int, ...} $idnaInfo */
return (bool) ($idnaInfo['errors'] & IDNA_ERROR_LABEL_TOO_LONG); return (bool) ($idnaInfo['errors'] & IDNA_ERROR_LABEL_TOO_LONG);
} }
return strlen($label) > self::LABEL_MAX_LENGTH; return strlen($label) > self::LABEL_MAX_LENGTH;
@@ -323,4 +324,4 @@ class DomainPart extends PartParser
{ {
return $this->domainPart; return $this->domainPart;
} }
} }
+6 -2
View File
@@ -17,7 +17,9 @@ class DoubleQuote extends PartParser
{ {
$validQuotedString = $this->checkDQUOTE(); $validQuotedString = $this->checkDQUOTE();
if ($validQuotedString->isInvalid()) return $validQuotedString; if ($validQuotedString->isInvalid()) {
return $validQuotedString;
}
$special = [ $special = [
EmailLexer::S_CR => true, EmailLexer::S_CR => true,
@@ -56,7 +58,9 @@ class DoubleQuote extends PartParser
if ($prev->isA(EmailLexer::S_BACKSLASH)) { if ($prev->isA(EmailLexer::S_BACKSLASH)) {
$validQuotedString = $this->checkDQUOTE(); $validQuotedString = $this->checkDQUOTE();
if ($validQuotedString->isInvalid()) return $validQuotedString; if ($validQuotedString->isInvalid()) {
return $validQuotedString;
}
} }
if (!$this->lexer->isNextToken(EmailLexer::S_AT) && !$prev->isA(EmailLexer::S_BACKSLASH)) { if (!$this->lexer->isNextToken(EmailLexer::S_AT) && !$prev->isA(EmailLexer::S_BACKSLASH)) {
+4 -10
View File
@@ -118,7 +118,7 @@ class LocalPart extends PartParser
$foldingWS = new FoldingWhiteSpace($this->lexer); $foldingWS = new FoldingWhiteSpace($this->lexer);
$resultFWS = $foldingWS->parse(); $resultFWS = $foldingWS->parse();
if ($resultFWS->isValid()) { if ($resultFWS->isValid()) {
$this->warnings = array_merge($this->warnings, $foldingWS->getWarnings()); $this->warnings = [...$this->warnings, ...$foldingWS->getWarnings()];
} }
return $resultFWS; return $resultFWS;
} }
@@ -132,7 +132,7 @@ class LocalPart extends PartParser
{ {
$dquoteParser = new DoubleQuote($this->lexer); $dquoteParser = new DoubleQuote($this->lexer);
$parseAgain = $dquoteParser->parse(); $parseAgain = $dquoteParser->parse();
$this->warnings = array_merge($this->warnings, $dquoteParser->getWarnings()); $this->warnings = [...$this->warnings, ...$dquoteParser->getWarnings()];
return $parseAgain; return $parseAgain;
} }
@@ -141,10 +141,8 @@ class LocalPart extends PartParser
{ {
$commentParser = new Comment($this->lexer, new LocalComment()); $commentParser = new Comment($this->lexer, new LocalComment());
$result = $commentParser->parse(); $result = $commentParser->parse();
$this->warnings = array_merge($this->warnings, $commentParser->getWarnings()); $this->warnings = [...$this->warnings, ...$commentParser->getWarnings()];
if ($result->isInvalid()) {
return $result;
}
return $result; return $result;
} }
@@ -159,10 +157,6 @@ class LocalPart extends PartParser
return new InvalidEmail(new ExpectingATEXT('Found ATOM after escaping'), $this->lexer->current->value); return new InvalidEmail(new ExpectingATEXT('Found ATOM after escaping'), $this->lexer->current->value);
} }
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) {
return new ValidEmail();
}
return new ValidEmail(); return new ValidEmail();
} }
} }
+1 -1
View File
@@ -40,7 +40,7 @@ abstract class PartParser
{ {
$foldingWS = new FoldingWhiteSpace($this->lexer); $foldingWS = new FoldingWhiteSpace($this->lexer);
$resultFWS = $foldingWS->parse(); $resultFWS = $foldingWS->parse();
$this->warnings = array_merge($this->warnings, $foldingWS->getWarnings()); $this->warnings = [...$this->warnings, ...$foldingWS->getWarnings()];
return $resultFWS; return $resultFWS;
} }
+1 -1
View File
@@ -7,7 +7,7 @@ class UnusualElements implements Reason
/** /**
* @var string $element * @var string $element
*/ */
private $element = ''; private $element;
public function __construct(string $element) public function __construct(string $element)
{ {
+8 -5
View File
@@ -13,10 +13,6 @@ use Egulias\EmailValidator\Warning\Warning;
class DNSCheckValidation implements EmailValidation class DNSCheckValidation implements EmailValidation
{ {
/**
* @var int
*/
protected const DNS_RECORD_TYPES_TO_CHECK = DNS_MX + DNS_A + DNS_AAAA;
/** /**
* Reserved Top Level DNS Names (https://tools.ietf.org/html/rfc2606#section-2), * Reserved Top Level DNS Names (https://tools.ietf.org/html/rfc2606#section-2),
@@ -149,7 +145,7 @@ 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); $dnsRecordsResult = $this->dnsGetRecord->getRecords($host, DNS_A + DNS_MX);
if ($dnsRecordsResult->withError()) { if ($dnsRecordsResult->withError()) {
$this->error = new InvalidEmail(new UnableToGetDNSRecord(), ''); $this->error = new InvalidEmail(new UnableToGetDNSRecord(), '');
@@ -158,6 +154,13 @@ class DNSCheckValidation implements EmailValidation
$dnsRecords = $dnsRecordsResult->getRecords(); $dnsRecords = $dnsRecordsResult->getRecords();
// Combined check for A+MX+AAAA can fail with SERVFAIL, even in the presence of valid A/MX records
$aaaaRecordsResult = $this->dnsGetRecord->getRecords($host, DNS_AAAA);
if (! $aaaaRecordsResult->withError()) {
$dnsRecords = array_merge($dnsRecords, $aaaaRecordsResult->getRecords());
}
// No MX, A or AAAA DNS records // No MX, A or AAAA DNS records
if ($dnsRecords === []) { if ($dnsRecords === []) {
$this->error = new InvalidEmail(new ReasonNoDNSRecord(), ''); $this->error = new InvalidEmail(new ReasonNoDNSRecord(), '');
+1 -2
View File
@@ -7,13 +7,12 @@ class DNSGetRecordWrapper
/** /**
* @param string $host * @param string $host
* @param int $type * @param int $type
* *
* @return DNSRecords * @return DNSRecords
*/ */
public function getRecords(string $host, int $type): DNSRecords public function getRecords(string $host, int $type): DNSRecords
{ {
// A workaround to fix https://bugs.php.net/bug.php?id=73149 // A workaround to fix https://bugs.php.net/bug.php?id=73149
/** @psalm-suppress InvalidArgument */
set_error_handler( set_error_handler(
static function (int $errorLevel, string $errorMessage): never { static function (int $errorLevel, string $errorMessage): never {
throw new \RuntimeException("Unable to get DNS record for the host: $errorMessage"); throw new \RuntimeException("Unable to get DNS record for the host: $errorMessage");
+3 -16
View File
@@ -4,29 +4,16 @@ namespace Egulias\EmailValidator\Validation;
class DNSRecords class DNSRecords
{ {
/** /**
* @var array $records * @param list<array<array-key, mixed>> $records
*/
private $records = [];
/**
* @var bool $error
*/
private $error = false;
/**
* @param array $records
* @param bool $error * @param bool $error
*/ */
public function __construct(array $records, bool $error = false) public function __construct(private readonly array $records, private readonly bool $error = false)
{ {
$this->records = $records;
$this->error = $error;
} }
/** /**
* @return array * @return list<array<array-key, mixed>>
*/ */
public function getRecords(): array public function getRecords(): array
{ {
@@ -22,9 +22,6 @@ class SpoofCheckValidation implements EmailValidation
} }
} }
/**
* @psalm-suppress InvalidArgument
*/
public function isValid(string $email, EmailLexer $emailLexer) : bool public function isValid(string $email, EmailLexer $emailLexer) : bool
{ {
$checker = new Spoofchecker(); $checker = new Spoofchecker();
@@ -37,9 +34,6 @@ class SpoofCheckValidation implements EmailValidation
return $this->error === null; return $this->error === null;
} }
/**
* @return InvalidEmail
*/
public function getError() : ?InvalidEmail public function getError() : ?InvalidEmail
{ {
return $this->error; return $this->error;
+2 -15
View File
@@ -22,11 +22,6 @@ class MultipleValidationWithAnd implements EmailValidation
*/ */
public const ALLOW_ALL_ERRORS = 1; public const ALLOW_ALL_ERRORS = 1;
/**
* @var EmailValidation[]
*/
private $validations = [];
/** /**
* @var Warning[] * @var Warning[]
*/ */
@@ -37,23 +32,15 @@ class MultipleValidationWithAnd implements EmailValidation
*/ */
private $error; private $error;
/**
* @var int
*/
private $mode;
/** /**
* @param EmailValidation[] $validations The validations. * @param EmailValidation[] $validations The validations.
* @param int $mode The validation mode (one of the constants). * @param int $mode The validation mode (one of the constants).
*/ */
public function __construct(array $validations, $mode = self::ALLOW_ALL_ERRORS) public function __construct(private readonly array $validations, private readonly int $mode = self::ALLOW_ALL_ERRORS)
{ {
if (count($validations) == 0) { if (count($validations) == 0) {
throw new EmptyValidationList(); throw new EmptyValidationList();
} }
$this->validations = $validations;
$this->mode = $mode;
} }
/** /**
@@ -66,7 +53,7 @@ class MultipleValidationWithAnd implements EmailValidation
$emailLexer->reset(); $emailLexer->reset();
$validationResult = $validation->isValid($email, $emailLexer); $validationResult = $validation->isValid($email, $emailLexer);
$result = $result && $validationResult; $result = $result && $validationResult;
$this->warnings = array_merge($this->warnings, $validation->getWarnings()); $this->warnings = [...$this->warnings, ...$validation->getWarnings()];
if (!$validationResult) { if (!$validationResult) {
$this->processError($validation); $this->processError($validation);
} }
+3 -8
View File
@@ -10,11 +10,6 @@ use Egulias\EmailValidator\Warning\Warning;
class RFCValidation implements EmailValidation class RFCValidation implements EmailValidation
{ {
/**
* @var EmailParser|null
*/
private $parser;
/** /**
* @var Warning[] * @var Warning[]
*/ */
@@ -27,10 +22,10 @@ class RFCValidation implements EmailValidation
public function isValid(string $email, EmailLexer $emailLexer): bool public function isValid(string $email, EmailLexer $emailLexer): bool
{ {
$this->parser = new EmailParser($emailLexer); $parser = new EmailParser($emailLexer);
try { try {
$result = $this->parser->parse($email); $result = $parser->parse($email);
$this->warnings = $this->parser->getWarnings(); $this->warnings = $parser->getWarnings();
if ($result->isInvalid()) { if ($result->isInvalid()) {
/** @psalm-suppress PropertyTypeCoercion */ /** @psalm-suppress PropertyTypeCoercion */
$this->error = $result; $this->error = $result;
+12 -2
View File
@@ -2,16 +2,26 @@
namespace Egulias\EmailValidator\Warning; namespace Egulias\EmailValidator\Warning;
use UnitEnum;
class QuotedPart extends Warning class QuotedPart extends Warning
{ {
public const CODE = 36; public const CODE = 36;
/** /**
* @param scalar|null $prevToken * @param UnitEnum|string|int|null $prevToken
* @param scalar|null $postToken * @param UnitEnum|string|int|null $postToken
*/ */
public function __construct($prevToken, $postToken) public function __construct($prevToken, $postToken)
{ {
if ($prevToken instanceof UnitEnum) {
$prevToken = $prevToken->name;
}
if ($postToken instanceof UnitEnum) {
$postToken = $postToken->name;
}
$this->message = "Deprecated Quoted String found between $prevToken and $postToken"; $this->message = "Deprecated Quoted String found between $prevToken and $postToken";
} }
} }
+2 -2
View File
@@ -7,8 +7,8 @@ class QuotedString extends Warning
public const CODE = 11; public const CODE = 11;
/** /**
* @param scalar $prevToken * @param string|int $prevToken
* @param scalar $postToken * @param string|int $postToken
*/ */
public function __construct($prevToken, $postToken) public function __construct($prevToken, $postToken)
{ {
+1 -1
View File
@@ -48,6 +48,6 @@ abstract class Warning
*/ */
public function __toString(): string public function __toString(): string
{ {
return $this->message() . " rfc: " . $this->rfcNumber . "internal code: " . strval(static::CODE); return $this->message() . " rfc: " . $this->rfcNumber . "internal code: " . static::CODE;
} }
} }
+4 -4
View File
@@ -51,11 +51,11 @@ class EmailLexerTest extends TestCase
$this->assertEquals(EmailLexer::INVALID, $lexer->current->type); $this->assertEquals(EmailLexer::INVALID, $lexer->current->type);
} }
public function invalidUTF8CharsProvider() public static function invalidUTF8CharsProvider()
{ {
$chars = array(); $chars = array();
for ($i = 0; $i < 0x100; ++$i) { for ($i = 0; $i < 0x100; ++$i) {
$c = $this->utf8Chr($i); $c = self::utf8Chr($i);
if (preg_match('/(?=\p{Cc})(?=[^\t\n\n\r])/u', $c) && !preg_match('/\x{0000}/u', $c)) { if (preg_match('/(?=\p{Cc})(?=[^\t\n\n\r])/u', $c) && !preg_match('/\x{0000}/u', $c)) {
$chars[] = array($c); $chars[] = array($c);
} }
@@ -64,7 +64,7 @@ class EmailLexerTest extends TestCase
return $chars; return $chars;
} }
protected function utf8Chr($code_point) protected static function utf8Chr($code_point)
{ {
if ($code_point < 0 || 0x10FFFF < $code_point || (0xD800 <= $code_point && $code_point <= 0xDFFF)) { if ($code_point < 0 || 0x10FFFF < $code_point || (0xD800 <= $code_point && $code_point <= 0xDFFF)) {
@@ -123,7 +123,7 @@ class EmailLexerTest extends TestCase
$this->assertTrue($lexer->find(EmailLexer::S_HTAB)); $this->assertTrue($lexer->find(EmailLexer::S_HTAB));
} }
public function getTokens() public static function getTokens()
{ {
return array( return array(
array("foo", EmailLexer::GENERIC), array("foo", EmailLexer::GENERIC),
+1 -1
View File
@@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase;
class EmailParserTest extends TestCase class EmailParserTest extends TestCase
{ {
public function emailPartsProvider() public static function emailPartsProvider()
{ {
return [ return [
['test@foo.com', 'test', 'foo.com'], ['test@foo.com', 'test', 'foo.com'],
@@ -16,7 +16,7 @@ use PHPUnit\Framework\TestCase;
class DNSCheckValidationTest extends TestCase class DNSCheckValidationTest extends TestCase
{ {
public function validEmailsProvider() public static function validEmailsProvider()
{ {
return [ return [
// dot-atom // dot-atom
@@ -32,12 +32,13 @@ class DNSCheckValidationTest extends TestCase
['"Fred\ Bloggs"@ietf.org'], ['"Fred\ Bloggs"@ietf.org'],
['"Joe.\\Blow"@ietf.org'], ['"Joe.\\Blow"@ietf.org'],
// unicide // unicode
['ñandu.cl'], ['info@ñandu.cl'],
['ñandu@ñandu.cl'],
]; ];
} }
public function localOrReservedEmailsProvider() public static function localOrReservedEmailsProvider()
{ {
return [ return [
// Reserved Top Level DNS Names // Reserved Top Level DNS Names
@@ -25,7 +25,7 @@ class SpoofCheckValidationTest extends TestCase
$this->assertFalse($validation->isValid("Кириллица"."latin漢字"."ひらがな"."カタカナ", new EmailLexer())); $this->assertFalse($validation->isValid("Кириллица"."latin漢字"."ひらがな"."カタカナ", new EmailLexer()));
} }
public function validUTF8EmailsProvider() public static function validUTF8EmailsProvider()
{ {
return [ return [
// Cyrillic // Cyrillic
@@ -19,7 +19,7 @@ class MessageIDValidationTest extends TestCase
$this->assertTrue($validator->isValid($messageID, new EmailLexer())); $this->assertTrue($validator->isValid($messageID, new EmailLexer()));
} }
public function validMessageIDs() : array public static function validMessageIDs() : array
{ {
return [ return [
['a@b.c+&%$.d'], ['a@b.c+&%$.d'],
@@ -38,7 +38,7 @@ class MessageIDValidationTest extends TestCase
$this->assertFalse($validator->isValid($messageID, new EmailLexer())); $this->assertFalse($validator->isValid($messageID, new EmailLexer()));
} }
public function invalidMessageIDs() : array public static function invalidMessageIDs() : array
{ {
return [ return [
['example'], ['example'],
@@ -38,7 +38,7 @@ class NoRFCWarningsValidationTest extends TestCase
$this->assertNull($validation->getError()); $this->assertNull($validation->getError());
} }
public function getValidEmailsWithoutWarnings() public static function getValidEmailsWithoutWarnings()
{ {
return [ return [
['example@example.com',], ['example@example.com',],
@@ -62,7 +62,7 @@ class RFCValidationDomainPartTest extends TestCase
$this->assertTrue($this->validator->isValid($email, $this->lexer)); $this->assertTrue($this->validator->isValid($email, $this->lexer));
} }
public function getValidEmails() public static function getValidEmails()
{ {
return array( return array(
['fabien@symfony.com'], ['fabien@symfony.com'],
@@ -88,7 +88,7 @@ class RFCValidationDomainPartTest extends TestCase
$this->assertFalse($this->validator->isValid($email, $this->lexer)); $this->assertFalse($this->validator->isValid($email, $this->lexer));
} }
public function getInvalidEmails() public static function getInvalidEmails()
{ {
return [ return [
['test@example.com test'], ['test@example.com test'],
@@ -161,7 +161,7 @@ class RFCValidationDomainPartTest extends TestCase
$this->assertEquals($error, $this->validator->getError()); $this->assertEquals($error, $this->validator->getError());
} }
public function getInvalidEmailsWithErrors() public static function getInvalidEmailsWithErrors()
{ {
return [ return [
[new InvalidEmail(new NoDomainPart(), ''), 'example@'], [new InvalidEmail(new NoDomainPart(), ''), 'example@'],
@@ -203,7 +203,7 @@ class RFCValidationDomainPartTest extends TestCase
} }
} }
public function getValidEmailsWithWarnings() public static function getValidEmailsWithWarnings()
{ {
return [ return [
//Check if this is actually possible //Check if this is actually possible
@@ -232,7 +232,7 @@ class RFCValidationDomainPartTest extends TestCase
]; ];
} }
public function invalidUTF16Chars() public static function invalidUTF16Chars()
{ {
return [ return [
['example@symƒony.com'], ['example@symƒony.com'],
@@ -54,7 +54,7 @@ class RFCValidationTest extends TestCase
$this->assertTrue($this->validator->isValid($email, $this->lexer)); $this->assertTrue($this->validator->isValid($email, $this->lexer));
} }
public function getValidEmails() public static function getValidEmails()
{ {
return array( return array(
['â@iana.org'], ['â@iana.org'],
@@ -91,7 +91,7 @@ class RFCValidationTest extends TestCase
$this->assertEquals($expectedWarnings, $this->validator->getWarnings()); $this->assertEquals($expectedWarnings, $this->validator->getWarnings());
} }
public function getValidEmailsWithWarnings() public static function getValidEmailsWithWarnings()
{ {
return [ return [
['a5aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com', [new LocalTooLong()]], ['a5aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com', [new LocalTooLong()]],
@@ -120,7 +120,7 @@ class RFCValidationTest extends TestCase
$this->assertFalse($this->validator->isValid($email, $this->lexer)); $this->assertFalse($this->validator->isValid($email, $this->lexer));
} }
public function getInvalidEmails() public static function getInvalidEmails()
{ {
return [ return [
['user name@example.com'], ['user name@example.com'],
@@ -150,6 +150,8 @@ class RFCValidationTest extends TestCase
['\r\n \r\n test@iana.org'], ['\r\n \r\n test@iana.org'],
['test;123@foobar.com'], ['test;123@foobar.com'],
['examp║le@symfony.com'], ['examp║le@symfony.com'],
['example@invalid-.domain.com'],
['example@-invalid.com'],
['0'], ['0'],
[0], [0],
]; ];
@@ -164,7 +166,7 @@ class RFCValidationTest extends TestCase
$this->assertEquals($error, $this->validator->getError()); $this->assertEquals($error, $this->validator->getError());
} }
public function getInvalidEmailsWithErrors() public static function getInvalidEmailsWithErrors()
{ {
return [ return [
[new InvalidEmail(new NoLocalPart(), "@"), '@example.co.uk'], [new InvalidEmail(new NoLocalPart(), "@"), '@example.co.uk'],