mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-23 20:29:06 -05:00
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:
1 parent
d8e9ad23d3
commit
f997bdc81a
4 files changed
+52
-4
No files matched your search
@@ -793,7 +793,12 @@ def digest_verdict(
|
||||
actual = hashes()[algorithm].lower()
|
||||
if algorithm != "md5":
|
||||
return actual in declared
|
||||
if any(actual == d or (len(d) < 32 and actual.startswith(d)) for d in declared):
|
||||
# Recalbox hashes a .zip by its members only (Bios.cpp:64-68), so the
|
||||
# container's own md5 answers nothing there.
|
||||
composite_only = file_entry.get("zip_digest") == "composite"
|
||||
if not composite_only and any(
|
||||
actual == d or (len(d) < 32 and actual.startswith(d)) for d in declared
|
||||
):
|
||||
return True
|
||||
member_digest = composite()
|
||||
return bool(member_digest) and member_digest.lower() in declared
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -60,9 +60,16 @@ characters by prefix, and only for a file whose name the entry also names.
|
||||
|
||||
Recalbox hashes a ZIP with `Zip::Md5Composite` (`es-core/src/utils/Zip.cpp:71-96` in
|
||||
recalbox-emulationstation at `f4cd0ae4`): one MD5 over the contents of every member,
|
||||
read in filename order. The members' own MD5s are not involved. `verify.py` computes
|
||||
the same value with `md5_composite()` (`scripts/hashing.py`). When a ZIP file's direct
|
||||
MD5 does not match, the composite is tried before reporting a mismatch.
|
||||
read in filename order. The members' own MD5s are not involved, and neither is the
|
||||
MD5 of the ZIP file itself: `Bios::Scan` takes the composite for every `.zip`
|
||||
(`es-app/src/bios/Bios.cpp:64-68`). `verify.py` computes the same value with
|
||||
`md5_composite()` (`scripts/hashing.py`).
|
||||
|
||||
The registry gives Recalbox `zip_digest: composite`. For a platform so marked, a
|
||||
`.zip` entry is checked against its composite alone, by the resolver
|
||||
(`resolve_local_file`) and by the pack check (`digest_verdict` in
|
||||
`scripts/validation.py`). On other platforms the ZIP file's direct MD5 is tried first
|
||||
and the composite after it.
|
||||
|
||||
### Multi-hash (Recalbox)
|
||||
|
||||
|
||||
Reference in new issue
Block a user