mirror of
https://github.com/django/django.git
synced 2025-02-04 22:47:53 +00:00
Fixed issue where IDNA 2008 encoded domains were not validated
This commit is contained in:
parent
7e41a7a47d
commit
78e5cb0941
@ -6,7 +6,7 @@ from urllib.parse import urlsplit
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.deconstruct import deconstructible
|
||||
from django.utils.encoding import punycode
|
||||
from django.utils.encoding import idna2008_encode
|
||||
from django.utils.ipv6 import is_valid_ipv6_address
|
||||
from django.utils.regex_helper import _lazy_re_compile
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@ -254,7 +254,8 @@ class EmailValidator:
|
||||
):
|
||||
# Try for possible IDN domain-part
|
||||
try:
|
||||
domain_part = punycode(domain_part)
|
||||
domain_part = idna2008_encode(domain_part)
|
||||
|
||||
except UnicodeError:
|
||||
pass
|
||||
else:
|
||||
@ -679,4 +680,4 @@ class ProhibitNullCharactersValidator:
|
||||
isinstance(other, self.__class__)
|
||||
and self.message == other.message
|
||||
and self.code == other.code
|
||||
)
|
||||
)
|
@ -4,7 +4,7 @@ import locale
|
||||
from decimal import Decimal
|
||||
from types import NoneType
|
||||
from urllib.parse import quote
|
||||
|
||||
import unicodedata
|
||||
from django.utils.functional import Promise
|
||||
|
||||
|
||||
@ -209,6 +209,22 @@ def punycode(domain):
|
||||
"""Return the Punycode of the given domain if it's non-ASCII."""
|
||||
return domain.encode("idna").decode("ascii")
|
||||
|
||||
def idna2008_encode(domain):
|
||||
"""
|
||||
Encode a domain name according to IDNA 2008 (simplified version).
|
||||
"""
|
||||
def encode_label(label):
|
||||
if all(ord(c) < 128 for c in label):
|
||||
# Label contains only ASCII characters
|
||||
return label
|
||||
# Normalize and encode to Punycode
|
||||
normalized_label = unicodedata.normalize('NFC', label)
|
||||
return f"xn--{normalized_label.encode('punycode').decode('ascii')}"
|
||||
|
||||
labels = domain.split(".")
|
||||
ascii_labels = [encode_label(label) for label in labels]
|
||||
return ".".join(ascii_labels)
|
||||
|
||||
|
||||
def repercent_broken_unicode(path):
|
||||
"""
|
||||
|
@ -319,6 +319,22 @@ TEST_DATA = [
|
||||
(validate_email, "example@inv-.alid-.com", ValidationError),
|
||||
(validate_email, "example@inv-.-alid.com", ValidationError),
|
||||
(validate_email, 'test@example.com\n\n<script src="x.js">', ValidationError),
|
||||
(validate_email, 'email@domain.com', None),
|
||||
(validate_email, 'email@xn--4ca9at.com', None),
|
||||
(validate_email, 'email@öäü.com', None),
|
||||
(validate_email, 'email@עִתוֹן.example.il', None),
|
||||
(validate_email, 'email@މިހާރު.example.mv', None),
|
||||
(validate_email, 'email@漢字.example.com', None),
|
||||
(validate_email, "editor@މިހާރު.example.mv", None),
|
||||
(validate_email, 'email@', ValidationError),
|
||||
(validate_email, '@domain.com', ValidationError),
|
||||
(validate_email, 'email.domain.com', ValidationError),
|
||||
(validate_email, 'email@domain@domain.com', ValidationError),
|
||||
(validate_email, 'email@domain..com', ValidationError),
|
||||
(validate_email, 'email@.domain.com', ValidationError),
|
||||
(validate_email, 'email@-domain.com', ValidationError),
|
||||
(validate_email, 'email@domain-.com', ValidationError),
|
||||
(validate_email, 'email@domain.com-', ValidationError),
|
||||
# Quoted-string format (CR not allowed)
|
||||
(validate_email, '"\\\011"@here.com', None),
|
||||
(validate_email, '"\\\012"@here.com', ValidationError),
|
||||
|
Loading…
x
Reference in New Issue
Block a user