From 3a408edffde8a006a644d9c2d7bd32973421b924 Mon Sep 17 00:00:00 2001 From: pgjones Date: Tue, 26 Jul 2022 19:20:37 +0100 Subject: [PATCH 1/2] Bugfix ensure that the entire part is matched Previously the router would accept a partial match of a part, which is contrary to how the router is meant to work. For example if the rule to be matched was `d+` the router would match `2dfd` as `2` and silently forget the rest. --- CHANGES.rst | 2 ++ src/werkzeug/routing/rules.py | 2 +- tests/test_routing.py | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 662bf0ccd..70d7b9715 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,6 +7,8 @@ Unreleased - Fix router so that ``/path/`` will match a rule ``/path`` if strict slashes mode is disabled for the rule. :issue:`2467` +- Fix router so that partial part matches are not allowed + i.e. ``/2df`` does not match ``/``. :pr:`2470` - Restore ``ValidationError`` to be importable from ``werkzeug.routing``. :issue:`2465` diff --git a/src/werkzeug/routing/rules.py b/src/werkzeug/routing/rules.py index f16e5668a..5a33f894d 100644 --- a/src/werkzeug/routing/rules.py +++ b/src/werkzeug/routing/rules.py @@ -625,7 +625,7 @@ def _parse_rule(self, rule: str) -> t.Iterable[RulePart]: -len(argument_weights), argument_weights, ) - if final: + if not static: content += r"$\Z" yield RulePart( content=content, final=final, static=static, weight=weight diff --git a/tests/test_routing.py b/tests/test_routing.py index 0c28a1867..4f9fc2cc3 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -1400,3 +1400,18 @@ def test_newline_match(): with pytest.raises(NotFound): a.match("/hello\n") + + +def test_weighting(): + m = r.Map( + [ + r.Rule("/", endpoint="int"), + r.Rule("/", endpoint="uuid"), + ] + ) + a = m.bind("localhost") + + assert a.match("/2b5b0911-fdcf-4dd2-921b-28ace88db8a0") == ( + "uuid", + {"value": uuid.UUID("2b5b0911-fdcf-4dd2-921b-28ace88db8a0")}, + ) From b59eb67b65de96832e91b55a3c5b8e9e6d9a185c Mon Sep 17 00:00:00 2001 From: pgjones Date: Tue, 26 Jul 2022 21:55:00 +0100 Subject: [PATCH 2/2] Switch $\Z to \Z in matching regex This was the aim of d761d0e7acceb89f56d76434a74aeacf95d5ed49 but a typo included both. \Z is a stricter form of $. --- src/werkzeug/routing/rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/werkzeug/routing/rules.py b/src/werkzeug/routing/rules.py index 5a33f894d..29c785688 100644 --- a/src/werkzeug/routing/rules.py +++ b/src/werkzeug/routing/rules.py @@ -626,7 +626,7 @@ def _parse_rule(self, rule: str) -> t.Iterable[RulePart]: argument_weights, ) if not static: - content += r"$\Z" + content += r"\Z" yield RulePart( content=content, final=final, static=static, weight=weight )