diff --git a/tests/test_patterns.py b/tests/test_patterns.py index 48ab530f..9596159c 100644 --- a/tests/test_patterns.py +++ b/tests/test_patterns.py @@ -186,6 +186,13 @@ def test_error_unclosed_brace(): list(expand_patterns("test[a]{1-3")) +def test_error_open_range_missing_end(): + """"{2-}" consumes the dash and finds no end: same error class as "{-2}", + not a silent expansion to zero permutations.""" + with pytest.raises(ValueError, match="range end"): + list(expand_patterns("test[a-c]{2-}")) + + def test_error_lone_open_bracket(): with pytest.raises(ValueError): list(expand_patterns("[")) diff --git a/user_scanner/core/patterns.py b/user_scanner/core/patterns.py index 065447c3..5dbda591 100644 --- a/user_scanner/core/patterns.py +++ b/user_scanner/core/patterns.py @@ -98,7 +98,12 @@ def _parse_lenset(lexer: Lexer) -> Set[int]: lexer.next() rhs = lexer.parse_number() - if lhs is not None and rhs is not None: + # "{2-}" consumed the dash but has no end: erroring matches + # "{-2}", while skipping silently expands to zero permutations + # and the scan runs on no targets without a word. + if rhs is None: + raise ValueError('Missing range end after "-" in lenset') + if lhs is not None: for i in range(lhs, rhs + 1): lenset.add(i) elif lhs is not None: