diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2010-04-10 07:35:31 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2010-04-10 07:35:31 +0000 |
| commit | b579350cd16601a82efd6a497fed07f086371817 (patch) | |
| tree | cb43785852ec33d4021a5974783fdaeb552945cf /django | |
| parent | f4eac3d87fd377466cbdcbaf147314485fec517d (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.py | 41 |
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) |
