Fixed #26478 -- Made {% for %} reject invalid unpacking vars with quotes or vertical bars.

This commit is contained in:
Tim Martin 2016-12-18 08:08:53 +00:00 committed by Tim Graham
parent 9f16ea21c4
commit e3f095b086
2 changed files with 24 additions and 5 deletions

View File

@ -17,10 +17,10 @@ from django.utils.safestring import mark_safe
from .base import ( from .base import (
BLOCK_TAG_END, BLOCK_TAG_START, COMMENT_TAG_END, COMMENT_TAG_START, BLOCK_TAG_END, BLOCK_TAG_START, COMMENT_TAG_END, COMMENT_TAG_START,
SINGLE_BRACE_END, SINGLE_BRACE_START, VARIABLE_ATTRIBUTE_SEPARATOR, FILTER_SEPARATOR, SINGLE_BRACE_END, SINGLE_BRACE_START,
VARIABLE_TAG_END, VARIABLE_TAG_START, Context, Node, NodeList, VARIABLE_ATTRIBUTE_SEPARATOR, VARIABLE_TAG_END, VARIABLE_TAG_START,
TemplateSyntaxError, VariableDoesNotExist, kwarg_re, Context, Node, NodeList, TemplateSyntaxError, VariableDoesNotExist,
render_value_in_context, token_kwargs, kwarg_re, render_value_in_context, token_kwargs,
) )
from .defaultfilters import date from .defaultfilters import date
from .library import Library from .library import Library
@ -816,9 +816,10 @@ def do_for(parser, token):
raise TemplateSyntaxError("'for' statements should use the format" raise TemplateSyntaxError("'for' statements should use the format"
" 'for x in y': %s" % token.contents) " 'for x in y': %s" % token.contents)
invalid_chars = frozenset((' ', '"', "'", FILTER_SEPARATOR))
loopvars = re.split(r' *, *', ' '.join(bits[1:in_index])) loopvars = re.split(r' *, *', ' '.join(bits[1:in_index]))
for var in loopvars: for var in loopvars:
if not var or ' ' in var: if not var or not invalid_chars.isdisjoint(var):
raise TemplateSyntaxError("'for' tag received an invalid argument:" raise TemplateSyntaxError("'for' tag received an invalid argument:"
" %s" % token.contents) " %s" % token.contents)

View File

@ -87,6 +87,24 @@ class ForTagTests(SimpleTestCase):
with self.assertRaisesMessage(TemplateSyntaxError, msg): with self.assertRaisesMessage(TemplateSyntaxError, msg):
self.engine.render_to_string('for-tag-unpack08', {'items': (('one', 1), ('two', 2))}) self.engine.render_to_string('for-tag-unpack08', {'items': (('one', 1), ('two', 2))})
@setup({'double-quote': '{% for "k" in items %}{{ "k" }}/{% endfor %}'})
def test_unpack_double_quote(self):
msg = """'for' tag received an invalid argument: for "k" in items"""
with self.assertRaisesMessage(TemplateSyntaxError, msg):
self.engine.render_to_string('double-quote', {'items': (1, 2)})
@setup({'single-quote': "{% for 'k' in items %}{{ k }}/{% endfor %}"})
def test_unpack_single_quote(self):
msg = """'for' tag received an invalid argument: for 'k' in items"""
with self.assertRaisesMessage(TemplateSyntaxError, msg):
self.engine.render_to_string('single-quote', {'items': (1, 2)})
@setup({'vertical-bar': '{% for k|upper in items %}{{ k|upper }}/{% endfor %}'})
def test_unpack_vertical_bar(self):
msg = "'for' tag received an invalid argument: for k|upper in items"
with self.assertRaisesMessage(TemplateSyntaxError, msg):
self.engine.render_to_string('vertical-bar', {'items': (1, 2)})
@setup({'for-tag-unpack09': '{% for val in items %}{{ val.0 }}:{{ val.1 }}/{% endfor %}'}) @setup({'for-tag-unpack09': '{% for val in items %}{{ val.0 }}:{{ val.1 }}/{% endfor %}'})
def test_for_tag_unpack09(self): def test_for_tag_unpack09(self):
""" """