Skip to content

Commit

Permalink
[3.2.x] Fixed #32345 -- Fixed preserving encoded query strings in set…
Browse files Browse the repository at this point in the history
…_language() view.

Thanks Johannes Maron for the review.

Backport of 6822aa5 from master
  • Loading branch information
sacovo authored and felixxm committed Jan 29, 2021
1 parent 18cac6b commit 0a3d93f
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 7 deletions.
5 changes: 3 additions & 2 deletions django/urls/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from urllib.parse import urlsplit, urlunsplit
from urllib.parse import unquote, urlsplit, urlunsplit

from asgiref.local import Local

Expand Down Expand Up @@ -163,7 +163,8 @@ def translate_url(url, lang_code):
"""
parsed = urlsplit(url)
try:
match = resolve(parsed.path)
# URL may be encoded.
match = resolve(unquote(parsed.path))
except Resolver404:
pass
else:
Expand Down
3 changes: 0 additions & 3 deletions django/views/i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import json
import os
import re
from urllib.parse import unquote

from django.apps import apps
from django.conf import settings
Expand Down Expand Up @@ -41,8 +40,6 @@ def set_language(request):
)
):
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(
url=next_url,
allowed_hosts={request.get_host()},
Expand Down
6 changes: 4 additions & 2 deletions tests/view_tests/tests/test_i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,14 @@ def test_setlang_cookie(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.
self.assertEqual(reverse('with_parameter', kwargs={'parameter': 'x'}), '/test-setlang/x/')
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)
self.assertRedirects(response, encoded_url, fetch_redirect_response=False)
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
Expand Down

0 comments on commit 0a3d93f

Please sign in to comment.