Fixed #22123 -- EmailValidator now also accepts IPv6 literals in addresses
This commit is contained in:
parent
173aa51997
commit
98f13762d7
|
@ -109,9 +109,11 @@ class EmailValidator(object):
|
|||
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"$)', # quoted-string
|
||||
re.IGNORECASE)
|
||||
domain_regex = re.compile(
|
||||
r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,})$' # domain
|
||||
# literal form, ipv4 address (SMTP 4.1.3)
|
||||
r'|^\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$',
|
||||
r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,})$',
|
||||
re.IGNORECASE)
|
||||
literal_regex = re.compile(
|
||||
# literal form, ipv4 or ipv6 address (SMTP 4.1.3)
|
||||
r'\[([A-f0-9:\.]+)\]$',
|
||||
re.IGNORECASE)
|
||||
domain_whitelist = ['localhost']
|
||||
|
||||
|
@ -135,18 +137,30 @@ class EmailValidator(object):
|
|||
raise ValidationError(self.message, code=self.code)
|
||||
|
||||
if (not domain_part in self.domain_whitelist and
|
||||
not self.domain_regex.match(domain_part)):
|
||||
not self.validate_domain_part(domain_part)):
|
||||
# Try for possible IDN domain-part
|
||||
try:
|
||||
domain_part = domain_part.encode('idna').decode('ascii')
|
||||
if not self.domain_regex.match(domain_part):
|
||||
raise ValidationError(self.message, code=self.code)
|
||||
else:
|
||||
if self.validate_domain_part(domain_part):
|
||||
return
|
||||
except UnicodeError:
|
||||
pass
|
||||
raise ValidationError(self.message, code=self.code)
|
||||
|
||||
def validate_domain_part(self, domain_part):
|
||||
if self.domain_regex.match(domain_part):
|
||||
return True
|
||||
|
||||
literal_match = self.literal_regex.match(domain_part)
|
||||
if literal_match:
|
||||
ip_address = literal_match.group(1)
|
||||
try:
|
||||
validate_ipv46_address(ip_address)
|
||||
return True
|
||||
except ValidationError:
|
||||
pass
|
||||
return False
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, EmailValidator) and (self.domain_whitelist == other.domain_whitelist) and (self.message == other.message) and (self.code == other.code)
|
||||
|
||||
|
|
|
@ -760,6 +760,9 @@ Validators
|
|||
``schemes`` argument which allows customization of the accepted URI schemes
|
||||
(instead of the defaults ``http(s)`` and ``ftp(s)``).
|
||||
|
||||
* :func:`~django.core.validators.validate_email` now accepts addresses with
|
||||
IPv6 literals, like ``example@[2001:db8::1]``, as specified in RFC 5321.
|
||||
|
||||
Backwards incompatible changes in 1.7
|
||||
=====================================
|
||||
|
||||
|
|
|
@ -33,6 +33,9 @@ TEST_DATA = (
|
|||
(validate_email, 'email@here.com', None),
|
||||
(validate_email, 'weirder-email@here.and.there.com', None),
|
||||
(validate_email, 'email@[127.0.0.1]', None),
|
||||
(validate_email, 'email@[2001:dB8::1]', None),
|
||||
(validate_email, 'email@[2001:dB8:0:0:0:0:0:1]', None),
|
||||
(validate_email, 'email@[::fffF:127.0.0.1]', None),
|
||||
(validate_email, 'example@valid-----hyphens.com', None),
|
||||
(validate_email, 'example@valid-with-hyphens.com', None),
|
||||
(validate_email, 'test@domain.with.idn.tld.उदाहरण.परीक्षा', None),
|
||||
|
@ -49,6 +52,10 @@ TEST_DATA = (
|
|||
(validate_email, 'abc@.com', ValidationError),
|
||||
(validate_email, 'something@@somewhere.com', ValidationError),
|
||||
(validate_email, 'email@127.0.0.1', ValidationError),
|
||||
(validate_email, 'email@[127.0.0.256]', ValidationError),
|
||||
(validate_email, 'email@[2001:db8::12345]', ValidationError),
|
||||
(validate_email, 'email@[2001:db8:0:0:0:0:1]', ValidationError),
|
||||
(validate_email, 'email@[::ffff:127.0.0.256]', ValidationError),
|
||||
(validate_email, 'example@invalid-.com', ValidationError),
|
||||
(validate_email, 'example@-invalid.com', ValidationError),
|
||||
(validate_email, 'example@inv-.alid-.com', ValidationError),
|
||||
|
|
Loading…
Reference in New Issue