summaryrefslogtreecommitdiff
path: root/django/utils/html.py
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2012-01-07 18:15:28 +0000
committerAymeric Augustin <aymeric.augustin@m4x.org>2012-01-07 18:15:28 +0000
commite3a7bfccbb83712caf0645e4e33f5c03d9dc462b (patch)
tree586ed337ed7ead1568522a96bea303afa9845b32 /django/utils/html.py
parentc3697a091b7ff0d19f13821b18516ec8eaa1b8f8 (diff)
Fixed #9655 -- Prevented the urlize template filter from double-quoting URLs. Thanks Claude Paroz for writing the tests.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17347 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/utils/html.py')
-rw-r--r--django/utils/html.py14
1 files changed, 12 insertions, 2 deletions
diff --git a/django/utils/html.py b/django/utils/html.py
index 2687eb5232..4f74a7492c 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -17,6 +17,7 @@ TRAILING_PUNCTUATION = ['.', ',', ')', '>', '\n', '&gt;']
DOTS = [u'&middot;', u'*', u'\u2022', u'&#149;', u'&bull;', u'&#8226;']
unencoded_ampersands_re = re.compile(r'&(?!(\w+|#\d+);)')
+unquoted_percents_re = re.compile(r'%(?![0-9A-Fa-f]{2})')
word_split_re = re.compile(r'(\s+)')
punctuation_re = re.compile('^(?P<lead>(?:%s)*)(?P<middle>.*?)(?P<trail>(?:%s)*)$' % \
('|'.join([re.escape(x) for x in LEADING_PUNCTUATION]),
@@ -100,6 +101,15 @@ def fix_ampersands(value):
return unencoded_ampersands_re.sub('&amp;', force_unicode(value))
fix_ampersands = allow_lazy(fix_ampersands, unicode)
+def smart_urlquote(url):
+ """Quotes an URL if it isn't already quoted."""
+ # An URL is considered unquoted if it contains no % character, or if it
+ # contains a % not followed by two hexadecimal digits. See #9655.
+ if '%' not in url or unquoted_percents_re.search(url):
+ # See http://bugs.python.org/issue2637
+ return urlquote(url, safe='!*\'();:@&=+$,/?#[]~')
+ return url
+
def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
"""
Converts any URLs in text into clickable links.
@@ -130,11 +140,11 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
# Make URL we want to point to.
url = None
if middle.startswith('http://') or middle.startswith('https://'):
- url = urlquote(middle, safe='/&=:;#?+*')
+ url = smart_urlquote(middle)
elif middle.startswith('www.') or ('@' not in middle and \
middle and middle[0] in string.ascii_letters + string.digits and \
(middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))):
- url = urlquote('http://%s' % middle, safe='/&=:;#?+*')
+ url = smart_urlquote('http://%s' % middle)
elif '@' in middle and not ':' in middle and simple_email_re.match(middle):
url = 'mailto:%s' % middle
nofollow_attr = ''