fix: the pack check applies the frontend's rule

The integrity step compared a member's md5 by hand and ignored hash_rule, so under RomM's rule (size, then any of md5, sha1 and crc32) it would refuse a revision the builder rightly shipped on its sha1. The rule now lives in digest_verdict, which the path check and the pack member check both call. The member's archive digest is computed without the path cache, whose key a buffer's reused address made collide.
This commit is contained in:
Abdessamad Derraz committed 2026-10-20 02:11:53 +02:00
1 parent 20b4ce37e6
commit ac47faf7f2
4 files changed
+111 -40

No files matched your search

+14 -4
View File
@@ -10,6 +10,7 @@ import os
import zipfile
import zlib
from pathlib import Path
from typing import BinaryIO
_ALL_ALGORITHMS = frozenset({"sha1", "md5", "sha256", "crc32", "adler32"})
@@ -102,7 +103,18 @@ def md5_composite(filepath: str | Path) -> str:
cached = _md5_composite_cache.get(key)
if cached is not None:
return cached
with zipfile.ZipFile(filepath) as zf:
result = md5_composite_of(filepath)
_md5_composite_cache[key] = result
return result
def md5_composite_of(source: str | Path | BinaryIO) -> str:
"""md5_composite without the cache, for an archive held in memory.
A buffer has no stable name: keyed by its repr, a later buffer at the
same address read back another archive's digest.
"""
with zipfile.ZipFile(source) as zf:
names = sorted(n for n in zf.namelist() if not n.endswith("/"))
h = hashlib.md5()
for name in names:
@@ -110,9 +122,7 @@ def md5_composite(filepath: str | Path) -> str:
if info.file_size > 512 * 1024 * 1024:
continue # skip oversized entries
h.update(zf.read(name))
result = h.hexdigest()
_md5_composite_cache[key] = result
return result
return h.hexdigest()
def parse_hash_list(raw: str | list | int | None) -> list[str]:
"""Normalize any hash field into its accepted values, lowercase.