Fixed #5945 -- Treat string literals in template filter arguments as safe
strings for auto-escaping purposes. git-svn-id: http://code.djangoproject.com/svn/django/trunk@6680 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
0b0ef3f0c5
commit
0928fa5566
|
@ -594,7 +594,7 @@ class FilterExpression(object):
|
|||
arg_vals = []
|
||||
for lookup, arg in args:
|
||||
if not lookup:
|
||||
arg_vals.append(arg)
|
||||
arg_vals.append(mark_safe(arg))
|
||||
else:
|
||||
arg_vals.append(arg.resolve(context))
|
||||
if getattr(func, 'needs_autoescape', False):
|
||||
|
@ -707,7 +707,7 @@ class Variable(object):
|
|||
# If it's wrapped with quotes (single or double), then
|
||||
# we're also dealing with a literal.
|
||||
if var[0] in "\"'" and var[0] == var[-1]:
|
||||
self.literal = var[1:-1]
|
||||
self.literal = mark_safe(var[1:-1])
|
||||
else:
|
||||
# Otherwise we'll set self.lookups so that resolve() knows we're
|
||||
# dealing with a bonafide variable
|
||||
|
|
|
@ -401,6 +401,32 @@ auto-escaping is on, these extra filters won't change the output -- any
|
|||
variables that use the ``escape`` filter do not have further automatic
|
||||
escaping applied to them.
|
||||
|
||||
String literals and automatic escaping
|
||||
--------------------------------------
|
||||
|
||||
Sometimes you will pass a string literal as an argument to a filter. For
|
||||
example::
|
||||
|
||||
{{ data|default:"This is a string literal." }}
|
||||
|
||||
All string literals are inserted **without** any automatic escaping into the
|
||||
template, if they are used (it's as if they were all passed through the
|
||||
``safe`` filter). The reasoning behind this is that the template author is in
|
||||
control of what goes into the string literal, so they can make sure the text
|
||||
is correctly escaped when the template is written.
|
||||
|
||||
This means you would write ::
|
||||
|
||||
{{ data|default:"3 > 2" }}
|
||||
|
||||
...rather than ::
|
||||
|
||||
{{ data|default:"3 > 2" }} <-- Bad! Don't do this.
|
||||
|
||||
This doesn't affect what happens to data coming from the variable itself.
|
||||
The variable's contents are still automatically escaped, if necessary, since
|
||||
they're beyond the control of the template author.
|
||||
|
||||
Using the built-in reference
|
||||
============================
|
||||
|
||||
|
|
|
@ -177,18 +177,17 @@ def get_filter_tests():
|
|||
'filter-unordered_list04': ('{% autoescape off %}{{ a|unordered_list }}{% endautoescape %}', {"a": ["x>", [[mark_safe("<y"), []]]]}, "\t<li>x>\n\t<ul>\n\t\t<li><y</li>\n\t</ul>\n\t</li>"),
|
||||
'filter-unordered_list05': ('{% autoescape off %}{{ a|unordered_list }}{% endautoescape %}', {"a": ["x>", [["<y", []]]]}, "\t<li>x>\n\t<ul>\n\t\t<li><y</li>\n\t</ul>\n\t</li>"),
|
||||
|
||||
# If the input to "default" filter is marked as safe, then so is the
|
||||
# output. However, if the default arg is used, auto-escaping kicks in
|
||||
# (if enabled), because we cannot mark the default as safe.
|
||||
# Literal string arguments to the default filter are always treated as
|
||||
# safe strings, regardless of the auto-escaping state.
|
||||
#
|
||||
# Note: we have to use {"a": ""} here, otherwise the invalid template
|
||||
# variable string interferes with the test result.
|
||||
'filter-default01': ('{{ a|default:"x<" }}', {"a": ""}, "x<"),
|
||||
'filter-default01': ('{{ a|default:"x<" }}', {"a": ""}, "x<"),
|
||||
'filter-default02': ('{% autoescape off %}{{ a|default:"x<" }}{% endautoescape %}', {"a": ""}, "x<"),
|
||||
'filter-default03': ('{{ a|default:"x<" }}', {"a": mark_safe("x>")}, "x>"),
|
||||
'filter-default04': ('{% autoescape off %}{{ a|default:"x<" }}{% endautoescape %}', {"a": mark_safe("x>")}, "x>"),
|
||||
|
||||
'filter-default_if_none01': ('{{ a|default:"x<" }}', {"a": None}, "x<"),
|
||||
'filter-default_if_none01': ('{{ a|default:"x<" }}', {"a": None}, "x<"),
|
||||
'filter-default_if_none02': ('{% autoescape off %}{{ a|default:"x<" }}{% endautoescape %}', {"a": None}, "x<"),
|
||||
|
||||
'filter-phone2numeric01': ('{{ a|phone2numeric }} {{ b|phone2numeric }}', {"a": "<1-800-call-me>", "b": mark_safe("<1-800-call-me>") }, "<1-800-2255-63> <1-800-2255-63>"),
|
||||
|
|
|
@ -318,9 +318,9 @@ class Templates(unittest.TestCase):
|
|||
# Chained filters, with an argument to the first one
|
||||
'filter-syntax09': ('{{ var|removetags:"b i"|upper|lower }}', {"var": "<b><i>Yes</i></b>"}, "yes"),
|
||||
|
||||
# Escaped string as argument
|
||||
# Literal string as argument is always "safe" from auto-escaping..
|
||||
'filter-syntax10': (r'{{ var|default_if_none:" endquote\" hah" }}',
|
||||
{"var": None}, ' endquote" hah'),
|
||||
{"var": None}, ' endquote" hah'),
|
||||
|
||||
# Variable as argument
|
||||
'filter-syntax11': (r'{{ var|default_if_none:var2 }}', {"var": None, "var2": "happy"}, 'happy'),
|
||||
|
@ -735,9 +735,10 @@ class Templates(unittest.TestCase):
|
|||
'i18n12': ('{% load i18n %}{% get_available_languages as langs %}{% for lang in langs %}{% ifequal lang.0 "de" %}{{ lang.0 }}{% endifequal %}{% endfor %}', {}, 'de'),
|
||||
|
||||
# translation of constant strings
|
||||
'i18n13': ('{{ _("Page not found") }}', {'LANGUAGE_CODE': 'de'}, 'Seite nicht gefunden'),
|
||||
'i18n13': ('{{ _("Password") }}', {'LANGUAGE_CODE': 'de'}, 'Passwort'),
|
||||
'i18n14': ('{% cycle "foo" _("Password") _(\'Password\') as c %} {% cycle c %} {% cycle c %}', {'LANGUAGE_CODE': 'de'}, 'foo Passwort Passwort'),
|
||||
'i18n15': ('{{ absent|default:_("Password") }}', {'LANGUAGE_CODE': 'de', 'absent': ""}, 'Passwort'),
|
||||
'i18n16': ('{{ _("<") }}', {'LANGUAGE_CODE': 'de'}, '<'),
|
||||
|
||||
### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
|
||||
|
||||
|
@ -885,9 +886,9 @@ class Templates(unittest.TestCase):
|
|||
'autoescape-tag06': ("{{ first }}", {"first": mark_safe("<b>first</b>")}, "<b>first</b>"),
|
||||
'autoescape-tag07': ("{% autoescape on %}{{ first }}{% endautoescape %}", {"first": mark_safe(u"<b>Apple</b>")}, u"<b>Apple</b>"),
|
||||
|
||||
# String arguments to filters, if used in the result, are escaped,
|
||||
# too.
|
||||
'basic-syntax08': (r'{% autoescape on %}{{ var|default_if_none:" endquote\" hah" }}{% endautoescape %}', {"var": None}, ' endquote" hah'),
|
||||
# Literal string arguments to filters, if used in the result, are
|
||||
# safe.
|
||||
'basic-syntax08': (r'{% autoescape on %}{{ var|default_if_none:" endquote\" hah" }}{% endautoescape %}', {"var": None}, ' endquote" hah'),
|
||||
|
||||
# The "safe" and "escape" filters cannot work due to internal
|
||||
# implementation details (fortunately, the (no)autoescape block
|
||||
|
|
Loading…
Reference in New Issue