From 3cdaceb90ae34879ba2783498e7b7d375b586ff4 Mon Sep 17 00:00:00 2001 From: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com> Date: Tue, 17 Feb 2026 16:08:18 -0800 Subject: [PATCH] fix: enforce maximum of 1024 items in range expressions Range expressions like '1-1025' were accepted despite exceeding the spec limit of 1024 items. Add validation in IntRangeExpr._validate() to reject range expressions that produce more than 1024 values. Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com> --- src/openjd/model/_range_expr.py | 4 ++++ .../openjd/model/_internal/test_range_expr.py | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/openjd/model/_range_expr.py b/src/openjd/model/_range_expr.py index 7c789945..33df5288 100644 --- a/src/openjd/model/_range_expr.py +++ b/src/openjd/model/_range_expr.py @@ -150,6 +150,10 @@ def ranges(self) -> list[IntRange]: def _validate(self) -> None: """raises: ValueError - if not valid""" + if len(self) > 1024: + raise ValueError( + f"Range expression produces {len(self)} values, but the maximum is 1024." + ) # Validate that the ranges are not overlapping prev_range: IntRange | None = None for range_ in self.ranges: diff --git a/test/openjd/model/_internal/test_range_expr.py b/test/openjd/model/_internal/test_range_expr.py index f79d2ade..e8984fdc 100644 --- a/test/openjd/model/_internal/test_range_expr.py +++ b/test/openjd/model/_internal/test_range_expr.py @@ -362,6 +362,30 @@ def test_contains(self) -> None: assert -3 not in IntRangeExpr.from_str("-1--2:-1") assert 0 not in IntRangeExpr.from_str("-1--2:-1") + def test_range_expr_max_1024_items_succeeds(self): + expr = IntRangeExpr.from_str("1-1024") + assert len(expr) == 1024 + + def test_range_expr_1025_items_fails(self): + with pytest.raises(ExpressionError): + IntRangeExpr.from_str("1-1025") + + def test_range_expr_combined_subranges_exceed_1024_fails(self): + with pytest.raises(ExpressionError): + IntRangeExpr.from_str("1-600,700-1300") + + def test_range_expr_stepped_within_limit_succeeds(self): + expr = IntRangeExpr.from_str("1-2047:2") + assert len(expr) == 1024 + + def test_range_expr_stepped_exceeds_limit_fails(self): + with pytest.raises(ExpressionError): + IntRangeExpr.from_str("1-3000:2") + + def test_range_expr_negative_range_exceeds_limit_fails(self): + with pytest.raises(ExpressionError): + IntRangeExpr.from_str("-512-512") + class TestIntRange: def test_length(self):