From dd7198701a38519f1844376873d783aee5b094d6 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Fri, 10 Apr 2009 04:49:00 +0000 Subject: [PATCH] [1.0.X] Fixed #9315 -- Handle spaces in URL tag arguments. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks Natalia Bidart and Matías Bordese for most of this patch. Backport of r10462 from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10463 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 2 ++ django/template/__init__.py | 3 +-- django/template/defaulttags.py | 2 +- django/utils/text.py | 8 +++++++- tests/regressiontests/templates/tests.py | 1 + tests/regressiontests/text/tests.py | 12 ++++++++++++ 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 0bff3c5177..87837663ad 100644 --- a/AUTHORS +++ b/AUTHORS @@ -59,11 +59,13 @@ answer newbie questions, and generally made Django that much better: James Bennett Julian Bez Arvis Bickovskis + Natalia Bidart Paul Bissex Simon Blanchard David Blewett Matt Boersma boobsd@gmail.com + Matías Bordese Andrew Brehaut brut.alll@gmail.com btoll@bestweb.net diff --git a/django/template/__init__.py b/django/template/__init__.py index bdc4b890d1..b94ac50232 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -465,8 +465,7 @@ filter_raw_string = r""" 'i18n_close' : re.escape(")"), } -filter_raw_string = filter_raw_string.replace("\n", "").replace(" ", "") -filter_re = re.compile(filter_raw_string, re.UNICODE) +filter_re = re.compile(filter_raw_string, re.UNICODE|re.VERBOSE) class FilterExpression(object): """ diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 342d1fb34a..8d623005fd 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -1066,7 +1066,7 @@ def url(parser, token): The URL will look like ``/clients/client/123/``. """ - bits = token.contents.split(' ') + bits = token.split_contents() if len(bits) < 2: raise TemplateSyntaxError("'%s' takes at least one argument" " (path to a view)" % bits[0]) diff --git a/django/utils/text.py b/django/utils/text.py index cd631983d7..1116f05158 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -197,7 +197,13 @@ def javascript_quote(s, quote_double_quotes=False): return str(ustring_re.sub(fix, s)) javascript_quote = allow_lazy(javascript_quote, unicode) -smart_split_re = re.compile('("(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'(?:[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'|[^\\s]+)') +# Expression to match some_token and some_token="with spaces" (and similarly +# for single-quoted strings). +smart_split_re = re.compile(r""" + ([^\s"]*"(?:[^"\\]*(?:\\.[^"\\]*)*)"\S*| + [^\s']*'(?:[^'\\]*(?:\\.[^'\\]*)*)'\S*| + \S+)""", re.VERBOSE) + def smart_split(text): r""" Generator that splits a string by spaces, leaving quoted phrases together. diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index aecf94d461..51ad9c574c 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -947,6 +947,7 @@ class Templates(unittest.TestCase): 'url07': (u'{% url regressiontests.templates.views.client2 tag=v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), 'url08': (u'{% url метка_оператора v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), 'url09': (u'{% url метка_оператора_2 tag=v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), + 'url10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'), # Failures 'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError), diff --git a/tests/regressiontests/text/tests.py b/tests/regressiontests/text/tests.py index 7cfe44517a..d1db80dc34 100644 --- a/tests/regressiontests/text/tests.py +++ b/tests/regressiontests/text/tests.py @@ -15,6 +15,18 @@ r""" [u'"a', u"'one"] >>> print list(smart_split(r'''all friends' tests'''))[1] friends' +>>> list(smart_split(u'url search_page words="something else"')) +[u'url', u'search_page', u'words="something else"'] +>>> list(smart_split(u"url search_page words='something else'")) +[u'url', u'search_page', u"words='something else'"] +>>> list(smart_split(u'url search_page words "something else"')) +[u'url', u'search_page', u'words', u'"something else"'] +>>> list(smart_split(u'url search_page words-"something else"')) +[u'url', u'search_page', u'words-"something else"'] +>>> list(smart_split(u'url search_page words=hello')) +[u'url', u'search_page', u'words=hello'] +>>> list(smart_split(u'url search_page words="something else')) +[u'url', u'search_page', u'words="something', u'else'] ### urlquote ############################################################# >>> from django.utils.http import urlquote, urlquote_plus