FILTER_VALIDATE_EMAIL disallows a number of potentially existing email addresses.

This includes valid examples such as:
- mesut@özil.de (valid IMA)
- mesut.özil@arsenal.com (valid IMA)
- инфо@кто.рф (valid IMA)
- admin@localhost (locally valid)
- admin@something (locally valid)

The OR referred to an address formally incorrect per RFC but obviously existing:
- test.@aon.at

Many more complex syntaxes are allowed per RFC though usually not used or accepted.

Original report

Just tried to create a user that has an email with a dot at the end, like test.@aon.at - which is a valid email address. I know two people who have such an address.
Drupal refuses to create that user and says that the email is not valid.

The code that verifies the email must have an issue here.

Comments

chx’s picture

Project: Core development » Drupal core
Version: » 8.x-dev
Component: Code » user system
nerdoc’s picture

This should be fairly easy to fix, but as I am not a Drupal developer I did not find where the regex is that checks an email address name. Any hints?

jlindsey15’s picture

Assigned: Unassigned » jlindsey15

Although I believe the root of this problem lies in php more generally, I think I could work around it to allow this kind of address - the code might be a bit a bit inelegant though...

pancho’s picture

Title: not possible to create user with email address that has a dot at the end » PHP's FILTER_VALIDATE_EMAIL rejects valid email addresses

Drupal's valid_email_address() internally uses PHP's FILTER_VALIDATE_EMAIL (see http://php.net/manual/filter.filters.validate.php), which is nice because we don't have to maintain it ourselves.

However, the PHP filter seems to be too strict in some cases. "admin@localhost" doesn't validate either, neither do IDNs.
Most certainly we won't switch to a homebrew regex just for a few cases on the edge of the specification. But it seems the range of unsupported cases is compelling enough to refrain from using FILTER_VALIDATE_EMAIL.

jlindsey15’s picture

@pancho - if we refrain from using filter_validate_email, don't we kind of need our own regex?

What I was thinking was to keep using filter_validate_email, but to just add a little code to cover these edge cases, since there has to be a finite (and probably small) number of them.

jlindsey15’s picture

After doing some research, it seems that an address like test.@aon.at does not comply with RFC specifications. Trailing dots are not allowed in the local part. That doesn't necessarily mean we shouldn't allow it, but it's debatable whether such an address is valid.

Correct me if I'm wrong, but I think recent versions of PHP support @localhost addresses. Also there has been some discussion about this previously: https://drupal.org/node/308138.

Solving the IDN issue would be more tricky, and I think that would require a homebrewed regex (which I'm happy to work on). Overall, I think we need to decide between pretty good, works-in-almost-all-cases, easy to maintain code, and "perfect" but harder to maintain code.

pancho’s picture

Priority: Normal » Major
Status: Active » Needs review
StatusFileSize
new529 bytes

1.
Thanks for your research regarding trailing dots. If they aren't allowed, these edge cases certainly aren't a reason to switch back to a homebrew regex.

However we need to take another look at IDNs and test@localhost style addresses:

2.

Solving the IDN issue would be more tricky, and I think that would require a homebrewed regex

Actually, FILTER_VALIDATE_EMAIL is supposed to accept IDNs. However, while not being documented, it is necessary to convert the address to punycode first. So we simply need to wrap the address in idn_to_ascii() before doing the filter_var() check.

Closed #389278: Create IDN encoding and decoding functions because we already require PHP 5.3 now.

3.

Correct me if I'm wrong, but I think recent versions of PHP support @localhost addresses.

From the other issue it seemed to be so. However on bugs.php.net, the discussion went back and forth, and it seems, support has been silently removed again. For the current state, see Rasmus' comment from 2012-08-16 on https://bugs.php.net/bug.php?id=49576.
We could fix it by adding '.local' before doing the filter_var() check, if no TLD is given.

Question is, if we can agree on allowing these. Some argumented against it in #308138: Make valid_email_address() support IDNs, but in the end, our validity test is shallow anyway. Why would we want to disallow test@localhost, while allowing no@valid.mail?
At least we should explicitely allow 'localhost' because it is used by many admins for testing purposes.

Status: Needs review » Needs work

The last submitted patch, 1427516-7.no-tests.patch, failed testing.

jlindsey15’s picture

Status: Needs work » Needs review
StatusFileSize
new682 bytes

I don't think you can call idn_to_ascii() on the whole address - it's just for the domain right? We'll see if this works...

Status: Needs review » Needs work

The last submitted patch, email-validation-1427516-9.patch, failed testing.

jlindsey15’s picture

Status: Needs work » Needs review
StatusFileSize
new700 bytes

That last one had a couple boneheaded errors.

Status: Needs review » Needs work

The last submitted patch, email-validation-1427516-11.patch, failed testing.

jlindsey15’s picture

Status: Needs work » Needs review
StatusFileSize
new696 bytes

Status: Needs review » Needs work

The last submitted patch, email-validation-1427516-13.patch, failed testing.

jlindsey15’s picture

Status: Needs work » Needs review
StatusFileSize
new698 bytes

Aha! The last patch adds an extra @ symbol to every email address. This should work.

andymartha’s picture

Status: Needs review » Needs work
StatusFileSize
new30.71 KB
new43.09 KB

After applying the patch email-validation-1427516-15.patch by jlindsey15 in #15 to a Drupal 8 fresh install 8/9, unfortunately all I received were server errors for creating new users like admin@localhost .

Please see screenshots.
beforeemailvalidation1427516.png

afteremailvalidation1427516.png

tim.plunkett’s picture

Title: PHP's FILTER_VALIDATE_EMAIL rejects valid email addresses » PHP's FILTER_VALIDATE_EMAIL rejects edge case email addresses
Priority: Major » Normal

Not a major bug.

tr’s picture

Issue summary: View changes
Issue tags: +IDN

Added IDN tag

pancho’s picture

Title: PHP's FILTER_VALIDATE_EMAIL rejects edge case email addresses » PHP's FILTER_VALIDATE_EMAIL rejects valid email addresses
Issue summary: View changes

Regarding IDN and IMA (see Wikipedia), this is not just an edge case. We're currently locking out all internatonalized mail addresses.

Mixologic’s picture

@Pancho - one thing that needs to be explictly clear that I think has been glossed over is that idn_to_ascii() and idn_to_utf8() are not always available in php 5.3 or php 5.4. They are part of an additional php extention, 'intl', that must be loaded in order for those extensions to function. Basically anywhere that you're going to use those idn functions probably should be wrapped with

if (extension_exists('intl')){
  $domain_ascii =  idn_to_ascii($domain_unicode);
}

Granted if somebody wants to support links to things like http://яндекс.рф , they probably will know that they need to have the intl module enabled. However, without it you will get a Fatal error: Call to undefined function idn_to_ascii().

cilefen’s picture

Status: Needs work » Closed (cannot reproduce)
Related issues: +#2343043: valid_email_address() should use egulias/EmailValidator and become deprecated

#2343043: valid_email_address() should use egulias/EmailValidator and become deprecated and some related issues replaced filter_var(). Open a new issue if this is a problem with the new valid_email_address().

tr’s picture

Version: 8.0.x-dev » 7.x-dev
Status: Closed (cannot reproduce) » Needs work

Still a problem in D7 ...

cilefen’s picture

Priority: Normal » Major
Status: Needs work » Active

This issue is major and active because some people will not be able to create accounts with their valid email addresses. We could back-port #2343043: valid_email_address() should use egulias/EmailValidator and become deprecated. But, I do not know if the Drupal 7 maintainers have a policy of allowing third-party PHP libraries in Drupal core.

cilefen’s picture

Sorry for the noise. @tim.plunkett, I see you had downgraded this to Normal a while ago. It would feel Major to me if I could not create an account. Do what you must if you disagree but can you please include your reasoning if you do?

dcam’s picture

This related issue seems like it's probably a duplicate.

cilefen’s picture

Title: PHP's FILTER_VALIDATE_EMAIL rejects valid email addresses » valid_email_address() rejects valid email addresses
cilefen’s picture

cilefen’s picture

I just posted a Drupal 7 back-port on #2343043: valid_email_address() should use egulias/EmailValidator and become deprecated. If one of the affected admins could test it out, that would be great.

anybody’s picture

This is still open and clearly MAJOR! The functionality is UNUSABLE for international domain names!
Let's please review and fix #2343043: valid_email_address() should use egulias/EmailValidator and become deprecated.

cilefen’s picture

This issue is possibly a critical because for the affected users the software is unusable.

andypost’s picture

poker10’s picture

Status: Postponed » Closed (won't fix)

Thanks everyone for reporting this and discussion. #2966195: valid_email_address() should be easily overridable is now committed, therefore closing this as Won't fix. Sites which require this are now able to do custom changes to the valid_email_address() validation via the new hook. It is unlikely that we would do changes to the behavior of the valid_email_address() itself in this D7 phase, as it is widely used function and such changes would affect majority of sites.