Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #12072 -- Certain characters no longer break url tag. Thanks, A…

…lexander Dutton.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12503 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 349827996b5bcf29886bd1e57bc07147d840229e 1 parent 6ed7bd5
Justin Bronn authored February 23, 2010
1  AUTHORS
@@ -142,6 +142,7 @@ answer newbie questions, and generally made Django that much better:
142 142
     Andrew Durdin <adurdin@gmail.com>
143 143
     dusk@woofle.net
144 144
     Andy Dustman <farcepest@gmail.com>
  145
+    Alexander Dutton <dev@alexdutton.co.uk>
145 146
     J. Clifford Dyer <jcd@sdf.lonestar.org>
146 147
     Clint Ecker
147 148
     Nick Efford <nick@efford.org>
28  django/template/defaulttags.py
@@ -1071,6 +1071,13 @@ def templatetag(parser, token):
1071 1071
     return TemplateTagNode(tag)
1072 1072
 templatetag = register.tag(templatetag)
1073 1073
 
  1074
+# Regex for URL arguments including filters
  1075
+url_arg_re = re.compile(
  1076
+    r"(?:(%(name)s)=)?(%(value)s(?:\|%(name)s(?::%(value)s)?)*)" % {
  1077
+        'name':'\w+',
  1078
+        'value':'''(?:(?:'[^']*')|(?:"[^"]*")|(?:[\w\.-]+))'''},
  1079
+    re.VERBOSE)
  1080
+
1074 1081
 def url(parser, token):
1075 1082
     """
1076 1083
     Returns an absolute URL matching given view with its parameters.
@@ -1118,13 +1125,20 @@ def url(parser, token):
1118 1125
                 asvar = bits.next()
1119 1126
                 break
1120 1127
             else:
1121  
-                for arg in bit.split(","):
1122  
-                    if '=' in arg:
1123  
-                        k, v = arg.split('=', 1)
1124  
-                        k = k.strip()
1125  
-                        kwargs[k] = parser.compile_filter(v)
1126  
-                    elif arg:
1127  
-                        args.append(parser.compile_filter(arg))
  1128
+                end = 0
  1129
+                for i, match in enumerate(url_arg_re.finditer(bit)):
  1130
+                    if (i == 0 and match.start() != 0) or \
  1131
+                          (i > 0 and (bit[end:match.start()] != ',')):
  1132
+                        raise TemplateSyntaxError("Malformed arguments to url tag")
  1133
+                    end = match.end()
  1134
+                    name, value = match.group(1), match.group(2)
  1135
+                    if name:
  1136
+                        kwargs[name] = parser.compile_filter(value)
  1137
+                    else:
  1138
+                        args.append(parser.compile_filter(value))
  1139
+                if end != len(bit):
  1140
+                    raise TemplateSyntaxError("Malformed arguments to url tag")
  1141
+
1128 1142
     return URLNode(viewname, args, kwargs, asvar)
1129 1143
 url = register.tag(url)
1130 1144
 
9  tests/regressiontests/templates/tests.py
@@ -1031,11 +1031,20 @@ def get_template_tests(self):
1031 1031
             'url08': (u'{% url метка_оператора v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
1032 1032
             'url09': (u'{% url метка_оператора_2 tag=v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
1033 1033
             'url10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'),
  1034
+            'url11': ('{% url regressiontests.templates.views.client_action id=client.id,action="==" %}', {'client': {'id': 1}}, '/url_tag/client/1/==/'),
  1035
+            'url12': ('{% url regressiontests.templates.views.client_action id=client.id,action="," %}', {'client': {'id': 1}}, '/url_tag/client/1/,/'),
  1036
+            'url12': ('{% url regressiontests.templates.views.client_action id=client.id,action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
1034 1037
 
1035 1038
             # Failures
1036 1039
             'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
1037 1040
             'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch),
1038 1041
             'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch),
  1042
+            'url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError),
  1043
+            'url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError),
  1044
+            'url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError),
  1045
+            'url-fail07': ('{% url view a.id!id %}', {}, template.TemplateSyntaxError),
  1046
+            'url-fail08': ('{% url view id="unterminatedstring %}', {}, template.TemplateSyntaxError),
  1047
+            'url-fail09': ('{% url view id=", %}', {}, template.TemplateSyntaxError),
1039 1048
 
1040 1049
             # {% url ... as var %}
1041 1050
             'url-asvar01': ('{% url regressiontests.templates.views.index as url %}', {}, ''),

0 notes on commit 3498279

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