mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-11 20:43:50 -06:00
fix: read crc32 past a copier header in slots
Geargrafx drops a 512-byte header before its crc32 (src/media.cpp:754-773 at 7c447b0b), and its profile lists both sizes. slots compared the crc32 of the whole file, so EmuELEC's headered syscard3.pce read as contested.
This commit is contained in:
1 parent
6bf62d5746
commit
74a4a036ea
2 files changed
+64
No files matched your search
@@ -20,6 +20,7 @@ feeds the report this module prints.
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import zlib
|
||||
from dataclasses import dataclass, field
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
@@ -892,10 +893,37 @@ def _accepted_by_all(path: str, entries: list[dict], db: dict) -> bool:
|
||||
for field_name in ("md5", "sha1", "sha256", "crc32"):
|
||||
declared = _declared_hashes(entry, field_name)
|
||||
if declared and str(record.get(field_name, "")).lower() not in declared:
|
||||
if field_name == "crc32" and _headerless_crc32(path, record, entry) in declared:
|
||||
continue
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
COPIER_HEADER = 512
|
||||
|
||||
|
||||
def _headerless_crc32(path: str, record: dict, entry: dict) -> str | None:
|
||||
"""The crc32 of a file past its 512-byte copier header, when the entry
|
||||
declares both the file's size and the size without the header.
|
||||
|
||||
Geargrafx drops the header when the file is 512 bytes over the expected
|
||||
size and computes the crc32 on the rest (src/media.cpp:754-773). The
|
||||
profile lists both sizes. EmuELEC's headered syscard3.pce (crc32
|
||||
64f78e3c) is the 6d9a73ef image the profile names.
|
||||
"""
|
||||
sizes = entry.get("size")
|
||||
declared = sizes if isinstance(sizes, list) else [sizes]
|
||||
size = record.get("size")
|
||||
if not isinstance(size, int) or not {size, size - COPIER_HEADER} <= set(declared):
|
||||
return None
|
||||
try:
|
||||
with open(path, "rb") as f:
|
||||
f.seek(COPIER_HEADER)
|
||||
return f"{zlib.crc32(f.read()):08x}"
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
|
||||
def _same_file_family(paths: list[str]) -> bool:
|
||||
"""Whether the paths are one file and its own pinned variants.
|
||||
|
||||
|
||||
Reference in new issue
Block a user