Loading django/utils/html.py +19 −8 Original line number Diff line number Diff line Loading @@ -11,8 +11,8 @@ from django.utils.functional import allow_lazy from django.utils.text import normalize_newlines # Configuration for urlize() function. LEADING_PUNCTUATION = ['(', '<', '<'] TRAILING_PUNCTUATION = ['.', ',', ')', '>', '\n', '>'] TRAILING_PUNCTUATION = ['.', ',', ':', ';'] WRAPPING_PUNCTUATION = [('(', ')'), ('<', '>'), ('<', '>')] # List of possible strings used for bullets in bulleted lists. DOTS = [u'·', u'*', u'\u2022', u'•', u'•', u'•'] Loading @@ -20,9 +20,6 @@ DOTS = [u'·', u'*', u'\u2022', u'•', u'•', u'•'] 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]), '|'.join([re.escape(x) for x in TRAILING_PUNCTUATION]))) simple_url_re = re.compile(r'^https?://\w') simple_url_2_re = re.compile(r'^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org|[a-z]{2})$') simple_email_re = re.compile(r'^\S+@\S+\.\S+$') Loading Loading @@ -147,9 +144,22 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): for i, word in enumerate(words): match = None if '.' in word or '@' in word or ':' in word: match = punctuation_re.match(word) if match: lead, middle, trail = match.groups() # Deal with punctuation. lead, middle, trail = '', word, '' for punctuation in TRAILING_PUNCTUATION: if middle.endswith(punctuation): middle = middle[:-len(punctuation)] trail = punctuation + trail for opening, closing in WRAPPING_PUNCTUATION: if middle.startswith(opening): middle = middle[len(opening):] lead = lead + opening # Keep parentheses at the end only if they're balanced. if (middle.endswith(closing) and middle.count(closing) == middle.count(opening) + 1): middle = middle[:-len(closing)] trail = closing + trail # Make URL we want to point to. url = None nofollow_attr = ' rel="nofollow"' if nofollow else '' Loading @@ -162,6 +172,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): domain = domain.encode('idna') url = 'mailto:%s@%s' % (local, domain) nofollow_attr = '' # Make link. if url: trimmed = trim_url(middle) Loading tests/regressiontests/defaultfilters/tests.py +8 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,14 @@ class DefaultFiltersTests(TestCase): u'<a href="http://en.wikipedia.org/wiki/Caf%C3%A9" rel="nofollow">' u'http://en.wikipedia.org/wiki/Café</a>') # Check urlize keeps balanced parentheses - see #11911 self.assertEqual(urlize('http://en.wikipedia.org/wiki/Django_(web_framework)'), u'<a href="http://en.wikipedia.org/wiki/Django_(web_framework)" rel="nofollow">' u'http://en.wikipedia.org/wiki/Django_(web_framework)</a>') self.assertEqual(urlize('(see http://en.wikipedia.org/wiki/Django_(web_framework))'), u'(see <a href="http://en.wikipedia.org/wiki/Django_(web_framework)" rel="nofollow">' u'http://en.wikipedia.org/wiki/Django_(web_framework)</a>)') # Check urlize adds nofollow properly - see #12183 self.assertEqual(urlize('foo@bar.com or www.bar.com'), u'<a href="mailto:foo@bar.com">foo@bar.com</a> or ' Loading Loading
django/utils/html.py +19 −8 Original line number Diff line number Diff line Loading @@ -11,8 +11,8 @@ from django.utils.functional import allow_lazy from django.utils.text import normalize_newlines # Configuration for urlize() function. LEADING_PUNCTUATION = ['(', '<', '<'] TRAILING_PUNCTUATION = ['.', ',', ')', '>', '\n', '>'] TRAILING_PUNCTUATION = ['.', ',', ':', ';'] WRAPPING_PUNCTUATION = [('(', ')'), ('<', '>'), ('<', '>')] # List of possible strings used for bullets in bulleted lists. DOTS = [u'·', u'*', u'\u2022', u'•', u'•', u'•'] Loading @@ -20,9 +20,6 @@ DOTS = [u'·', u'*', u'\u2022', u'•', u'•', u'•'] 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]), '|'.join([re.escape(x) for x in TRAILING_PUNCTUATION]))) simple_url_re = re.compile(r'^https?://\w') simple_url_2_re = re.compile(r'^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org|[a-z]{2})$') simple_email_re = re.compile(r'^\S+@\S+\.\S+$') Loading Loading @@ -147,9 +144,22 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): for i, word in enumerate(words): match = None if '.' in word or '@' in word or ':' in word: match = punctuation_re.match(word) if match: lead, middle, trail = match.groups() # Deal with punctuation. lead, middle, trail = '', word, '' for punctuation in TRAILING_PUNCTUATION: if middle.endswith(punctuation): middle = middle[:-len(punctuation)] trail = punctuation + trail for opening, closing in WRAPPING_PUNCTUATION: if middle.startswith(opening): middle = middle[len(opening):] lead = lead + opening # Keep parentheses at the end only if they're balanced. if (middle.endswith(closing) and middle.count(closing) == middle.count(opening) + 1): middle = middle[:-len(closing)] trail = closing + trail # Make URL we want to point to. url = None nofollow_attr = ' rel="nofollow"' if nofollow else '' Loading @@ -162,6 +172,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): domain = domain.encode('idna') url = 'mailto:%s@%s' % (local, domain) nofollow_attr = '' # Make link. if url: trimmed = trim_url(middle) Loading
tests/regressiontests/defaultfilters/tests.py +8 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,14 @@ class DefaultFiltersTests(TestCase): u'<a href="http://en.wikipedia.org/wiki/Caf%C3%A9" rel="nofollow">' u'http://en.wikipedia.org/wiki/Café</a>') # Check urlize keeps balanced parentheses - see #11911 self.assertEqual(urlize('http://en.wikipedia.org/wiki/Django_(web_framework)'), u'<a href="http://en.wikipedia.org/wiki/Django_(web_framework)" rel="nofollow">' u'http://en.wikipedia.org/wiki/Django_(web_framework)</a>') self.assertEqual(urlize('(see http://en.wikipedia.org/wiki/Django_(web_framework))'), u'(see <a href="http://en.wikipedia.org/wiki/Django_(web_framework)" rel="nofollow">' u'http://en.wikipedia.org/wiki/Django_(web_framework)</a>)') # Check urlize adds nofollow properly - see #12183 self.assertEqual(urlize('foo@bar.com or www.bar.com'), u'<a href="mailto:foo@bar.com">foo@bar.com</a> or ' Loading