Index: django/utils/html.py
===================================================================
--- django/utils/html.py (revision 7028)
+++ django/utils/html.py (working copy)
@@ -102,18 +102,24 @@
if middle.startswith('www.') or ('@' not in middle and not middle.startswith('http://') and \
len(middle) > 0 and middle[0] in string.ascii_letters + string.digits and \
(middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))):
- middle = '%s' % (
- urlquote(middle, safe='/&=:;#?+'), nofollow_attr,
- trim_url(middle))
+ middle = 'http://%s' % middle
if middle.startswith('http://') or middle.startswith('https://'):
+ url = urlquote(middle, safe='/&=:;#?+')
+ if autoescape and not safe_input:
+ url = escape(url)
+ trimmed_url = trim_url(middle)
middle = '%s' % (
- urlquote(middle, safe='/&=:;#?+'), nofollow_attr,
- trim_url(middle))
- if '@' in middle and not middle.startswith('www.') and \
- not ':' in middle and simple_email_re.match(middle):
+ url, nofollow_attr, trimmed_url
+ )
+ elif '@' in middle and not middle.startswith('www.') and \
+ not ':' in middle and simple_email_re.match(middle):
+ if autoescape:
+ middle = conditional_escape(middle)
middle = '%s' % (middle, middle)
if lead + middle + trail != word:
- words[i] = lead + middle + trail
+ if autoescape and not safe_input:
+ lead, trail = escape(lead), escape(trail)
+ words[i] = mark_safe(lead + middle + trail)
elif autoescape and not safe_input:
words[i] = escape(word)
elif safe_input:
Index: tests/regressiontests/templates/filters.py
===================================================================
--- tests/regressiontests/templates/filters.py (revision 7028)
+++ tests/regressiontests/templates/filters.py (working copy)
@@ -98,8 +98,8 @@
'filter-upper01': ('{% autoescape off %}{{ a|upper }} {{ b|upper }}{% endautoescape %}', {"a": "a & b", "b": mark_safe("a & b")}, u"A & B A & B"),
'filter-upper02': ('{{ a|upper }} {{ b|upper }}', {"a": "a & b", "b": mark_safe("a & b")}, u"A & B A & B"),
- 'filter-urlize01': ('{% autoescape off %}{{ a|urlize }} {{ b|urlize }}{% endautoescape %}', {"a": "http://example.com/x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'http://example.com/x=&y= http://example.com?x=&y='),
- 'filter-urlize02': ('{{ a|urlize }} {{ b|urlize }}', {"a": "http://example.com/x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'http://example.com/x=&y= http://example.com?x=&y='),
+ 'filter-urlize01': ('{% autoescape off %}{{ a|urlize }} {{ b|urlize }}{% endautoescape %}', {"a": "http://example.com/x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'http://example.com/x=&y= http://example.com?x=&y='),
+ 'filter-urlize02': ('{{ a|urlize }} {{ b|urlize }}', {"a": "http://example.com/?x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'http://example.com/?x=&y= http://example.com?x=&y='),
'filter-urlize03': ('{% autoescape off %}{{ a|urlize }}{% endautoescape %}', {"a": mark_safe("a & b")}, 'a & b'),
'filter-urlize04': ('{{ a|urlize }}', {"a": mark_safe("a & b")}, 'a & b'),
@@ -108,8 +108,8 @@
'filter-urlize05': ('{% autoescape off %}{{ a|urlize }}{% endautoescape %}', {"a": ""}, ""),
'filter-urlize06': ('{{ a|urlize }}', {"a": ""}, '<script>alert('foo')</script>'),
- 'filter-urlizetrunc01': ('{% autoescape off %}{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}{% endautoescape %}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" http:... "Safe" http:...'),
- 'filter-urlizetrunc02': ('{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" http:... "Safe" http:...'),
+ 'filter-urlizetrunc01': ('{% autoescape off %}{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}{% endautoescape %}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" http:... "Safe" http:...'),
+ 'filter-urlizetrunc02': ('{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}', {"a": '"Unsafe" http://example.com/?x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" http:... "Safe" http:...'),
'filter-wordcount01': ('{% autoescape off %}{{ a|wordcount }} {{ b|wordcount }}{% endautoescape %}', {"a": "a & b", "b": mark_safe("a & b")}, "3 3"),
'filter-wordcount02': ('{{ a|wordcount }} {{ b|wordcount }}', {"a": "a & b", "b": mark_safe("a & b")}, "3 3"),
@@ -240,7 +240,7 @@
'chaining13': ('{{ a|safe|force_escape }}', {"a": "a < b"}, "a < b"),
'chaining14': ('{% autoescape off %}{{ a|safe|force_escape }}{% endautoescape %}', {"a": "a < b"}, "a < b"),
- # Filters decorated with stringfilter still respect is_safe.
+ # Filters decorated with stringfilter still respect is_safe.
'autoescape-stringfilter01': (r'{{ unsafe|capfirst }}', {'unsafe': UnsafeClass()}, 'You & me'),
'autoescape-stringfilter02': (r'{% autoescape off %}{{ unsafe|capfirst }}{% endautoescape %}', {'unsafe': UnsafeClass()}, 'You & me'),
'autoescape-stringfilter03': (r'{{ safe|capfirst }}', {'safe': SafeClass()}, 'You > me'),