1
0
mirror of https://github.com/django/django.git synced 2025-06-06 20:19:13 +00:00

[5.2.x] Fixed #36017 -- Used EmailValidator in urlize to detect emails.

Backport of 61dae11df52fae71fc3050974ac459f362c9dfd7 from main.
This commit is contained in:
greg 2025-01-20 08:49:37 +01:00 committed by Sarah Boyce
parent 35d402f4e9
commit dab04b89af
2 changed files with 9 additions and 23 deletions

View File

@ -8,7 +8,8 @@ from collections.abc import Mapping
from html.parser import HTMLParser from html.parser import HTMLParser
from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation, ValidationError
from django.core.validators import EmailValidator
from django.utils.deprecation import RemovedInDjango60Warning from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.encoding import punycode from django.utils.encoding import punycode
from django.utils.functional import Promise, cached_property, keep_lazy, keep_lazy_text from django.utils.functional import Promise, cached_property, keep_lazy, keep_lazy_text
@ -463,20 +464,9 @@ class Urlizer:
@staticmethod @staticmethod
def is_email_simple(value): def is_email_simple(value):
"""Return True if value looks like an email address.""" """Return True if value looks like an email address."""
# An @ must be in the middle of the value.
if "@" not in value or value.startswith("@") or value.endswith("@"):
return False
try: try:
p1, p2 = value.split("@") EmailValidator(allowlist=[])(value)
except ValueError: except ValidationError:
# value contains more than one @.
return False
# Max length for domain name labels is 63 characters per RFC 1034.
# Helps to avoid ReDoS vectors in the domain part.
if len(p2) > 63:
return False
# Dot must be in p2 (e.g. example.com)
if "." not in p2 or p2.startswith("."):
return False return False
return True return True

View File

@ -379,15 +379,9 @@ class TestUtilsHtml(SimpleTestCase):
( (
# RFC 6068 requires a mailto URI to percent-encode a number of # RFC 6068 requires a mailto URI to percent-encode a number of
# characters that can appear in <addr-spec>. # characters that can appear in <addr-spec>.
"yes;this=is&a%valid!email@example.com", "yes+this=is&a%valid!email@example.com",
'<a href="mailto:yes%3Bthis%3Dis%26a%25valid%21email@example.com"' '<a href="mailto:yes%2Bthis%3Dis%26a%25valid%21email@example.com"'
">yes;this=is&a%valid!email@example.com</a>", ">yes+this=is&a%valid!email@example.com</a>",
),
(
# Urlizer shouldn't urlize the "?org" part of this. But since
# it does, RFC 6068 requires percent encoding the "?".
"test@example.com?org",
'<a href="mailto:test@example.com%3Forg">test@example.com?org</a>',
), ),
) )
for value, output in tests: for value, output in tests:
@ -407,6 +401,8 @@ class TestUtilsHtml(SimpleTestCase):
"foo@.example.com", "foo@.example.com",
"foo@localhost", "foo@localhost",
"foo@localhost.", "foo@localhost.",
"test@example?;+!.com",
"email me@example.com,then I'll respond",
# trim_punctuation catastrophic tests # trim_punctuation catastrophic tests
"(" * 100_000 + ":" + ")" * 100_000, "(" * 100_000 + ":" + ")" * 100_000,
"(" * 100_000 + "&:" + ")" * 100_000, "(" * 100_000 + "&:" + ")" * 100_000,