diff --git a/django/utils/html.py b/django/utils/html.py index 1cb09357c2..d7ecde64c3 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -290,17 +290,17 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): smart_urlquote. For example: http://example.com?x=1&y=<2> => http://example.com?x=1&y=<2> """ - if not safe_input: - return text, text, trail unescaped = (text + trail).replace( '&', '&').replace('<', '<').replace( '>', '>').replace('"', '"').replace(''', "'") - # ';' in trail can be either trailing punctuation or end-of-entity marker - if unescaped.endswith(';'): - return text, unescaped[:-1], trail - else: + if trail and unescaped.endswith(trail): + # Remove trail for unescaped if it was not consumed by unescape + unescaped = unescaped[:-len(trail)] + elif trail == ';': + # Trail was consumed by unescape (as end-of-entity marker), move it to text text += trail - return text, unescaped, '' + trail = '' + return text, unescaped, trail words = word_split_re.split(force_text(text)) for i, word in enumerate(words): diff --git a/tests/template_tests/filter_tests/test_urlize.py b/tests/template_tests/filter_tests/test_urlize.py index 716bf9e6f5..1c55d64751 100644 --- a/tests/template_tests/filter_tests/test_urlize.py +++ b/tests/template_tests/filter_tests/test_urlize.py @@ -73,6 +73,14 @@ class UrlizeTests(SimpleTestCase): 'Email me at <me@example.com>', ) + @setup({'urlize09': '{% autoescape off %}{{ a|urlize }}{% endautoescape %}'}) + def test_urlize09(self): + output = self.engine.render_to_string('urlize09', {'a': "http://example.com/?x=&y=<2>"}) + self.assertEqual( + output, + 'http://example.com/?x=&y=<2>', + ) + class FunctionTests(SimpleTestCase):