Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Validator] #18156 In "strict" mode, email validator inaccurately cla… #18428

Closed
wants to merge 4 commits into from

Conversation

natechicago
Copy link
Contributor

Q A
Branch? master
Bug fix? yes
New feature? yes
BC breaks? no
Deprecations? yes
Tests pass? yes
Fixed tickets #18156
License MIT
Doc PR 6429

Email validation can now occur in one of four different modes/profiles:

  • Basic regex
  • HTML5 regex
  • RFC-compliant (non-strict; informational warnings raised during validation are ignored)
  • RFC-compliant (strict; warnings will cause an otherwise-valid email to be considered invalid)

The legacy "strict" mode has been marked as deprecated, but for now is still fully supported.

…ely claims certain valid emails are invalid

Email validation can now occur in one of four different modes/profiles:
 - Basic regex
 - HTML5 regex
 - RFC-compliant (non-strict; informational warnings raised during validation are ignored)
 - RFC-compliant (strict; warnings will cause an otherwise-valid email to be considered invalid)
* @param string $profile If the constraint does not define a validation
* profile, this will specify which profile to use.
*/
public function __construct($strict = false, $profile = Email::PROFILE_BASIC_REGX)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$profile should default to null, use $strict only if $profile is null. so strict can be ignored, if profile is given.

public function __construct($strict = false, $profile = null)
{
    $this->isStrict = $strict;
    $this->defaultProfile = $profile === null
        ? $strict
            ? Email::PROFILE_RFC_DISALLOW_WARNINGS
            : Email::PROFILE_BASIC_REGX
        : $profile;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is much better, as my original implementation would have misbehaved in the edge case situation with both config options set (strict_email = TRUE, and email_profile='html5'). Thanks for catching that!

@natechicago
Copy link
Contributor Author

I'm not quite sure why the new tests are failing under Travis CI's PHP 7. They don't contain any controversial code, and they pass without any problems in my local PHP 7 environment.

…ely claims certain valid emails are invalid

Changes from code review.
@xabbuh
Copy link
Member

xabbuh commented Apr 6, 2016

@natechicago I guess the failure is related to the minimal allowed version of the validation library (which will be used in the PHP 7 build) and the fact that you use addresses with parentheses/brackets (there have been some recent changes in the validator library fixing issues with them). Would it be possible to choose other example data for the tests that will pass with older versions of the library?

…ely claims certain valid emails are invalid

Changes from code review.
@natechicago
Copy link
Contributor Author

@xabbuh thanks for pointing me in the right direction! The tests are now compliant with the minimal allowed version of the egulias/email-validation library.

if (!class_exists('\Egulias\EmailValidator\EmailValidator')) {
throw new RuntimeException(
'Standards-compliant email validation requires egulias/email-validator'
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be on one line

…ely claims certain valid emails are invalid

Changes from code review.
@backbone87
Copy link
Contributor

the failing test is unrelated to this ticket, can someone review?

types "basic regex" and "RFC (disallow warnings)". The desired mode of
validation can be specified using the `Email` constraint's new `profile`
option. The constraint's `strict` option (equivalent to the 'rfc-no-warn'
profile) has been deprecated and will be removed in Symfony 4.0.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of the strict option must be documented in the UPGRADE_4.0.md file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And we will need to trigger deprecations.

@ro0NL
Copy link
Contributor

ro0NL commented Apr 23, 2016

What about custom profiles? Perhaps implement protected function validateProfile($profile)?

@ro0NL
Copy link
Contributor

ro0NL commented Apr 23, 2016

What about a EmailProfileInterface..?

@backbone87
Copy link
Contributor

@ro0NL i think thats too much overengineering

@ro0NL
Copy link
Contributor

ro0NL commented Apr 24, 2016

@backbone87 agree 👍 custom validation can be done with an additional constraint anyways.

Still.. the EmailValidator class isn't really extendable right now to allow easy built-in customization, i.e. the addition of protected function validateProfile($profile) (or to be consistent; checkProfile) would still be useful imho. Same goes for changing the visibility ofcheckMX and checkHost from private to protected, that would improve extending significantly. What do you think?

@javiereguiluz
Copy link
Member

I'm -1 to this proposal. My reasons:

  1. Validation is a binary thing: either the email address is valid or it's not.
    But this PR proposes four different behaviors: maybe it's valid (basic), probably it's valid (html5), almost certainly it's valid but I'll ignore errors (rfc non-strict) and almost certainly it's valid and I'll trigger errors (rfc strict).

  2. The decision to add all kinds of validation variations smells like a "decision by committee", which is one of the worst things you can do when developing a feature.

  3. Some developers refuse to accept that there are problems which cannot be solved with code. But that's a fact, and validating email addresses is one of the best examples.

  4. Even with the four proposed validations, millions of valid email addresses will be considered invalid. They are the infamous Japanese emails which are "technically wrong" but "fully working" in the real world (see this and this for details).


In #18177 I proposed an alternative solution:

  • Simplify everything to provide just a regexp-based validator which validates
    emails as "probably valid".
  • If you want 100% certainty, send a confirmation email message.

@ro0NL
Copy link
Contributor

ro0NL commented Apr 24, 2016

I upvoted #18177 :-) Do you agree on profiles as a nice to have or should symfony force you with simple regex validation only, and "hey.. build something to send a confirmation email" or use a custom callback/regexp/whatever constraint additionally.

I personally favor a simple regex by default, i.e. the basic profile (/^.+\@\S+\.\S+$/) and a confirmation email at application-level. But still like to see these additional profiles being available. Perhaps more explicit in separate classes, but that would be overengineering things.

Edit: even the basic profile is to restricted on the dot part imho... =/

Edit 2: my point is.. even if we use the HTML5 regex as you proposed in #18177 than the EmailValidator could still produce false negatives right? (e.g. the weird japanese emails you mentioned), i.e. whats the goal for the EmailValidator? To be really generic so we avoid any false negatives/positives whatsoever, being technically correct, or being both?

@egulias
Copy link
Contributor

egulias commented Apr 29, 2016

Hello again.
Just to let you know there's a roadmap for v2 of the library (https://github.com/egulias/EmailValidator/milestones/v2.0.0) where you will be able to use any validation "strategy" (egulias/EmailValidator#62) you like. RFC strictness will become one of such strategies (like DNS check , HTML5 regexp or even filter_var) to allow for extension and customization.
I'll be happy to also do the PR to Symfony to add the new version and the configuration need, something like
validator: email_validator:[HTML5Validation, DNSValidation]
This way knowing, customizing and using the email validation would be easier.
Also take into account using any form of RegExp:

  • will not allow UTF8 emails (not just Japanese)
  • will not work with Swiftmailer <=5 (uses a quite complex RegExp) and 6 uses EmailValidator same validator.

@ro0NL the initial idea was to be technically correct , with v2 I'm aiming to be both.
@javiereguiluz issue swiftmailer/swiftmailer#71 from swiftmailer was closed with the use, in v6, of the EmailValidator lib we are here trying to find out if it is useful or not.

@egulias
Copy link
Contributor

egulias commented May 2, 2016

FYI
API proposal for isValid

@fabpot
Copy link
Member

fabpot commented Jun 14, 2016

I'm also 👎 on adding "email validation strategies". We decided to rely on an external library for email validation and we should stick with whatever they provide. In any case, someone can create their own email validator if that makes sense in their use case, no need to change Symfony's internal one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants