fix: check a recalbox zip by its composite only

Bios::Scan takes Zip::Md5Composite for every .zip (Bios.cpp:64-68). The resolver already honoured zip_digest: composite, but digest_verdict accepted the container's own md5 first, so the pack check passed bytes Recalbox marks red. The page described that order.
This commit is contained in:
Abdessamad Derraz committed 2026-10-21 09:57:06 +02:00
1 parent d8e9ad23d3
commit f997bdc81a
4 files changed
+52 -4

No files matched your search

+24
View File
@@ -1206,6 +1206,30 @@ class OneBaselineVerdict(unittest.TestCase):
("frontend_digest_exact", None),
)
def test_a_composite_only_archive_ignores_its_raw_md5(self):
"""Recalbox hashes a .zip by its members (Bios.cpp:64-68), and the
pack check accepted the container's own md5 before the composite:
neocd.bin shipped as neocdz.zip passed while Recalbox marks it red."""
import hashlib
from scripts.common import md5_composite
from scripts.validation import digest_verdict
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as directory:
archive = self._archive(Path(directory), "rom.bin")
raw = hashlib.md5(Path(archive).read_bytes()).hexdigest()
members = md5_composite(archive)
for declared, accepted in ((raw, False), (members, True)):
entry = {"name": "dragon32.zip", "md5": declared, "zip_digest": "composite"}
with self.subTest(declared=declared):
self.assertIs(
digest_verdict(entry, 0, lambda: {"md5": raw}, "md5", "",
lambda: members),
accepted,
)
plain = {"name": "dragon32.zip", "md5": raw}
self.assertTrue(digest_verdict(plain, 0, lambda: {"md5": raw}, "md5"))
def test_a_release_asset_keeps_its_answer(self):
from scripts.slots import apply_override
+12
View File
@@ -322,6 +322,18 @@ class Md5CompositeDefinition(unittest.TestCase):
self.assertIn("contents of every member", section)
self.assertNotIn("inner file MD5s", section)
def test_composite_only_is_read_by_both_checks(self):
"""The page said the direct MD5 is tried before the composite, which
Recalbox never does for a .zip, and the pack check did the same."""
import common
import validation
section = _section(_page("verification-modes.md"), "md5_composite (Recalbox ZIP verification)")
self.assertIn("zip_digest: composite", section)
self.assertNotIn("is tried before reporting a mismatch", section)
for function in (common.resolve_local_file, validation.digest_verdict):
self.assertIn('get("zip_digest") == "composite"', inspect.getsource(function))
class ValidationIndexScope(unittest.TestCase):
"""The page said the index reads every profile. verify and the builder