mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
fix: resolve the region audit like the pack
This commit is contained in:
1 parent
45275811f0
commit
8a0c3b34ea
2 files changed
+49
-31
No files matched your search
+18
-20
@@ -19,7 +19,7 @@ from pathlib import Path
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
|
||||
import region
|
||||
from common import load_emulator_profiles, load_database, parse_md5_list
|
||||
from common import load_database, load_emulator_profiles, resolve_local_file
|
||||
|
||||
# No-Intro filename tokens: full English territory names.
|
||||
NOINTRO = {
|
||||
@@ -100,24 +100,21 @@ def catalog_regions(db: dict) -> dict[str, tuple[set[str], str]]:
|
||||
return out
|
||||
|
||||
|
||||
def resolve_sha1(file_entry: dict, db: dict) -> str | None:
|
||||
"""Resolve a profile file entry to a repo SHA1, or None when ambiguous."""
|
||||
files = db["files"]
|
||||
indexes = db["indexes"]
|
||||
raw_sha1 = file_entry.get("sha1")
|
||||
declared = raw_sha1 if isinstance(raw_sha1, list) else [raw_sha1]
|
||||
sha1_hits = [str(value).lower() for value in declared if value]
|
||||
sha1_hits = [value for value in sha1_hits if value in files]
|
||||
if len(sha1_hits) == 1:
|
||||
return sha1_hits[0]
|
||||
for md5 in parse_md5_list(file_entry.get("md5")):
|
||||
hit = indexes["by_md5"].get(md5)
|
||||
if hit:
|
||||
return hit
|
||||
hits = indexes["by_name"].get(file_entry.get("name", ""), [])
|
||||
if isinstance(hits, str):
|
||||
hits = [hits]
|
||||
return hits[0] if len(hits) == 1 else None
|
||||
def resolve_sha1(file_entry: dict, db: dict, by_path: dict | None = None) -> str | None:
|
||||
"""The repo SHA1 a profile entry resolves to, by the pack's own resolver.
|
||||
|
||||
A private resolver read sha1, then md5, then a lone name: entries that
|
||||
identify their file by path (Dolphin's three IPL.bin), by crc32
|
||||
(geargrafx) or by sha256 (mednafen) were never checked at all.
|
||||
"""
|
||||
if by_path is None:
|
||||
by_path = {entry.get("path", ""): sha1 for sha1, entry in db["files"].items()}
|
||||
path, status = resolve_local_file(
|
||||
file_entry, db, dest_hint=file_entry.get("path") or ""
|
||||
)
|
||||
if not path or status in ("not_found", "hash_mismatch"):
|
||||
return None
|
||||
return by_path.get(path)
|
||||
|
||||
|
||||
def build_report(profiles: dict, db: dict) -> dict:
|
||||
@@ -130,6 +127,7 @@ def build_report(profiles: dict, db: dict) -> dict:
|
||||
for slugs, _name in catalog.values():
|
||||
vocabulary.update(slugs)
|
||||
|
||||
by_path = {entry.get("path", ""): sha1 for sha1, entry in db["files"].items()}
|
||||
for emu_name, profile in sorted(profiles.items()):
|
||||
if profile.get("type") in ("launcher", "alias"):
|
||||
continue
|
||||
@@ -137,7 +135,7 @@ def build_report(profiles: dict, db: dict) -> dict:
|
||||
if not isinstance(f, dict) or not f.get("region"):
|
||||
continue
|
||||
declared = region.normalize_declared(f["region"])
|
||||
sha1 = resolve_sha1(f, db)
|
||||
sha1 = resolve_sha1(dict(f, source_profile=emu_name), db, by_path)
|
||||
if not sha1 or sha1 not in catalog:
|
||||
unchecked += 1
|
||||
continue
|
||||
|
||||
@@ -939,17 +939,37 @@ class RegionRegressions(unittest.TestCase):
|
||||
)
|
||||
self.assertNotEqual(north_america, europe)
|
||||
|
||||
def test_region_audit_accepts_list_valued_md5(self):
|
||||
sha1 = "a" * 40
|
||||
md5 = "b" * 32
|
||||
db = {
|
||||
"files": {sha1: {}},
|
||||
"indexes": {"by_md5": {md5: sha1}, "by_name": {}},
|
||||
}
|
||||
self.assertEqual(
|
||||
region_audit.resolve_sha1({"name": "bios.bin", "md5": [md5]}, db),
|
||||
sha1,
|
||||
)
|
||||
def test_region_audit_resolves_the_way_the_pack_does(self):
|
||||
"""A private resolver read sha1, md5 and a lone name: an entry
|
||||
identified by its path (Dolphin's three IPL.bin) was never checked."""
|
||||
import hashlib # noqa: PLC0415
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as directory:
|
||||
previous = os.getcwd()
|
||||
os.chdir(directory)
|
||||
self.addCleanup(os.chdir, previous)
|
||||
files, shas = {}, {}
|
||||
for rel, payload in (("bios/GC/USA/IPL.bin", b"usa"), ("bios/GC/JAP/IPL.bin", b"jap")):
|
||||
Path(rel).parent.mkdir(parents=True, exist_ok=True)
|
||||
Path(rel).write_bytes(payload)
|
||||
sha1 = hashlib.sha1(payload).hexdigest()
|
||||
shas[rel] = sha1
|
||||
files[sha1] = {"path": rel, "name": "IPL.bin", "size": len(payload), "sha1": sha1,
|
||||
"md5": hashlib.md5(payload).hexdigest(),
|
||||
"sha256": hashlib.sha256(payload).hexdigest(), "crc32": "00000001"}
|
||||
from scripts import generate_db # noqa: PLC0415
|
||||
|
||||
db = {"files": files, "indexes": generate_db.build_indexes(files, {})}
|
||||
by_md5 = {e["md5"]: s for s, e in files.items()}
|
||||
self.assertEqual(
|
||||
region_audit.resolve_sha1({"name": "IPL.bin", "md5": [files[shas["bios/GC/USA/IPL.bin"]]["md5"]]}, db),
|
||||
shas["bios/GC/USA/IPL.bin"],
|
||||
)
|
||||
self.assertEqual(
|
||||
region_audit.resolve_sha1({"name": "IPL.bin", "path": "GC/JAP/IPL.bin"}, db),
|
||||
shas["bios/GC/JAP/IPL.bin"],
|
||||
)
|
||||
self.assertTrue(by_md5)
|
||||
|
||||
|
||||
class ArchiveSecurityRegressions(unittest.TestCase):
|
||||
|
||||
Reference in new issue
Block a user