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 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-07-04 17:40:45 +02:00
parent 6d886cb61c
commit 7672761d39
2 changed files with 16 additions and 3 deletions

View File

@ -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]}

View File

@ -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"] == []