1
0
mirror of https://github.com/django/django.git synced 2025-06-14 16:09:12 +00:00

Make punycode conversion support IDNA 2008

As a new dependency would be required it is kept optional, default would
be to used Python standard IDNA converter.
This commit is contained in:
Julien BERNARD 2022-11-09 14:54:59 -05:00
parent d6fbfea08d
commit 85b066c9f2
3 changed files with 21 additions and 9 deletions

View File

@ -211,7 +211,19 @@ def escape_uri_path(path):
def punycode(domain):
"""Return the Punycode of the given domain if it's non-ASCII."""
return domain.encode("idna").decode("ascii")
if not domain:
return domain
try:
# try importing idna package for IDNA 2008 compliance
import idna
# enable uts46 mapping for mapping: uppercase letters, normalization, etc.
return idna.encode(domain, uts46=True, transitional=False).decode("ascii")
except ImportError:
# will fall back to Python IDNA 2003
return domain.encode("idna").decode("ascii")
except idna.IDNAError as e:
raise UnicodeError(e) from e
def repercent_broken_unicode(path):

View File

@ -1062,11 +1062,11 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
),
# Address with long display name and unicode domain.
(
("To Example very long" * 4, "to@exampl.com"),
("To Example very long" * 4, "to@examplе.com"),
"utf-8",
"To Example very longTo Example very longTo Example very longT"
"o Example very\n"
" long <to@xn--exampl-nc1c.com>",
" long <to@xn--exampl-8of.com>",
),
):
with self.subTest(email_address=email_address, encoding=encoding):

View File

@ -227,18 +227,18 @@ class FunctionTests(SimpleTestCase):
#13704 - Check urlize handles IDN correctly
"""
self.assertEqual(
urlize("http://c✶.ws"),
'<a href="http://xn--c-lgq.ws" rel="nofollow">http://c✶.ws</a>',
urlize("http://ça.ws"),
'<a href="http://xn--a-5fa.ws" rel="nofollow">http://ça.ws</a>',
)
self.assertEqual(
urlize("www.c✶.ws"),
'<a href="http://www.xn--c-lgq.ws" rel="nofollow">www.c✶.ws</a>',
urlize("www.ça.ws"),
'<a href="http://www.xn--a-5fa.ws" rel="nofollow">www.ça.ws</a>',
)
self.assertEqual(
urlize("c✶.org"), '<a href="http://xn--c-lgq.org" rel="nofollow">c✶.org</a>'
urlize("ça.org"), '<a href="http://xn--a-5fa.org" rel="nofollow">ça.org</a>'
)
self.assertEqual(
urlize("info@c✶.org"), '<a href="mailto:info@xn--c-lgq.org">info@c✶.org</a>'
urlize("info@ça.org"), '<a href="mailto:info@xn--a-5fa.org">info@ça.org</a>'
)
def test_malformed(self):