The bug is caused by the call to `translate_url` function in
`set_language`. `translate_url` passes the URL on to `reverse`, which
assumes URLs that are not urlencoding, thus resulting in a double
urlencoded URL, which obviously will not work. Non-urlencoded URLs in
HTTP_REFERER work correctly.
An easy way to test this is to have a view with a URL with unicode
characters in it and use the translation selector widget provided in the
i18n docs, but with the `redirect_to` context variable undefined, which is
the way I found the bug.
AFAIK there's no standard about whether the browser should encode the URL
in HTTP_REFERER, but most of the new browsers do so anyway. The bug should
be easy to fix, thus, by just decoding the string in HTTP_REFERER – if it
was encoded, it will now be unencoded, if it was '''not''' encoded, it
will be unchanged (disregarding a corner case of ambiguous URLs with
substrings like `%C3%A4` verbatim with browsers that don't encode the
URLs). I'll make a pull request within a few days.
--
Ticket URL: <https://code.djangoproject.com/ticket/26466>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => assigned
* needs_better_patch: => 0
* owner: nobody => miikkas
* needs_tests: => 0
* needs_docs: => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/26466#comment:1>
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/26466#comment:2>
Old description:
> POSTing to `set_language` when `next` is not set causes Django to user
> HTTP_REFERER instead. If the URL in HTTP_REFERER is urlencoded, the
> resulting redirection will fail.
>
> The bug is caused by the call to `translate_url` function in
> `set_language`. `translate_url` passes the URL on to `reverse`, which
> assumes URLs that are not urlencoding, thus resulting in a double
> urlencoded URL, which obviously will not work. Non-urlencoded URLs in
> HTTP_REFERER work correctly.
>
> An easy way to test this is to have a view with a URL with unicode
> characters in it and use the translation selector widget provided in the
> i18n docs, but with the `redirect_to` context variable undefined, which
> is the way I found the bug.
>
> AFAIK there's no standard about whether the browser should encode the URL
> in HTTP_REFERER, but most of the new browsers do so anyway. The bug
> should be easy to fix, thus, by just decoding the string in HTTP_REFERER
> – if it was encoded, it will now be unencoded, if it was '''not'''
> encoded, it will be unchanged (disregarding a corner case of ambiguous
> URLs with substrings like `%C3%A4` verbatim with browsers that don't
> encode the URLs). I'll make a pull request within a few days.
New description:
POSTing to `set_language` when `next` is not set causes Django to use
HTTP_REFERER instead. If the URL in HTTP_REFERER is urlencoded, the
resulting redirection will fail.
The bug is caused by the call to `translate_url` function in
`set_language`. `translate_url` passes the URL on to `reverse`, which
assumes URLs that are not urlencoded, thus resulting in a double
urlencoded URL, which obviously will not work. Non-urlencoded URLs in
HTTP_REFERER work correctly.
An easy way to test this is to have a view with a URL with unicode
characters in it and use the translation selector widget provided in the
i18n docs, but with the `redirect_to` context variable undefined –
basically the way I found this bug.
AFAIK there's no standard about whether the browser should encode the URL
in HTTP_REFERER, but most of the new browsers do so anyway. The bug should
be easy to fix, thus, by just decoding the string in HTTP_REFERER – if it
was encoded, it will now be unencoded, if it was '''not''' encoded, it
will be unchanged (disregarding a corner case of ambiguous URLs with
substrings like `%C3%A4` verbatim with browsers that don't encode the
URLs). I'll make a pull request within a few days.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/26466#comment:3>
* has_patch: 0 => 1
Comment:
I have created a fix for the bug and a regression test for the fix. The
patch is available at the following branch:
* https://github.com/miikkas/django/tree/ticket_26466
--
Ticket URL: <https://code.djangoproject.com/ticket/26466#comment:4>
Comment (by miikkas):
Django's own `urlunquote` had to be used here instead of Python's
`unquote` – the latter caused unicode problems on Py2 test suite. Anyway,
the patch has been updated and everything should work now.
--
Ticket URL: <https://code.djangoproject.com/ticket/26466#comment:5>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"9e3f141701b96b6974b3386f83dc76e70a41377d" 9e3f1417]:
{{{
#!CommitTicketReference repository=""
revision="9e3f141701b96b6974b3386f83dc76e70a41377d"
Fixed #26466 -- Added HTTP_REFERER decoding to i18n set_language() view.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/26466#comment:6>