fix: read the database size of a declared hash

A platform declaration that names only an md5 left the size check
undecided, and an undecided same-named match overrode a profile's
system:. The size the database holds for that md5 now refutes it: clk's
Oric basic10.rom no longer joins Batocera's BK list.
This commit is contained in:
Abdessamad Derraz committed 2026-11-05 11:44:40 +01:00
1 parent a434c1a8a0
commit f69bd7cbd5
2 files changed
+34 -5

No files matched your search

+14 -5
View File
@@ -508,14 +508,19 @@ def _sizes_clash(a: dict, b: dict) -> bool:
return False
def _identity_values(entry: dict, db: dict | None) -> set[str]:
"""Every hash an entry declares, with the siblings the database knows."""
def _identity(entry: dict, db: dict | None) -> dict:
"""The entry with the hashes and size the database knows for its hash."""
probe = {k: entry[k] for k in ("sha1", "md5", "crc32", "size") if entry.get(k)}
if db and probe and not any(isinstance(v, list) for v in probe.values()):
_enrich_hashes(probe, db)
return {**entry, **{k: v for k, v in probe.items() if not entry.get(k)}}
def _identity_values(entry: dict) -> set[str]:
"""Every hash an identity declares."""
values: set[str] = set()
for field in ("sha1", "md5", "sha256", "crc32"):
values |= _declared(entry, field) | _declared(probe, field)
values |= _declared(entry, field)
return values
@@ -525,10 +530,14 @@ def _declaration_verdict(entry: dict, declaration: dict, db: dict | None) -> str
A shared hash proves it. Sizes no value of which agrees refute it, as
name_match_size_ok refutes a candidate. Two hashes at one size are two
revisions of one slot, as slots.py reads them, so they refute nothing.
The size the database holds for a declared hash counts as declared:
Batocera's BK BASIC10.ROM names only an md5, of a 24576-byte file, and
clk's 16 KB Oric basic10.rom was filed under the BK beside it.
"""
if _identity_values(entry, db) & _identity_values(declaration, db):
ours, theirs = _identity(entry, db), _identity(declaration, db)
if _identity_values(ours) & _identity_values(theirs):
return "same"
if _sizes_clash(entry, declaration):
if _sizes_clash(ours, theirs):
return "other"
return "undecided"
+20
View File
@@ -454,6 +454,26 @@ class TheModelIsAFunctionOfItsInputs(unittest.TestCase):
)
class DatabaseSizeRefutesASameNamedDeclaration(unittest.TestCase):
"""Batocera's BK system declares BASIC10.ROM by md5 alone. clk's Oric
basic10.rom, 16 KB with its own system:, was filed under the BK and
added to its list: the 24576 bytes the database holds for that md5
were never compared."""
def test_the_size_behind_a_declared_hash_counts(self):
bk_md5, oric_md5 = "3" * 32, "e" * 32
db = {"files": {"1" * 40: {"sha1": "1" * 40, "md5": bk_md5, "size": 24576}},
"indexes": {"by_md5": {bk_md5: "1" * 40}}}
profiles = {"clk": {"emulator": "clk", "type": "libretro", "systems": ["oric"],
"files": [{"name": "basic10.rom", "path": "Oric/basic10.rom",
"system": "oric", "size": 16384, "md5": oric_md5}]}}
config = {"cores": ["clk"], "systems": {"elektronika-bk": {"files": [
{"name": "BASIC10.ROM", "md5": bk_md5}]}}}
truth = generate_platform_truth("p", config, {}, profiles, db=db)
self.assertNotIn("basic10.rom", {
f["name"] for f in truth["systems"].get("elektronika-bk", {}).get("files", [])})
class RegionFollowsEveryReader(unittest.TestCase):
"""The first core to tag a file set its region in the truth: the ST-V
BIOS kept beetle_saturn's Americas and lost mednafen_stv's Korea, and