[FIX] http_routing: error occurs if the path is not "latin1" string

For multi language website, when request http:/localhost/en/something,
Odoo reroutes from the requested path /en/something to the new path
/something with lang=en_US in context.

If the new path is a unicode string like http:/localhost/vi/xin-chào,
http:/localhost/ru/привет, a error should occur at
werkzeug._compat.wsgi_decoding_dance() because the path was not latin1
string.

The utf-8 encoding followed by a latin-1 decoding is required by the
WSGI specification[^1]. latin-1 is used as an encoding passthrought:
that encoding has a representation for all the 256 bytes, i.e. it is
impossible that decoding a text will raise a ValueError. The WSGI spec
uses this trick to save values until the actual charset (present in
the Content-Type header) in known.

[^1]: https://peps.python.org/pep-3333/#a-note-on-string-types

closes odoo/odoo#143898

X-original-commit: 9b69b87c08b1d62b3581fe651bee692a4f217dff
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
This commit is contained in:
Julien Castiaux
2023-12-01 15:51:55 +00:00
parent caf4da2544
commit e5cc17323d
2 changed files with 12 additions and 0 deletions
+5
View File
@@ -518,6 +518,11 @@ class IrHttp(models.AbstractModel):
string. This act as a light redirection, it does not return a
3xx responses to the browser but still change the current URL.
"""
# WSGI encoding dance https://peps.python.org/pep-3333/#unicode-issues
if isinstance(path, str):
path = path.encode('utf-8')
path = path.decode('latin1', 'replace')
if query_string is None:
query_string = request.httprequest.environ['QUERY_STRING']
+7
View File
@@ -99,6 +99,13 @@ class TestLangUrl(HttpCase):
[anchor] = doc.xpath('//a[@id="foo"]')
self.assertEqual(anchor.get('href'), 'http://]', 'The invalid IP URL must be left untouched')
def test_06_reroute_unicode(self):
res = self.url_open('/fr/привет')
self.assertEqual(res.status_code, 404, "Rerouting didn't crash because of unicode path")
res = self.url_open('/fr/path?привет=1')
self.assertEqual(res.status_code, 404, "Rerouting didn't crash because of unicode query-string")
@tagged('-at_install', 'post_install')
class TestControllerRedirect(TestLangUrl):