fix: let a primary beat its variant across casing

Only a .variants/ copy matched IPLROM.X1 exactly, so x1 got
Recalbox's second md5 while iplrom.x1, the dump every platform
pins, sat beside it. When every exact-case match is a variant, a
primary in the same directory under its own name joins the
candidates. Another machine's font.rom or an alias pointing at a
different file does not.
This commit is contained in:
Abdessamad Derraz committed 2026-10-18 02:36:12 +02:00
1 parent fd6ae1f5c9
commit 1101c7640b
2 files changed
+81 -3

No files matched your search

+26 -3
View File
@@ -1269,11 +1269,34 @@ def resolve_local_file(
path = files_db[match_sha1]["path"]
if os.path.exists(path) and path not in candidates:
candidates.append(path)
if candidates and all("/.variants/" in p for p in candidates):
# Only variants answer the exact casing, but the primary they
# stand in for may be stored under another one: x1 asked for
# IPLROM.X1 and got Recalbox's second md5 while iplrom.x1, the
# dump every platform pins, sat in the same directory. A primary
# counts here only in a variant's own directory and under its own
# file name: an alias (iplrom.x1t names a font in System.dat) or
# another machine's font.rom is not that file.
homes = {p.split("/.variants/", 1)[0] for p in candidates}
folded = _casefold_name_index(by_name)
for try_name in names_to_try:
wanted = try_name.rsplit("/", 1)[-1].casefold()
for match_sha1 in folded.get(try_name.casefold(), []):
path = files_db.get(match_sha1, {}).get("path", "")
if (
"/.variants/" not in path
and os.path.dirname(path) in homes
and os.path.basename(path).casefold() == wanted
and _size_ok(match_sha1)
and os.path.exists(path)
and path not in candidates
):
candidates.append(path)
if not candidates:
# Case-insensitive fallback: upstream platforms disagree on
# casing (VEC_MineStorm.vec vs VEC_Minestorm.vec). Safe by
# invariant: dedup keeps a single casing per content, so a
# casefold match cannot pick a different file.
# casing (VEC_MineStorm.vec vs VEC_Minestorm.vec). Two casings
# can name two contents (FONT.ROM and font.rom), so this only
# runs when no casing matches exactly.
folded = _casefold_name_index(by_name)
for try_name in names_to_try:
for match_sha1 in folded.get(try_name.casefold(), []):
+55
View File
@@ -26,5 +26,60 @@ class CasefoldIndexFollowsItsSource(unittest.TestCase):
self.assertIn("b.bin", _casefold_name_index(index))
class APrimaryUnderAnotherCasing(unittest.TestCase):
"""x1 asked for IPLROM.X1; only Recalbox's second md5 sat under that
casing, in .variants/, and it won over iplrom.x1, the dump every
platform pins, in the same directory."""
def setUp(self):
import shutil # noqa: PLC0415
import tempfile # noqa: PLC0415
self.root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp"))
self.addCleanup(shutil.rmtree, self.root, True)
self.files: dict = {}
self.by_name: dict = {}
def _put(self, relative: str, data: bytes, indexed_as: str | None = None) -> None:
import hashlib # noqa: PLC0415
path = self.root / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(data)
sha1 = hashlib.sha1(data).hexdigest()
self.files[sha1] = {"path": str(path), "sha1": sha1, "size": len(data)}
name = indexed_as or path.name.split(".variants/")[-1]
if "/.variants/" in relative:
name = name.rsplit(".", 1)[0]
self.by_name.setdefault(name, []).append(sha1)
def _resolve(self, name: str) -> str:
from common import _casefold_index_cache, resolve_local_file # noqa: PLC0415
_casefold_index_cache.clear()
db = {"files": self.files, "indexes": {"by_name": self.by_name, "by_md5": {},
"by_path_suffix": {}, "by_crc32": {}}}
path, _status = resolve_local_file({"name": name}, db)
return str(Path(path).relative_to(self.root))
def test_the_primary_beside_the_variant_wins(self):
self._put("bios/Sharp/X1/iplrom.x1", b"pinned")
self._put("bios/Sharp/X1/.variants/IPLROM.X1.c4db9a6e", b"second md5")
self.assertEqual(self._resolve("IPLROM.X1"), "bios/Sharp/X1/iplrom.x1")
def test_another_machines_file_does_not(self):
self._put("bios/NEC/PC-88/font.rom", b"pc-88 font")
self._put("bios/NEC/PC-98/.variants/FONT.ROM.541271ea", b"pc-98 font")
self.assertEqual(self._resolve("FONT.ROM"),
"bios/NEC/PC-98/.variants/FONT.ROM.541271ea")
def test_an_alias_naming_another_file_does_not(self):
# System.dat pins a font's md5 under IPLROM.X1T.
self._put("bios/Sharp/X1/FNT0808.X1", b"font", indexed_as="iplrom.x1t")
self._put("bios/Sharp/X1/.variants/IPLROM.X1T.44620f57", b"turbo ipl")
self.assertEqual(self._resolve("IPLROM.X1T"),
"bios/Sharp/X1/.variants/IPLROM.X1T.44620f57")
if __name__ == "__main__":
unittest.main()