summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgreg <marianigregory@pm.me>2025-01-20 08:49:37 +0100
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-01-20 14:04:35 +0100
commitdab04b89af91467e9a95ffaf30c1904fce7fff47 (patch)
treea3a515ae0839fd486f449ebe5bde9129e63f9abb
parent35d402f4e9505e4d6b6cc1e9f2e9dbaf1780a87e (diff)
[5.2.x] Fixed #36017 -- Used EmailValidator in urlize to detect emails.
Backport of 61dae11df52fae71fc3050974ac459f362c9dfd7 from main.
-rw-r--r--django/utils/html.py18
-rw-r--r--tests/utils_tests/test_html.py14
2 files changed, 9 insertions, 23 deletions
diff --git a/django/utils/html.py b/django/utils/html.py
index 10036c38c4..ab1363e2de 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -8,7 +8,8 @@ from collections.abc import Mapping
from html.parser import HTMLParser
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.encoding import punycode
from django.utils.functional import Promise, cached_property, keep_lazy, keep_lazy_text
@@ -463,20 +464,9 @@ class Urlizer:
@staticmethod
def is_email_simple(value):
"""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:
- p1, p2 = value.split("@")
- except ValueError:
- # 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("."):
+ EmailValidator(allowlist=[])(value)
+ except ValidationError:
return False
return True
diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py
index 0beaf98bff..341e211c96 100644
--- a/tests/utils_tests/test_html.py
+++ b/tests/utils_tests/test_html.py
@@ -379,15 +379,9 @@ class TestUtilsHtml(SimpleTestCase):
(
# RFC 6068 requires a mailto URI to percent-encode a number of
# characters that can appear in <addr-spec>.
- "yes;this=is&a%valid!email@example.com",
- '<a href="mailto:yes%3Bthis%3Dis%26a%25valid%21email@example.com"'
- ">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>',
+ "yes+this=is&a%valid!email@example.com",
+ '<a href="mailto:yes%2Bthis%3Dis%26a%25valid%21email@example.com"'
+ ">yes+this=is&a%valid!email@example.com</a>",
),
)
for value, output in tests:
@@ -407,6 +401,8 @@ class TestUtilsHtml(SimpleTestCase):
"foo@.example.com",
"foo@localhost",
"foo@localhost.",
+ "test@example?;+!.com",
+ "email me@example.com,then I'll respond",
# trim_punctuation catastrophic tests
"(" * 100_000 + ":" + ")" * 100_000,
"(" * 100_000 + "&:" + ")" * 100_000,