[3.2.x] Fixed #32345 -- Fixed preserving encoded query strings in set_language() view.

Thanks Johannes Maron for the review.

Backport of 6822aa5c6c from master
This commit is contained in:
Sandro Covo 2021-01-12 22:19:53 +01:00 committed by Mariusz Felisiak
parent 18cac6bbfb
commit 0a3d93ffba
3 changed files with 7 additions and 7 deletions

View File

@ -1,4 +1,4 @@
from urllib.parse import urlsplit, urlunsplit from urllib.parse import unquote, urlsplit, urlunsplit
from asgiref.local import Local from asgiref.local import Local
@ -163,7 +163,8 @@ def translate_url(url, lang_code):
""" """
parsed = urlsplit(url) parsed = urlsplit(url)
try: try:
match = resolve(parsed.path) # URL may be encoded.
match = resolve(unquote(parsed.path))
except Resolver404: except Resolver404:
pass pass
else: else:

View File

@ -2,7 +2,6 @@ import itertools
import json import json
import os import os
import re import re
from urllib.parse import unquote
from django.apps import apps from django.apps import apps
from django.conf import settings from django.conf import settings
@ -41,8 +40,6 @@ def set_language(request):
) )
): ):
next_url = request.META.get('HTTP_REFERER') next_url = request.META.get('HTTP_REFERER')
# HTTP_REFERER may be encoded.
next_url = next_url and unquote(next_url)
if not url_has_allowed_host_and_scheme( if not url_has_allowed_host_and_scheme(
url=next_url, url=next_url,
allowed_hosts={request.get_host()}, allowed_hosts={request.get_host()},

View File

@ -199,12 +199,14 @@ class SetLanguageTests(TestCase):
def test_setlang_decodes_http_referer_url(self): def test_setlang_decodes_http_referer_url(self):
""" """
The set_language view decodes the HTTP_REFERER URL. The set_language view decodes the HTTP_REFERER URL and preserves an
encoded query string.
""" """
# The URL & view must exist for this to work as a regression test. # The URL & view must exist for this to work as a regression test.
self.assertEqual(reverse('with_parameter', kwargs={'parameter': 'x'}), '/test-setlang/x/') self.assertEqual(reverse('with_parameter', kwargs={'parameter': 'x'}), '/test-setlang/x/')
lang_code = self._get_inactive_language_code() lang_code = self._get_inactive_language_code()
encoded_url = '/test-setlang/%C3%A4/' # (%C3%A4 decodes to ä) # %C3%A4 decodes to ä, %26 to &.
encoded_url = '/test-setlang/%C3%A4/?foo=bar&baz=alpha%26omega'
response = self.client.post('/i18n/setlang/', {'language': lang_code}, HTTP_REFERER=encoded_url) response = self.client.post('/i18n/setlang/', {'language': lang_code}, HTTP_REFERER=encoded_url)
self.assertRedirects(response, encoded_url, fetch_redirect_response=False) self.assertRedirects(response, encoded_url, fetch_redirect_response=False)
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)