From 7672761d39f5d70f2ed95e2adcb8032fbe17dc18 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Sat, 4 Jul 2026 17:40:45 +0200 Subject: [PATCH] fix(toolbox): mesh-exclusion union tolerates malformed blob fields (ref #806) The union_blobs function now guards against non-list field values (e.g. int, bool, None) that could cause TypeError during iteration. Instead of assuming a field is always a list, the function checks isinstance() before iterating. Adds test_union_blobs_tolerates_malformed_fields() to verify that a valid blob with malformed fields does not crash the entire federation sync. Co-Authored-By: Claude Opus 4.8 --- .../secubox_toolbox/mesh_exclusion.py | 7 ++++--- .../tests/test_mesh_exclusion_sync.py | 12 ++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/secubox-toolbox/secubox_toolbox/mesh_exclusion.py b/packages/secubox-toolbox/secubox_toolbox/mesh_exclusion.py index a9f6341e..8661ef8e 100644 --- a/packages/secubox-toolbox/secubox_toolbox/mesh_exclusion.py +++ b/packages/secubox-toolbox/secubox_toolbox/mesh_exclusion.py @@ -185,9 +185,10 @@ def pull_blobs() -> list: def union_blobs(blobs: list) -> dict: s, b, d = set(), set(), set() for p in blobs: - s.update(x for x in (p.get("splice") or []) if isinstance(x, str)) - b.update(x for x in (p.get("bypass") or []) if isinstance(x, str)) - d.update(x for x in (p.get("disabled") or []) if isinstance(x, str)) + for key, acc in (("splice", s), ("bypass", b), ("disabled", d)): + v = p.get(key) + if isinstance(v, list): + acc.update(x for x in v if isinstance(x, str)) return {"splice": sorted(s)[:FED_MAX], "bypass": sorted(b)[:FED_MAX], "disabled": sorted(d)[:FED_MAX]} diff --git a/packages/secubox-toolbox/tests/test_mesh_exclusion_sync.py b/packages/secubox-toolbox/tests/test_mesh_exclusion_sync.py index 14bd45ff..2b52b1f6 100644 --- a/packages/secubox-toolbox/tests/test_mesh_exclusion_sync.py +++ b/packages/secubox-toolbox/tests/test_mesh_exclusion_sync.py @@ -24,3 +24,15 @@ def test_sync_writes_fed_files_only_on_change(tmp_path, monkeypatch): assert r1["changed"] is True r2 = mx.sync() # same content → no rewrite assert r2["changed"] is False + + +def test_union_blobs_tolerates_malformed_fields(): + # a verified-but-malformed blob (non-list field) must be skipped, not crash + blobs = [ + {"node": "bad", "splice": 123, "bypass": True, "disabled": None}, + {"node": "ok", "splice": ["a.com"], "bypass": [], "disabled": ["d.com"]}, + ] + u = mx.union_blobs(blobs) # must not raise + assert u["splice"] == ["a.com"] + assert u["disabled"] == ["d.com"] + assert u["bypass"] == []