supply-chain-risk-auditor: discard undecodable cache entries (#291)

This commit is contained in:
iflov
2026-08-31 21:40:51 +09:00
committed by GitHub
parent d1f1575cff
commit 7e7a9b2a5d
4 changed files with 16 additions and 3 deletions
@@ -1,6 +1,6 @@
{
"name": "supply-chain-risk-auditor",
"version": "2.0.1",
"version": "2.0.2",
"description": "Audit a project's npm, PyPI, and Go dependencies for supply-chain risk: version-matched advisories for direct dependencies and the full lockfile tree, abandoned upstreams, npm publisher concentration, and install scripts",
"author": {
"name": "Eric Quintero"
@@ -150,7 +150,7 @@ class Http:
return None
try:
stored = json.loads(path.read_text(encoding="utf-8"), strict=False)
except (json.JSONDecodeError, OSError):
except (json.JSONDecodeError, UnicodeDecodeError, OSError):
# A run interrupted mid-write leaves a truncated file that would otherwise
# crash every later run. Drop it and refetch.
self.stats["errors"] += 1
@@ -138,6 +138,19 @@ def test_truncated_cache_entry_is_dropped(tmp_path: Path):
assert not path.exists()
def test_non_utf8_cache_entry_is_dropped(tmp_path: Path):
"""Undecodable cache bytes are corruption, not a permanent client crash."""
http = Http(tmp_path, offline=True)
path = seed(http, "GET", "https://example.com/x", {"ok": 1})
path.write_bytes(b"\xff")
with pytest.raises(Unavailable):
http.get_json("https://example.com/x")
assert http.stats["errors"] == 1
assert not path.exists()
def test_cache_owner_is_verified_on_posix(tmp_path: Path):
"""The usual case: ownership checks out, so there is no caveat to report."""
http = Http(tmp_path, offline=True)