Drop urlize_quoted_links (#7548)

This commit is contained in:
Tom Christie 2020-09-23 15:39:06 +01:00 committed by GitHub
parent c6e24521da
commit ae649336b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 96 deletions

View File

@ -418,7 +418,7 @@ class BrowsableAPIRenderer(BaseRenderer):
if render_style == 'binary':
return '[%d bytes of binary content]' % len(content)
return content
return content.decode('utf-8') if isinstance(content, bytes) else content
def show_form_for_method(self, view, method, request, obj):
"""

View File

@ -176,9 +176,9 @@
<div class="response-info" aria-label="{% trans "response info" %}">
<pre class="prettyprint"><span class="meta nocode"><b>HTTP {{ response.status_code }} {{ response.status_text }}</b>{% for key, val in response_headers|items %}
<b>{{ key }}:</b> <span class="lit">{{ val|break_long_headers|urlize_quoted_links }}</span>{% endfor %}
<b>{{ key }}:</b> <span class="lit">{{ val|break_long_headers|urlize }}</span>{% endfor %}
</span>{{ content|urlize_quoted_links }}</pre>
</span>{{ content|urlize }}</pre>
</div>
</div>

View File

@ -4,9 +4,9 @@ from collections import OrderedDict
from django import template
from django.template import loader
from django.urls import NoReverseMatch, reverse
from django.utils.encoding import force_str, iri_to_uri
from django.utils.encoding import iri_to_uri
from django.utils.html import escape, format_html, smart_urlquote
from django.utils.safestring import SafeData, mark_safe
from django.utils.safestring import mark_safe
from rest_framework.compat import apply_markdown, pygments_highlight
from rest_framework.renderers import HTMLFormRenderer
@ -311,85 +311,6 @@ def smart_urlquote_wrapper(matched_url):
return None
@register.filter(needs_autoescape=True)
def urlize_quoted_links(text, trim_url_limit=None, nofollow=True, autoescape=True):
"""
Converts any URLs in text into clickable links.
Works on http://, https://, www. links, and also on links ending in one of
the original seven gTLDs (.com, .edu, .gov, .int, .mil, .net, and .org).
Links can have trailing punctuation (periods, commas, close-parens) and
leading punctuation (opening parens) and it'll still do the right thing.
If trim_url_limit is not None, the URLs in link text longer than this limit
will truncated to trim_url_limit-3 characters and appended with an ellipsis.
If nofollow is True, the URLs in link text will get a rel="nofollow"
attribute.
If autoescape is True, the link text and URLs will get autoescaped.
"""
def trim_url(x, limit=trim_url_limit):
return limit is not None and (len(x) > limit and ('%s...' % x[:max(0, limit - 3)])) or x
safe_input = isinstance(text, SafeData)
# Unfortunately, Django built-in cannot be used here, because escaping
# is to be performed on words, which have been forcibly coerced to text
def conditional_escape(text):
return escape(text) if autoescape and not safe_input else text
words = word_split_re.split(force_str(text))
for i, word in enumerate(words):
if '.' in word or '@' in word or ':' in word:
# 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 ''
if simple_url_re.match(middle):
url = smart_urlquote_wrapper(middle)
elif simple_url_2_re.match(middle):
url = smart_urlquote_wrapper('http://%s' % middle)
elif ':' not in middle and simple_email_re.match(middle):
local, domain = middle.rsplit('@', 1)
try:
domain = domain.encode('idna').decode('ascii')
except UnicodeError:
continue
url = 'mailto:%s@%s' % (local, domain)
nofollow_attr = ''
# Make link.
if url:
trimmed = trim_url(middle)
lead, trail = conditional_escape(lead), conditional_escape(trail)
url, trimmed = conditional_escape(url), conditional_escape(trimmed)
middle = '<a href="%s"%s>%s</a>' % (url, nofollow_attr, trimmed)
words[i] = '%s%s%s' % (lead, middle, trail)
else:
words[i] = conditional_escape(word)
else:
words[i] = conditional_escape(word)
return mark_safe(''.join(words))
@register.filter
def break_long_headers(header):
"""

View File

@ -2,13 +2,14 @@ import unittest
from django.template import Context, Template
from django.test import TestCase
from django.utils.html import urlize
from rest_framework.compat import coreapi, coreschema
from rest_framework.relations import Hyperlink
from rest_framework.templatetags import rest_framework
from rest_framework.templatetags.rest_framework import (
add_nested_class, add_query_param, as_string, break_long_headers,
format_value, get_pagination_html, schema_links, urlize_quoted_links
format_value, get_pagination_html, schema_links
)
from rest_framework.test import APIRequestFactory
@ -246,7 +247,7 @@ class Issue1386Tests(TestCase):
def test_issue_1386(self):
"""
Test function urlize_quoted_links with different args
Test function urlize with different args
"""
correct_urls = [
"asdf.com",
@ -255,7 +256,7 @@ class Issue1386Tests(TestCase):
"as.d8f.ghj8.gov",
]
for i in correct_urls:
res = urlize_quoted_links(i)
res = urlize(i)
self.assertNotEqual(res, i)
self.assertIn(i, res)
@ -264,11 +265,11 @@ class Issue1386Tests(TestCase):
"asdf.netnet",
]
for i in incorrect_urls:
res = urlize_quoted_links(i)
res = urlize(i)
self.assertEqual(i, res)
# example from issue #1386, this shouldn't raise an exception
urlize_quoted_links("asdf:[/p]zxcv.com")
urlize("asdf:[/p]zxcv.com")
def test_smart_urlquote_wrapper_handles_value_error(self):
def mock_smart_urlquote(url):
@ -289,7 +290,10 @@ class URLizerTests(TestCase):
For all items in dict test assert that the value is urlized key
"""
for original, urlized in data.items():
assert urlize_quoted_links(original, nofollow=False) == urlized
print('====')
print(repr(urlize(original, nofollow=False)))
print(repr(urlized))
assert urlize(original, nofollow=False) == urlized
def test_json_with_url(self):
"""
@ -297,26 +301,26 @@ class URLizerTests(TestCase):
"""
data = {}
data['"url": "http://api/users/1/", '] = \
'&quot;url&quot;: &quot;<a href="http://api/users/1/">http://api/users/1/</a>&quot;, '
'"url": "<a href="http://api/users/1/">http://api/users/1/</a>", '
data['"foo_set": [\n "http://api/foos/1/"\n], '] = \
'&quot;foo_set&quot;: [\n &quot;<a href="http://api/foos/1/">http://api/foos/1/</a>&quot;\n], '
'"foo_set": [\n "<a href="http://api/foos/1/">http://api/foos/1/</a>"\n], '
self._urlize_dict_check(data)
def test_template_render_with_autoescape(self):
"""
Test that HTML is correctly escaped in Browsable API views.
"""
template = Template("{% load rest_framework %}{{ content|urlize_quoted_links }}")
template = Template("{% load rest_framework %}{{ content|urlize }}")
rendered = template.render(Context({'content': '<script>alert()</script> http://example.com'}))
assert rendered == '&lt;script&gt;alert()&lt;/script&gt;' \
' <a href="http://example.com" rel="nofollow">http://example.com</a>'
def test_template_render_with_noautoescape(self):
"""
Test if the autoescape value is getting passed to urlize_quoted_links filter.
Test if the autoescape value is getting passed to urlize filter.
"""
template = Template("{% load rest_framework %}"
"{% autoescape off %}{{ content|urlize_quoted_links }}"
"{% autoescape off %}{{ content|urlize }}"
"{% endautoescape %}")
rendered = template.render(Context({'content': '<b> "http://example.com" </b>'}))
assert rendered == '<b> "<a href="http://example.com" rel="nofollow">http://example.com</a>" </b>'