From df40740ae033b014ebc2a080d5e3fc21326ce117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 20 Oct 2026 10:55:13 +0200 Subject: [PATCH] ZipFileReader: Lock the archive when looking up a file Texture replacement looks up files from several IO threads at once, while another thread may be reading from the same archive. libzip isn't thread safe, and a name lookup writes to the archive: it caches each name's guessed encoding, and allocates a converted copy of CP437 names. Co-Authored-By: Claude Opus 5.5 (1M context) --- Common/File/VFS/ZipFileReader.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Common/File/VFS/ZipFileReader.cpp b/Common/File/VFS/ZipFileReader.cpp index d9dcf4a84c..595083f0f3 100644 --- a/Common/File/VFS/ZipFileReader.cpp +++ b/Common/File/VFS/ZipFileReader.cpp @@ -351,6 +351,9 @@ public: VFSFileReference *ZipFileReader::GetFile(std::string_view path) { std::string p(path); + // Texture replacement looks up files from several threads. libzip isn't thread safe, and the lookup + // writes to the archive (it caches each name's encoding, and a converted copy for CP437 names). + std::lock_guard guard(lock_); // An exact match uses libzip's hash table, the case insensitive one compares every name in the zip. int zi = zip_name_locate(zip_file_, p.c_str(), 0); if (zi < 0) {