diff --git a/django/utils/html.py b/django/utils/html.py index 9c519978f5..4198f69555 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -1,5 +1,6 @@ """HTML utilities suitable for global use.""" +import html import json import re from html.parser import HTMLParser @@ -24,15 +25,6 @@ word_split_re = re.compile(r'''([\s<>"']+)''') simple_url_re = re.compile(r'^https?://\[?\w', re.IGNORECASE) simple_url_2_re = re.compile(r'^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org)($|/.*)$', re.IGNORECASE) -_html_escapes = { - ord('&'): '&', - ord('<'): '<', - ord('>'): '>', - ord('"'): '"', - ord("'"): ''', -} - - @keep_lazy(str, SafeString) def escape(text): """ @@ -43,7 +35,7 @@ def escape(text): This may result in double-escaping. If this is a concern, use conditional_escape() instead. """ - return mark_safe(str(text).translate(_html_escapes)) + return mark_safe(html.escape(str(text))) _js_escapes = { @@ -266,7 +258,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): http://example.com?x=1&y=<2> => http://example.com?x=1&y=<2> """ return text.replace('&', '&').replace('<', '<').replace( - '>', '>').replace('"', '"').replace(''', "'") + '>', '>').replace('"', '"').replace(''', "'").replace(''', "'") def trim_punctuation(lead, middle, trail): """ diff --git a/tests/admin_docs/test_views.py b/tests/admin_docs/test_views.py index bcadff7d8a..cffa435747 100644 --- a/tests/admin_docs/test_views.py +++ b/tests/admin_docs/test_views.py @@ -199,7 +199,7 @@ class TestModelDetailView(TestDataMixin, AdminDocsTestCase): """ Methods with keyword arguments should have their arguments displayed. """ - self.assertContains(self.response, "
Username: -Good luck picking a username that doesn't already exist.
Password1:
Password2:
Can't find my keys
I'm a little teapot
'<p>Local variable</p>'
'Oops'