minizip-ng: Stop using compatibility mode

This commit is contained in:
Joshua Vandaële 2025-02-25 11:12:08 +01:00
parent 6dd0793f1b
commit b8608a4ae5
No known key found for this signature in database
GPG key ID: 5E8F4E7EDBD390EA
10 changed files with 114 additions and 77 deletions

View file

@ -675,8 +675,8 @@ dolphin_find_optional_system_library_pkgconfig(ZSTD libzstd>=1.4.0 zstd::zstd Ex
add_subdirectory(Externals/zlib-ng)
dolphin_find_optional_system_library_pkgconfig(MINIZIP
"minizip>=4.0.4" minizip::minizip Externals/minizip-ng
dolphin_find_optional_system_library_pkgconfig(minizip-ng
"minizip-ng>=4.0.4" minizip-ng::minizip-ng Externals/minizip-ng
)
dolphin_find_optional_system_library(LZO Externals/LZO)

View file

@ -3,10 +3,10 @@ project(minizip C)
add_library(minizip STATIC
minizip-ng/mz.h
# minizip-ng/compat/crypt.h
minizip-ng/compat/ioapi.c
minizip-ng/compat/ioapi.h
minizip-ng/compat/unzip.c
minizip-ng/compat/unzip.h
# minizip-ng/compat/ioapi.c
# minizip-ng/compat/ioapi.h
# minizip-ng/compat/unzip.c
# minizip-ng/compat/unzip.h
# minizip-ng/compat/zip.c
# minizip-ng/compat/zip.h
minizip-ng/mz_crypt.c
@ -90,4 +90,4 @@ endif()
target_link_libraries(minizip PUBLIC ZLIB::ZLIB)
add_library(minizip::minizip ALIAS minizip)
add_library(minizip-ng::minizip-ng ALIAS minizip)

View file

@ -23,8 +23,6 @@
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="minizip-ng\compat\ioapi.c" />
<ClCompile Include="minizip-ng\compat\unzip.c" />
<ClCompile Include="minizip-ng\mz_crypt.c" />
<ClCompile Include="minizip-ng\mz_os.c" />
<ClCompile Include="minizip-ng\mz_os_win32.c" />
@ -39,8 +37,6 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="minizip-ng\mz.h" />
<ClCompile Include="minizip-ng\compat\ioapi.h" />
<ClCompile Include="minizip-ng\compat\unzip.h" />
<ClInclude Include="minizip-ng\mz_crypt.h" />
<ClInclude Include="minizip-ng\mz_os.h" />
<ClInclude Include="minizip-ng\mz_strm.h" />

View file

@ -172,7 +172,7 @@ PUBLIC
enet::enet
fmt::fmt
MbedTLS::mbedtls
minizip::minizip
minizip-ng::minizip-ng
sfml-network
PRIVATE

View file

@ -5,7 +5,9 @@
#include <algorithm>
#include <unzip.h>
#include <mz.h>
#include <mz_zip.h>
#include <mz_zip_rw.h>
#include "Common/CommonTypes.h"
#include "Common/ScopeGuard.h"
@ -13,14 +15,14 @@
namespace Common
{
// Reads all of the current file. destination must be big enough to fit the whole file.
inline bool ReadFileFromZip(unzFile file, u8* destination, u64 len)
inline bool ReadFileFromZip(void* zip_reader, u8* destination, u64 len)
{
const u64 MAX_BUFFER_SIZE = 65535;
if (unzOpenCurrentFile(file) != UNZ_OK)
if (mz_zip_reader_entry_open(zip_reader) != MZ_OK)
return false;
Common::ScopeGuard guard{[&] { unzCloseCurrentFile(file); }};
Common::ScopeGuard guard{[&] { mz_zip_reader_entry_close(zip_reader); }};
u64 bytes_to_go = len;
while (bytes_to_go > 0)
@ -28,7 +30,7 @@ inline bool ReadFileFromZip(unzFile file, u8* destination, u64 len)
// NOTE: multiples of 4G can't cause read_len == 0 && bytes_to_go > 0, as MAX_BUFFER_SIZE is
// small.
const u32 read_len = static_cast<u32>(std::min(bytes_to_go, MAX_BUFFER_SIZE));
const int rv = unzReadCurrentFile(file, destination, read_len);
const int rv = mz_zip_reader_entry_read(zip_reader, destination, read_len);
if (rv < 0)
return false;
@ -37,11 +39,11 @@ inline bool ReadFileFromZip(unzFile file, u8* destination, u64 len)
destination += bytes_read;
}
return unzEndOfFile(file) == 1;
return bytes_to_go == 0;
}
template <typename ContiguousContainer>
bool ReadFileFromZip(unzFile file, ContiguousContainer* destination)
bool ReadFileFromZip(void* file, ContiguousContainer* destination)
{
return ReadFileFromZip(file, reinterpret_cast<u8*>(destination->data()), destination->size());
}

View file

@ -12,6 +12,10 @@
#include <mgba/core/timing.h>
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gba/gba.h>
#include <mz.h>
#include <mz_strm.h>
#include <mz_zip.h>
#include <mz_zip_rw.h>
#include "AudioCommon/AudioCommon.h"
#include "Common/ChunkFile.h"
@ -88,21 +92,27 @@ static VFile* OpenROM_Archive(const char* path)
static VFile* OpenROM_Zip(const char* path)
{
VFile* vf{};
unzFile zip = unzOpen(path);
if (!zip)
void* zip_reader = nullptr;
zip_reader = mz_zip_reader_create();
if (!zip_reader)
return {};
Common::ScopeGuard file_guard{[&] { mz_zip_reader_delete(&zip_reader); }};
if (mz_zip_reader_open_file(zip_reader, path) != MZ_OK)
return nullptr;
do
{
unz_file_info info{};
if (unzGetCurrentFileInfo(zip, &info, nullptr, 0, nullptr, 0, nullptr, 0) != UNZ_OK ||
!info.uncompressed_size)
mz_zip_file* info;
if (mz_zip_reader_entry_get_info(zip_reader, &info) != MZ_OK || !info->uncompressed_size)
continue;
std::vector<u8> buffer(info.uncompressed_size);
if (!Common::ReadFileFromZip(zip, &buffer))
std::vector<u8> buffer(info->uncompressed_size);
if (!Common::ReadFileFromZip(zip_reader, &buffer))
continue;
vf = VFileMemChunk(buffer.data(), info.uncompressed_size);
vf = VFileMemChunk(buffer.data(), info->uncompressed_size);
if (mCoreIsCompatible(vf) == mPLATFORM_GBA)
{
vf->seek(vf, 0, SEEK_SET);
@ -111,8 +121,7 @@ static VFile* OpenROM_Zip(const char* path)
vf->close(vf);
vf = nullptr;
} while (unzGoToNextFile(zip) == UNZ_OK);
unzClose(zip);
} while (mz_zip_reader_goto_next_entry(zip_reader) != MZ_END_OF_LIST);
return vf;
}

View file

@ -75,7 +75,7 @@ PUBLIC
PRIVATE
fmt::fmt
minizip::minizip
minizip-ng::minizip-ng
pugixml
ZLIB::ZLIB
)

View file

@ -13,8 +13,11 @@
#include <unordered_set>
#include <mbedtls/md5.h>
#include <mz.h>
#include <mz_strm.h>
#include <mz_zip.h>
#include <mz_zip_rw.h>
#include <pugixml.hpp>
#include <unzip.h>
#include "Common/Align.h"
#include "Common/Assert.h"
@ -157,25 +160,29 @@ RedumpVerifier::DownloadStatus RedumpVerifier::DownloadDatfile(const std::string
std::vector<u8> RedumpVerifier::ReadDatfile(const std::string& system)
{
unzFile file = unzOpen(GetPathForSystem(system).c_str());
if (!file)
void* zip_reader = nullptr;
zip_reader = mz_zip_reader_create();
if (!zip_reader)
return {};
Common::ScopeGuard file_guard{[&] { unzClose(file); }};
Common::ScopeGuard file_guard{[&] { mz_zip_reader_delete(&zip_reader); }};
if (mz_zip_reader_open_file(zip_reader, GetPathForSystem(system).c_str()) != MZ_OK)
return {};
// Check that the zip file contains exactly one file
if (unzGoToFirstFile(file) != UNZ_OK)
if (mz_zip_reader_goto_first_entry(zip_reader) != MZ_OK)
return {};
if (unzGoToNextFile(file) != UNZ_END_OF_LIST_OF_FILE)
if (mz_zip_reader_goto_next_entry(zip_reader) != MZ_END_OF_LIST)
return {};
// Read the file
if (unzGoToFirstFile(file) != UNZ_OK)
if (mz_zip_reader_goto_first_entry(zip_reader) != MZ_OK)
return {};
unz_file_info file_info;
unzGetCurrentFileInfo(file, &file_info, nullptr, 0, nullptr, 0, nullptr, 0);
std::vector<u8> data(file_info.uncompressed_size);
if (!Common::ReadFileFromZip(file, &data))
mz_zip_file* file_info;
mz_zip_reader_entry_get_info(zip_reader, &file_info);
std::vector<u8> data(file_info->uncompressed_size);
if (!Common::ReadFileFromZip(zip_reader, data.data(), file_info->uncompressed_size))
return {};
return data;

View file

@ -28,7 +28,7 @@ PUBLIC
common
core
cpp-optparse
minizip::minizip
minizip-ng::minizip-ng
pugixml
PRIVATE

View file

@ -8,7 +8,9 @@
#include <mz.h>
#include <mz_os.h>
#include <unzip.h>
#include <mz_strm.h>
#include <mz_zip.h>
#include <mz_zip_rw.h>
#include "Common/CommonPaths.h"
#include "Common/Contains.h"
@ -28,34 +30,47 @@ constexpr char TEXTURE_PATH[] = HIRES_TEXTURES_DIR DIR_SEP;
ResourcePack::ResourcePack(const std::string& path) : m_path(path)
{
auto file = unzOpen(path.c_str());
Common::ScopeGuard file_guard{[&] { unzClose(file); }};
void* zip_reader = nullptr;
zip_reader = mz_zip_reader_create();
if (!zip_reader)
{
m_valid = false;
m_error = "Failed to create zip reader";
return;
}
if (file == nullptr)
Common::ScopeGuard file_guard{[&] { mz_zip_reader_delete(&zip_reader); }};
if (mz_zip_reader_open_file(zip_reader, path.c_str()) != MZ_OK)
{
m_valid = false;
m_error = "Failed to open resource pack";
return;
}
if (unzLocateFile(file, "manifest.json", 0) == UNZ_END_OF_LIST_OF_FILE)
if (mz_zip_reader_locate_entry(zip_reader, "manifest.json", 0) != MZ_OK)
{
m_valid = false;
m_error = "Resource pack is missing a manifest.";
return;
}
unz_file_info64 manifest_info{};
unzGetCurrentFileInfo64(file, &manifest_info, nullptr, 0, nullptr, 0, nullptr, 0);
mz_zip_file* manifest_info;
if (mz_zip_reader_entry_get_info(zip_reader, &manifest_info) != MZ_OK)
{
m_valid = false;
m_error = "Failed to get manifest info";
return;
}
std::string manifest_contents(manifest_info.uncompressed_size, '\0');
if (!Common::ReadFileFromZip(file, &manifest_contents))
std::string manifest_contents(manifest_info->uncompressed_size, '\0');
if (!Common::ReadFileFromZip(zip_reader, &manifest_contents))
{
m_valid = false;
m_error = "Failed to read manifest.json";
return;
}
unzCloseCurrentFile(file);
mz_zip_reader_entry_close(zip_reader);
m_manifest = std::make_shared<Manifest>(manifest_contents);
if (!m_manifest->IsValid())
@ -65,14 +80,14 @@ ResourcePack::ResourcePack(const std::string& path) : m_path(path)
return;
}
if (unzLocateFile(file, "logo.png", 0) != UNZ_END_OF_LIST_OF_FILE)
if (mz_zip_reader_locate_entry(zip_reader, "logo.png", 0) == MZ_OK)
{
unz_file_info64 logo_info{};
unzGetCurrentFileInfo64(file, &logo_info, nullptr, 0, nullptr, 0, nullptr, 0);
mz_zip_file* logo_info;
mz_zip_reader_entry_get_info(zip_reader, &logo_info);
m_logo_data.resize(logo_info.uncompressed_size);
m_logo_data.resize(logo_info->uncompressed_size);
if (!Common::ReadFileFromZip(file, &m_logo_data))
if (!Common::ReadFileFromZip(zip_reader, &m_logo_data))
{
m_valid = false;
m_error = "Failed to read logo.png";
@ -80,21 +95,20 @@ ResourcePack::ResourcePack(const std::string& path) : m_path(path)
}
}
unzGoToFirstFile(file);
mz_zip_reader_goto_first_entry(zip_reader);
do
{
std::string filename(256, '\0');
unz_file_info64 texture_info{};
unzGetCurrentFileInfo64(file, &texture_info, filename.data(), static_cast<u16>(filename.size()),
nullptr, 0, nullptr, 0);
mz_zip_file* texture_info;
mz_zip_reader_entry_get_info(zip_reader, &texture_info);
if (!filename.starts_with("textures/") || texture_info.uncompressed_size == 0)
if (!filename.starts_with("textures/") || texture_info->uncompressed_size == 0)
continue;
// If a texture is compressed and the manifest doesn't state that, abort.
if (!m_manifest->IsCompressed() && texture_info.compression_method != 0)
if (!m_manifest->IsCompressed() && texture_info->compression_method != 0)
{
m_valid = false;
m_error = "Texture " + filename + " is compressed!";
@ -102,7 +116,7 @@ ResourcePack::ResourcePack(const std::string& path) : m_path(path)
}
m_textures.push_back(filename.substr(9));
} while (unzGoToNextFile(file) != UNZ_END_OF_LIST_OF_FILE);
} while (mz_zip_reader_goto_next_entry(zip_reader) != MZ_END_OF_LIST);
}
bool ResourcePack::IsValid() const
@ -143,29 +157,36 @@ bool ResourcePack::Install(const std::string& path)
return false;
}
auto file = unzOpen(m_path.c_str());
if (file == nullptr)
void* zip_reader = nullptr;
zip_reader = mz_zip_reader_create();
if (!zip_reader)
{
m_valid = false;
m_error = "Failed to read zip reader";
return false;
}
Common::ScopeGuard file_guard{[&] { mz_zip_reader_delete(&zip_reader); }};
if (mz_zip_reader_open_file(zip_reader, m_path.c_str()) != MZ_OK)
{
m_valid = false;
m_error = "Failed to open resource pack";
return false;
}
Common::ScopeGuard file_guard{[&] { unzClose(file); }};
if (unzGoToFirstFile(file) != MZ_OK)
if (mz_zip_reader_goto_first_entry(zip_reader) != MZ_OK)
return false;
std::string texture_zip_path;
do
{
texture_zip_path.resize(UINT16_MAX + 1, '\0');
unz_file_info64 texture_info{};
if (unzGetCurrentFileInfo64(file, &texture_info, texture_zip_path.data(), UINT16_MAX, nullptr,
0, nullptr, 0) != MZ_OK)
mz_zip_file* texture_info{};
if (mz_zip_reader_entry_get_info(zip_reader, &texture_info) != MZ_OK)
{
return false;
}
TruncateToCString(&texture_zip_path);
const std::string texture_zip_path = texture_info->filename;
const std::string texture_zip_path_prefix = "textures/";
if (!texture_zip_path.starts_with(texture_zip_path_prefix))
@ -203,14 +224,15 @@ bool ResourcePack::Install(const std::string& path)
return false;
}
const size_t data_size = static_cast<size_t>(texture_info.uncompressed_size);
const size_t data_size = static_cast<size_t>(texture_info->uncompressed_size);
auto data = std::make_unique<u8[]>(data_size);
if (!Common::ReadFileFromZip(file, data.get(), data_size))
if (!Common::ReadFileFromZip(zip_reader, data.get(), data_size))
{
m_error = "Failed to read texture " + texture;
return false;
}
mz_zip_reader_entry_close(zip_reader);
File::IOFile out(texture_path, "wb");
if (!out)
{
@ -222,7 +244,8 @@ bool ResourcePack::Install(const std::string& path)
m_error = "Failed to write " + texture;
return false;
}
} while (unzGoToNextFile(file) == MZ_OK);
} while (mz_zip_reader_goto_next_entry(zip_reader) == MZ_OK);
SetInstalled(*this, true);
return true;