Ticket #5971: 5971-tokenparser-consistency-r10001.diff

File 5971-tokenparser-consistency-r10001.diff, 3.3 KB (added by ramiro, 6 years ago)

Unified and updated patches (implementation bt Dmitri Fedortchenko and tests by adamv)

  • django/template/__init__.py

    diff --git a/django/template/__init__.py b/django/template/__init__.py
    a b  
    409409        "A microparser that parses for a value: some string constant or variable name."
    410410        subject = self.subject
    411411        i = self.pointer
     412
     413        def __next_space_index(subject, i):
     414            """Increment pointer until a real space (i.e. a space not within quotes) is encountered"""
     415            while i < len(subject) and subject[i] not in (' ', '\t'):
     416                if subject[i] in ('"', "'"):
     417                    c = subject[i]
     418                    i += 1
     419                    while i < len(subject) and subject[i] != c:
     420                        i += 1
     421                    if i >= len(subject):
     422                        raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
     423                i += 1
     424            return i
     425
    412426        if i >= len(subject):
    413427            raise TemplateSyntaxError("Searching for value. Expected another value but found end of string: %s" % subject)
    414428        if subject[i] in ('"', "'"):
     
    419433            if i >= len(subject):
    420434                raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
    421435            i += 1
     436
     437            # Continue parsing until next "real" space, so that filters are also included
     438            i = __next_space_index(subject, i)
     439
    422440            res = subject[p:i]
    423441            while i < len(subject) and subject[i] in (' ', '\t'):
    424442                i += 1
     
    427445            return res
    428446        else:
    429447            p = i
    430             while i < len(subject) and subject[i] not in (' ', '\t'):
    431                 if subject[i] in ('"', "'"):
    432                     c = subject[i]
    433                     i += 1
    434                     while i < len(subject) and subject[i] != c:
    435                         i += 1
    436                     if i >= len(subject):
    437                         raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
    438                 i += 1
     448            i = __next_space_index(subject, i)
    439449            s = subject[p:i]
    440450            while i < len(subject) and subject[i] in (' ', '\t'):
    441451                i += 1
  • new file tests/regressiontests/tokenparser/tests.py

    diff --git a/tests/regressiontests/tokenparser/__init__.py b/tests/regressiontests/tokenparser/__init__.py
    new file mode 100644
    diff --git a/tests/regressiontests/tokenparser/models.py b/tests/regressiontests/tokenparser/models.py
    new file mode 100644
    diff --git a/tests/regressiontests/tokenparser/tests.py b/tests/regressiontests/tokenparser/tests.py
    new file mode 100644
    - +  
     1"""
     2Tests for TokenParser behavior in the face of quoted strings with spaces.
     3
     4>>> from django.template import TokenParser
     5
     6
     7Test case 1: {% tag thevar|filter sometag %}
     8
     9>>> p = TokenParser("tag thevar|filter sometag")
     10>>> p.tagname
     11'tag'
     12
     13>>> p.value()
     14'thevar|filter'
     15
     16>>> p.more()
     17True
     18
     19>>> p.tag()
     20'sometag'
     21
     22>>> p.more()
     23False
     24
     25
     26Test case 2: {% tag "a value"|filter sometag %}
     27
     28>>> p = TokenParser('tag "a value"|filter sometag')
     29>>> p.tagname
     30'tag'
     31
     32>>> p.value()
     33'"a value"|filter'
     34
     35>>> p.more()
     36True
     37
     38>>> p.tag()
     39'sometag'
     40
     41
     42>>> p.more()
     43False
     44"""
Back to Top