Skip to content

fix: parse downloaded coverage.xml with defusedxml (#50) - #57

Merged
tschm merged 2 commits into
mainfrom
rhiza_fix_50_20260925
Sep 25, 2026
Merged

tschm merged 2 commits into
mainfrom
rhiza_fix_50_20260925

Conversation

@tschm

@tschm tschm commented Sep 25, 2026

Copy link
Copy Markdown
Member

Closes #50

Acceptance criterion (verbatim): "bandit over collector/jq_collector reports no B314/B405, either fixed or suppressed with a written reason."

Which branch, and who chose it: the criterion allows two outcomes. This takes the fixed one, defusedxml, as recommended in triage and selected by the maintainer. A # nosec would have recorded why the stdlib parser was acceptable; this makes it unnecessary.

What changed

  • jq_collector/github.py: from xml.etree import ElementTree → from defusedxml import ElementTree. The API is the same: fromstring and ParseError are both there, so the parse site and the except in coverage_percent are untouched. defusedxml refuses entity declarations and external references with a ValueError subclass, which that except already maps to "malformed report, log and carry on" rather than a failed refresh. The existing _MAX_UNPACKED_BYTES cap still bounds the size.
  • pyproject.toml / uv.lock: defusedxml>=0.7 as a runtime dependency, and types-defusedxml in the dev group so mypy keeps checking the call. The image installs from uv export --locked, so it picks this up with no Dockerfile change.
  • tests/test_coverage.py: one new case in the existing malformed-report parametrization, declares-an-entity. The payload is well-formed and its entity expands to a valid line-rate, so the stdlib parser would read it as 100%. I checked that it fails with the old import and passes with this one, so the defence can't be silently reverted.

Gates (from collector/, as ci.yml runs them)

  • ruff check / ruff format --check jq_collector tests: clean
  • uv run --frozen mypy: no issues in 11 files
  • pytest --cov=jq_collector: 452 passed, 100%; the same on --python 3.11
  • bandit -r jq_collector: no B314/B405. The remaining findings are B404/B603/B607 on the fixed-argument git calls in localgit.py and origin.py, outside this issue.
  • deptry jq_collector (in the project env): no issues

Merge note: #54 also edits github.py (type annotations), in hunks that don't touch these lines, so the two should merge cleanly in either order.

🤖 Generated with Claude Code

@tschm
tschm merged commit 5e8eab0 into main Sep 25, 2026
5 checks passed
@tschm
tschm deleted the rhiza_fix_50_20260925 branch September 25, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parse downloaded coverage.xml with defusedxml (bandit B314)

1 participant