egulias / emailvalidator Goto Github PK
View Code? Open in Web Editor NEWPHP Email address validator
License: MIT License
PHP Email address validator
License: MIT License
If i'm reading the code correctly, line 38 of Parser/DomainPart.php fails an email address than ends with a dot. Technically all email addresses end in a dot as all "top-level" domains are relative to the root domain, "." — for example http://google.com./ is the true website of Google, and http://google.com/ is merely a local alias for it, which your DNS resolver could point to somewhere other than the global "com." domain
https://scrutinizer-ci.com/ provides CI for code analysis
We received another error for an e-mail address passing validation:
[email protected] test
This will happen if a user copies and pastes their e-mail address from some sort of document with words after it, and they aren't paying attention.
This e-mail should NOT pass validation.
Thanks again @egulias!
Right now the validator is around 12 times slower than filter_var
.
tê[email protected]
pass the validator
It should pass the validator.
As an example, if I use the following code, this addresses does not pass the validator :
public static function ValidateAddress($address) {
if(filter_var($address, FILTER_VALIDATE_EMAIL) === false) {
return false;
}
// We only check the presence of a dot on the domain part
$components = explode("@", $address);
$domain = $components[1];
if (strpos($domain, ".") === false) {
return false;
}
return true;
}
Strategy to make an email invalid if there are any warnings.
@egulias Thank you very much for patching the bug, however, this introduced another (minor) bug into the Symfony integration.
It appears you're adding these special character (double quotes, escaping) to the warnings array. In Symfony, when you add strict = true
into the constraint, it passes the strict variable into the library, which returns warnings as an error.
If somebody has the brian\ [email protected] e-mail address, in Symfony, it will fail out, where it should be a valid e-mail address.
The good news is the local parts that we were getting errors from are no longer being accepted.
I don't know if this was by design, but I think we need to rethink how EmailValidator will return double quotes and escaped. Should those be warnings or just allowed?
Thanks!
As a first approach, use the Strategy pattern so upon construction EmailValidator requires the strategies objects to be used for validation.
Strategies will be evaluated in an AND fashion. E.g
//$result has been setted after the first validation
foreach ($this->strategies as $strategy) {
$result = $result && $strategy->isValid($email, $this->lexer, $this->getWarnings());
}
Right now $this->lexer
is mutable, probably needs to be immutable so there's no riks while passing it around.
Should also define ValidationStretegy::isValid
interface.
RFCs validation would be the only one "hardcoded" within the validator. Probably being added in the constructor.
EmailValidator::__construct(ValidationStrategies $stretegies)
README.md and files in documentation/* should have UNIX-type line endings.
Create InvalidEmailException
as an interface and make custom exception for every case extending from it.
Hi!
I suppose there is a problem with cyrillic domains.
This email marked as invalid but domain and email is ok
1500111@профи-инвест.рф
http://профи-инвест.рф
Hi,
Why this email $@$#$#
is valid for your library with strict mode
$validator->isValid('$@$#$#', false, true) // true
and is not valid with is_email()
function?
is_email('$@$#$#') // false
Is it really a valid email address?
The validator bypasses Ill-formed byte sequences. The definition of UTF-8 string can be seen in RFC 3629 or "Table 3-7. Well-Formed UTF-8 Byte Sequences" in the Unicode Standard (from my answer on stackoverflow).
$validator = new EmailValidator;
$email = "\x80\x81\x82@\x83\x84\x85.\x86\x87\x88";
var_dump(
true === $validator->isValid($email)
);
The way for validating UTF-8 string is using htmlspecialchars or preg_match.
function utf8_validate($str) {
return $str === htmlspecialchars_decode(htmlspecialchars($str, ENT_QUOTES, 'UTF-8'));
}
function utf8_validate2($str) {
return false !== preg_match('/./u', $str);
}
See #46
Whilst investigating a Symfony issue (symfony/symfony#11722) I started working on comparing this library to the originals test suite. In doing so I've encountered multiple instances where this library produces a different result. There are 30 errors for syntax only checks and another 12 errors when DNS is consulted. My results and ugly git branch.
/cc @brianfreytag
According to my knowledge (correct me if I am wrong) the email "username @example.com" is not a valid one. However, it does pass as a valid one in the validator.
It is in the same vein as "user [email protected]", which does get marked as invalid.
It would be great to add some useful tag. Either mark it as 1.0 and stable or as beta or something else. (I don't know how you think of the state of the project).
This would help people to not update each commit when they do a composer update.
$validator = new \Egulias\EmailValidator\EmailValidator();
var_dump($validator->isValid('email.email@email.!"£$%^&*'));
Expected result: false
Actual result: true
I got an exception from swiftmailer:
Uncaught PHP Exception Swift_RfcComplianceException: "Address in mailbox given [test@foo;bar.com] does not comply with RFC 2822, 3.6.2."
https://coveralls.io/ is a CI that runs coverages reports.
Somehow expose why a given email is invalid.
This will probably mean throwing custom exceptions (a needed refactor anyway).
Original discussion #51
The goal of this ported library was to ultimately integrate it as a Symfony 2 Validator. Thus there are some changes that need to be done before.
The first one is to depend on Doctrine\Lexer instead of JMS\Lexer since the firs one is already a dependency of Symfony.
I'm trying to validate that email "boobooin@mailru" it get a valid response. But it's not.
Correct email consist dot - "[email protected]"
Tried with CheckDNS and Strict enabled - same result.
Tried email with no existed domain "[email protected]" with CheckDNS enabled. Same incorrect result.
What am i doing wrong? Thanks in advance!
Transform the suite into a Symfony Validator Constraint so it can be used (https://github.com/symfony/Validator/blob/master/Constraints/EmailValidator.php)
Hi.
It seems may faster use dig
.
For example:
public function isMxExists($email)
{
$domain = explode('@', $email);
$domain = array_pop($domain);
/** You can use cache here for a day. */
exec("dig -t MX {$domain} +noall +answer +short", $result);
return !empty($result);
}
Currently localPart and domainPart parsers depend on the position where the lexer is when they start parsing.
They should 'lex' the string that they get, the caller is the responsible for knowing what is passing.
Check https://github.com/egulias/EmailValidator4J
one of the example:
$email = 'á[email protected]';
$validaotr = new \Egulias\EmailValidator\EmailValidator();
var_dump($validaotr->isValid($email));
$message = \Swift_Message::newInstance()->setFrom($email);
another one is #41 and i believe that there are other cases
error message: Address in mailbox given [...] does not comply with RFC 2822, 3.6.2.
Should be (see // here!)
use Egulias\EmailValidator\EmailValidator;
$validator = new EmailValidator;
$email = '[email protected]';
$result = $validator->isValid($email);
if ($result) {
echo $email . ' is a valid email address';
// here!
}
if ($validator->hasWarnings()) {
echo 'Warning! ' . $email . ' has unusual/deprecated features (result code ' . var_export($validator->getWarnings(), true) . ')';
} else {
echo $email . ' is not a valid email address (result code ' . $validator->getError() . ')';
}
The "symfony/validator": "dev-master"
is used inside composer.json
But does not seem to be used anywhere, second you should try not require a master version if a looser version would also work.
If you really require at least 2.4 you can fix this with.
~2.4
if i install the version 1.2.6 have i the following problem:
Problem 1
- Installation request for egulias/email-validator v1.2.6 -> satisfiable by egulias/email-validator[1.2.6].
- egulias/email-validator 1.2.6 requires doctrine/lexer dev-master -> no matching package found.
Problem 2
- egulias/email-validator 1.2.6 requires doctrine/lexer dev-master -> no matching package found.
- tubssp/aura 2.5.x-dev requires egulias/email-validator v1.2.6 -> satisfiable by egulias/email-validator[1.2.6].
- Installation request for tubssp/aura 2.5.x-dev -> satisfiable by tubssp/aura[2.5.x-dev].
but the version 1.X of lexer ist needet from others:
Problem 1
- The requested package doctrine/lexer could not be found in any version, there may be a typo in the package name.
Problem 2
- Installation request for tubssp/aura 2.5.x-dev -> satisfiable by tubssp/aura[2.5.x-dev].
- tubssp/aura 2.5.x-dev requires doctrine/lexer master -> no matching package found.
Problem 3
- Installation request for egulias/email-validator v1.2.6 -> satisfiable by egulias/email-validator[1.2.6].
- egulias/email-validator 1.2.6 requires doctrine/lexer dev-master -> no matching package found.
Problem 4
- doctrine/orm v2.4.6 requires doctrine/dbal ~2.4 -> satisfiable by doctrine/dbal[v2.4.3, v2.4.0, v2.4.1, v2.4.2].
- doctrine/orm v2.4.6 requires doctrine/dbal ~2.4 -> satisfiable by doctrine/dbal[v2.4.3, v2.4.0, v2.4.1, v2.4.2].
- doctrine/dbal v2.4.3 requires doctrine/common ~2.4 -> satisfiable by doctrine/common[v2.4.2, v2.4.0, v2.4.1].
- doctrine/dbal v2.4.0 requires doctrine/common ~2.4 -> satisfiable by doctrine/common[v2.4.2, v2.4.0, v2.4.1].
- doctrine/dbal v2.4.1 requires doctrine/common ~2.4 -> satisfiable by doctrine/common[v2.4.2, v2.4.0, v2.4.1].
- doctrine/dbal v2.4.2 requires doctrine/common ~2.4 -> satisfiable by doctrine/common[v2.4.2, v2.4.0, v2.4.1].
- doctrine/dbal v2.4.3 requires doctrine/common ~2.4 -> satisfiable by doctrine/common[v2.4.2, v2.4.0, v2.4.1].
- doctrine/common v2.4.2 requires doctrine/lexer 1.* -> no matching package found.
- doctrine/common v2.4.2 requires doctrine/lexer 1.* -> no matching package found.
- doctrine/common v2.4.1 requires doctrine/lexer 1.* -> no matching package found.
- doctrine/common v2.4.0 requires doctrine/lexer 1.* -> no matching package found.
- Installation request for doctrine/orm v2.4.6 -> satisfiable by doctrine/orm[v2.4.6].
Hi there,
I'm writing after using this module through Drupal 8. Emails in @something.com.au are marked invalid and it's kind of a big deal for us ;)
Do you think there's an easy fix to that? I didn't look into your code so far...
Thanks for your time.
Implement the interface for checking DNS of the domain of an email
Example:
$email = "[email protected])";
Validation gives true. Expected to be false.
Check the right working and if it's being tested
Require latest from 5.5
Feature request : make a sanitization filter
For example, "ex@mple@tes t.com" would trim forbidden characters and result with "[email protected]"
$validator = new \Egulias\EmailValidator\EmailValidator();
if ($validator->isValid('test [email protected]')) {
echo 'valid';
}
Acording to the validator this email is valid.
Remove EmailValidator class constants and make them classes.
This line https://github.com/egulias/EmailValidator/blob/master/src/Egulias/EmailValidator/EmailLexer.php#L78 is there to make the tests pass regarding #18 but since UTF-8 is now supported and allowed by the RFCs, should be removed.
For example [email protected]]
is considered valid. If DNS checking is enabled it returns a warning
Backslash \
are not valid at any point of the domain part. Currently are validated when are before GENERIC but not at the end of the end (http://tools.ietf.org/html/rfc5322#section-3.2.3).
When an exception of type InvalidEmailException
is catched, use the exception message (https://github.com/egulias/EmailValidator/blob/master/src/Egulias/EmailValidator/EmailValidator.php#L83) as the error reported.
Sorry for no-replying previous issue. How about adding options for using intl's Spoofchecker (uspoof.h) to prevent IDN homograph attack?
Gmail require Unicode Highly Restricted restriction level for that purpose (Protecting Gmail in a global world). Highly Restricted restricion level can be used since ICU 51 and later. ICU version can be checked by INTL_ICU_VERSION
or INTL_ICU_DATA_VERSION
These constants can be used PHP 5.3.7 and later. Here is sample code.
if (version_compare(INTL_ICU_VERSION, '51.0', '>=')) {
exit('You need ICU 51 and later');
}
$spoof = new Spoofchecker;
$spoof->setChecks(Spoofchecker::SINGLE_SCRIPT);
// Cyrillic
$str = 'Кириллица';
// Latin + Han + Hiragana + Katakana
$str2 = "latin".漢字"."ひらがな"."カタカナ";
// Latin + Han + Hangul
$str3 = "latin"."漢字"."조선말";
// Latin + Han + Bopomofo
$str4 = "latin"."漢字"."ㄅㄆㄇㄈ";
var_dump(
false === $spoof->isSuspicious($str),
false === $spoof->isSuspicious($str2),
false === $spoof->isSuspicious($str3),
false === $spoof->isSuspicious($str4),
true === $spoof->isSuspicious($str.$str2)
);
You can also use locale-based restrictions.
$spoof = new Spoofchecker;
// Latin + Han + Hiragana + Katakana
$spoof->setAllowedLocales('en_US,ja_JP');
var_dump(
false === $spoof->isSuspicious('latin'.'漢字'.'ひらがな'.'カタカナ')
);
// Latin + Han + Hangul
$spoof->setAllowedLocales('en_US,ko_KR');
var_dump(
false === $spoof->isSuspicious('latin'.'漢字'.'조선말')
);
// Latin + Han + Bopomofo
$spoof->setAllowedLocales('en_US,zh_TW');
var_dump(
false === $spoof->isSuspicious('latin'.'漢字'.'ㄅㄆㄇㄈ')
);
Mozilla discusses using Moderately Restrictive profile (IDN Display Algorithm). Unfortunately, intl module doesnt't provide method (calling uspoof_setRestrictionLevel
) and constants (ASCII
, SINGLE_SCRIPT_RESTRICTIVE
, HIGHLY_RESTRICTIVE
, MODERATELY_RESTRICTIVE
, MINIMALLY_RESTRICTIVE
, UNRESTRICTIVE
) for changing restriction level. I am going to create feature request for adding the method to intl module. Here is my test for intl module adding setRestrictionLevel
method and constants.
If MX record does not exists, fall back tocheck A record
This line: https://github.com/egulias/EmailValidator/blob/master/src/Egulias/EmailValidator/Parser/LocalPart.php#L52
The constant is wrong, since the value of the error should no be dependant on the value for that evaluation
There are certain special characters
"(),:;<>@[\]
that have special requirements.
The validator is currently allowing:
And other examples like those.
It is also saying things are invalid that are valid like:
There are a whole lot of RFC things that are coming through that should be blocked and it's blocking a lot of things that should be getting through.
This snippet was used for validating TLD
if (isset($this->atomList[self::COMPONENT_DOMAIN][$this->elementCount][0]) &&
is_numeric($this->atomList[self::COMPONENT_DOMAIN][$this->elementCount][0])
) {
$this->warnings[] = self::RFC5321_TLDNUMERIC;
}
Add tests for it and check if still valid
Let's take e.g. str_repeat('a', 254) . '@gmail.com'
, which used to cause the warnings RFC5322_LOCAL_TOOLONG
and RFC5322_TOOLONG
. But with version 1.2.4, so after merging #33, there's no warning anymore.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.