From 260ac4ee86aa3990c1bf294d9d1f7eb0b11caff6 Mon Sep 17 00:00:00 2001 From: Sev Date: Mon, 21 Sep 2026 11:25:53 +0700 Subject: [PATCH] zipio: CRC fallback accepts a file longer than the first load chunk nc_zipset_read's second pass matched by CRC only when the member's size equalled expect_len. expect_len is the FIRST load's length, so a file loaded as LOAD + CONTINUE (mslug 201-p1: 2 MB in two 1 MB chunks) could never match by CRC. A MAME 0.139-era set whose 201-p1.bin is byte-identical to 201-p1.p1 was refused as 'missing ROM' by name, then by size. With >=, mslug, samsho2 and viewpoin from a 0.139 dump convert; the output is byte-identical to a conversion from a modern-named set (sha256, 6/6). --- src/zipio.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/zipio.c b/src/zipio.c index d23e12b..bdffaf0 100644 --- a/src/zipio.c +++ b/src/zipio.c @@ -106,8 +106,13 @@ uint8_t *nc_zipset_read(nc_zipset *zs, const char *name, uint32_t crc, mz_zip_archive_file_stat st; if (!mz_zip_reader_file_stat(za, i, &st)) continue; + /* >=, not ==: expect_len is the FIRST load chunk, and a file + * loaded as LOAD + CONTINUE (mslug 201-p1, 2 MB in two 1 MB + * chunks) is longer than it. Under == the CRC pass could never + * match a renamed multi-chunk file, so a MAME 0.139 set whose + * 201-p1.bin is byte-identical to 201-p1.p1 was "missing". */ if ((uint32_t)st.m_crc32 == crc && - (size_t)st.m_uncomp_size == expect_len) + (size_t)st.m_uncomp_size >= expect_len) return extract(za, i, out_len, out_crc); } }