From 0333c9494ed9d7d1e572d4a34872f04ff87b02be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Fri, 28 Dec 2018 12:54:26 +0100 Subject: [PATCH] misc: avoid URLs starting with double slash (#29373) --- tests/test_variadic_url.py | 14 +++++++------- wcs/qommon/misc.py | 11 ++++++++++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/tests/test_variadic_url.py b/tests/test_variadic_url.py index e8f274f49..690cc1565 100644 --- a/tests/test_variadic_url.py +++ b/tests/test_variadic_url.py @@ -164,6 +164,8 @@ def test_url_server(pub): {'url': url}) == 'http://www.example.net/foobar' assert get_variadic_url('[url]/foobar/', {'url': url}) == 'http://www.example.net/foobar/' + assert get_variadic_url('{{url}}/foobar/', + {'url': url}) == 'http://www.example.net/foobar/' assert get_variadic_url('[url]foo/bar/', {'url': 'http://www.example.net/'}) == 'http://www.example.net/foo/bar/' assert get_variadic_url('[url]foobar/', @@ -174,7 +176,7 @@ def test_url_server(pub): assert get_variadic_url('{{ url }}/foobar', {'url': 'http://www.example.net'}) == 'http://www.example.net/foobar' assert get_variadic_url('{{ url }}/foobar', # Django is more conservative here: - {'url': 'http://www.example.net/'}) == 'http://www.example.net//foobar' + {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar' # to be "smart", use Django templates language: for url in ('http://www.example.net', 'http://www.example.net/'): assert get_variadic_url('{{ url }}{% if url|last != "/" %}/{% endif %}foobar', @@ -207,7 +209,7 @@ def test_url_server_qs(pub): assert get_variadic_url('{{ url }}/?foo=bar', {'url': 'http://www.example.net'}) == 'http://www.example.net/?foo=bar' assert get_variadic_url('{{ url }}/?foo=bar', - {'url': 'http://www.example.net/'}) == 'http://www.example.net//?foo=bar' + {'url': 'http://www.example.net/'}) == 'http://www.example.net/?foo=bar' def test_url_server_more(pub): @@ -222,7 +224,7 @@ def test_url_server_more(pub): assert get_variadic_url('{{ url }}/foobar/json?toto', {'url': 'http://www.example.net'}) == 'http://www.example.net/foobar/json?toto' assert get_variadic_url('{{ url }}/foobar/json?toto', - {'url': 'http://www.example.net/'}) == 'http://www.example.net//foobar/json?toto' + {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/json?toto' assert get_variadic_url('{{ url }}foobar/json?toto', {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/json?toto' @@ -239,7 +241,7 @@ def test_url_server_even_more(pub): assert get_variadic_url('{{ url }}/foobar/json?foo=bar', {'url': 'http://www.example.net'}) == 'http://www.example.net/foobar/json?foo=bar' assert get_variadic_url('{{ url }}/foobar/json?foo=bar', - {'url': 'http://www.example.net/'}) == 'http://www.example.net//foobar/json?foo=bar' + {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/json?foo=bar' assert get_variadic_url('{{ url }}foobar/json?foo=bar', {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/json?foo=bar' @@ -249,14 +251,12 @@ def test_url_server_even_more_more(pub): {'url': 'http://www.example.net'}) == 'http://www.example.net/foobar/baz/json?foo=bar' assert get_variadic_url('[url]/foobar/baz/json?foo=bar', {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/baz/json?foo=bar' - assert get_variadic_url('[url]foobar/baz/json?foo=bar', - {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/baz/json?foo=bar' # Django is more conservative assert get_variadic_url('{{ url }}/foobar/baz/json?foo=bar', {'url': 'http://www.example.net'}) == 'http://www.example.net/foobar/baz/json?foo=bar' assert get_variadic_url('{{ url }}/foobar/baz/json?foo=bar', - {'url': 'http://www.example.net/'}) == 'http://www.example.net//foobar/baz/json?foo=bar' + {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/baz/json?foo=bar' assert get_variadic_url('{{ url }}foobar/baz/json?foo=bar', {'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/baz/json?foo=bar' diff --git a/wcs/qommon/misc.py b/wcs/qommon/misc.py index 56a2ef347..114e9c986 100644 --- a/wcs/qommon/misc.py +++ b/wcs/qommon/misc.py @@ -346,7 +346,16 @@ def get_variadic_url(url, variables, encode_query=True): # django template if '{{' in url or '{%' in url: try: - return Template(url).render(variables) + url = Template(url).render(variables) + p = urlparse.urlsplit(url) + scheme, netloc, path, query, fragment = ( + p.scheme, p.netloc, p.path, p.query, p.fragment) + if path.startswith('//'): + # don't let double slash happen at the root of the URL, this + # happens when a template such as {{url}}/path is used (with + # {{url}} already ending with a slash). + path = path[1:] + return urlparse.urlunsplit((scheme, netloc, path, query, fragment)) except (TemplateSyntaxError, VariableDoesNotExist): return url