diff --git a/scripts/verify.py b/scripts/verify.py index 93d62fec..7853cad2 100644 --- a/scripts/verify.py +++ b/scripts/verify.py @@ -189,6 +189,17 @@ def verify_entry_md5( } if not md5_list: + if resolve_status == "hash_mismatch": + # No md5 to compare does not mean nothing was compared: the entry + # declares a sha1 or a crc32 the local file contradicts, and the + # builder drops it for exactly that. Reporting OK here said the + # collection holds bytes it does not. + return { + **base, + "status": Status.UNTESTED, + "path": local_path, + "reason": "declared hash contradicted by the local file", + } return {**base, "status": Status.OK, "path": local_path} if resolve_status == "md5_exact": diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index 56206114..9f3faf24 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -899,6 +899,37 @@ class ArchiveSecurityRegressions(unittest.TestCase): ) +class NoMd5IsNotNothingChecked(unittest.TestCase): + """A declared hash that is not an md5 still contradicts. + + verify_entry_md5 returned OK the moment the entry declared no md5, so an + entry whose sha256 the local file contradicts read as covered while the + builder was already excluding it. RetroDECK's dsifirmware.bin declares a + sha256 and no md5. + """ + + def setUp(self): + import verify + + self.verify = verify + + def _entry(self): + return {"name": "dsifirmware.bin", "sha256": "b" * 64} + + def test_a_contradicted_sha256_is_not_reported_ok(self): + result = self.verify.verify_entry_md5( + self._entry(), "bios/whatever.bin", "hash_mismatch" + ) + self.assertNotEqual(result["status"], self.verify.Status.OK) + self.assertIn("contradicted", result.get("reason", "")) + + def test_a_clean_resolution_is_still_ok(self): + result = self.verify.verify_entry_md5( + self._entry(), "bios/whatever.bin", "sha256_exact" + ) + self.assertEqual(result["status"], self.verify.Status.OK) + + class InstallerBoundaryRegressions(unittest.TestCase): def _manifest(self, dest: str) -> dict: return {