From 86b73ea4322b277b28d79dc46a542dc1c06f151c Mon Sep 17 00:00:00 2001 From: pgjones Date: Sat, 9 Mar 2024 22:14:44 +0000 Subject: [PATCH] Raise an error if the converter arguments cannot be parsed This could happen for example with `min=0;max=500` as the `;` is not a word character everything before it is ignored in the regex during the finditer call. This then lefts the user confused as the `min=0;` was silently ignored. --- CHANGES.rst | 2 ++ src/werkzeug/routing/rules.py | 8 ++++++++ tests/test_routing.py | 3 +++ 3 files changed, 13 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index c7f5aeba5..b2f2a08f6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,8 @@ Unreleased - Fix response_wrapper type check in test client. :issue:`2831` - Make the return type of ``MultiPartParser.parse`` more precise. :issue:`2840` +- Raise an error if converter arguments cannot be + parsed. :issue:`2822` Version 3.0.1 ------------- diff --git a/src/werkzeug/routing/rules.py b/src/werkzeug/routing/rules.py index ea32d1dca..7029d8bc0 100644 --- a/src/werkzeug/routing/rules.py +++ b/src/werkzeug/routing/rules.py @@ -67,6 +67,7 @@ class RulePart: _simple_rule_re = re.compile(r"<([^>]+)>") _converter_args_re = re.compile( r""" + \s* ((?P\w+)\s*=\s*)? (?P True|False| @@ -112,8 +113,14 @@ def parse_converter_args(argstr: str) -> tuple[tuple[t.Any, ...], dict[str, t.An argstr += "," args = [] kwargs = {} + position = 0 for item in _converter_args_re.finditer(argstr): + if item.start() != position: + raise ValueError( + f"Cannot parse converter argument '{argstr[position:item.start()]}'" + ) + value = item.group("stringval") if value is None: value = item.group("value") @@ -123,6 +130,7 @@ def parse_converter_args(argstr: str) -> tuple[tuple[t.Any, ...], dict[str, t.An else: name = item.group("name") kwargs[name] = value + position = item.end() return tuple(args), kwargs diff --git a/tests/test_routing.py b/tests/test_routing.py index 5291348c0..02db898d6 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -1076,6 +1076,9 @@ def test_converter_parser(): args, kwargs = r.parse_converter_args('"foo", "bar"') assert args == ("foo", "bar") + with pytest.raises(ValueError): + r.parse_converter_args("min=0;max=500") + def test_alias_redirects(): m = r.Map(