From afceabaf3c35e83f45602711fe31fd1d39a31623 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 08:14:17 +0100 Subject: [PATCH] fix: bios_integrity stops when git fails modified_for_git read the stdout of git status without its exit code: a corrupt index printed nothing, the working change read as unmodified, and --apply wrote HEAD's blob over it. Every git call now raises on a non-zero status, and the command exits 2 naming the git error. --- scripts/bios_integrity.py | 19 +++++++++++++++++-- tests/test_autorun.py | 10 ++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/scripts/bios_integrity.py b/scripts/bios_integrity.py index 72d1caf71..1b0a69b17 100644 --- a/scripts/bios_integrity.py +++ b/scripts/bios_integrity.py @@ -91,8 +91,19 @@ def sha1_of(path: Path) -> str: return digest.hexdigest() +class GitFailed(RuntimeError): + """A git command failed: its empty output says nothing about the file.""" + + def git(root: Path, *args: str) -> subprocess.CompletedProcess: - return subprocess.run(["git", "-C", str(root), *args], capture_output=True, check=False) + """Run git in root. A failure raises: an unreadable index read as an empty + status made a session's working change look unmodified, and --apply wrote + HEAD's bytes over it.""" + done = subprocess.run(["git", "-C", str(root), *args], capture_output=True, check=False) + if done.returncode: + message = done.stderr.decode(errors="replace").strip() + raise GitFailed(f"git {' '.join(args)} exited {done.returncode}: {message}") + return done def head_blob(root: Path, path: str) -> str: @@ -197,7 +208,11 @@ def main() -> int: from common import load_database root = Path.cwd() - report = check(root, load_database(args.db), args.apply) + try: + report = check(root, load_database(args.db), args.apply) + except GitFailed as exc: + print(f"ERROR: {exc}. Nothing was restored past this point.", file=sys.stderr) + return 2 if args.json: print(json.dumps(report.as_dict(), indent=2)) else: diff --git a/tests/test_autorun.py b/tests/test_autorun.py index c8c04e0ad..ad15f7421 100644 --- a/tests/test_autorun.py +++ b/tests/test_autorun.py @@ -891,6 +891,16 @@ class BiosIntegrity(Scratch): self.assertEqual([(f.path, f.verdict) for f in report.findings], [(rel, bib.SKIPPED)]) self.assertEqual((self.repo / rel).read_bytes(), b"\x02" * 80) + def test_an_unreadable_index_stops_before_any_restore(self): + """git status failed on a corrupt index, its empty stdout read as + "unmodified", and --apply wrote HEAD's bytes over the session's.""" + rel = "bios/Sony/edited.bin" + (self.repo / rel).write_bytes(b"\x02" * 80) + (self.repo / ".git" / "index").write_bytes(b"garbage\n") + with self.assertRaises(bib.GitFailed): + bib.check(self.repo, self.db, apply=True) + self.assertEqual((self.repo / rel).read_bytes(), b"\x02" * 80) + def test_a_mismatch_the_second_read_does_not_confirm_is_a_misread(self): reads = {} expected = {e["path"]: e["sha1"] for e in self.db["files"].values()}