Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #5971 - Fixed inconsistent behaviour of the TokenParser when pa…

…rsing filters that follow constant strings or variables. Thanks Dmitri Fedortchenko, Adam Vandenberg and Ramiro Morales.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12471 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit b459f5b7e3be65bbd554e03626ff255d4a68e9fc 1 parent a88cbc1
Jannis Leidel authored February 21, 2010
1  AUTHORS
@@ -462,6 +462,7 @@ answer newbie questions, and generally made Django that much better:
462 462
     tt@gurgle.no
463 463
     David Tulig <david.tulig@gmail.com>
464 464
     Amit Upadhyay <http://www.amitu.com/blog/>
  465
+    Adam Vandenberg
465 466
     Geert Vanderkelen
466 467
     Vasil Vangelovski
467 468
     I.S. van Oostveen <v.oostveen@idca.nl>
28  django/template/__init__.py
@@ -421,6 +421,20 @@ def value(self):
421 421
         "A microparser that parses for a value: some string constant or variable name."
422 422
         subject = self.subject
423 423
         i = self.pointer
  424
+
  425
+        def next_space_index(subject, i):
  426
+            "Increment pointer until a real space (i.e. a space not within quotes) is encountered"
  427
+            while i < len(subject) and subject[i] not in (' ', '\t'):
  428
+                if subject[i] in ('"', "'"):
  429
+                    c = subject[i]
  430
+                    i += 1
  431
+                    while i < len(subject) and subject[i] != c:
  432
+                        i += 1
  433
+                    if i >= len(subject):
  434
+                        raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
  435
+            	i += 1
  436
+            return i
  437
+
424 438
         if i >= len(subject):
425 439
             raise TemplateSyntaxError("Searching for value. Expected another value but found end of string: %s" % subject)
426 440
         if subject[i] in ('"', "'"):
@@ -431,6 +445,10 @@ def value(self):
431 445
             if i >= len(subject):
432 446
                 raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
433 447
             i += 1
  448
+
  449
+            # Continue parsing until next "real" space, so that filters are also included
  450
+            i = next_space_index(subject, i)
  451
+
434 452
             res = subject[p:i]
435 453
             while i < len(subject) and subject[i] in (' ', '\t'):
436 454
                 i += 1
@@ -439,15 +457,7 @@ def value(self):
439 457
             return res
440 458
         else:
441 459
             p = i
442  
-            while i < len(subject) and subject[i] not in (' ', '\t'):
443  
-                if subject[i] in ('"', "'"):
444  
-                    c = subject[i]
445  
-                    i += 1
446  
-                    while i < len(subject) and subject[i] != c:
447  
-                        i += 1
448  
-                    if i >= len(subject):
449  
-                        raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
450  
-                i += 1
  460
+            i = next_space_index(subject, i)
451 461
             s = subject[p:i]
452 462
             while i < len(subject) and subject[i] in (' ', '\t'):
453 463
                 i += 1
49  tests/regressiontests/templates/parser.py
@@ -2,6 +2,55 @@
2 2
 Testing some internals of the template processing. These are *not* examples to be copied in user code.
3 3
 """
4 4
 
  5
+token_parsing=r"""
  6
+Tests for TokenParser behavior in the face of quoted strings with spaces.
  7
+
  8
+>>> from django.template import TokenParser
  9
+
  10
+
  11
+Test case 1: {% tag thevar|filter sometag %}
  12
+
  13
+>>> p = TokenParser("tag thevar|filter sometag")
  14
+>>> p.tagname
  15
+'tag'
  16
+>>> p.value()
  17
+'thevar|filter'
  18
+>>> p.more()
  19
+True
  20
+>>> p.tag()
  21
+'sometag'
  22
+>>> p.more()
  23
+False
  24
+
  25
+Test case 2: {% tag "a value"|filter sometag %}
  26
+
  27
+>>> p = TokenParser('tag "a value"|filter sometag')
  28
+>>> p.tagname
  29
+'tag'
  30
+>>> p.value()
  31
+'"a value"|filter'
  32
+>>> p.more()
  33
+True
  34
+>>> p.tag()
  35
+'sometag'
  36
+>>> p.more()
  37
+False
  38
+
  39
+Test case 3: {% tag 'a value'|filter sometag %}
  40
+
  41
+>>> p = TokenParser("tag 'a value'|filter sometag")
  42
+>>> p.tagname
  43
+'tag'
  44
+>>> p.value()
  45
+"'a value'|filter"
  46
+>>> p.more()
  47
+True
  48
+>>> p.tag()
  49
+'sometag'
  50
+>>> p.more()
  51
+False
  52
+"""
  53
+
5 54
 filter_parsing = r"""
6 55
 >>> from django.template import FilterExpression, Parser
7 56
 
4  tests/regressiontests/templates/tests.py
@@ -22,7 +22,7 @@
22 22
 
23 23
 from context import context_tests
24 24
 from custom import custom_filters
25  
-from parser import filter_parsing, variable_parsing
  25
+from parser import token_parsing, filter_parsing, variable_parsing
26 26
 from unicode import unicode_tests
27 27
 from smartif import *
28 28
 
@@ -37,7 +37,9 @@
37 37
 __test__ = {
38 38
     'unicode': unicode_tests,
39 39
     'context': context_tests,
  40
+    'token_parsing': token_parsing,
40 41
     'filter_parsing': filter_parsing,
  42
+    'variable_parsing': variable_parsing,
41 43
     'custom_filters': custom_filters,
42 44
 }
43 45
 

0 notes on commit b459f5b

Please sign in to comment.
Something went wrong with that request. Please try again.