Opened 2 years ago

Closed 2 years ago

#19882 closed Bug (fixed)

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

Reported by: bmispelon Owned by: bmispelon
Component: Template system Version: master
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 Changed 2 years ago by carljm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

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

comment:2 Changed 2 years ago by bmispelon

  • Owner changed from nobody to bmispelon
  • Status changed from new to assigned

comment:3 Changed 2 years ago by Baptiste Mispelon <bmispelon@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In f13bfbec70e096f230e3dcda88a2cb215e7f8899:

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

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