From 371cbe472baf4edf9dead9d4efb0edacb6d04e0e Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Tue, 17 Jan 2023 14:04:48 +0000 Subject: [PATCH] [FIX] http_routing: prevent unslug to fail when there is anchor or qs Due to the end part of the regex `(?=$|/)`, it will not find and thus not unslug string if they end up with a query string or and anchor except if there is a trailing slash before. First, it's unlikely that there will be a trailing slash as it's not common and on top of that, Odoo try to enforce non trailing slash in URL. Second, it's not that hard to makes those cases work. Before this commit, the following string would "match" and be unslug: - /blog-1 - /blog-1/ - /blog-1/register - /blog-1/?qs=2 - /blog-1/#anchor But those would not: - /blog-1?qs=2 - /blog-1#anchor Part-of: odoo/odoo#107782 --- addons/http_routing/models/ir_http.py | 2 +- addons/website/tests/test_converter.py | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py index 657895dc823..94db3fedc60 100644 --- a/addons/http_routing/models/ir_http.py +++ b/addons/http_routing/models/ir_http.py @@ -100,7 +100,7 @@ def slug(value): # NOTE: as the pattern is used as it for the ModelConverter (ir_http.py), do not use any flags -_UNSLUG_RE = re.compile(r'(?:(\w{1,2}|\w[A-Za-z0-9-_]+?\w)-)?(-?\d+)(?=$|/)') +_UNSLUG_RE = re.compile(r'(?:(\w{1,2}|\w[A-Za-z0-9-_]+?\w)-)?(-?\d+)(?=$|\/|#|\?)') def unslug(s): diff --git a/addons/website/tests/test_converter.py b/addons/website/tests/test_converter.py index 9a688c74ed9..6dac445cc4a 100644 --- a/addons/website/tests/test_converter.py +++ b/addons/website/tests/test_converter.py @@ -21,10 +21,16 @@ class TestUnslug(BaseCase): '--1': (None, None), 'foo---1': (None, None), 'foo1': (None, None), + # qs & anchor & trailing slash + 'foo-1/': ('foo', 1), + 'foo-1/?qs=1': ('foo', 1), + 'foo-1/#anchor': ('foo', 1), + 'foo-1?qs=1': ('foo', 1), + 'foo-1#anchor': ('foo', 1), } for slug, expected in tests.items(): - self.assertEqual(unslug(slug), expected) + self.assertEqual(unslug(slug), expected, "%r case failed" % slug) class TestTitleToSlug(BaseCase): """