+174
-24
lines changedFilter options
+174
-24
lines changed Original file line number Diff line number Diff line change
@@ -191,7 +191,7 @@ def iriencode(value):
191
191
192
192
@register.filter(is_safe=True, needs_autoescape=True)
193
193
@stringfilter
194
-
def linenumbers(value, autoescape=None):
194
+
def linenumbers(value, autoescape=True):
195
195
"""Displays text with line numbers."""
196
196
lines = value.split('\n')
197
197
# Find the maximum width of the line count, for use with zero padding
@@ -353,14 +353,14 @@ def urlencode(value, safe=None):
353
353
354
354
@register.filter(is_safe=True, needs_autoescape=True)
355
355
@stringfilter
356
-
def urlize(value, autoescape=None):
356
+
def urlize(value, autoescape=True):
357
357
"""Converts URLs in plain text into clickable links."""
358
358
return mark_safe(_urlize(value, nofollow=True, autoescape=autoescape))
359
359
360
360
361
361
@register.filter(is_safe=True, needs_autoescape=True)
362
362
@stringfilter
363
-
def urlizetrunc(value, limit, autoescape=None):
363
+
def urlizetrunc(value, limit, autoescape=True):
364
364
"""
365
365
Converts URLs into clickable links, truncating URLs to the given character
366
366
limit, and adding 'rel=nofollow' attribute to discourage spamming.
@@ -457,7 +457,7 @@ def force_escape(value):
457
457
458
458
@register.filter("linebreaks", is_safe=True, needs_autoescape=True)
459
459
@stringfilter
460
-
def linebreaks_filter(value, autoescape=None):
460
+
def linebreaks_filter(value, autoescape=True):
461
461
"""
462
462
Replaces line breaks in plain text with appropriate HTML; a single
463
463
newline becomes an HTML line break (``<br />``) and a new line
@@ -469,7 +469,7 @@ def linebreaks_filter(value, autoescape=None):
469
469
470
470
@register.filter(is_safe=True, needs_autoescape=True)
471
471
@stringfilter
472
-
def linebreaksbr(value, autoescape=None):
472
+
def linebreaksbr(value, autoescape=True):
473
473
"""
474
474
Converts all newlines in a piece of plain text to HTML line breaks
475
475
(``<br />``).
@@ -552,7 +552,7 @@ def first(value):
552
552
553
553
554
554
@register.filter(is_safe=True, needs_autoescape=True)
555
-
def join(value, arg, autoescape=None):
555
+
def join(value, arg, autoescape=True):
556
556
"""
557
557
Joins a list with a string, like Python's ``str.join(list)``.
558
558
"""
@@ -622,7 +622,7 @@ def slice_filter(value, arg):
622
622
623
623
624
624
@register.filter(is_safe=True, needs_autoescape=True)
625
-
def unordered_list(value, autoescape=None):
625
+
def unordered_list(value, autoescape=True):
626
626
"""
627
627
Recursively takes a self-nested list and returns an HTML unordered list --
628
628
WITHOUT opening and closing <ul> tags.
Original file line number Diff line number Diff line change
@@ -281,7 +281,9 @@ Template filter code falls into one of two situations:
281
281
(If you don't specify this flag, it defaults to ``False``). This flag tells
282
282
Django that your filter function wants to be passed an extra keyword
283
283
argument, called ``autoescape``, that is ``True`` if auto-escaping is in
284
-
effect and ``False`` otherwise.
284
+
effect and ``False`` otherwise. It is recommended to set the default of the
285
+
``autoescape`` parameter to ``True``, so that if you call the function
286
+
from Python code it will have escaping enabled by default.
285
287
286
288
For example, let's write a filter that emphasizes the first character of
287
289
a string::
@@ -293,7 +295,7 @@ Template filter code falls into one of two situations:
293
295
register = template.Library()
294
296
295
297
@register.filter(needs_autoescape=True)
296
-
def initial_letter_filter(text, autoescape=None):
298
+
def initial_letter_filter(text, autoescape=True):
297
299
first, other = text[0], text[1:]
298
300
if autoescape:
299
301
esc = conditional_escape
@@ -323,19 +325,28 @@ Template filter code falls into one of two situations:
323
325
324
326
.. warning:: Avoiding XSS vulnerabilities when reusing built-in filters
325
327
326
-
Be careful when reusing Django's built-in filters. You'll need to pass
327
-
``autoescape=True`` to the filter in order to get the proper autoescaping
328
-
behavior and avoid a cross-site script vulnerability.
328
+
.. versionchanged:: 1.8
329
+
330
+
Django's built-in filters have ``autoescape=True`` by default in order to
331
+
get the proper autoescaping behavior and avoid a cross-site script
332
+
vulnerability.
333
+
334
+
In older versions of Django, be careful when reusing Django's built-in
335
+
filters as ``autoescape`` defaults to ``None``. You'll need to pass
336
+
``autoescape=True`` to get autoescaping.
329
337
330
338
For example, if you wanted to write a custom filter called
331
339
``urlize_and_linebreaks`` that combined the :tfilter:`urlize` and
332
340
:tfilter:`linebreaksbr` filters, the filter would look like::
333
341
334
342
from django.template.defaultfilters import linebreaksbr, urlize
335
343
336
-
@register.filter
337
-
def urlize_and_linebreaks(text):
338
-
return linebreaksbr(urlize(text, autoescape=True), autoescape=True)
344
+
@register.filter(needs_autoescape=True)
345
+
def urlize_and_linebreaks(text, autoescape=True):
346
+
return linebreaksbr(
347
+
urlize(text, autoescape=autoescape),
348
+
autoescape=autoescape
349
+
)
339
350
340
351
Then:
341
352
Original file line number Diff line number Diff line change
@@ -1011,6 +1011,26 @@ those writing third-party backends in updating their code:
1011
1011
now takes a second argument named ``obj_id`` which is the serialized
1012
1012
identifier used to retrieve the object before deletion.
1013
1013
1014
+
Default autoescaping of functions in ``django.template.defaultfilters``
1015
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1016
+
1017
+
In order to make built-in template filters that output HTML "safe by default"
1018
+
when calling them in Python code, the following functions in
1019
+
``django.template.defaultfilters`` have been changed to automatically escape
1020
+
their input value:
1021
+
1022
+
* ``join``
1023
+
* ``linebreaksbr``
1024
+
* ``linebreaks_filter``
1025
+
* ``linenumbers``
1026
+
* ``unordered_list``
1027
+
* ``urlize``
1028
+
* ``urlizetrunc``
1029
+
1030
+
You can revert to the old behavior by specifying ``autoescape=False`` if you
1031
+
are passing trusted content. This change doesn't have any effect when using
1032
+
the corresponding filters in templates.
1033
+
1014
1034
Miscellaneous
1015
1035
~~~~~~~~~~~~~
1016
1036
Original file line number Diff line number Diff line change
@@ -54,3 +54,15 @@ class FunctionTests(SimpleTestCase):
54
54
55
55
def test_list(self):
56
56
self.assertEqual(join([0, 1, 2], 'glue'), '0glue1glue2')
57
+
58
+
def test_autoescape(self):
59
+
self.assertEqual(
60
+
join(['<a>', '<img>', '</a>'], '<br>'),
61
+
'<a><br><img><br></a>',
62
+
)
63
+
64
+
def test_autoescape_off(self):
65
+
self.assertEqual(
66
+
join(['<a>', '<img>', '</a>'], '<br>', autoescape=False),
67
+
'<a><br><img><br></a>',
68
+
)
Original file line number Diff line number Diff line change
@@ -39,3 +39,15 @@ def test_carriage_newline(self):
39
39
40
40
def test_non_string_input(self):
41
41
self.assertEqual(linebreaks_filter(123), '<p>123</p>')
42
+
43
+
def test_autoescape(self):
44
+
self.assertEqual(
45
+
linebreaks_filter('foo\n<a>bar</a>\nbuz'),
46
+
'<p>foo<br /><a>bar</a><br />buz</p>',
47
+
)
48
+
49
+
def test_autoescape_off(self):
50
+
self.assertEqual(
51
+
linebreaks_filter('foo\n<a>bar</a>\nbuz', autoescape=False),
52
+
'<p>foo<br /><a>bar</a><br />buz</p>',
53
+
)
Original file line number Diff line number Diff line change
@@ -36,3 +36,15 @@ def test_carriage_newline(self):
36
36
37
37
def test_non_string_input(self):
38
38
self.assertEqual(linebreaksbr(123), '123')
39
+
40
+
def test_autoescape(self):
41
+
self.assertEqual(
42
+
linebreaksbr('foo\n<a>bar</a>\nbuz'),
43
+
'foo<br /><a>bar</a><br />buz',
44
+
)
45
+
46
+
def test_autoescape_off(self):
47
+
self.assertEqual(
48
+
linebreaksbr('foo\n<a>bar</a>\nbuz', autoescape=False),
49
+
'foo<br /><a>bar</a><br />buz',
50
+
)
Original file line number Diff line number Diff line change
@@ -44,3 +44,15 @@ def test_linenumbers2(self):
44
44
45
45
def test_non_string_input(self):
46
46
self.assertEqual(linenumbers(123), '1. 123')
47
+
48
+
def test_autoescape(self):
49
+
self.assertEqual(
50
+
linenumbers('foo\n<a>bar</a>\nbuz'),
51
+
'1. foo\n2. <a>bar</a>\n3. buz',
52
+
)
53
+
54
+
def test_autoescape_off(self):
55
+
self.assertEqual(
56
+
linenumbers('foo\n<a>bar</a>\nbuz', autoescape=False),
57
+
'1. foo\n2. <a>bar</a>\n3. buz'
58
+
)
Original file line number Diff line number Diff line change
@@ -99,6 +99,18 @@ def test_nested_multiple2(self):
99
99
'\n\t\t<li>Illinois</li>\n\t</ul>\n\t</li>',
100
100
)
101
101
102
+
def test_autoescape(self):
103
+
self.assertEqual(
104
+
unordered_list(['<a>item 1</a>', 'item 2']),
105
+
'\t<li><a>item 1</a></li>\n\t<li>item 2</li>',
106
+
)
107
+
108
+
def test_autoescape_off(self):
109
+
self.assertEqual(
110
+
unordered_list(['<a>item 1</a>', 'item 2'], autoescape=False),
111
+
'\t<li><a>item 1</a></li>\n\t<li>item 2</li>',
112
+
)
113
+
102
114
def test_ulitem(self):
103
115
@python_2_unicode_compatible
104
116
class ULItem(object):
@@ -110,13 +122,48 @@ def __str__(self):
110
122
111
123
a = ULItem('a')
112
124
b = ULItem('b')
113
-
self.assertEqual(unordered_list([a, b]), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
125
+
c = ULItem('<a>c</a>')
126
+
self.assertEqual(
127
+
unordered_list([a, b, c]),
128
+
'\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>\n\t<li>ulitem-<a>c</a></li>',
129
+
)
130
+
131
+
def item_generator():
132
+
yield a
133
+
yield b
134
+
yield c
135
+
136
+
self.assertEqual(
137
+
unordered_list(item_generator()),
138
+
'\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>\n\t<li>ulitem-<a>c</a></li>',
139
+
)
140
+
141
+
def test_ulitem_autoescape_off(self):
142
+
@python_2_unicode_compatible
143
+
class ULItem(object):
144
+
def __init__(self, title):
145
+
self.title = title
146
+
147
+
def __str__(self):
148
+
return 'ulitem-%s' % str(self.title)
149
+
150
+
a = ULItem('a')
151
+
b = ULItem('b')
152
+
c = ULItem('<a>c</a>')
153
+
self.assertEqual(
154
+
unordered_list([a, b, c], autoescape=False),
155
+
'\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>\n\t<li>ulitem-<a>c</a></li>',
156
+
)
114
157
115
158
def item_generator():
116
159
yield a
117
160
yield b
161
+
yield c
118
162
119
-
self.assertEqual(unordered_list(item_generator()), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
163
+
self.assertEqual(
164
+
unordered_list(item_generator(), autoescape=False),
165
+
'\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>\n\t<li>ulitem-<a>c</a></li>',
166
+
)
120
167
121
168
@ignore_warnings(category=RemovedInDjango20Warning)
122
169
def test_legacy(self):
Original file line number Diff line number Diff line change
@@ -259,27 +259,27 @@ def test_quotation_marks(self):
259
259
#20364 - Check urlize correctly include quotation marks in links
260
260
"""
261
261
self.assertEqual(
262
-
urlize('before "hi@example.com" afterwards'),
262
+
urlize('before "hi@example.com" afterwards', autoescape=False),
263
263
'before "<a href="mailto:hi@example.com">hi@example.com</a>" afterwards',
264
264
)
265
265
self.assertEqual(
266
-
urlize('before hi@example.com" afterwards'),
266
+
urlize('before hi@example.com" afterwards', autoescape=False),
267
267
'before <a href="mailto:hi@example.com">hi@example.com</a>" afterwards',
268
268
)
269
269
self.assertEqual(
270
-
urlize('before "hi@example.com afterwards'),
270
+
urlize('before "hi@example.com afterwards', autoescape=False),
271
271
'before "<a href="mailto:hi@example.com">hi@example.com</a> afterwards',
272
272
)
273
273
self.assertEqual(
274
-
urlize('before \'hi@example.com\' afterwards'),
274
+
urlize('before \'hi@example.com\' afterwards', autoescape=False),
275
275
'before \'<a href="mailto:hi@example.com">hi@example.com</a>\' afterwards',
276
276
)
277
277
self.assertEqual(
278
-
urlize('before hi@example.com\' afterwards'),
278
+
urlize('before hi@example.com\' afterwards', autoescape=False),
279
279
'before <a href="mailto:hi@example.com">hi@example.com</a>\' afterwards',
280
280
)
281
281
self.assertEqual(
282
-
urlize('before \'hi@example.com afterwards'),
282
+
urlize('before \'hi@example.com afterwards', autoescape=False),
283
283
'before \'<a href="mailto:hi@example.com">hi@example.com</a> afterwards',
284
284
)
285
285
@@ -288,7 +288,7 @@ def test_quote_commas(self):
288
288
#20364 - Check urlize copes with commas following URLs in quotes
289
289
"""
290
290
self.assertEqual(
291
-
urlize('Email us at "hi@example.com", or phone us at +xx.yy'),
291
+
urlize('Email us at "hi@example.com", or phone us at +xx.yy', autoescape=False),
292
292
'Email us at "<a href="mailto:hi@example.com">hi@example.com</a>", or phone us at +xx.yy',
293
293
)
294
294
@@ -316,3 +316,15 @@ def test_exclamation_marks(self):
316
316
317
317
def test_non_string_input(self):
318
318
self.assertEqual(urlize(123), '123')
319
+
320
+
def test_autoescape(self):
321
+
self.assertEqual(
322
+
urlize('foo<a href=" google.com ">bar</a>buz'),
323
+
'foo<a href=" <a href="http://google.com" rel="nofollow">google.com</a> ">bar</a>buz',
324
+
)
325
+
326
+
def test_autoescape_off(self):
327
+
self.assertEqual(
328
+
urlize('foo<a href=" google.com ">bar</a>buz', autoescape=False),
329
+
'foo<a href=" <a href="http://google.com" rel="nofollow">google.com</a> ">bar</a>buz',
330
+
)
Original file line number Diff line number Diff line change
@@ -78,3 +78,15 @@ def test_query_string(self):
78
78
79
79
def test_non_string_input(self):
80
80
self.assertEqual(urlizetrunc(123, 1), '123')
81
+
82
+
def test_autoescape(self):
83
+
self.assertEqual(
84
+
urlizetrunc('foo<a href=" google.com ">bar</a>buz', 10),
85
+
'foo<a href=" <a href="http://google.com" rel="nofollow">google.com</a> ">bar</a>buz',
86
+
)
87
+
88
+
def test_autoescape_off(self):
89
+
self.assertEqual(
90
+
urlizetrunc('foo<a href=" google.com ">bar</a>buz', 9, autoescape=False),
91
+
'foo<a href=" <a href="http://google.com" rel="nofollow">google...</a> ">bar</a>buz',
92
+
)
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4