1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

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
This commit is contained in:
Russell Keith-Magee
2010-04-10 07:35:31 +00:00
parent f4eac3d87f
commit b579350cd1
3 changed files with 45 additions and 11 deletions

View File

@@ -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)