summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2010-04-10 07:35:31 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2010-04-10 07:35:31 +0000
commitb579350cd16601a82efd6a497fed07f086371817 (patch)
treecb43785852ec33d4021a5974783fdaeb552945cf /django
parentf4eac3d87fd377466cbdcbaf147314485fec517d (diff)
Fixed #13275 -- Modified the parsing logic of the {% url %} tag to avoid catastrophic backtracking. Thanks to SmileyChris for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12943 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
-rw-r--r--django/template/defaulttags.py41
1 files changed, 31 insertions, 10 deletions
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 6d77eeddd7..9dd5fb766f 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -1065,10 +1065,6 @@ def templatetag(parser, token):
return TemplateTagNode(tag)
templatetag = register.tag(templatetag)
-# Backwards compatibility check which will fail against for old comma
-# separated arguments in the url tag.
-url_backwards_re = re.compile(r'''(('[^']*'|"[^"]*"|[^,]+)=?)+$''')
-
def url(parser, token):
"""
Returns an absolute URL matching given view with its parameters.
@@ -1117,13 +1113,38 @@ def url(parser, token):
asvar = bits[-1]
bits = bits[:-2]
- # Backwards compatibility: {% url urlname arg1,arg2 %} or
- # {% url urlname arg1,arg2 as foo %} cases.
- if bits:
- old_args = ''.join(bits)
- if not url_backwards_re.match(old_args):
- bits = old_args.split(",")
+ # Backwards compatibility: check for the old comma separated format
+ # {% url urlname arg1,arg2 %}
+ # Initial check - that the first space separated bit has a comma in it
+ if bits and ',' in bits[0]:
+ check_old_format = True
+ # In order to *really* be old format, there must be a comma
+ # in *every* space separated bit, except the last.
+ for bit in bits[1:-1]:
+ if ',' not in bit:
+ # No comma in this bit. Either the comma we found
+ # in bit 1 was a false positive (e.g., comma in a string),
+ # or there is a syntax problem with missing commas
+ check_old_format = False
+ break
+ else:
+ # No comma found - must be new format.
+ check_old_format = False
+
+ if check_old_format:
+ # Confirm that this is old format by trying to parse the first
+ # argument. An exception will be raised if the comma is
+ # unexpected (i.e. outside of a static string).
+ match = kwarg_re.match(bits[0])
+ if match:
+ value = match.groups()[1]
+ try:
+ parser.compile_filter(value)
+ except TemplateSyntaxError:
+ bits = ''.join(bits).split(',')
+ # Now all the bits are parsed into new format,
+ # process them as template vars
if len(bits):
for bit in bits:
match = kwarg_re.match(bit)