mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-17 17:03:27 -05:00
fix: key the zip member index on all its inputs
This commit is contained in:
1 parent
d1807af791
commit
53625156d6
2 files changed
+31
-2
No files matched your search
+8
-2
@@ -57,7 +57,7 @@ def zip_member_crcs(path: str) -> frozenset[str]:
|
||||
return _member_crcs(path, mtime)
|
||||
|
||||
|
||||
_zip_contents_cache: tuple[frozenset[tuple[str, float]], dict] | None = None
|
||||
_zip_contents_cache: tuple[tuple, dict] | None = None
|
||||
|
||||
def build_zip_contents_index(db: dict, max_entry_size: int = 512 * 1024 * 1024) -> dict:
|
||||
"""Build {inner_rom_md5: zip_file_sha1} for ROMs inside ZIP files.
|
||||
@@ -74,7 +74,13 @@ def build_zip_contents_index(db: dict, max_entry_size: int = 512 * 1024 * 1024)
|
||||
if path.endswith(".zip") and os.path.exists(path):
|
||||
zip_entries.append((path, sha1))
|
||||
|
||||
fingerprint = frozenset((path, os.path.getmtime(path)) for path, _ in zip_entries)
|
||||
# The bound and the sha1 each path carries are part of the answer: a
|
||||
# second call with a smaller bound got members the first one admitted,
|
||||
# and a regenerated database got the sha1 of the old one.
|
||||
fingerprint = (
|
||||
max_entry_size,
|
||||
frozenset((path, os.path.getmtime(path), sha1) for path, sha1 in zip_entries),
|
||||
)
|
||||
if _zip_contents_cache is not None and _zip_contents_cache[0] == fingerprint:
|
||||
return _zip_contents_cache[1]
|
||||
|
||||
|
||||
@@ -2448,6 +2448,29 @@ class AnUnreadableDatabaseStopsTheScan(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class TheZipIndexCacheKnowsItsInputs(unittest.TestCase):
|
||||
"""build_zip_contents_index cached on (path, mtime) alone: a smaller
|
||||
max_entry_size, or a database giving the same archive another sha1,
|
||||
got the first call's index back."""
|
||||
|
||||
def test_the_bound_and_the_sha1_are_part_of_the_key(self):
|
||||
from scripts import ziptools
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as directory:
|
||||
path = Path(directory) / "a.zip"
|
||||
with zipfile.ZipFile(path, "w") as archive:
|
||||
archive.writestr("big.bin", b"x" * 4096)
|
||||
ziptools._zip_contents_cache = None
|
||||
db = {"files": {"a" * 40: {"path": str(path)}}}
|
||||
self.assertEqual(len(ziptools.build_zip_contents_index(db)), 1)
|
||||
self.assertEqual(ziptools.build_zip_contents_index(db, max_entry_size=10), {})
|
||||
other = {"files": {"b" * 40: {"path": str(path)}}}
|
||||
self.assertEqual(
|
||||
set(ziptools.build_zip_contents_index(other).values()), {"b" * 40}
|
||||
)
|
||||
ziptools._zip_contents_cache = None
|
||||
|
||||
|
||||
class TheDatabaseCacheIsWrittenWhole(unittest.TestCase):
|
||||
"""A crash while serializing left a truncated db_cache.json behind, and
|
||||
the next run rehashed the whole collection from scratch."""
|
||||
|
||||
Reference in new issue
Block a user