Opened 11 years ago

Closed 11 years ago

#19882 closed Bug (fixed)

Forloop with a filter that has an argument containing whitespace raises a TemplateSyntaxError

Reported by: Baptiste Mispelon Owned by: Baptiste Mispelon
Component: Template system Version: dev
Severity: Normal Keywords: forloop filter TemplateSyntaxError
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

In a template, when looping over a variable that has a filter with an argument containing whitespace, a TemplateSyntaxError will be thrown.

Here's a small test case to reproduce the issue (the first template fails while the other two work as expected):

from django.template import Template, Context

for tpl in [
        '{% for x in ""|add:"a b c" %}{{ x }}{% endfor %}', # Doesn't work
        '{% with v=""|add:"a b c" %}{% for x in v %}{{ x }}{% endfor %}{% endwith %}',
        '{% with v="a b c" %}{% for x in ""|add:v %}{{ x }}{% endfor %}{% endwith %}'
    ]:
    s = Template(tpl).render(Context())
    assert s == u'a b c'

Here's the traceback that this produces:

Traceback (most recent call last):
  File "my_script.py", line 8, in <module>
    s = Template(tpl).render(Context())
  File "/path/to/venv/local/lib/python2.7/site-packages/django/template/base.py", line 125, in __init__
    self.nodelist = compile_string(template_string, origin)
  File "/path/to/venv/local/lib/python2.7/site-packages/django/template/base.py", line 153, in compile_string
    return parser.parse()
  File "/path/to/venv/local/lib/python2.7/site-packages/django/template/base.py", line 278, in parse
    compiled_result = compile_func(self, token)
  File "/path/to/venv/local/lib/python2.7/site-packages/django/template/defaulttags.py", line 758, in do_for
    " 'for x in y': %s" % token.contents)
django.template.base.TemplateSyntaxError: 'for' statements should use the format 'for x in y': for x in ""|add:"a b c"

It looks like token.contents.split() in the code of the tag gets confused by the whitespace and splits the string into too many parts.

Since the code searches for the "in" keyword from the end (position -2 since we are not reversed), then it fails.

Change History (3)

comment:1 by Carl Meyer, 11 years ago

Triage Stage: UnreviewedAccepted

Reproduced; this is clearly a bug. Thanks for the report!

comment:2 by Baptiste Mispelon, 11 years ago

Owner: changed from nobody to Baptiste Mispelon
Status: newassigned

comment:3 by Baptiste Mispelon <bmispelon@…>, 11 years ago

Resolution: fixed
Status: assignedclosed

In f13bfbec70e096f230e3dcda88a2cb215e7f8899:

Fixed #19882 -- Smarter tokenizing of {% for %} tag arguments.

Note: See TracTickets for help on using tickets.
Back to Top