From 2eb8d81e81f50d414e106139d281541a71c2ca57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A0=EC=B0=BD=EC=9A=B1?= Date: Sun, 12 Jul 2026 10:49:46 +0900 Subject: [PATCH] fix(edge): zones_from_config skips malformed rows without raising (IndexError/non-list guard) --- edge/zones.py | 7 +++++-- tests/test_zones.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/edge/zones.py b/edge/zones.py index 91af6f2..23718ff 100644 --- a/edge/zones.py +++ b/edge/zones.py @@ -5,7 +5,10 @@ from edge.detectors.zone import Zone def zones_from_config(config: dict) -> list[Zone]: out: list[Zone] = [] - for row in config.get("zones", []) or []: + rows = config.get("zones", []) or [] + if not isinstance(rows, list): + return [] + for row in rows: try: raw = row["polygon_json"] pts = json.loads(raw) if isinstance(raw, str) else raw @@ -13,7 +16,7 @@ def zones_from_config(config: dict) -> list[Zone]: if len(polygon) < 3: continue out.append(Zone(str(row["zone_id"]), str(row["level"]), polygon)) - except (KeyError, ValueError, TypeError, json.JSONDecodeError): + except (KeyError, ValueError, TypeError, IndexError, json.JSONDecodeError): continue return out diff --git a/tests/test_zones.py b/tests/test_zones.py index 67f015b..1fcb342 100644 --- a/tests/test_zones.py +++ b/tests/test_zones.py @@ -19,3 +19,15 @@ def test_skips_malformed_row(): def test_empty_config(): assert zones_from_config({}) == [] assert thresholds_from_config({}) == {} + +def test_skips_short_point_without_crashing(): + cfg = {"zones": [ + {"zone_id": "bad", "camera_id": "c", "level": "restricted", "polygon_json": "[[0,0],[9],[9,9]]"}, + {"zone_id": "ok", "camera_id": "c", "level": "restricted", "polygon_json": "[[0,0],[9,0],[9,9]]"}, + ]} + zones = zones_from_config(cfg) + # bad row skipped, good row survives -- function did not crash + assert [z.zone_id for z in zones] == ["ok"] + +def test_non_iterable_zones_returns_empty(): + assert zones_from_config({"zones": 5}) == []