mirror of
https://github.com/rommapp/romm.git
synced 2026-02-18 23:42:07 +01:00
[ROMM-2552] Rom hashes should only include top-level nested files
This commit is contained in:
@@ -330,16 +330,29 @@ class FSRomsHandler(FSHandler):
|
||||
):
|
||||
continue
|
||||
|
||||
# Check if this is a top-level file (not in a subdirectory)
|
||||
is_top_level = f_path.samefile(Path(abs_fs_path, rom.fs_name))
|
||||
|
||||
if hashable_platform:
|
||||
try:
|
||||
crc_c, rom_crc_c, md5_h, rom_md5_h, sha1_h, rom_sha1_h = (
|
||||
self._calculate_rom_hashes(
|
||||
Path(f_path, file_name),
|
||||
rom_crc_c,
|
||||
rom_md5_h,
|
||||
rom_sha1_h,
|
||||
if is_top_level:
|
||||
# Include this file in the main ROM hash calculation
|
||||
crc_c, rom_crc_c, md5_h, rom_md5_h, sha1_h, rom_sha1_h = (
|
||||
self._calculate_rom_hashes(
|
||||
Path(f_path, file_name),
|
||||
rom_crc_c,
|
||||
rom_md5_h,
|
||||
rom_sha1_h,
|
||||
)
|
||||
)
|
||||
else:
|
||||
# Calculate individual file hash only
|
||||
crc_c, _, md5_h, _, sha1_h, _ = self._calculate_rom_hashes(
|
||||
Path(f_path, file_name),
|
||||
0,
|
||||
hashlib.md5(usedforsecurity=False),
|
||||
hashlib.sha1(usedforsecurity=False),
|
||||
)
|
||||
)
|
||||
except zlib.error:
|
||||
crc_c = 0
|
||||
md5_h = hashlib.md5(usedforsecurity=False)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
00000000
|
||||
@@ -0,0 +1 @@
|
||||
11111111
|
||||
@@ -46,6 +46,28 @@ class TestFSRomsHandler:
|
||||
full_path="n64/roms/Paper Mario (USA).z64",
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def rom_single_nested(self, platform: Platform):
|
||||
return Rom(
|
||||
id=3,
|
||||
fs_name="Sonic (EU) [T]",
|
||||
fs_path="n64/roms",
|
||||
platform=platform,
|
||||
full_path="n64/roms/Sonic (EU) [T]",
|
||||
files=[
|
||||
RomFile(
|
||||
id=1,
|
||||
file_name="Sonic (EU) [T].n64",
|
||||
file_path="n64/roms",
|
||||
),
|
||||
RomFile(
|
||||
id=2,
|
||||
file_name="Sonic (EU) [T-En].z64",
|
||||
file_path="n64/roms/translation",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def rom_multi(self, platform: Platform):
|
||||
return Rom(
|
||||
@@ -555,3 +577,47 @@ class TestFSRomsHandler:
|
||||
async with await handler.stream_file("psx/roms/PaRappa the Rapper.zip") as f:
|
||||
content = await f.read()
|
||||
assert len(content) > 0
|
||||
|
||||
async def test_top_level_files_only_in_main_hash(
|
||||
self, handler: FSRomsHandler, rom_single_nested
|
||||
):
|
||||
"""Test that only top-level files contribute to main ROM hash calculation"""
|
||||
rom_files, rom_crc, rom_md5, rom_sha1, rom_ra = await handler.get_rom_files(
|
||||
rom_single_nested
|
||||
)
|
||||
|
||||
# Verify we have multiple files (base game + translation)
|
||||
assert len(rom_files) == 2
|
||||
|
||||
base_game_rom_file = None
|
||||
translation_rom_file = None
|
||||
|
||||
for rom_file in rom_files:
|
||||
if rom_file.file_name == "Sonic (EU) [T].n64":
|
||||
base_game_rom_file = rom_file
|
||||
elif rom_file.file_name == "Sonic (EU) [T-En].z64":
|
||||
translation_rom_file = rom_file
|
||||
|
||||
assert base_game_rom_file is not None, "Base game file not found"
|
||||
assert translation_rom_file is not None, "Translation file not found"
|
||||
|
||||
# Verify file categories
|
||||
assert base_game_rom_file.category is None
|
||||
assert translation_rom_file.category == RomFileCategory.TRANSLATION
|
||||
|
||||
# The main ROM hash should be different from the translation file hash
|
||||
# (this verifies that the translation is not included in the main hash)
|
||||
|
||||
assert (
|
||||
rom_md5 == base_game_rom_file.md5_hash
|
||||
), "Main ROM hash should include base game file"
|
||||
assert (
|
||||
rom_md5 != translation_rom_file.md5_hash
|
||||
), "Main ROM hash should not include translation file"
|
||||
|
||||
assert (
|
||||
rom_sha1 == base_game_rom_file.sha1_hash
|
||||
), "Main ROM hash should include base game file"
|
||||
assert (
|
||||
rom_sha1 != translation_rom_file.sha1_hash
|
||||
), "Main ROM hash should not include translation file"
|
||||
|
||||
Reference in New Issue
Block a user