windows: use utf8 internally. Support latin2, cyrillic, etc. pathnames

upgrade libzip to 1.7
imgui: use all glyphs from font including latin2, cyrillic, greek, etc.
This commit is contained in:
flyinghead 2021-01-19 11:11:01 +01:00
parent 0c62231b54
commit 16dec49e08
603 changed files with 67820 additions and 5638 deletions

View File

@ -171,6 +171,15 @@ else()
add_subdirectory(core/deps/zlib)
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/core/deps/zlib" "${CMAKE_CURRENT_BINARY_DIR}/core/deps/zlib")
target_link_libraries(${PROJECT_NAME} PRIVATE zlibstatic)
# help libzip find the package
set(ZLIB_FOUND TRUE)
if(MSVC)
# FIXME
set(ZLIB_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/core/deps/zlib/Release/zlibstatic.lib")
else()
set(ZLIB_LIBRARY "libzlibstatic.a")
endif()
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/core/deps/zlib" "${CMAKE_CURRENT_BINARY_DIR}/core/deps/zlib")
endif()
find_package(PkgConfig QUIET)
@ -288,6 +297,8 @@ target_sources(${PROJECT_NAME} PRIVATE
core/deps/crypto/sha256.cpp
core/deps/crypto/sha256.h)
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/nowide/include)
if(NOT FLAC_FOUND)
target_compile_definitions(${PROJECT_NAME} PRIVATE HAVE_CONFIG_H $<$<BOOL:MINGW>:HAVE_FSEEKO>)
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/flac/include core/deps/flac/src/libFLAC/include)
@ -325,9 +336,31 @@ if(NOT MINIUPNP_FOUND)
target_link_libraries(${PROJECT_NAME} PRIVATE miniupnpc::miniupnpc)
endif()
if(MSVC)
if(NOT LIBZIP_FOUND)
option(ENABLE_COMMONCRYPTO "Enable use of CommonCrypto" OFF)
option(ENABLE_GNUTLS "Enable use of GnuTLS" OFF)
option(ENABLE_MBEDTLS "Enable use of mbed TLS" OFF)
option(ENABLE_OPENSSL "Enable use of OpenSSL" OFF)
option(ENABLE_WINDOWS_CRYPTO "Enable use of Windows cryptography libraries" OFF)
option(ENABLE_BZIP2 "Enable use of BZip2" OFF)
option(ENABLE_LZMA "Enable use of LZMA" OFF)
option(ENABLE_ZSTD "Enable use of Zstandard" OFF)
option(BUILD_TOOLS "Build tools in the src directory (zipcmp, zipmerge, ziptool)" OFF)
option(BUILD_REGRESS "Build regression tests" OFF)
option(BUILD_EXAMPLES "Build examples" OFF)
option(BUILD_DOC "Build documentation" OFF)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
option(LIBZIP_DO_INSTALL "Install libzip and the related files" OFF)
add_subdirectory(core/deps/libzip)
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/libzip/lib)
target_link_libraries(${PROJECT_NAME} PRIVATE zip)
endif()
if(WIN32)
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/dirent)
else()
endif()
if(NOT MSVC)
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/picotcp/include core/deps/picotcp/modules)
target_sources(${PROJECT_NAME} PRIVATE
core/deps/picotcp/include/arch/pico_arm9.h
@ -387,68 +420,6 @@ else()
core/deps/picotcp/stack/pico_socket_multicast.c
core/deps/picotcp/stack/pico_stack.c
core/deps/picotcp/stack/pico_tree.c)
if(NOT LIBZIP_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/libzip)
target_sources(${PROJECT_NAME} PRIVATE
core/deps/libzip/config.h
core/deps/libzip/mkstemp.c
core/deps/libzip/zip.h
core/deps/libzip/zip_add.c
core/deps/libzip/zip_add_dir.c
core/deps/libzip/zip_close.c
core/deps/libzip/zip_delete.c
core/deps/libzip/zip_dirent.c
core/deps/libzip/zip_entry_free.c
core/deps/libzip/zip_entry_new.c
core/deps/libzip/zip_error.c
core/deps/libzip/zip_error_clear.c
core/deps/libzip/zip_error_get.c
core/deps/libzip/zip_error_get_sys_type.c
core/deps/libzip/zip_error_strerror.c
core/deps/libzip/zip_error_to_str.c
core/deps/libzip/zip_err_str.c
core/deps/libzip/zip_fclose.c
core/deps/libzip/zip_file_error_clear.c
core/deps/libzip/zip_file_error_get.c
core/deps/libzip/zip_file_get_offset.c
core/deps/libzip/zip_filerange_crc.c
core/deps/libzip/zip_file_strerror.c
core/deps/libzip/zip_fopen.c
core/deps/libzip/zip_fopen_index.c
core/deps/libzip/zip_fread.c
core/deps/libzip/zip_free.c
core/deps/libzip/zip_get_archive_comment.c
core/deps/libzip/zip_get_archive_flag.c
core/deps/libzip/zip_get_file_comment.c
core/deps/libzip/zip_get_name.c
core/deps/libzip/zip_get_num_files.c
core/deps/libzip/zip_memdup.c
core/deps/libzip/zip_name_locate.c
core/deps/libzip/zip_new.c
core/deps/libzip/zip_open.c
core/deps/libzip/zip_rename.c
core/deps/libzip/zip_replace.c
core/deps/libzip/zip_set_archive_comment.c
core/deps/libzip/zip_set_archive_flag.c
core/deps/libzip/zip_set_file_comment.c
core/deps/libzip/zip_set_name.c
core/deps/libzip/zip_source_buffer.c
core/deps/libzip/zip_source_file.c
core/deps/libzip/zip_source_filep.c
core/deps/libzip/zip_source_free.c
core/deps/libzip/zip_source_function.c
core/deps/libzip/zip_source_zip.c
core/deps/libzip/zip_stat.c
core/deps/libzip/zip_stat_index.c
core/deps/libzip/zip_stat_init.c
core/deps/libzip/zip_strerror.c
core/deps/libzip/zip_unchange_all.c
core/deps/libzip/zip_unchange_archive.c
core/deps/libzip/zip_unchange.c
core/deps/libzip/zip_unchange_data.c
core/deps/libzip/zipint.h)
endif()
endif()
target_compile_definitions(${PROJECT_NAME} PRIVATE _7ZIP_ST)
@ -463,12 +434,9 @@ target_sources(${PROJECT_NAME} PRIVATE
core/archive/archive.cpp
core/archive/archive.h
core/archive/rzip.cpp
core/archive/rzip.h)
if(NOT MSVC)
target_sources(${PROJECT_NAME} PRIVATE
core/archive/ZipArchive.cpp
core/archive/ZipArchive.h)
endif()
core/archive/rzip.h
core/archive/ZipArchive.cpp
core/archive/ZipArchive.h)
target_sources(${PROJECT_NAME} PRIVATE
core/arm_emitter/arm_coding.h
@ -672,7 +640,6 @@ target_sources(${PROJECT_NAME} PRIVATE
core/imgread/common.cpp
core/imgread/common.h
core/imgread/cue.cpp
core/imgread/gd_driver.h
core/imgread/gdi.cpp
core/imgread/ImgReader.cpp
core/imgread/ioctl.cpp

View File

@ -31,8 +31,21 @@ bool SzArchive::Open(const char* path)
{
SzArEx_Init(&szarchive);
if (InFile_Open(&archiveStream.file, path))
File_Construct(&archiveStream.file);
#ifdef USE_WINDOWS_FILE
nowide::wstackstring wpath;
if (!wpath.convert(path))
return false;
archiveStream.file.handle = CreateFileW(wpath.c_str(),
GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (archiveStream.file.handle == INVALID_HANDLE_VALUE)
return false;
#else
archiveStream.file.file = nowide::fopen(path, "rb");
if (archiveStream.file.file == nullptr)
return false;
#endif
FileInStream_CreateVTable(&archiveStream);
LookToRead2_CreateVTable(&lookStream, false);
lookStream.buf = (Byte *)ISzAlloc_Alloc(&g_Alloc, kInputBufSize);

View File

@ -27,8 +27,20 @@ ZipArchive::~ZipArchive()
bool ZipArchive::Open(const char* path)
{
zip = zip_open(path, 0, NULL);
return (zip != NULL);
FILE *file = nowide::fopen(path, "rb");
if (file == nullptr)
return false;
zip_error_t error;
zip_source_t *source = zip_source_filep_create(file, 0, -1, &error);
if (source == nullptr)
{
std::fclose(file);
return false;
}
zip = zip_open_from_source(source, 0, NULL);
if (zip == nullptr)
zip_source_free(source);
return zip != nullptr;
}
ArchiveFile* ZipArchive::OpenFile(const char* name)

View File

@ -21,9 +21,7 @@
#include "archive.h"
#include "7zArchive.h"
#ifndef _MSC_VER
#include "ZipArchive.h"
#endif
Archive *OpenArchive(const char *path)
{
@ -34,12 +32,10 @@ Archive *OpenArchive(const char *path)
return sz_archive;
delete sz_archive;
#ifndef _MSC_VER
Archive *zip_archive = new ZipArchive();
if (zip_archive->Open(base_path.c_str()) || zip_archive->Open((base_path + ".zip").c_str()) || zip_archive->Open((base_path + ".ZIP").c_str()))
return zip_archive;
delete zip_archive;
#endif
return NULL;
}

View File

@ -25,16 +25,16 @@ bool RZipFile::Open(const std::string& path, bool write)
{
verify(file == nullptr);
file = fopen(path.c_str(), write ? "wb" : "rb");
file = nowide::fopen(path.c_str(), write ? "wb" : "rb");
if (file == nullptr)
return false;
if (!write)
{
u8 header[sizeof(RZipHeader)];
if (fread(header, sizeof(header), 1, file) != 1
if (std::fread(header, sizeof(header), 1, file) != 1
|| memcmp(header, RZipHeader, sizeof(header))
|| fread(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|| fread(&size, sizeof(size), 1, file) != 1)
|| std::fread(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|| std::fread(&size, sizeof(size), 1, file) != 1)
{
Close();
return false;
@ -51,7 +51,7 @@ void RZipFile::Close()
{
if (file != nullptr)
{
fclose(file);
std::fclose(file);
file = nullptr;
if (chunk != nullptr)
{
@ -74,10 +74,10 @@ size_t RZipFile::Read(void *data, size_t length)
chunkSize = 0;
chunkIndex = 0;
u32 zippedSize;
if (fread(&zippedSize, sizeof(zippedSize), 1, file) != 1)
if (std::fread(&zippedSize, sizeof(zippedSize), 1, file) != 1)
break;
u8 *zipped = new u8[zippedSize];
if (fread(zipped, zippedSize, 1, file) != 1)
if (std::fread(zipped, zippedSize, 1, file) != 1)
{
delete [] zipped;
break;
@ -104,12 +104,12 @@ size_t RZipFile::Read(void *data, size_t length)
size_t RZipFile::Write(const void *data, size_t length)
{
verify(file != nullptr);
verify(ftell(file) == 0);
verify(std::ftell(file) == 0);
maxChunkSize = 1024 * 1024;
if (fwrite(RZipHeader, sizeof(RZipHeader), 1, file) != 1
|| fwrite(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|| fwrite(&length, sizeof(length), 1, file) != 1)
if (std::fwrite(RZipHeader, sizeof(RZipHeader), 1, file) != 1
|| std::fwrite(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|| std::fwrite(&length, sizeof(length), 1, file) != 1)
return 0;
const u8 *p = (const u8 *)data;
u8 *zipped = new u8[maxChunkSize];
@ -121,8 +121,8 @@ size_t RZipFile::Write(const void *data, size_t length)
if (compress(zipped, &zippedSize, p, uncompressedSize) != Z_OK)
break;
u32 sz = (u32)zippedSize;
if (fwrite(&sz, sizeof(sz), 1, file) != 1
|| fwrite(zipped, zippedSize, 1, file) != 1)
if (std::fwrite(&sz, sizeof(sz), 1, file) != 1
|| std::fwrite(zipped, zippedSize, 1, file) != 1)
return 0;
p += uncompressedSize;
rv += uncompressedSize;

View File

@ -20,7 +20,7 @@ static bool has_game_specific_config = false;
void savecfgf()
{
FILE* cfgfile = fopen(cfgPath.c_str(),"wt");
FILE* cfgfile = nowide::fopen(cfgPath.c_str(), "wt");
if (!cfgfile)
{
WARN_LOG(COMMON, "Error: Unable to open file '%s' for saving", cfgPath.c_str());
@ -28,7 +28,7 @@ void savecfgf()
else
{
cfgdb.save(cfgfile);
fclose(cfgfile);
std::fclose(cfgfile);
}
}
void cfgSaveStr(const char * Section, const char * Key, const char * String)
@ -85,10 +85,10 @@ bool cfgOpen()
std::string config_path_read = get_readonly_config_path(filename);
cfgPath = get_writable_config_path(filename);
FILE* cfgfile = fopen(config_path_read.c_str(),"r");
FILE* cfgfile = nowide::fopen(config_path_read.c_str(), "r");
if(cfgfile != NULL) {
cfgdb.parse(cfgfile);
fclose(cfgfile);
std::fclose(cfgfile);
}
else
{

View File

@ -205,7 +205,7 @@ void ConfigFile::parse(FILE* file)
int cline = 0;
while(file && !feof(file))
{
if (fgets(line, 512, file) == NULL || feof(file))
if (std::fgets(line, 512, file) == NULL || std::feof(file))
{
break;
}
@ -274,16 +274,16 @@ void ConfigFile::save(FILE* file)
const std::string& section_name = section_it.first;
const ConfigSection& section = section_it.second;
fprintf(file, "[%s]\n", section_name.c_str());
std::fprintf(file, "[%s]\n", section_name.c_str());
for (const auto& entry_it : section.entries)
{
const std::string& entry_name = entry_it.first;
const ConfigEntry& entry = entry_it.second;
fprintf(file, "%s = %s\n", entry_name.c_str(), entry.get_string().c_str());
std::fprintf(file, "%s = %s\n", entry_name.c_str(), entry.get_string().c_str());
}
fputs("\n", file);
std::fputs("\n", file);
}
}

View File

@ -7,7 +7,7 @@ RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ \
hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/interpr/ hw/sh4/modules/ plugins/ profiler/ oslib/ \
hw/extdev/ hw/arm/ hw/naomi/ imgread/ ./ deps/coreio/ deps/zlib/ deps/chdr/ deps/crypto/ \
deps/libelf/ deps/chdpsr/ arm_emitter/ rend/ reios/ deps/xbrz/ \
deps/libzip/ deps/imgui/ archive/ input/ log/ wsi/ network/ hw/bba/
deps/imgui/ archive/ input/ log/ wsi/ network/ hw/bba/
ifndef NOT_ARM
RZDCY_MODULES += rec-ARM/
@ -59,6 +59,9 @@ endif
ifdef USE_SDL
RZDCY_MODULES += sdl/
ifdef FOR_WINDOWS
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/SDL2-2.0.12/include
endif
endif
ifdef FOR_LINUX
@ -70,10 +73,11 @@ endif
ifdef FOR_WINDOWS
RZDCY_MODULES += windows/
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/dirent
endif
ifdef FOR_PANDORA
RZDCY_CFLAGS := \
RZDCY_CFLAGS += \
$(CFLAGS) -c -O3 \
-DNDEBUG -DPANDORA\
-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp \
@ -82,7 +86,7 @@ RZDCY_CFLAGS := \
RZDCY_CFLAGS += -march=armv7-a -mtune=cortex-a8 -mfpu=neon
else
ifdef FOR_ANDROID
RZDCY_CFLAGS := \
RZDCY_CFLAGS += \
$(CFLAGS) -c -O3 \
-D_ANDROID -DNDEBUG \
-frename-registers -fsingle-precision-constant -ffast-math \
@ -95,17 +99,9 @@ RZDCY_CFLAGS := \
RZDCY_CFLAGS += -march=armv8-a
endif
endif
else
RZDCY_CFLAGS :=
endif
endif
ifdef FOR_WINDOWS
ifdef USE_SDL
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/SDL2-2.0.12/include
endif
endif
ifdef USE_VULKAN
ifdef FOR_WINDOWS
RZDCY_CFLAGS += -DVK_USE_PLATFORM_WIN32_KHR
@ -121,11 +117,11 @@ endif
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/rend/gles -I$(RZDCY_SRC_DIR)/deps \
-I$(RZDCY_SRC_DIR)/deps/vixl -I$(RZDCY_SRC_DIR)/khronos -I$(RZDCY_SRC_DIR)/deps/glslang \
-I$(RZDCY_SRC_DIR)/deps/glm -I$(RZDCY_SRC_DIR)/deps/xbyak
-I$(RZDCY_SRC_DIR)/deps/glm -I$(RZDCY_SRC_DIR)/deps/xbyak -I$(RZDCY_SRC_DIR)/deps/nowide/include
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/picotcp/include -I$(RZDCY_SRC_DIR)/deps/picotcp/modules
RZDCY_MODULES += hw/modem/ deps/picotcp/modules/ deps/picotcp/stack/
ifndef FOR_WINDOWS
ifdef USE_SYSTEM_MINIUPNPC
RZDCY_CFLAGS += -I/usr/include/miniupnpc
else
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/miniupnpc
@ -153,7 +149,6 @@ ifdef CHD5_LZMA
RZDCY_CFLAGS += -D_7ZIP_ST -DCHD5_LZMA
endif
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/libzip
RZDCY_CFLAGS += -DZ_HAVE_UNISTD_H -I$(RZDCY_SRC_DIR)/deps/zlib
RZDCY_CFLAGS += -DXXH_INLINE_ALL -I$(RZDCY_SRC_DIR)/deps/xxHash -I$(RZDCY_SRC_DIR)/deps/stb
@ -164,6 +159,133 @@ RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(w
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.c))
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.S))
ifdef STATIC_LIBZIP
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/libzip/lib
LIBZIP_DIR = $(RZDCY_SRC_DIR)/deps/libzip/lib
RZDCY_FILES += $(LIBZIP_DIR)/zip_add.c \
$(LIBZIP_DIR)/zip_add_dir.c \
$(LIBZIP_DIR)/zip_add_entry.c \
$(LIBZIP_DIR)/zip_algorithm_deflate.c \
$(LIBZIP_DIR)/zip_buffer.c \
$(LIBZIP_DIR)/zip_close.c \
$(LIBZIP_DIR)/zip_delete.c \
$(LIBZIP_DIR)/zip_dir_add.c \
$(LIBZIP_DIR)/zip_dirent.c \
$(LIBZIP_DIR)/zip_discard.c \
$(LIBZIP_DIR)/zip_entry.c \
$(LIBZIP_DIR)/zip_error.c \
$(LIBZIP_DIR)/zip_error_clear.c \
$(LIBZIP_DIR)/zip_error_get.c \
$(LIBZIP_DIR)/zip_error_get_sys_type.c \
$(LIBZIP_DIR)/zip_error_strerror.c \
$(LIBZIP_DIR)/zip_error_to_str.c \
$(LIBZIP_DIR)/zip_extra_field.c \
$(LIBZIP_DIR)/zip_extra_field_api.c \
$(LIBZIP_DIR)/zip_fclose.c \
$(LIBZIP_DIR)/zip_fdopen.c \
$(LIBZIP_DIR)/zip_file_add.c \
$(LIBZIP_DIR)/zip_file_error_clear.c \
$(LIBZIP_DIR)/zip_file_error_get.c \
$(LIBZIP_DIR)/zip_file_get_comment.c \
$(LIBZIP_DIR)/zip_file_get_external_attributes.c \
$(LIBZIP_DIR)/zip_file_get_offset.c \
$(LIBZIP_DIR)/zip_file_rename.c \
$(LIBZIP_DIR)/zip_file_replace.c \
$(LIBZIP_DIR)/zip_file_set_comment.c \
$(LIBZIP_DIR)/zip_file_set_encryption.c \
$(LIBZIP_DIR)/zip_file_set_external_attributes.c \
$(LIBZIP_DIR)/zip_file_set_mtime.c \
$(LIBZIP_DIR)/zip_file_strerror.c \
$(LIBZIP_DIR)/zip_fopen.c \
$(LIBZIP_DIR)/zip_fopen_encrypted.c \
$(LIBZIP_DIR)/zip_fopen_index.c \
$(LIBZIP_DIR)/zip_fopen_index_encrypted.c \
$(LIBZIP_DIR)/zip_fread.c \
$(LIBZIP_DIR)/zip_fseek.c \
$(LIBZIP_DIR)/zip_ftell.c \
$(LIBZIP_DIR)/zip_get_archive_comment.c \
$(LIBZIP_DIR)/zip_get_archive_flag.c \
$(LIBZIP_DIR)/zip_get_encryption_implementation.c \
$(LIBZIP_DIR)/zip_get_file_comment.c \
$(LIBZIP_DIR)/zip_get_name.c \
$(LIBZIP_DIR)/zip_get_num_entries.c \
$(LIBZIP_DIR)/zip_get_num_files.c \
$(LIBZIP_DIR)/zip_hash.c \
$(LIBZIP_DIR)/zip_io_util.c \
$(LIBZIP_DIR)/zip_libzip_version.c \
$(LIBZIP_DIR)/zip_memdup.c \
$(LIBZIP_DIR)/zip_name_locate.c \
$(LIBZIP_DIR)/zip_new.c \
$(LIBZIP_DIR)/zip_open.c \
$(LIBZIP_DIR)/zip_pkware.c \
$(LIBZIP_DIR)/zip_progress.c \
$(LIBZIP_DIR)/zip_rename.c \
$(LIBZIP_DIR)/zip_replace.c \
$(LIBZIP_DIR)/zip_set_archive_comment.c \
$(LIBZIP_DIR)/zip_set_archive_flag.c \
$(LIBZIP_DIR)/zip_set_default_password.c \
$(LIBZIP_DIR)/zip_set_file_comment.c \
$(LIBZIP_DIR)/zip_set_file_compression.c \
$(LIBZIP_DIR)/zip_set_name.c \
$(LIBZIP_DIR)/zip_source_accept_empty.c \
$(LIBZIP_DIR)/zip_source_begin_write.c \
$(LIBZIP_DIR)/zip_source_begin_write_cloning.c \
$(LIBZIP_DIR)/zip_source_buffer.c \
$(LIBZIP_DIR)/zip_source_call.c \
$(LIBZIP_DIR)/zip_source_close.c \
$(LIBZIP_DIR)/zip_source_commit_write.c \
$(LIBZIP_DIR)/zip_source_compress.c \
$(LIBZIP_DIR)/zip_source_crc.c \
$(LIBZIP_DIR)/zip_source_error.c \
$(LIBZIP_DIR)/zip_source_file_common.c \
$(LIBZIP_DIR)/zip_source_file_stdio.c \
$(LIBZIP_DIR)/zip_source_free.c \
$(LIBZIP_DIR)/zip_source_function.c \
$(LIBZIP_DIR)/zip_source_get_file_attributes.c \
$(LIBZIP_DIR)/zip_source_is_deleted.c \
$(LIBZIP_DIR)/zip_source_layered.c \
$(LIBZIP_DIR)/zip_source_open.c \
$(LIBZIP_DIR)/zip_source_pkware_decode.c \
$(LIBZIP_DIR)/zip_source_pkware_encode.c \
$(LIBZIP_DIR)/zip_source_read.c \
$(LIBZIP_DIR)/zip_source_remove.c \
$(LIBZIP_DIR)/zip_source_rollback_write.c \
$(LIBZIP_DIR)/zip_source_seek.c \
$(LIBZIP_DIR)/zip_source_seek_write.c \
$(LIBZIP_DIR)/zip_source_stat.c \
$(LIBZIP_DIR)/zip_source_supports.c \
$(LIBZIP_DIR)/zip_source_tell.c \
$(LIBZIP_DIR)/zip_source_tell_write.c \
$(LIBZIP_DIR)/zip_source_window.c \
$(LIBZIP_DIR)/zip_source_write.c \
$(LIBZIP_DIR)/zip_source_zip.c \
$(LIBZIP_DIR)/zip_source_zip_new.c \
$(LIBZIP_DIR)/zip_stat.c \
$(LIBZIP_DIR)/zip_stat_index.c \
$(LIBZIP_DIR)/zip_stat_init.c \
$(LIBZIP_DIR)/zip_strerror.c \
$(LIBZIP_DIR)/zip_string.c \
$(LIBZIP_DIR)/zip_unchange.c \
$(LIBZIP_DIR)/zip_unchange_all.c \
$(LIBZIP_DIR)/zip_unchange_archive.c \
$(LIBZIP_DIR)/zip_unchange_data.c \
$(LIBZIP_DIR)/zip_utf-8.c \
$(LIBZIP_DIR)/zip_err_str.c
ifdef FOR_WINDOWS
RZDCY_FILES += $(LIBZIP_DIR)/zip_source_file_win32.c \
$(LIBZIP_DIR)/zip_source_file_win32_named.c \
$(LIBZIP_DIR)/zip_source_file_win32_utf16.c \
$(LIBZIP_DIR)/zip_source_file_win32_utf8.c \
$(LIBZIP_DIR)/zip_source_file_win32_ansi.c \
$(LIBZIP_DIR)/zip_random_win32.c
else
RZDCY_FILES += $(LIBZIP_DIR)/zip_mkstempm.c \
$(LIBZIP_DIR)/zip_source_file_stdio_named.c \
$(LIBZIP_DIR)/zip_random_unix.c
endif
endif
$(VERSION_HEADER):
echo "#define REICAST_VERSION \"`git describe --tags --always`\"" > $(VERSION_HEADER)
echo "#define GIT_HASH \"`git rev-parse --short HEAD`\"" >> $(VERSION_HEADER)

View File

@ -2,7 +2,6 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "deps/coreio/coreio.h"
#include "cdipsr.h"
// Global variables
@ -12,11 +11,6 @@ unsigned long temp_value;
/////////////////////////////////////////////////////////////////////////////
#define FILE core_file
#define fread(buff,sz,cnt,fc) core_fread(fc,buff,sz*cnt)
#define fseek core_fseek
#define ftell core_ftell
unsigned long ask_type(FILE *fsource, long header_position)
{
@ -117,7 +111,8 @@ void CDI_get_tracks (FILE *fsource, image_s *image)
bool CDI_init (FILE *fsource, image_s *image, const char *fsourcename)
{
image->length = core_fsize(fsource);
fseek(fsource, 0, SEEK_END);
image->length = ftell(fsource);
if (image->length < 8)
{

View File

@ -1,8 +1,6 @@
#ifndef __CDI_H__
#define __CDI_H__
#include "deps/coreio/coreio.h"
/* Basic structures */
typedef struct image_s
@ -38,11 +36,11 @@ typedef struct track_s
#define CDI_V3 0x80000005
#define CDI_V35 0x80000006
unsigned long ask_type(core_file *fsource, long header_position);
bool CDI_init(core_file *fsource, image_s *image, const char *fsourcename);
void CDI_get_sessions(core_file *fsource, image_s *image);
void CDI_get_tracks(core_file *fsource, image_s *image);
void CDI_read_track(core_file *fsource, image_s *image, track_s *track);
void CDI_skip_next_session(core_file *fsource, image_s *image);
unsigned long ask_type(FILE *fsource, long header_position);
bool CDI_init(FILE *fsource, image_s *image, const char *fsourcename);
void CDI_get_sessions(FILE *fsource, image_s *image);
void CDI_get_tracks(FILE *fsource, image_s *image);
void CDI_read_track(FILE *fsource, image_s *image, track_s *track);
void CDI_skip_next_session(FILE *fsource, image_s *image);
#endif

View File

@ -359,6 +359,9 @@ struct _chd_verify_result
/* open an existing CHD file */
chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd);
/* open an existing CHD with an already-opened core_file */
chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd);
/* close a CHD file */
void chd_close(chd_file *chd);

View File

@ -22,7 +22,7 @@ typedef int8_t INT8;
#define core_fread(fc, buff, len) fread(buff, 1, len, fc)
#define core_fclose fclose
#define core_ftell ftell
static size_t core_fsize(core_file *f)
inline static size_t core_fsize(core_file *f)
{
long p = ftell(f);
fseek(f, 0, SEEK_END);

View File

@ -455,7 +455,7 @@ _wopendir(
* Returns pointer to static directory entry which may be overwritten by
* subsequent calls to _wreaddir().
*/
static struct _wdirent*
inline static struct _wdirent*
_wreaddir(
_WDIR *dirp)
{
@ -723,7 +723,7 @@ opendir(
/*
* Read next directory entry.
*/
static struct dirent*
inline static struct dirent*
readdir(
DIR *dirp)
{
@ -861,7 +861,7 @@ closedir(
/*
* Rewind directory stream to beginning.
*/
static void
inline static void
rewinddir(
DIR* dirp)
{
@ -872,7 +872,7 @@ rewinddir(
/*
* Scan directory for entries.
*/
static int
inline static int
scandir(
const char *dirname,
struct dirent ***namelist,
@ -1019,7 +1019,7 @@ alphasort(
}
/* Sort versions */
static int
inline static int
versionsort(
const struct dirent **a, const struct dirent **b)
{

View File

@ -0,0 +1,162 @@
# libzip API changes
This file describes changes in the libzip API and how to adapt your
code for them.
You can define `ZIP_DISABLE_DEPRECATED` before including `<zip.h>` to hide
prototypes for deprecated functions, to find out about functions that
might be removed at some point.
## Changed in libzip-1.0
### new type `zip_error_t`
Error information is stored in the newly public type `zip_error_t`. Use
this to access information about an error, instead of the deprecated
functions that operated on two ints.
deprecated functions:
- `zip_error_get_sys_type()`
- `zip_error_get()`
- `zip_error_to_str()`
- `zip_file_error_get()`
See their man pages for instructions on how to replace them.
The most common affected use is `zip_open`. The new recommended usage
is:
```c
int err;
if ((za = zip_open(archive, flags, &err)) == NULL) {
zip_error_t error;
zip_error_init_with_code(&error, err);
fprintf(stderr, "can't open zip archive '%s': %s\n", archive, zip_error_strerror(&error));
zip_error_fini(&error);
}
```
### more typedefs
The following typedefs have been added for better readability:
```c
typedef struct zip zip_t;
typedef struct zip_file zip_file_t;
typedef struct zip_source zip_source_t;
typedef struct zip_stat zip_stat_t;
```
This means you can use "`zip_t`" instead of "`struct zip`", etc.
### torrentzip support removed
torrentzip depends on a particular zlib version which is by now quite
old.
## Changed in libzip-0.11
### new type `zip_flags_t`
The functions which have flags now use the `zip_flags_t` type for this.
All old flags fit; you need only to adapt code if you were saving flags in a
local variable. Use `zip_flags_t` for such a variable.
This affects:
- `zip_fopen()`
- `zip_fopen_encrypted()`
- `zip_fopen_index()`
- `zip_fopen_index_encrypted()`
- `zip_get_archive_comment()`
- `zip_get_archive_flag()`
- `zip_get_num_entries()`
- `zip_get_name()`
- `zip_name_locate()`
- `zip_set_archive_flag()`
- `zip_source_zip()`
- `zip_stat()`
- `zip_stat_index()`
#### `ZIP_FL_*`, `ZIP_AFL_*`, `ZIP_STAT_*` are now unsigned constants
To match the new `zip_flags_t` type.
#### `zip_add()`, `zip_add_dir()`
These functions were replaced with `zip_file_add()` and `zip_dir_add()`, respectively,
to add a flags argument.
#### `zip_rename()`, `zip_replace()`
These functions were replaced with `zip_file_rename()` and `zip_file_replace()`,
respectively, to add a flags argument.
#### `zip_get_file_comment()`
This function was replaced with `zip_file_get_comment()`; one argument was promoted from
`int` to `zip_uint32_t`, the other is now a `zip_flags_t`.
#### `zip_set_file_comment()`
This function was replaced with `zip_file_set_comment()`; an argument was promoted from
`int` to `zip_uint16_t`, and a `zip_flags_t` argument was added.
### integer type size changes
Some argument and return values were not the right size or sign.
#### `zip_name_locate()`
The return value was `int`, which can be too small. The function now returns `zip_int64_t`.
#### `zip_get_num_entries()`
The return type is now signed, to allow signaling errors.
#### `zip_set_archive_comment()`
The last argument changed from `int` to `zip_uint16_t`.
### extra field handling rewritten
The `zip_get_file_extra()` and `zip_set_file_extra()` functions were removed.
They only worked on the whole extra field set.
Instead, you can now set, get, count, and delete each extra field separately,
using the functions:
- `zip_file_extra_field_delete()`
- `zip_file_extra_field_delete_by_id()`
- `zip_file_extra_field_get()`
- `zip_file_extra_field_get_by_id()`
- `zip_file_extra_fields_count()`
- `zip_file_extra_fields_count_by_id()`
- `zip_file_extra_field_set()`
Please read the corresponding man pages for details.
### new functions
#### `zip_discard()`
The new `zip_discard()` function closes an archive without committing the
scheduled changes.
#### `zip_set_file_compression()`
The new `zip_set_file_compression()` function allows setting compression
levels for files.
### argument changes
#### file names
File names arguments are now allowed to be `NULL` to have an empty file name.
This mostly affects `zip_file_add()`, `zip_dir_add()`, and `zip_file_rename()`.
For `zip_get_name()`, `zip_file_get_comment()`, and `zip_get_archive_comment()`, if
the file name or comment is empty, a string of length 0 is returned.
`NULL` is returned for errors only.
Previously, `NULL` was returned for empty/unset file names and comments and
errors, leaving no way to differentiate between the two.

2
core/deps/libzip/AUTHORS Normal file
View File

@ -0,0 +1,2 @@
Dieter Baron <dillo@nih.at>
Thomas Klausner <tk@giga.or.at>

View File

@ -0,0 +1,445 @@
cmake_minimum_required(VERSION 3.0.2)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
if (${CMAKE_VERSION} VERSION_LESS "3.17.0")
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake-compat)
endif()
project(libzip
VERSION 1.7.3.1
LANGUAGES C)
option(ENABLE_COMMONCRYPTO "Enable use of CommonCrypto" ON)
option(ENABLE_GNUTLS "Enable use of GnuTLS" ON)
option(ENABLE_MBEDTLS "Enable use of mbed TLS" ON)
option(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
option(ENABLE_WINDOWS_CRYPTO "Enable use of Windows cryptography libraries" ON)
option(ENABLE_BZIP2 "Enable use of BZip2" ON)
option(ENABLE_LZMA "Enable use of LZMA" ON)
option(ENABLE_ZSTD "Enable use of Zstandard" ON)
option(BUILD_TOOLS "Build tools in the src directory (zipcmp, zipmerge, ziptool)" ON)
option(BUILD_REGRESS "Build regression tests" ON)
option(BUILD_EXAMPLES "Build examples" ON)
option(BUILD_DOC "Build documentation" ON)
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(CheckLibraryExists)
include(CheckSymbolExists)
include(CheckTypeSize)
include(CheckCSourceRuns)
include(CheckCSourceCompiles)
include(CheckStructHasMember)
include(TestBigEndian)
include(GNUInstallDirs)
if(ENABLE_COMMONCRYPTO)
check_include_files(CommonCrypto/CommonCrypto.h COMMONCRYPTO_FOUND)
endif()
if(ENABLE_GNUTLS)
find_package(Nettle 3.0)
find_package(GnuTLS)
endif()
if(ENABLE_MBEDTLS)
find_package(MbedTLS 1.0)
endif()
if(ENABLE_OPENSSL)
find_package(OpenSSL)
endif()
if(WIN32)
if(ENABLE_WINDOWS_CRYPTO)
set(WINDOWS_CRYPTO_FOUND TRUE)
endif()
endif()
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(LIBZIP_DO_INSTALL "Install libzip and the related files" ON)
option(SHARED_LIB_VERSIONNING "Add SO version in .so build" ON)
find_program(MDOCTOOL NAMES mandoc groff)
if (MDOCTOOL)
set(DOCUMENTATION_FORMAT "mdoc" CACHE STRING "Documentation format")
else()
find_program(MANTOOL NAMES nroff)
if (MANTOOL)
set(DOCUMENTATION_FORMAT "man" CACHE STRING "Documentation format")
else()
set(DOCUMENTATION_FORMAT "html" CACHE STRING "Documentation format")
endif()
endif()
include(Dist)
Dist(${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION})
#ADD_CUSTOM_TARGET(uninstall
# COMMAND cat ${PROJECT_BINARY_DIR}/install_manifest.txt | xargs rm
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
# )
if(BUILD_SHARED_LIBS)
set(HAVE_SHARED TRUE)
else()
set(ZIP_STATIC TRUE)
endif()
# Checks
check_function_exists(_close HAVE__CLOSE)
check_function_exists(_dup HAVE__DUP)
check_function_exists(_fdopen HAVE__FDOPEN)
check_function_exists(_fileno HAVE__FILENO)
check_function_exists(_setmode HAVE__SETMODE)
check_function_exists(_snprintf HAVE__SNPRINTF)
check_function_exists(_strdup HAVE__STRDUP)
check_function_exists(_stricmp HAVE__STRICMP)
check_function_exists(_strtoi64 HAVE__STRTOI64)
check_function_exists(_strtoui64 HAVE__STRTOUI64)
check_function_exists(_unlink HAVE__UNLINK)
check_function_exists(arc4random HAVE_ARC4RANDOM)
check_function_exists(clonefile HAVE_CLONEFILE)
check_function_exists(explicit_bzero HAVE_EXPLICIT_BZERO)
check_function_exists(explicit_memset HAVE_EXPLICIT_MEMSET)
check_function_exists(fileno HAVE_FILENO)
check_function_exists(fseeko HAVE_FSEEKO)
check_function_exists(ftello HAVE_FTELLO)
check_function_exists(getprogname HAVE_GETPROGNAME)
check_function_exists(localtime_r HAVE_LOCALTIME_R)
check_function_exists(setmode HAVE_SETMODE)
check_function_exists(strcasecmp HAVE_STRCASECMP)
check_function_exists(strdup HAVE_STRDUP)
check_function_exists(stricmp HAVE_STRICMP)
check_function_exists(strtoll HAVE_STRTOLL)
check_function_exists(strtoull HAVE_STRTOULL)
check_include_files("sys/types.h;sys/stat.h;fts.h" HAVE_FTS_H)
# fts functions may be in external library
if(HAVE_FTS_H)
check_function_exists(fts_open HAVE_FTS_OPEN)
if(NOT HAVE_FTS_OPEN)
check_library_exists(fts fts_open "" HAVE_LIB_FTS)
else(NOT HAVE_FTS_OPEN)
set(HAVE_LIB_FTS "" CACHE INTERNAL "")
endif(NOT HAVE_FTS_OPEN)
else(HAVE_FTS_H)
set(HAVE_LIB_FTS "" CACHE INTERNAL "")
endif(HAVE_FTS_H)
if(HAVE_LIB_FTS)
set(FTS_LIB fts CACHE INTERNAL "")
else()
set(FTS_LIB "" CACHE INTERNAL "")
endif()
check_include_files(stdbool.h HAVE_STDBOOL_H)
check_include_files(strings.h HAVE_STRINGS_H)
check_include_files(unistd.h HAVE_UNISTD_H)
check_include_files(inttypes.h HAVE_INTTYPES_H_LIBZIP)
check_include_files(stdint.h HAVE_STDINT_H_LIBZIP)
check_include_files(sys/types.h HAVE_SYS_TYPES_H_LIBZIP)
# TODO: fix test
# this test does not find __progname even when it exists
#check_symbol_exists(__progname stdlib.h HAVE___PROGNAME)
check_type_size(__int8 __INT8_LIBZIP)
check_type_size(int8_t INT8_T_LIBZIP)
check_type_size(uint8_t UINT8_T_LIBZIP)
check_type_size(__int16 __INT16_LIBZIP)
check_type_size(int16_t INT16_T_LIBZIP)
check_type_size(uint16_t UINT16_T_LIBZIP)
check_type_size(__int32 __INT32_LIBZIP)
check_type_size(int32_t INT32_T_LIBZIP)
check_type_size(uint32_t UINT32_T_LIBZIP)
check_type_size(__int64 __INT64_LIBZIP)
check_type_size(int64_t INT64_T_LIBZIP)
check_type_size(uint64_t UINT64_T_LIBZIP)
check_type_size("short" SHORT_LIBZIP)
check_type_size("int" INT_LIBZIP)
check_type_size("long" LONG_LIBZIP)
check_type_size("long long" LONG_LONG_LIBZIP)
check_type_size("off_t" SIZEOF_OFF_T)
check_type_size("size_t" SIZEOF_SIZE_T)
check_c_source_compiles("#include <sys/ioctl.h>
#include <linux/fs.h>
int main(int argc, char *argv[]) { unsigned long x = FICLONERANGE; }" HAVE_FICLONERANGE)
check_c_source_compiles("
int foo(char * _Nullable bar);
int main(int argc, char *argv[]) { }" HAVE_NULLABLE)
test_big_endian(WORDS_BIGENDIAN)
find_package(ZLIB 1.1.2 REQUIRED)
if(ENABLE_BZIP2)
find_package(BZip2)
if(BZIP2_FOUND)
set(HAVE_LIBBZ2 1)
else()
message(WARNING "-- bzip2 library not found; bzip2 support disabled")
endif(BZIP2_FOUND)
endif(ENABLE_BZIP2)
if(ENABLE_LZMA)
find_package(LibLZMA 5.2)
if(LIBLZMA_FOUND)
set(HAVE_LIBLZMA 1)
else()
message(WARNING "-- lzma library not found; lzma/xz support disabled")
endif(LIBLZMA_FOUND)
endif(ENABLE_LZMA)
if(ENABLE_ZSTD)
find_package(Zstd)
if(Zstd_FOUND)
set(HAVE_LIBZSTD 1)
else()
message(WARNING "-- zstd library not found; zstandard support disabled")
endif(Zstd_FOUND)
endif(ENABLE_ZSTD)
if (COMMONCRYPTO_FOUND)
set(HAVE_CRYPTO 1)
set(HAVE_COMMONCRYPTO 1)
elseif (WINDOWS_CRYPTO_FOUND)
set(HAVE_CRYPTO 1)
set(HAVE_WINDOWS_CRYPTO 1)
elseif (GNUTLS_FOUND AND NETTLE_FOUND)
set(HAVE_CRYPTO 1)
set(HAVE_GNUTLS 1)
elseif (OPENSSL_FOUND)
set(HAVE_CRYPTO 1)
set(HAVE_OPENSSL 1)
elseif (MBEDTLS_FOUND)
set(HAVE_CRYPTO 1)
set(HAVE_MBEDTLS 1)
endif()
if (NOT HAVE_CRYPTO)
message(WARNING "-- neither Common Crypto, GnuTLS, mbed TLS, OpenSSL, nor Windows Cryptography found; AES support disabled")
endif()
if(MSVC)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
add_compile_definitions(_CRT_NONSTDC_NO_DEPRECATE)
endif(MSVC)
if(WIN32)
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
add_compile_definitions(MS_UWP)
endif(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
endif(WIN32)
# rpath handling: use rpath in installed binaries
if(NOT CMAKE_SYSTEM_NAME MATCHES Linux)
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif()
# for code completion frameworks
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Testing
ENABLE_TESTING()
# Targets
ADD_SUBDIRECTORY(lib)
if(BUILD_DOC)
ADD_SUBDIRECTORY(man)
endif()
if(BUILD_TOOLS)
ADD_SUBDIRECTORY(src)
else(BUILD_TOOLS)
if(BUILD_REGRESS)
message(WARNING "-- tools build has been disabled, but they are needed for regression tests; regression testing disabled")
set(BUILD_REGRESS OFF)
endif(BUILD_REGRESS)
endif()
include(FindPerl)
if(NOT PERL_FOUND)
message(WARNING "-- perl not found, regression testing disabled")
set(BUILD_REGRESS OFF)
endif()
if(BUILD_REGRESS)
add_subdirectory(regress)
endif()
if(BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
# pkgconfig file
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix \${prefix})
SET(bindir ${CMAKE_INSTALL_FULL_BINDIR})
SET(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
SET(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
if(CMAKE_SYSTEM_NAME MATCHES BSD)
set(PKG_CONFIG_RPATH "-Wl,-R\${libdir}")
endif(CMAKE_SYSTEM_NAME MATCHES BSD)
get_target_property(LIBS_PRIVATE zip LINK_LIBRARIES)
foreach(LIB ${LIBS_PRIVATE})
if(LIB MATCHES "^/")
get_filename_component(LIB ${LIB} NAME_WE)
string(REGEX REPLACE "^lib" "" LIB ${LIB})
endif()
set(LIBS "${LIBS} -l${LIB}")
endforeach()
string(REGEX REPLACE "-lBZip2::BZip2" "-lbz2" LIBS ${LIBS})
string(REGEX REPLACE "-lLibLZMA::LibLZMA" "-llzma" LIBS ${LIBS})
string(REGEX REPLACE "-lOpenSSL::Crypto" "-lssl -lcrypto" LIBS ${LIBS})
string(REGEX REPLACE "-lZLIB::ZLIB" "-lz" LIBS ${LIBS})
string(REGEX REPLACE "-lGnuTLS::GnuTLS" "-lgnutls" LIBS ${LIBS})
string(REGEX REPLACE "-lNettle::Nettle" "-lnettle" LIBS ${LIBS})
configure_file(libzip.pc.in libzip.pc @ONLY)
if(LIBZIP_DO_INSTALL)
install(FILES ${PROJECT_BINARY_DIR}/libzip.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
# fixed size integral types
if(HAVE_INTTYPES_H_LIBZIP)
set(LIBZIP_TYPES_INCLUDE "#if !defined(__STDC_FORMAT_MACROS)
#define __STDC_FORMAT_MACROS 1
#endif
#include <inttypes.h>")
elseif(HAVE_STDINT_H_LIBZIP)
set(LIBZIP_TYPES_INCLUDE "#include <stdint.h>")
elseif(HAVE_SYS_TYPES_H_LIBZIP)
set(LIBZIP_TYPES_INCLUDE "#include <sys/types.h>")
endif()
if(HAVE_INT8_T_LIBZIP)
set(ZIP_INT8_T int8_t)
elseif(HAVE___INT8_LIBZIP)
set(ZIP_INT8_T __int8)
else()
set(ZIP_INT8_T "signed char")
endif()
if(HAVE_UINT8_T_LIBZIP)
set(ZIP_UINT8_T uint8_t)
elseif(HAVE___INT8_LIBZIP)
set(ZIP_UINT8_T "unsigned __int8")
else()
set(ZIP_UINT8_T "unsigned char")
endif()
if(HAVE_INT16_T_LIBZIP)
set(ZIP_INT16_T int16_t)
elseif(HAVE___INT16_LIBZIP)
set(INT16_T_LIBZIP __int16)
elseif(SHORT_LIBZIP EQUAL 2)
set(INT16_T_LIBZIP short)
endif()
if(HAVE_UINT16_T_LIBZIP)
set(ZIP_UINT16_T uint16_t)
elseif(HAVE___INT16_LIBZIP)
set(UINT16_T_LIBZIP "unsigned __int16")
elseif(SHORT_LIBZIP EQUAL 2)
set(UINT16_T_LIBZIP "unsigned short")
endif()
if(HAVE_INT32_T_LIBZIP)
set(ZIP_INT32_T int32_t)
elseif(HAVE___INT32_LIBZIP)
set(ZIP_INT32_T __int32)
elseif(INT_LIBZIP EQUAL 4)
set(ZIP_INT32_T int)
elseif(LONG_LIBZIP EQUAL 4)
set(ZIP_INT32_T long)
endif()
if(HAVE_UINT32_T_LIBZIP)
set(ZIP_UINT32_T uint32_t)
elseif(HAVE___INT32_LIBZIP)
set(ZIP_UINT32_T "unsigned __int32")
elseif(INT_LIBZIP EQUAL 4)
set(ZIP_UINT32_T "unsigned int")
elseif(LONG_LIBZIP EQUAL 4)
set(ZIP_UINT32_T "unsigned long")
endif()
if(HAVE_INT64_T_LIBZIP)
set(ZIP_INT64_T int64_t)
elseif(HAVE___INT64_LIBZIP)
set(ZIP_INT64_T __int64)
elseif(LONG_LIBZIP EQUAL 8)
set(ZIP_INT64_T long)
elseif(LONG_LONG_LIBZIP EQUAL 8)
set(ZIP_INT64_T "long long")
endif()
if(HAVE_UINT64_T_LIBZIP)
set(ZIP_UINT64_T uint64_t)
elseif(HAVE___INT64_LIBZIP)
set(ZIP_UINT64_T "unsigned __int64")
elseif(LONG_LIBZIP EQUAL 8)
set(ZIP_UINT64_T "unsigned long")
elseif(LONG_LONG_LIBZIP EQUAL 8)
set(ZIP_UINT64_T "unsigned long long")
endif()
if(HAVE_NULLABLE)
set(ZIP_NULLABLE_DEFINES)
else()
set(ZIP_NULLABLE_DEFINES "#define _Nullable
#define _Nonnull")
endif()
# write out config file
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake-config.h.in ${PROJECT_BINARY_DIR}/config.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake-zipconf.h.in ${PROJECT_BINARY_DIR}/zipconf.h)
# for tests
set(srcdir ${CMAKE_CURRENT_SOURCE_DIR}/regress)
set(abs_srcdir ${CMAKE_CURRENT_SOURCE_DIR}/regress)
set(top_builddir ${PROJECT_BINARY_DIR}) # used to find config.h
configure_file(regress/nihtest.conf.in ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/nihtest.conf @ONLY)
file(COPY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/nihtest.conf
DESTINATION ${PROJECT_BINARY_DIR}/regress
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
configure_file(regress/runtest.in ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/runtest @ONLY)
file(COPY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/runtest
DESTINATION ${PROJECT_BINARY_DIR}/regress
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
# create package config file
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
COMPATIBILITY AnyNewerVersion)
configure_package_config_file("${PROJECT_NAME}-config.cmake.in" "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libzip)
if(LIBZIP_DO_INSTALL)
# Add targets to the build-tree export set
export(TARGETS zip
FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-targets.cmake")
# installation
install(FILES ${PROJECT_BINARY_DIR}/zipconf.h DESTINATION include)
install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
install(EXPORT ${PROJECT_NAME}-targets NAMESPACE libzip:: FILE ${PROJECT_NAME}-targets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
endif()

View File

@ -0,0 +1,69 @@
libzip uses [cmake](https://cmake.org) to build.
For running the tests, you need to have [perl](https://www.perl.org).
You'll need [zlib](http://www.zlib.net/) (at least version 1.1.2). It
comes with most operating systems.
For supporting bzip2-compressed zip archives, you need
[bzip2](http://bzip.org/).
For supporting lzma- and xz-compressed zip archives, you need
[liblzma](https://tukaani.org/xz/) which is part of xz, at least version 5.2.
For supporting zstd-compressed zip archives, you need
[zstd](https://github.com/facebook/zstd/).
For AES (encryption) support, you need one of these cryptographic libraries,
listed in order of preference:
- Apple's CommonCrypto (available on macOS and iOS)
- [GnuTLS](https://www.gnutls.org/) and [Nettle](https://www.lysator.liu.se/~nisse/nettle/) (at least nettle 3.0)
- [mbed TLS](https://tls.mbed.org/)
- [OpenSSL](https://www.openssl.org/) >= 1.0.
- Microsoft Windows Cryptography Framework
If you don't want a library even if it is installed, you can
pass `-DENABLE_<LIBRARY>=OFF` to cmake, where `<LIBRARY>` is one of
`COMMONCRYPTO`, `GNUTLS`, `MBEDTLS`, or `OPENSSL`.
The basic usage is
```sh
mkdir build
cd build
cmake ..
make
make test
make install
```
Some useful parameters you can pass to `cmake` with `-Dparameter=value`:
- `BUILD_SHARED_LIBS`: set to `ON` or `OFF` to enable/disable building
of shared libraries, defaults to `ON`
- `CMAKE_INSTALL_PREFIX`: for setting the installation path
- `DOCUMENTATION_FORMAT`: choose one of `man`, `mdoc`, and `html` for
the installed documentation (default: decided by cmake depending on
available tools)
- `LIBZIP_DO_INSTALL`: If you include libzip as a subproject, link it
statically and do not want to let it install its files, set this
variable to `OFF`. Defaults to `ON`.
If you want to compile with custom `CFLAGS`, set them in the environment
before running `cmake`:
```sh
CFLAGS=-DMY_CUSTOM_FLAG cmake ..
```
If you are compiling on a system with a small stack size, add
`-DZIP_ALLOCATE_BUFFER` to `CFLAGS`.
If you are building on a 32-bit Linux system it might be necessary
to define `_FILE_OFFSET_BITS` to `64`. Your distro will need to provide
a `fts.h` file that is new enough to support this, or the build
will break in `zipcmp`.
You can get verbose build output with by passing `VERBOSE=1` to
`make`.
You can also check the [cmake FAQ](https://cmake.org/Wiki/CMake_FAQ).

31
core/deps/libzip/LICENSE Normal file
View File

@ -0,0 +1,31 @@
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

281
core/deps/libzip/NEWS.md Normal file
View File

@ -0,0 +1,281 @@
1.8.0 [2020-xx-xx]
==================
* Add support for zstd (Zstandard) compression.
* Add support for lzma (ID 14) compression.
1.7.3 [2020-07-15]
==================
* Support cmake < 3.17 again.
* Fix pkgconfig file (regression in 1.7.2).
1.7.2 [2020-07-11]
==================
* Fixes for the CMake `find_project()` files.
* libzip moved to the CMake `libzip::` `NAMESPACE`.
* CMake usage best practice cleanups.
1.7.1 [2020-06-13]
==================
* Restore `LIBZIP_VERSION_{MAJOR,MINOR,MICRO}` symbols.
* Fixes warnings reported by PVS-Studio.
* Add `LIBZIP_DO_INSTALL` build setting to make it easier to use
libzip as subproject.
1.7.0 [2020-06-05]
==================
* Add support for encrypting using traditional PKWare encryption.
* Add `zip_compression_method_supported()`.
* Add `zip_encryption_method_supported()`.
* Add the `ZIP_SOURCE_GET_FILE_ATTRIBUTES` source command.
* Refactor stdio file backend.
* Add CMake find_project() support.
1.6.1 [2020-02-03]
==================
* Bugfix for double-free in `zipcmp(1)` during cleanup.
1.6.0 [2020-01-24]
==================
* Avoid using `umask()` since it's not thread-safe.
* Set close-on-exec flag when opening files.
* Do not accept empty files as valid zip archives any longer.
* Add support for XZ compressed files (using liblzma).
* Add support for cancelling while closing zip archives.
* Add support for setting the time in the on-disk format.
1.5.2 [2019-03-12]
==================
* Fix bug in AES encryption affecting certain file sizes
* Keep file permissions when modifying zip archives
* Support systems with small stack size.
* Support mbed TLS as crypto backend.
* Add nullability annotations.
1.5.1 [2018-04-11]
==================
* Choose format of installed documentation based on available tools.
* Fix visibility of symbols.
* Fix zipcmp directory support.
* Don't set RPATH on Linux.
* Use Libs.private for link dependencies in pkg-config file.
* Fix build with LibreSSL.
* Various bugfixes.
1.5.0 [2018-03-11]
==================
* Use standard cryptographic library instead of custom AES implementation.
This also simplifies the license.
* Use `clang-format` to format the source code.
* More Windows improvements.
1.4.0 [2017-12-29]
==================
* Improve build with cmake
* Retire autoconf/automake build system
* Add `zip_source_buffer_fragment()`.
* Add support to clone unchanged beginning of archive (instead of rewriting it).
Supported for buffer sources and on Apple File System.
* Add support for Microsoft Universal Windows Platform.
1.3.2 [2017-11-20]
==================
* Fix bug introduced in last: zip_t was erroneously freed if zip_close() failed.
1.3.1 [2017-11-19]
==================
* Install zipconf.h into ${PREFIX}/include
* Add zip_libzip_version()
* Fix AES tests on Linux
1.3.0 [2017-09-02]
==================
* Support bzip2 compressed zip archives
* Improve file progress callback code
* Fix zip_fdopen()
* CVE-2017-12858: Fix double free()
* CVE-2017-14107: Improve EOCD64 parsing
1.2.0 [2017-02-19]
==================
* Support for AES encryption (Winzip version), both encryption
and decryption
* Support legacy zip files with >64k entries
* Fix seeking in zip_source_file if start > 0
* Add zip_fseek() for seeking in uncompressed data
* Add zip_ftell() for telling position in uncompressed data
* Add zip_register_progress_callback() for UI updates during zip_close()
1.1.3 [2016-05-28]
==================
* Fix build on Windows when using autoconf
1.1.2 [2016-02-19]
==================
* Improve support for 3MF files
1.1.1 [2016-02-07]
==================
* Build fixes for Linux
* Fix some warnings reported by PVS-Studio
1.1 [2016-01-26]
================
* ziptool(1): command line tool to modify zip archives
* Speedups for archives with many entries
* Coverity fixes
* Better APK support
* Support for running tests on Windows
* More build fixes for Windows
* Portability fixes
* Documentation improvements
1.0.1 [2015-05-04]
==================
* Build fixes for Windows
1.0 [2015-05-03]
================
* Implemented an I/O abstraction layer
* Added support for native Windows API for files
* Added support for setting the last modification time for a file
* Added a new type zip_error_t for errors
* Added more typedefs for structs
* Torrentzip support was removed
* CVE-2015-2331 was fixed
* Addressed all Coverity CIDs
0.11.2 [2013-12-19]
===================
* Support querying/setting operating system and external attributes
* For newly added files, set operating system to UNIX, permissions
to 0666 (0777 for directories)
* Fix bug when writing zip archives containing files bigger than 4GB
0.11.1 [2013-04-27]
===================
* Fix bugs in zip_set_file_compression()
* Include Xcode build infrastructure
0.11 [2013-03-23]
=================
* Added Zip64 support (large file support)
* Added UTF-8 support for file names, file comments, and archive comments
* Changed API for name and comment related functions for UTF-8 support
* Added zip_discard()
* Added ZIP_TRUNCATE for zip_open()
* Added zip_set_file_compression()
* Added API for accessing and modifying extra fields
* Improved API type consistency
* Use gcc4's visibility __attribute__
* More changes for Windows support
* Additional test cases
0.10.1 [2012-03-20]
===================
* Fixed CVE-2012-1162
* Fixed CVE-2012-1163
0.10 [2010-03-18]
=================
* Added zip_get_num_entries(), deprecated zip_get_num_files()
* Better windows support
* Support for traditional PKWARE encryption added
* Fix opening archives with more than 65535 entries
* Fix some memory leaks
* Fix cmake build and installation
* Fix memory leak in error case in zip_open()
* Fixed CVE-2011-0421 (no security implications though)
* More documentation
0.9.3 [2010-02-01]
==================
* Include m4/ directory in distribution; some packagers need it
0.9.2 [2010-01-31]
==================
* Avoid passing uninitialized data to deflate()
* Fix memory leak when closing zip archives
0.9.1 [2010-01-24]
==================
* Fix infinite loop on reading some broken files
* Optimization in time conversion (don't call localtime())
* Clear data descriptor flag in central directory, fixing Open Office files
* Allow more than 64k entries
0.9 [2008-07-25]
==================
* on Windows, explicitly set dllimport/dllexport
* remove erroneous references to GPL
* add support for torrentzip
* new functions: zip_get_archive_flag, zip_set_archive_flag
* zip_source_zip: add flag to force recompression
* zip_sorce_file: only keep file open while reading from it
0.8 [2007-06-06]
==================
* fix for zip archives larger than 2GiB
* fix zip_error_strerror to include libzip error string
* add support for reading streamed zip files
* new functions: zip_add_dir, zip_error_clear, zip_file_error_clear
* add basic support for building with CMake (incomplete)
0.7.1 [2006-05-18]
==================
* bugfix for zip_close
0.7 [2006-05-06]
================
* struct zip_stat increased for future encryption support
* zip_add return value changed (now returns new index of added file)
* shared library major bump because of previous two
* added functions for reading and writing file and archive comments
New functions: zip_get_archive_comment, zip_get_file_comment,
zip_set_archive_comment, zip_set_file_comment, zip_unchange_archive
0.6.1 [2005-07-14]
==================
* various bug fixes
0.6 [2005-06-09]
================
* first standalone release
* changed license to three-clause BSD
* overhauled API
* added man pages
* install zipcmp and zipmerge

View File

@ -0,0 +1,39 @@
This is libzip, a C library for reading, creating, and modifying
zip and zip64 archives. Files can be added from data buffers, files,
or compressed data copied directly from other zip archives. Changes
made without closing the archive can be reverted. Decryption and
encryption of Winzip AES and legacy PKware encrypted files is
supported. The API is documented by man pages.
libzip is fully documented via man pages. HTML versions of the man
pages are on [libzip.org](https://libzip.org/documentation/) and
in the [man](man) directory. You can start with
[libzip(3)](https://libzip.org/documentation/libzip.html), which
lists
all others. Example source code is in the [examples](examples) and
[src](src) subdirectories.
If you have developed an application using libzip, you can find out
about API changes and how to adapt your code for them in the included
file [API-CHANGES.md](API-CHANGES.md).
See the [INSTALL.md](INSTALL.md) file for installation instructions and
dependencies.
If you make a binary distribution, please include a pointer to the
distribution site:
> https://libzip.org/
The latest version can always be found there. The official repository
is at [github](https://github.com/nih-at/libzip/).
There is a mailing list for developers using libzip. You can
subscribe to it by sending a mail with the subject "subscribe
libzip-discuss" to minimalist at nih.at. List mail should be sent
to libzip-discuss at nih.at. Use this for bug reports or questions.
If you want to reach the authors in private, use <libzip@nih.at>.
[![Travis Build Status](https://api.travis-ci.org/nih-at/libzip.svg?branch=master)](https://travis-ci.org/nih-at/libzip)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/f1bqqt9djvf22f5g?svg=true)](https://ci.appveyor.com/project/nih-at/libzip)
[![Coverity Status](https://scan.coverity.com/projects/127/badge.svg)](https://scan.coverity.com/projects/libzip)

117
core/deps/libzip/THANKS Normal file
View File

@ -0,0 +1,117 @@
Thanks to Info-ZIP for info on the DOS-time/date conversion code,
and some other general information gathered from their sources.
Thanks to these people for suggestions, testing, and bug reports:
Agostino Sarubbo
Alexander Galanin <al@galanin.nnov.ru>
Alexandr Shadchin <alexandr.shadchin@gmail.com>
Alexey Bykov <gnfalex@rambler.ru>
Andreas Falkenhahn <andreas@falkenhahn.com>
Andrew Brampton <brampton@gmail.com>
Andrew Molyneux <andrew@molyneuxfamily.co.uk>
Ankur Kothari <ankz.kothari@gmail.com>
Antonin Décimo <antonin.decimo@gmail.com>
Arseniy Terekhin <senyai@gmail.com>
BALATON Zoltan <balaton@eik.bme.hu>
Benjamin Gilbert <bgilbert@backtick.net>
Beuc <beuc@beuc.net>
Boaz Stolk <bstolk@aweta.nl>
Bogdan <bogiebog@gmail.com>
Brian 'geeknik' Carpenter <geeknik@protonmail.ch>
Carl Mastrangelo <notcarl@google.com>
Cédric Tabin
celan69
Charlie Li <git@vishwin.info>
Chris Nehren <cnehren+libzip@pobox.com>
Christoph Cullmann <cullmann@kde.org>
Christoph M. Becker <cmbecker69@gmx.de>
Coverity <info@coverity.com>
Dane Springmeyer <dane.springmeyer@gmail.com>
Ларионов Даниил <scumcoder@yandex.ru>
David Demelier <demelier.david@gmail.com>
Dean Ellis <dellis1972@googlemail.com>
Declan Moran
Del Merritt <del@alum.mit.edu>
Dmytro Rybachenko <atmoliton@gmail.com>
Elvis Angelaccio
Erwin Haid <erwin.haid@gmx.de>
Eun-cheol Joo
Fabrice Fontaine
Florian Delizy <florian.delizy@gmail.com>
Force Charlie <charlieio@outlook.com>
François Simon <AT.GFI.Francois.SIMON@sesam-vitale.fr>
Frederik Ramm <frederik@remote.org>
gk7huki <gk7huki@gmail.com>
Hanno Böck <hanno@hboeck.de>
HeeMyung
Heiko Becker
Heiko Hund <heiko@ist.eigentlich.net>
Ilya Voronin
Info-ZIP group
Jan Weiß <jan@geheimwerk.de>
Jay Freeman (saurik) <saurik@saurik.com>
jloqfjgk@github
Joachim Reichel <joachim.reichel@gmx.de>
João Custódio <joao_custodio@symantec.com>
Joel Ebrahimi <joel.ebrahimi@gmail.com>
Jono Spiro <jono.spiro@gmail.com>
Julien Schueller <schueller@phimeca.com>
kensington <kensington@gentoo.org>
Keith Jones <keith@keithjjones.com>
Khaled Mardam-Bey
Kohei Yoshida <kohei.yoshida@gmail.com>
Leith Bade <leith@mapbox.com>
Lubomir I. Ivanov <neolit123@gmail.com>
Maël Nison
Martin Buchholz <martinrb@google.com>
Martin Herkt <lachs0r@srsfckn.biz>
Martin Szulecki <m.szulecki@libimobiledevice.org>
Michael Balzer
Michael Beck <mm.beck@gmx.net>
Michał Janiszewski <janisozaur+libzip@gmail.com>
Michal Vyskocil <mvyskocil@suse.cz>
Mikhail Gusarov <dottedmag@dottedmag.net>.
Miklos Vajna
Morris Hafner
Oliver Kaiser <under.northern.sky@googlemail.com>
Oliver Kuckertz <oliver.kuckertz@mologie.de>
OSS-Fuzz Team
Ørjan Malde <red@foxi.me>
Pascal Terjan <pterjan@gmail.com>
Patrick Spendrin <ps_ml@gmx.de>
Paul Harris <harris.pc@gmail.com>
Paul Sheppard <shepsoft@googlemail.com>
Pavel Raiskup <praiskup@redhat.com>
Pierre Joye <pierre.php@gmail.com>
Pierre-Louis Cabelguen <plcabelguen@googlemail.com>
Randy <randy408@protonmail.com>
Remi Collet <remi@fedoraproject.org>
Richard Schütz
Rick Carback <carback1@umbc.edu>
Rikard Falkeborn <rikard.falkeborn@gmail.com>
Robert Norris <rw_norris@hotmail.com>
Roberto Tirabassi <rtirabassi@3di.it>
Roland Ortloff <Ortloff.R@gmx.de>
Rosen Penev <rosenp@gmail.com>
Ryan Burns <rtburns@protonmail.com>
Sebastian Kemper <sebastian_ml@gmx.net>
Sebastian Schmitt <sebastian.schmitt@auvesy.de>
Sergei Ozerov <ru.programmist@gmail.com>
Simon Talbot <simont@nse.co.uk>
Stephen Bryant <steve@bawue.de>
Tabata Shintaro <tabata.shintaro@gmail.com>
Tarmo Pikaro <tapika@yahoo.com>
Taylor C. Richberger
TC
Tim Lunn <Tim@feathertop.org>
Timo Warns <warns@pre-sense.de>
Tom Callaway <tcallawa@redhat.com>
Tomas Hoger <thoger@redhat.com>
Tomáš Malý <malytomas@ucpu.cz>
Torsten Paul <Torsten.Paul@gmx.de>
Transporter <ogre.transporter@gmail.com>
Vassili Courzakis <vcoxvco@googlemail.com>
William Lee
Wojciech Michalski <wmichalski@quay.pl>
Wolfgang Glunz <Wolfgang.Glunz@gmx.de>

172
core/deps/libzip/TODO.md Normal file
View File

@ -0,0 +1,172 @@
## Prefixes
For example for adding extractors for self-extracting zip archives.
````c
zip_set_archive_prefix(struct zip *za, const zip_uint8_t *data, zip_uint64_t length);
const zip_uint8_t *zip_get_archive_prefix(struct zip *za, zip_uint64_t *lengthp);
````
## Compression
* add lzma2 support
* add deflate64 support (https://github.com/madler/zlib/blob/master/contrib/infback9/infback9.h)
## API Issues
* `zip_get_archive_comment` has `int *lenp` argument. Cleaner would be `zip_uint32_t *`.
rename and fix. which other functions for naming consistency?
* rename remaining `zip_XXX_{file,archive}_*` to `zip_{file,archive}_XXX_*`?
* compression/crypt implementations: how to set error code on failure
* compression/crypt error messages a la `ZIP_ER_ZLIB` (no detailed info passing)
## Features
* add seek support for AES-encrypted files
* consistently use `_zip_crypto_clear()` for passwords
* support setting extra fields from `zip_source`
* introduce layers of extra fields:
* original
* from `zip_source`
* manually set
* when querying extra fields, search all of them in reverse order
* add whiteout (deleted) flag
* allow invalid data flag, used when computing extra field size before writing data
* new command `ZIP_SOURCE_EXTRA_FIELDS`
* no support for multiple copies of same extra field
* delete all extra fields during `zip_replace()`
* function to copy file from one archive to another
* set `O_CLOEXEC` flag after fopen and mkstemp
* `zip_file_set_mtime()`: support InfoZIP time stamps
* support streaming output (creating new archive to e.g. stdout)
* add function to read/set ASCII file flag
* `zip_commit()` (to finish changes without closing archive)
* add custom compression function support
* `zip_source_zip()`: allow rewinding
* `zipcmp`: add option for file content comparison
* `zipcmp`: add more paranoid checks:
* external attributes/opsys
* last_mod
* version needed/made by
* general purpose bit flags
* add more consistency checks:
* for stored files, test compressed = uncompressed
* data descriptor
* local headers come before central dir
* support for old compression methods?
## Bugs
* ensure that nentries is small enough not to cause overflow (size_t for entry, uint64 for CD on disk)
* check for limits imposed by format (central dir size, file size, extra fields, ...)
* `_zip_u2d_time()`: handle `localtime(3)` failure
* POSIX: `zip_open()`: check whether file can be created and fail if not
* fix inconsistent usage of valid flags (not checked in many places)
* `cdr == NULL` -> `ER_NOENT` vs. `idx > cdir->nentry` -> `ER_INVAL` inconsistent (still there?)
## Cleanup
* go over cdir parser and rename various offset/size variables to make it clearer
* use bool
* use `ZIP_SOURCE_SUPPORTS_{READABLE,SEEKABLE,WRITABLE}`
* use `zip_source_seek_compute_offset()`
* get rid of `zip_get_{compression,encryption}_implementation()`
* use `zip_*int*_t` internally
* `zip_source_file()`: don't allow write if start/len specify a part of the file
## Documentation
* document: `zip_source_write()`: length can't be > `ZIP_INT64_MAX`
* document: `ZIP_SOURCE_CLOSE` implementation can't return error
* keep error codes in man pages in sync
* document error codes in new man pages
## Infrastructure
* review guidelines/community standards
- [Linux Foundation Core Infrastructure Initiative Best Practices](https://bestpractices.coreinfrastructure.org/)
- [Readme Maturity Level](https://github.com/LappleApple/feedmereadmes/blob/master/README-maturity-model.md)
- [Github Community Profile](https://github.com/nih-at/libzip/community)
* test different crypto backends with TravisCI.
* improve man page formatting of tagged lists on webpage (`<dl>`)
* rewrite `make_zip_errors.sh` in cmake
* script to check if all exported symbols are marked with `ZIP_EXTERN`, add to `make distcheck`
## macOS / iOS framework
* get cmake to optionally build frameworks
## Test Case Issues
* test error cases with special source
- tell it which command should fail
- use it both as source for `zip_add` and `zip_open_from_source`
- `ziptool_regress`:
- `-e error_spec`: source containing zip fails depending on `error_spec`
- `add_with_error name content error_spec`: add content to archive, where source fails depending on `error_spec`
- `add_file_with_error name file_to_add offset len error_spec`: add file to archive, len bytes starting from offset, where source fails depending on `error_spec`
- `error_spec`:
- source command that fails
- error code that source returns
- conditions that must be met for error to trigger
- Nth call of command
- read/write: total byte count so far
- state of source (opened, EOF reached, ...)
* test for zipcmp reading directory (requires fts)
* add test case for clone with files > 4k
* consider testing for malloc/realloc failures
* Winzip AES support
* test cases decryption: <=20, >20, stat for both
* test cases encryption: no password, default password, file-specific password, 128/192/256, <=20, >20
* support testing on macOS
* add test cases for lots of files (including too many)
* add test cases for holes (between files, between files and cdir, between cdir and eocd, + zip64 where appropriate)
* test seek in `zip_source_crc()`
* test cases for `set_extra*`, `delete_extra*`, `*extra_field*`
* test cases for in memory archives
* add
* delete
* delete all
* modify
* use gcov output to increase test coverage
* add test case to change values for newly added files (name, compression method, comment, mtime, . . .)
* `zip_open()` file less than `EOCDLEN` bytes long
* test calls against old API
* rename file to dir/ and vice versa (fails)
* fix comment test to be newline insensitive
* check if http://bugs.python.org/issue20078 provides ideas for new tests
* (`add`, `replace`)
* add to empty zip
* add to existing zip
* add w/ existing file name [E]
* replace ok
* replace w/ illegal index [E]
* replace w/ deleted name [E]
* unchange added/replaced file
* (`close`)
* copy zip file
* open copy
* rename, delete, replace, add w/ new name, add w/ deleted name
* close
* zipcmp copy expected
* remove copy
* (`error_get)
* (`error_get_sys_type`)
* (`error_to_str`)
* (`extra_fields`)
* (`file_error_get`)
* (`file_strerror`)
* (`replace`)
* (`source_buffer`)
* (`source_file`)
* (`source_filep`)
* (`source_free`)
* (`source_function`)
* (`source_zip`)
* (`strerror`)
* (`unchange`)
* (`unchange_all`)
* `open(ZIP_RDONLY)`
* I/O abstraction layer
* `zip_open_from_source`
* read two zip entries interleaved

View File

@ -0,0 +1,63 @@
# Author: Declan Moran
# www.silverglint.com
# Thanks to damaex (https://github.com/damaex), for significant contributions
ANDROID_NDK_ROOT=/home/android/android-ndk-r19c
INSTALL_DIR=install
BUILD_DIR=build
START_DIR=$(pwd)
rm -rf $INSTALL_DIR
rm -rf $BUILD_DIR
mkdir -p $BUILD_DIR #"${ANDROID_TARGET_PLATFORM}"
#--------------------------------------------------------------------
build_it()
{
# builds either a static or shared lib depending on parm passed (ON or OFF)
want_shared=$1
cmake -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake \
-DCMAKE_INSTALL_PREFIX:PATH=../../${INSTALL_DIR}/${ANDROID_TARGET_PLATFORM} \
-DANDROID_ABI=${ANDROID_TARGET_PLATFORM} \
-DENABLE_OPENSSL:BOOL=OFF \
-DENABLE_COMMONCRYPTO:BOOL=OFF \
-DENABLE_GNUTLS:BOOL=OFF \
-DENABLE_MBEDTLS:BOOL=OFF \
-DENABLE_OPENSSL:BOOL=OFF \
-DENABLE_WINDOWS_CRYPTO:BOOL=OFF \
-DBUILD_TOOLS:BOOL=OFF \
-DBUILD_REGRESS:BOOL=OFF \
-DBUILD_EXAMPLES:BOOL=OFF \
-DBUILD_SHARED_LIBS:BOOL=$want_shared \
-DBUILD_DOC:BOOL=OFF \
-DANDROID_TOOLCHAIN=clang cmake -H.. -B$BUILD_DIR/${ANDROID_TARGET_PLATFORM}
#run make with all system threads and install
cd $BUILD_DIR/${ANDROID_TARGET_PLATFORM}
make install -j$(nproc --all)
cd $START_DIR
}
#--------------------------------------------------------------------
for ANDROID_TARGET_PLATFORM in armeabi-v7a arm64-v8a x86 x86_64
do
echo "Building libzip for ${ANDROID_TARGET_PLATFORM}"
build_it ON
build_it OFF
if [ $? -ne 0 ]; then
echo "Error executing: cmake"
exit 1
fi
if [ $? -ne 0 ]; then
echo "Error executing make install for platform: ${ANDROID_TARGET_PLATFORM}"
exit 1
fi
done

View File

@ -0,0 +1,122 @@
# Version: 1.0
# Dockerfile for building libzip for android
# https://github.com/dec1/libzip.git
# creates docker container with all tools, libraries and sources required to build libzip for android.
# Author: Declan Moran
# www.silverglint.com
# Usage:
#---------
# download the libzip repository
# > git clone https://github.com/dec1/libzip.git
# > cd libzip
#
# build docker image "my_img_zip" from the dockerfile in "docker" dir
# > docker build -t my_img_zip ./android/docker
#
# run docker container "my_ctr_zip" from this image, mounting the current dir. (Need to pass absolute host paths to mount volume- hence "pwd")
# > docker run -v $(pwd):/home/docker-share/libzip -it --entrypoint=/bin/bash --name my_ctr_zip my_img_zip
#
# Now inside docker container
# $ cd /home/docker-share/libzip/android
#
# Modify ./do.sh (on host), to match the boost and android ndk versions/paths in the "Configure here" section below
# Build from running docker container.
# $./do.sh
#
# "./build" dir contains required build, but owned by root. chown to your username/group
# > sudo chown -R <userid>:<groupid> ./build
# > sudo chown -R <userid>:<groupid> ./install
#
# Exit container, when build is finished.
# $ exit
#
FROM ubuntu:18.04
## --------------------------------------------------------------------
## Configure here
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# Here you can speciofy exactly what android ndk (and sdk) version you want to use.
# (2) Android SDK
# https://developer.android.com/studio#downloads
ARG SDK_URL_BASE=https://dl.google.com/android/repository
ARG SDK_FILE=sdk-tools-linux-4333796.zip
# the sdk platform to use
# https://developer.android.com/guide/topics/manifest/uses-sdk-element
ARG ANDROID_SDK_PLATFORM_VERS="platforms;android-28"
# (3) Android NDK
# https://developer.android.com/ndk/downloads
ARG NDK_URL_BASE=https://dl.google.com/android/repository
ARG NDK_FILE=android-ndk-r19c-linux-x86_64.zip
# ---------------------------------------------------------------------
## --------------------------------------------------------------------
RUN apt-get update
RUN apt-get -y dist-upgrade
# for downloading archives
RUN apt-get -y install wget
# for unzipping downloaded android archives
RUN apt-get -y install zip
RUN apt-get -y install cmake
RUN apt-get -y install lib32z1
# need this this to install some (32 bit) prerequisites for android builds
RUN dpkg --add-architecture i386
RUN apt-get update
RUN apt-get -y dist-upgrade
RUN apt-get install -y libc6:i386 libncurses5:i386 libstdc++6:i386 libbz2-1.0:i386
# need c compiler to set up create boost build system (before building boost with it and android toolchain)
RUN apt-get -y install build-essential
RUN apt-get -y install libc6-dev-i386
RUN apt-get -y install clang
RUN apt-get -y install openjdk-8-jdk
#--------------------------------------
ARG ANDROID_HOME=/home/android
WORKDIR ${ANDROID_HOME}
# SDK
# ----
# download android sdk command line tools
RUN wget ${SDK_URL_BASE}/$SDK_FILE
RUN unzip $SDK_FILE
ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:${ANDROID_HOME}/platform-tools
RUN yes | sdkmanager --licenses
RUN sdkmanager "platform-tools" $ANDROID_SDK_PLATFORM_VERS
#RUN sdkmanager "platform-tools" "platforms;android-28"
# NDK
# ----
RUN wget ${NDK_URL_BASE}/$NDK_FILE
RUN unzip $NDK_FILE

View File

@ -0,0 +1,10 @@
Cross compile libzip for android.
--------------------------------
Modify "do.sh" as appropriate if you need to specify a different ndk dir or wish to specify different build parameters
Prerequisites for the development machine - see docker/Dockerfile
You can either set you host machine up with these prerequisites or simply use docker (in which case you need not install anything on your host machine except docker itself).
See "Usage" in docker/Dockerfile for detailed instructions.

View File

@ -0,0 +1,91 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
CMakePushCheckState
-------------------
This module defines three macros: ``CMAKE_PUSH_CHECK_STATE()``
``CMAKE_POP_CHECK_STATE()`` and ``CMAKE_RESET_CHECK_STATE()`` These macros can
be used to save, restore and reset (i.e., clear contents) the state of
the variables ``CMAKE_REQUIRED_FLAGS``, ``CMAKE_REQUIRED_DEFINITIONS``,
``CMAKE_REQUIRED_LINK_OPTIONS``, ``CMAKE_REQUIRED_LIBRARIES``,
``CMAKE_REQUIRED_INCLUDES`` and ``CMAKE_EXTRA_INCLUDE_FILES`` used by the
various Check-files coming with CMake, like e.g. ``check_function_exists()``
etc.
The variable contents are pushed on a stack, pushing multiple times is
supported. This is useful e.g. when executing such tests in a Find-module,
where they have to be set, but after the Find-module has been executed they
should have the same value as they had before.
``CMAKE_PUSH_CHECK_STATE()`` macro receives optional argument ``RESET``.
Whether it's specified, ``CMAKE_PUSH_CHECK_STATE()`` will set all
``CMAKE_REQUIRED_*`` variables to empty values, same as
``CMAKE_RESET_CHECK_STATE()`` call will do.
Usage:
.. code-block:: cmake
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_DEFINITIONS -DSOME_MORE_DEF)
check_function_exists(...)
cmake_reset_check_state()
set(CMAKE_REQUIRED_DEFINITIONS -DANOTHER_DEF)
check_function_exists(...)
cmake_pop_check_state()
#]=======================================================================]
macro(CMAKE_RESET_CHECK_STATE)
set(CMAKE_EXTRA_INCLUDE_FILES)
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_DEFINITIONS)
set(CMAKE_REQUIRED_LINK_OPTIONS)
set(CMAKE_REQUIRED_LIBRARIES)
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_QUIET)
endmacro()
macro(CMAKE_PUSH_CHECK_STATE)
if(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER)
set(_CMAKE_PUSH_CHECK_STATE_COUNTER 0)
endif()
math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1")
set(_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_EXTRA_INCLUDE_FILES})
set(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_INCLUDES})
set(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS})
set(_CMAKE_REQUIRED_LINK_OPTIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LINK_OPTIONS})
set(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LIBRARIES})
set(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_FLAGS})
set(_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_QUIET})
if (${ARGC} GREATER 0 AND "${ARGV0}" STREQUAL "RESET")
cmake_reset_check_state()
endif()
endmacro()
macro(CMAKE_POP_CHECK_STATE)
# don't pop more than we pushed
if("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0")
set(CMAKE_EXTRA_INCLUDE_FILES ${_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_LINK_OPTIONS ${_CMAKE_REQUIRED_LINK_OPTIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_QUIET ${_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1")
endif()
endmacro()

View File

@ -0,0 +1,102 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
CheckLibraryExists
------------------
Check if the function exists.
.. command:: CHECK_LIBRARY_EXISTS
.. code-block:: cmake
CHECK_LIBRARY_EXISTS(LIBRARY FUNCTION LOCATION VARIABLE)
::
LIBRARY - the name of the library you are looking for
FUNCTION - the name of the function
LOCATION - location where the library should be found
VARIABLE - variable to store the result
Will be created as an internal cache variable.
The following variables may be set before calling this macro to modify
the way the check is run:
::
CMAKE_REQUIRED_FLAGS = string of compile command line flags
CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
CMAKE_REQUIRED_LINK_OPTIONS = list of options to pass to link command
CMAKE_REQUIRED_LIBRARIES = list of libraries to link
CMAKE_REQUIRED_QUIET = execute quietly without messages
#]=======================================================================]
if(__CheckLibraryExists_cmake__)
return()
endif()
set(__CheckLibraryExists_cmake__ TRUE)
macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
if(NOT DEFINED "${VARIABLE}")
set(MACRO_CHECK_LIBRARY_EXISTS_DEFINITION
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_START "Looking for ${FUNCTION} in ${LIBRARY}")
endif()
set(CHECK_LIBRARY_EXISTS_LINK_OPTIONS)
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_LIBRARY_EXISTS_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
endif()
set(CHECK_LIBRARY_EXISTS_LIBRARIES ${LIBRARY})
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_LIBRARY_EXISTS_LIBRARIES
${CHECK_LIBRARY_EXISTS_LIBRARIES} ${CMAKE_REQUIRED_LIBRARIES})
endif()
if(CMAKE_C_COMPILER_LOADED)
set(_cle_source ${CMAKE_ROOT}/Modules/CheckFunctionExists.c)
elseif(CMAKE_CXX_COMPILER_LOADED)
set(_cle_source ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckLibraryExists/CheckFunctionExists.cxx)
configure_file(${CMAKE_ROOT}/Modules/CheckFunctionExists.c "${_cle_source}" COPYONLY)
else()
message(FATAL_ERROR "CHECK_FUNCTION_EXISTS needs either C or CXX language enabled")
endif()
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
${_cle_source}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_LIBRARY_EXISTS_LINK_OPTIONS}
LINK_LIBRARIES ${CHECK_LIBRARY_EXISTS_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_LIBRARY_EXISTS_DEFINITION}
-DLINK_DIRECTORIES:STRING=${LOCATION}
OUTPUT_VARIABLE OUTPUT)
unset(_cle_source)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have library ${LIBRARY}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the function ${FUNCTION} exists in the ${LIBRARY} "
"passed with the following output:\n"
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have library ${LIBRARY}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the function ${FUNCTION} exists in the ${LIBRARY} "
"failed with the following output:\n"
"${OUTPUT}\n\n")
endif()
endif()
endmacro()

View File

@ -0,0 +1,169 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
CheckSymbolExists
-----------------
Provides a macro to check if a symbol exists as a function, variable,
or macro in ``C``.
.. command:: check_symbol_exists
.. code-block:: cmake
check_symbol_exists(<symbol> <files> <variable>)
Check that the ``<symbol>`` is available after including given header
``<files>`` and store the result in a ``<variable>``. Specify the list
of files in one argument as a semicolon-separated list.
``<variable>`` will be created as an internal cache variable.
If the header files define the symbol as a macro it is considered
available and assumed to work. If the header files declare the symbol
as a function or variable then the symbol must also be available for
linking (so intrinsics may not be detected).
If the symbol is a type, enum value, or intrinsic it will not be recognized
(consider using :module:`CheckTypeSize` or :module:`CheckCSourceCompiles`).
If the check needs to be done in C++, consider using
:module:`CheckCXXSymbolExists` instead.
The following variables may be set before calling this macro to modify
the way the check is run:
``CMAKE_REQUIRED_FLAGS``
string of compile command line flags.
``CMAKE_REQUIRED_DEFINITIONS``
a :ref:`;-list <CMake Language Lists>` of macros to define (-DFOO=bar).
``CMAKE_REQUIRED_INCLUDES``
a :ref:`;-list <CMake Language Lists>` of header search paths to pass to
the compiler.
``CMAKE_REQUIRED_LINK_OPTIONS``
a :ref:`;-list <CMake Language Lists>` of options to add to the link command.
``CMAKE_REQUIRED_LIBRARIES``
a :ref:`;-list <CMake Language Lists>` of libraries to add to the link
command. See policy :policy:`CMP0075`.
``CMAKE_REQUIRED_QUIET``
execute quietly without messages.
For example:
.. code-block:: cmake
include(CheckSymbolExists)
# Check for macro SEEK_SET
check_symbol_exists(SEEK_SET "stdio.h" HAVE_SEEK_SET)
# Check for function fopen
check_symbol_exists(fopen "stdio.h" HAVE_FOPEN)
#]=======================================================================]
if(__CheckSymbolExists_cmake__)
return()
endif()
set(__CheckSymbolExists_cmake__ TRUE)
cmake_policy(PUSH)
cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
if(CMAKE_C_COMPILER_LOADED)
__CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
elseif(CMAKE_CXX_COMPILER_LOADED)
__CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
else()
message(FATAL_ERROR "CHECK_SYMBOL_EXISTS needs either C or CXX language enabled")
endif()
endmacro()
macro(__CHECK_SYMBOL_EXISTS_IMPL SOURCEFILE SYMBOL FILES VARIABLE)
if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
set(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_SYMBOL_EXISTS_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
else()
set(CHECK_SYMBOL_EXISTS_LINK_OPTIONS)
endif()
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_SYMBOL_EXISTS_LIBS
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
else()
set(CHECK_SYMBOL_EXISTS_LIBS)
endif()
if(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_SYMBOL_EXISTS_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else()
set(CMAKE_SYMBOL_EXISTS_INCLUDES)
endif()
foreach(FILE ${FILES})
string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT
"#include <${FILE}>\n")
endforeach()
string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "
int main(int argc, char** argv)
{
(void)argv;")
set(_CSE_CHECK_NON_MACRO "return ((int*)(&${SYMBOL}))[argc];")
if("${SYMBOL}" MATCHES "^[a-zA-Z_][a-zA-Z0-9_]*$")
# The SYMBOL has a legal macro name. Test whether it exists as a macro.
string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "
#ifndef ${SYMBOL}
${_CSE_CHECK_NON_MACRO}
#else
(void)argc;
return 0;
#endif")
else()
# The SYMBOL cannot be a macro (e.g., a template function).
string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "
${_CSE_CHECK_NON_MACRO}")
endif()
string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "
}")
unset(_CSE_CHECK_NON_MACRO)
configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
"${SOURCEFILE}" @ONLY)
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_START "Looking for ${SYMBOL}")
endif()
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
"${SOURCEFILE}"
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_SYMBOL_EXISTS_LINK_OPTIONS}
${CHECK_SYMBOL_EXISTS_LIBS}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS}
"${CMAKE_SYMBOL_EXISTS_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the ${SYMBOL} "
"exist passed with the following output:\n"
"${OUTPUT}\nFile ${SOURCEFILE}:\n"
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the ${SYMBOL} "
"exist failed with the following output:\n"
"${OUTPUT}\nFile ${SOURCEFILE}:\n"
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
endif()
unset(CMAKE_CONFIGURABLE_FILE_CONTENT)
endif()
endmacro()
cmake_policy(POP)

View File

@ -0,0 +1,104 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindBZip2
---------
Try to find BZip2
IMPORTED Targets
^^^^^^^^^^^^^^^^
This module defines :prop_tgt:`IMPORTED` target ``BZip2::BZip2``, if
BZip2 has been found.
Result Variables
^^^^^^^^^^^^^^^^
This module defines the following variables:
``BZIP2_FOUND``
system has BZip2
``BZIP2_INCLUDE_DIRS``
the BZip2 include directories
``BZIP2_LIBRARIES``
Link these to use BZip2
``BZIP2_NEED_PREFIX``
this is set if the functions are prefixed with ``BZ2_``
``BZIP2_VERSION_STRING``
the version of BZip2 found
Cache variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``BZIP2_INCLUDE_DIR``
the BZip2 include directory
#]=======================================================================]
set(_BZIP2_PATHS PATHS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Bzip2;InstallPath]"
)
find_path(BZIP2_INCLUDE_DIR bzlib.h ${_BZIP2_PATHS} PATH_SUFFIXES include)
if (NOT BZIP2_LIBRARIES)
find_library(BZIP2_LIBRARY_RELEASE NAMES bz2 bzip2 libbz2 libbzip2 ${_BZIP2_PATHS} PATH_SUFFIXES lib)
find_library(BZIP2_LIBRARY_DEBUG NAMES bz2d bzip2d libbz2d libbzip2d ${_BZIP2_PATHS} PATH_SUFFIXES lib)
include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
SELECT_LIBRARY_CONFIGURATIONS(BZIP2)
else ()
file(TO_CMAKE_PATH "${BZIP2_LIBRARIES}" BZIP2_LIBRARIES)
endif ()
if (BZIP2_INCLUDE_DIR AND EXISTS "${BZIP2_INCLUDE_DIR}/bzlib.h")
file(STRINGS "${BZIP2_INCLUDE_DIR}/bzlib.h" BZLIB_H REGEX "bzip2/libbzip2 version [0-9]+\\.[^ ]+ of [0-9]+ ")
string(REGEX REPLACE ".* bzip2/libbzip2 version ([0-9]+\\.[^ ]+) of [0-9]+ .*" "\\1" BZIP2_VERSION_STRING "${BZLIB_H}")
endif ()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZip2
REQUIRED_VARS BZIP2_LIBRARIES BZIP2_INCLUDE_DIR
VERSION_VAR BZIP2_VERSION_STRING)
if (BZIP2_FOUND)
set(BZIP2_INCLUDE_DIRS ${BZIP2_INCLUDE_DIR})
include(${CMAKE_CURRENT_LIST_DIR}/CheckSymbolExists.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET ${BZip2_FIND_QUIETLY})
set(CMAKE_REQUIRED_INCLUDES ${BZIP2_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${BZIP2_LIBRARIES})
CHECK_SYMBOL_EXISTS(BZ2_bzCompressInit "bzlib.h" BZIP2_NEED_PREFIX)
cmake_pop_check_state()
if(NOT TARGET BZip2::BZip2)
add_library(BZip2::BZip2 UNKNOWN IMPORTED)
set_target_properties(BZip2::BZip2 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BZIP2_INCLUDE_DIRS}")
if(BZIP2_LIBRARY_RELEASE)
set_property(TARGET BZip2::BZip2 APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(BZip2::BZip2 PROPERTIES
IMPORTED_LOCATION_RELEASE "${BZIP2_LIBRARY_RELEASE}")
endif()
if(BZIP2_LIBRARY_DEBUG)
set_property(TARGET BZip2::BZip2 APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(BZip2::BZip2 PROPERTIES
IMPORTED_LOCATION_DEBUG "${BZIP2_LIBRARY_DEBUG}")
endif()
if(NOT BZIP2_LIBRARY_RELEASE AND NOT BZIP2_LIBRARY_DEBUG)
set_property(TARGET BZip2::BZip2 APPEND PROPERTY
IMPORTED_LOCATION "${BZIP2_LIBRARY}")
endif()
endif()
endif ()
mark_as_advanced(BZIP2_INCLUDE_DIR)

View File

@ -0,0 +1,82 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindGnuTLS
----------
Find the GNU Transport Layer Security library (gnutls)
IMPORTED Targets
^^^^^^^^^^^^^^^^
This module defines :prop_tgt:`IMPORTED` target ``GnuTLS::GnuTLS``, if
gnutls has been found.
Result Variables
^^^^^^^^^^^^^^^^
``GNUTLS_FOUND``
System has gnutls
``GNUTLS_INCLUDE_DIR``
The gnutls include directory
``GNUTLS_LIBRARIES``
The libraries needed to use gnutls
``GNUTLS_DEFINITIONS``
Compiler switches required for using gnutls
``GNUTLS_VERSION``
version of gnutls.
#]=======================================================================]
# Note that this doesn't try to find the gnutls-extra package.
if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY)
# in cache already
set(gnutls_FIND_QUIETLY TRUE)
endif ()
if (NOT WIN32)
# try using pkg-config to get the directories and then use these values
# in the find_path() and find_library() calls
# also fills in GNUTLS_DEFINITIONS, although that isn't normally useful
find_package(PkgConfig QUIET)
PKG_CHECK_MODULES(PC_GNUTLS QUIET gnutls)
set(GNUTLS_DEFINITIONS ${PC_GNUTLS_CFLAGS_OTHER})
set(GNUTLS_VERSION ${PC_GNUTLS_VERSION})
# keep for backward compatibility
set(GNUTLS_VERSION_STRING ${PC_GNUTLS_VERSION})
endif ()
find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h
HINTS
${PC_GNUTLS_INCLUDEDIR}
${PC_GNUTLS_INCLUDE_DIRS}
)
find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls
HINTS
${PC_GNUTLS_LIBDIR}
${PC_GNUTLS_LIBRARY_DIRS}
)
mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GnuTLS
REQUIRED_VARS GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR
VERSION_VAR GNUTLS_VERSION_STRING)
if(GNUTLS_FOUND)
set(GNUTLS_LIBRARIES ${GNUTLS_LIBRARY})
set(GNUTLS_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR})
if(NOT TARGET GnuTLS::GnuTLS)
add_library(GnuTLS::GnuTLS UNKNOWN IMPORTED)
set_target_properties(GnuTLS::GnuTLS PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GNUTLS_INCLUDE_DIRS}"
INTERFACE_COMPILE_DEFINITIONS "${GNUTLS_DEFINITIONS}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${GNUTLS_LIBRARIES}")
endif()
endif()

View File

@ -0,0 +1,124 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindLibLZMA
-----------
Find LZMA compression algorithm headers and library.
Imported Targets
^^^^^^^^^^^^^^^^
This module defines :prop_tgt:`IMPORTED` target ``LibLZMA::LibLZMA``, if
liblzma has been found.
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``LIBLZMA_FOUND``
True if liblzma headers and library were found.
``LIBLZMA_INCLUDE_DIRS``
Directory where liblzma headers are located.
``LIBLZMA_LIBRARIES``
Lzma libraries to link against.
``LIBLZMA_HAS_AUTO_DECODER``
True if lzma_auto_decoder() is found (required).
``LIBLZMA_HAS_EASY_ENCODER``
True if lzma_easy_encoder() is found (required).
``LIBLZMA_HAS_LZMA_PRESET``
True if lzma_lzma_preset() is found (required).
``LIBLZMA_VERSION_MAJOR``
The major version of lzma
``LIBLZMA_VERSION_MINOR``
The minor version of lzma
``LIBLZMA_VERSION_PATCH``
The patch version of lzma
``LIBLZMA_VERSION_STRING``
version number as a string (ex: "5.0.3")
#]=======================================================================]
find_path(LIBLZMA_INCLUDE_DIR lzma.h )
if(NOT LIBLZMA_LIBRARY)
find_library(LIBLZMA_LIBRARY_RELEASE NAMES lzma liblzma PATH_SUFFIXES lib)
find_library(LIBLZMA_LIBRARY_DEBUG NAMES lzmad liblzmad PATH_SUFFIXES lib)
include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
select_library_configurations(LIBLZMA)
else()
file(TO_CMAKE_PATH "${LIBLZMA_LIBRARY}" LIBLZMA_LIBRARY)
endif()
if(LIBLZMA_INCLUDE_DIR AND EXISTS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h")
file(STRINGS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h" LIBLZMA_HEADER_CONTENTS REGEX "#define LZMA_VERSION_[A-Z]+ [0-9]+")
string(REGEX REPLACE ".*#define LZMA_VERSION_MAJOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MAJOR "${LIBLZMA_HEADER_CONTENTS}")
string(REGEX REPLACE ".*#define LZMA_VERSION_MINOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MINOR "${LIBLZMA_HEADER_CONTENTS}")
string(REGEX REPLACE ".*#define LZMA_VERSION_PATCH ([0-9]+).*" "\\1" LIBLZMA_VERSION_PATCH "${LIBLZMA_HEADER_CONTENTS}")
set(LIBLZMA_VERSION_STRING "${LIBLZMA_VERSION_MAJOR}.${LIBLZMA_VERSION_MINOR}.${LIBLZMA_VERSION_PATCH}")
unset(LIBLZMA_HEADER_CONTENTS)
endif()
# We're using new code known now as XZ, even library still been called LZMA
# it can be found in http://tukaani.org/xz/
# Avoid using old codebase
if (LIBLZMA_LIBRARY)
include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
set(CMAKE_REQUIRED_QUIET ${LibLZMA_FIND_QUIETLY})
if(NOT LIBLZMA_LIBRARY_RELEASE AND NOT LIBLZMA_LIBRARY_DEBUG)
set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY})
elseif(LIBLZMA_LIBRARY_RELEASE)
set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY_RELEASE})
elseif(LIBLZMA_LIBRARY_DEBUG)
set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY_DEBUG})
endif()
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_auto_decoder "" LIBLZMA_HAS_AUTO_DECODER)
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_easy_encoder "" LIBLZMA_HAS_EASY_ENCODER)
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_lzma_preset "" LIBLZMA_HAS_LZMA_PRESET)
unset(LIBLZMA_LIBRARY_check)
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
endif ()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(LibLZMA REQUIRED_VARS LIBLZMA_LIBRARY
LIBLZMA_INCLUDE_DIR
LIBLZMA_HAS_AUTO_DECODER
LIBLZMA_HAS_EASY_ENCODER
LIBLZMA_HAS_LZMA_PRESET
VERSION_VAR LIBLZMA_VERSION_STRING
)
mark_as_advanced( LIBLZMA_INCLUDE_DIR LIBLZMA_LIBRARY )
if (LIBLZMA_FOUND)
set(LIBLZMA_LIBRARIES ${LIBLZMA_LIBRARY})
set(LIBLZMA_INCLUDE_DIRS ${LIBLZMA_INCLUDE_DIR})
if(NOT TARGET LibLZMA::LibLZMA)
add_library(LibLZMA::LibLZMA UNKNOWN IMPORTED)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${LIBLZMA_INCLUDE_DIR}
IMPORTED_LINK_INTERFACE_LANGUAGES C)
if(LIBLZMA_LIBRARY_RELEASE)
set_property(TARGET LibLZMA::LibLZMA APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
IMPORTED_LOCATION_RELEASE "${LIBLZMA_LIBRARY_RELEASE}")
endif()
if(LIBLZMA_LIBRARY_DEBUG)
set_property(TARGET LibLZMA::LibLZMA APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
IMPORTED_LOCATION_DEBUG "${LIBLZMA_LIBRARY_DEBUG}")
endif()
if(NOT LIBLZMA_LIBRARY_RELEASE AND NOT LIBLZMA_LIBRARY_DEBUG)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
IMPORTED_LOCATION "${LIBLZMA_LIBRARY}")
endif()
endif()
endif ()

View File

@ -0,0 +1,453 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindPackageHandleStandardArgs
-----------------------------
This module provides a function intended to be used in :ref:`Find Modules`
implementing :command:`find_package(<PackageName>)` calls. It handles the
``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``.
It also sets the ``<PackageName>_FOUND`` variable. The package is
considered found if all variables listed contain valid results, e.g.
valid filepaths.
.. command:: find_package_handle_standard_args
There are two signatures::
find_package_handle_standard_args(<PackageName>
(DEFAULT_MSG|<custom-failure-message>)
<required-var>...
)
find_package_handle_standard_args(<PackageName>
[FOUND_VAR <result-var>]
[REQUIRED_VARS <required-var>...]
[VERSION_VAR <version-var>]
[HANDLE_COMPONENTS]
[CONFIG_MODE]
[NAME_MISMATCHED]
[REASON_FAILURE_MESSAGE <reason-failure-message>]
[FAIL_MESSAGE <custom-failure-message>]
)
The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all
the variables ``<required-var>...`` are valid and any optional
constraints are satisfied, and ``FALSE`` otherwise. A success or
failure message may be displayed based on the results and on
whether the ``REQUIRED`` and/or ``QUIET`` option was given to
the :command:`find_package` call.
The options are:
``(DEFAULT_MSG|<custom-failure-message>)``
In the simple signature this specifies the failure message.
Use ``DEFAULT_MSG`` to ask for a default message to be computed
(recommended). Not valid in the full signature.
``FOUND_VAR <result-var>``
Obsolete. Specifies either ``<PackageName>_FOUND`` or
``<PACKAGENAME>_FOUND`` as the result variable. This exists only
for compatibility with older versions of CMake and is now ignored.
Result variables of both names are always set for compatibility.
``REQUIRED_VARS <required-var>...``
Specify the variables which are required for this package.
These may be named in the generated failure message asking the
user to set the missing variable values. Therefore these should
typically be cache entries such as ``FOO_LIBRARY`` and not output
variables like ``FOO_LIBRARIES``.
``VERSION_VAR <version-var>``
Specify the name of a variable that holds the version of the package
that has been found. This version will be checked against the
(potentially) specified required version given to the
:command:`find_package` call, including its ``EXACT`` option.
The default messages include information about the required
version and the version which has been actually found, both
if the version is ok or not.
``HANDLE_COMPONENTS``
Enable handling of package components. In this case, the command
will report which components have been found and which are missing,
and the ``<PackageName>_FOUND`` variable will be set to ``FALSE``
if any of the required components (i.e. not the ones listed after
the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are
missing.
``CONFIG_MODE``
Specify that the calling find module is a wrapper around a
call to ``find_package(<PackageName> NO_MODULE)``. This implies
a ``VERSION_VAR`` value of ``<PackageName>_VERSION``. The command
will automatically check whether the package configuration file
was found.
``REASON_FAILURE_MESSAGE <reason-failure-message>``
Specify a custom message of the reason for the failure which will be
appended to the default generated message.
``FAIL_MESSAGE <custom-failure-message>``
Specify a custom failure message instead of using the default
generated message. Not recommended.
``NAME_MISMATCHED``
Indicate that the ``<PackageName>`` does not match
``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a
warning, but it may be intentional for usage of the command for components
of a larger package.
Example for the simple signature:
.. code-block:: cmake
find_package_handle_standard_args(LibXml2 DEFAULT_MSG
LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
The ``LibXml2`` package is considered to be found if both
``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid.
Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found
and ``REQUIRED`` was used, it fails with a
:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was
used or not. If it is found, success will be reported, including
the content of the first ``<required-var>``. On repeated CMake runs,
the same message will not be printed again.
.. note::
If ``<PackageName>`` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the
calling module, a warning that there is a mismatch is given. The
``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using
the old signature and the ``NAME_MISMATCHED`` argument using the new
signature. To avoid forcing the caller to require newer versions of CMake for
usage, the variable's value will be used if defined when the
``NAME_MISMATCHED`` argument is not passed for the new signature (but using
both is an error)..
Example for the full signature:
.. code-block:: cmake
find_package_handle_standard_args(LibArchive
REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
VERSION_VAR LibArchive_VERSION)
In this case, the ``LibArchive`` package is considered to be found if
both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid.
Also the version of ``LibArchive`` will be checked by using the version
contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given,
the default messages will be printed.
Another example for the full signature:
.. code-block:: cmake
find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
find_package_handle_standard_args(Automoc4 CONFIG_MODE)
In this case, a ``FindAutmoc4.cmake`` module wraps a call to
``find_package(Automoc4 NO_MODULE)`` and adds an additional search
directory for ``automoc4``. Then the call to
``find_package_handle_standard_args`` produces a proper success/failure
message.
#]=======================================================================]
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
# internal helper macro
macro(_FPHSA_FAILURE_MESSAGE _msg)
set (__msg "${_msg}")
if (FPHSA_REASON_FAILURE_MESSAGE)
string(APPEND __msg "\n Reason given by package: ${FPHSA_REASON_FAILURE_MESSAGE}\n")
endif()
if (${_NAME}_FIND_REQUIRED)
message(FATAL_ERROR "${__msg}")
else ()
if (NOT ${_NAME}_FIND_QUIETLY)
message(STATUS "${__msg}")
endif ()
endif ()
endmacro()
# internal helper macro to generate the failure message when used in CONFIG_MODE:
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
# <PackageName>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
if(${_NAME}_CONFIG)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
else()
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
# List them all in the error message:
if(${_NAME}_CONSIDERED_CONFIGS)
set(configsText "")
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
math(EXPR configsCount "${configsCount} - 1")
foreach(currentConfigIndex RANGE ${configsCount})
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
string(APPEND configsText "\n ${filename} (version ${version})")
endforeach()
if (${_NAME}_NOT_FOUND_MESSAGE)
if (FPHSA_REASON_FAILURE_MESSAGE)
string(PREPEND FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}\n ")
else()
set(FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}")
endif()
else()
string(APPEND configsText "\n")
endif()
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:${configsText}")
else()
# Simple case: No Config-file was found at all:
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
endif()
endif()
endmacro()
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# Set up the arguments for `cmake_parse_arguments`.
set(options CONFIG_MODE HANDLE_COMPONENTS NAME_MISMATCHED)
set(oneValueArgs FAIL_MESSAGE REASON_FAILURE_MESSAGE VERSION_VAR FOUND_VAR)
set(multiValueArgs REQUIRED_VARS)
# Check whether we are in 'simple' or 'extended' mode:
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
unset(FPHSA_NAME_MISMATCHED_override)
if (DEFINED FPHSA_NAME_MISMATCHED)
# If the variable NAME_MISMATCHED variable is set, error if it is passed as
# an argument. The former is for old signatures, the latter is for new
# signatures.
list(FIND ARGN "NAME_MISMATCHED" name_mismatched_idx)
if (NOT name_mismatched_idx EQUAL "-1")
message(FATAL_ERROR
"The `NAME_MISMATCHED` argument may only be specified by the argument or "
"the variable, not both.")
endif ()
# But use the variable if it is not an argument to avoid forcing minimum
# CMake version bumps for calling modules.
set(FPHSA_NAME_MISMATCHED_override "${FPHSA_NAME_MISMATCHED}")
endif ()
if(${INDEX} EQUAL -1)
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
set(FPHSA_REQUIRED_VARS ${ARGN})
set(FPHSA_VERSION_VAR)
else()
cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
if(FPHSA_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
endif()
if(NOT FPHSA_FAIL_MESSAGE)
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
endif()
# In config-mode, we rely on the variable <PackageName>_CONFIG, which is set by find_package()
# when it successfully found the config-file, including version checking:
if(FPHSA_CONFIG_MODE)
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
endif()
if(NOT FPHSA_REQUIRED_VARS)
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
endif()
endif()
if (DEFINED FPHSA_NAME_MISMATCHED_override)
set(FPHSA_NAME_MISMATCHED "${FPHSA_NAME_MISMATCHED_override}")
endif ()
if (DEFINED CMAKE_FIND_PACKAGE_NAME
AND NOT FPHSA_NAME_MISMATCHED
AND NOT _NAME STREQUAL CMAKE_FIND_PACKAGE_NAME)
message(AUTHOR_WARNING
"The package name passed to `find_package_handle_standard_args` "
"(${_NAME}) does not match the name of the calling package "
"(${CMAKE_FIND_PACKAGE_NAME}). This can lead to problems in calling "
"code that expects `find_package` result variables (e.g., `_FOUND`) "
"to follow a certain pattern.")
endif ()
# now that we collected all arguments, process them
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
endif()
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
string(TOUPPER ${_NAME} _NAME_UPPER)
string(TOLOWER ${_NAME} _NAME_LOWER)
if(FPHSA_FOUND_VAR)
set(_FOUND_VAR_UPPER ${_NAME_UPPER}_FOUND)
set(_FOUND_VAR_MIXED ${_NAME}_FOUND)
if(FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_MIXED OR FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_UPPER)
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
else()
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_FOUND_VAR_MIXED}\" and \"${_FOUND_VAR_UPPER}\" are valid names.")
endif()
else()
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
endif()
# collect all variables which were not found, so they can be printed, so the
# user knows better what went wrong (#6375)
set(MISSING_VARS "")
set(DETAILS "")
# check if all passed variables are valid
set(FPHSA_FOUND_${_NAME} TRUE)
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
if(NOT ${_CURRENT_VAR})
set(FPHSA_FOUND_${_NAME} FALSE)
string(APPEND MISSING_VARS " ${_CURRENT_VAR}")
else()
string(APPEND DETAILS "[${${_CURRENT_VAR}}]")
endif()
endforeach()
if(FPHSA_FOUND_${_NAME})
set(${_NAME}_FOUND TRUE)
set(${_NAME_UPPER}_FOUND TRUE)
else()
set(${_NAME}_FOUND FALSE)
set(${_NAME_UPPER}_FOUND FALSE)
endif()
# component handling
unset(FOUND_COMPONENTS_MSG)
unset(MISSING_COMPONENTS_MSG)
if(FPHSA_HANDLE_COMPONENTS)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(${_NAME}_${comp}_FOUND)
if(NOT DEFINED FOUND_COMPONENTS_MSG)
set(FOUND_COMPONENTS_MSG "found components:")
endif()
string(APPEND FOUND_COMPONENTS_MSG " ${comp}")
else()
if(NOT DEFINED MISSING_COMPONENTS_MSG)
set(MISSING_COMPONENTS_MSG "missing components:")
endif()
string(APPEND MISSING_COMPONENTS_MSG " ${comp}")
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
string(APPEND MISSING_VARS " ${comp}")
endif()
endif()
endforeach()
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
string(APPEND DETAILS "[c${COMPONENT_MSG}]")
endif()
# version handling:
set(VERSION_MSG "")
set(VERSION_OK TRUE)
# check with DEFINED here as the requested or found version may be "0"
if (DEFINED ${_NAME}_FIND_VERSION)
if(DEFINED ${FPHSA_VERSION_VAR})
set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}})
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
# count the dots in the version string
string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}")
# add one dot because there is one dot more than there are components
string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
# Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
# is at most 4 here. Therefore a simple lookup table is used.
if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
set(_VERSION_REGEX "[^.]*")
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
set(_VERSION_REGEX "[^.]*\\.[^.]*")
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
else ()
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
endif ()
string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}")
unset(_VERSION_REGEX)
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")")
endif ()
unset(_VERSION_HEAD)
else ()
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION)
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")")
endif ()
endif ()
unset(_VERSION_DOTS)
else() # minimum version specified:
if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION)
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")")
endif ()
endif()
else()
# if the package was not found, but a version was given, add that to the output:
if(${_NAME}_FIND_VERSION_EXACT)
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
else()
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
endif()
endif()
else ()
# Check with DEFINED as the found version may be 0.
if(DEFINED ${FPHSA_VERSION_VAR})
set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")")
endif()
endif ()
if(VERSION_OK)
string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]")
else()
set(${_NAME}_FOUND FALSE)
endif()
# print the result:
if (${_NAME}_FOUND)
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
else ()
if(FPHSA_CONFIG_MODE)
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
else()
if(NOT VERSION_OK)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
else()
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}")
endif()
endif()
endif ()
set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,48 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindPackageMessage
------------------
.. code-block:: cmake
find_package_message(<name> "message for user" "find result details")
This function is intended to be used in FindXXX.cmake modules files.
It will print a message once for each unique find result. This is
useful for telling the user where a package was found. The first
argument specifies the name (XXX) of the package. The second argument
specifies the message to display. The third argument lists details
about the find result so that if they change the message will be
displayed again. The macro also obeys the QUIET argument to the
find_package command.
Example:
.. code-block:: cmake
if(X11_FOUND)
find_package_message(X11 "Found X11: ${X11_X11_LIB}"
"[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
else()
...
endif()
#]=======================================================================]
function(find_package_message pkg msg details)
# Avoid printing a message repeatedly for the same find result.
if(NOT ${pkg}_FIND_QUIETLY)
string(REPLACE "\n" "" details "${details}")
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
# The message has not yet been printed.
message(STATUS "${msg}")
# Save the find details in the cache to avoid printing the same
# message again.
set("${DETAILS_VAR}" "${details}"
CACHE INTERNAL "Details about finding ${pkg}")
endif()
endif()
endfunction()

View File

@ -0,0 +1,80 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
SelectLibraryConfigurations
---------------------------
.. code-block:: cmake
select_library_configurations(basename)
This macro takes a library base name as an argument, and will choose
good values for the variables
::
basename_LIBRARY
basename_LIBRARIES
basename_LIBRARY_DEBUG
basename_LIBRARY_RELEASE
depending on what has been found and set.
If only ``basename_LIBRARY_RELEASE`` is defined, ``basename_LIBRARY`` will
be set to the release value, and ``basename_LIBRARY_DEBUG`` will be set
to ``basename_LIBRARY_DEBUG-NOTFOUND``. If only ``basename_LIBRARY_DEBUG``
is defined, then ``basename_LIBRARY`` will take the debug value, and
``basename_LIBRARY_RELEASE`` will be set to ``basename_LIBRARY_RELEASE-NOTFOUND``.
If the generator supports configuration types, then ``basename_LIBRARY``
and ``basename_LIBRARIES`` will be set with debug and optimized flags
specifying the library to be used for the given configuration. If no
build type has been set or the generator in use does not support
configuration types, then ``basename_LIBRARY`` and ``basename_LIBRARIES``
will take only the release value, or the debug value if the release one
is not set.
#]=======================================================================]
# This macro was adapted from the FindQt4 CMake module and is maintained by Will
# Dicharry <wdicharry@stellarscience.com>.
macro(select_library_configurations basename)
if(NOT ${basename}_LIBRARY_RELEASE)
set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.")
endif()
if(NOT ${basename}_LIBRARY_DEBUG)
set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.")
endif()
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND
NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND
( _isMultiConfig OR CMAKE_BUILD_TYPE ) )
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
set( ${basename}_LIBRARY "" )
foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE )
list( APPEND ${basename}_LIBRARY optimized "${_libname}" )
endforeach()
foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG )
list( APPEND ${basename}_LIBRARY debug "${_libname}" )
endforeach()
elseif( ${basename}_LIBRARY_RELEASE )
set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} )
elseif( ${basename}_LIBRARY_DEBUG )
set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} )
else()
set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND")
endif()
set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" )
if( ${basename}_LIBRARY )
set( ${basename}_FOUND TRUE )
endif()
mark_as_advanced( ${basename}_LIBRARY_RELEASE
${basename}_LIBRARY_DEBUG
)
endmacro()

View File

@ -0,0 +1,62 @@
#ifndef HAD_CONFIG_H
#define HAD_CONFIG_H
#ifndef _HAD_ZIPCONF_H
#include "zipconf.h"
#endif
/* BEGIN DEFINES */
#cmakedefine HAVE___PROGNAME
#cmakedefine HAVE__CLOSE
#cmakedefine HAVE__DUP
#cmakedefine HAVE__FDOPEN
#cmakedefine HAVE__FILENO
#cmakedefine HAVE__SETMODE
#cmakedefine HAVE__SNPRINTF
#cmakedefine HAVE__STRDUP
#cmakedefine HAVE__STRICMP
#cmakedefine HAVE__STRTOI64
#cmakedefine HAVE__STRTOUI64
#cmakedefine HAVE__UMASK
#cmakedefine HAVE__UNLINK
#cmakedefine HAVE_ARC4RANDOM
#cmakedefine HAVE_CLONEFILE
#cmakedefine HAVE_COMMONCRYPTO
#cmakedefine HAVE_CRYPTO
#cmakedefine HAVE_FICLONERANGE
#cmakedefine HAVE_FILENO
#cmakedefine HAVE_FSEEKO
#cmakedefine HAVE_FTELLO
#cmakedefine HAVE_GETPROGNAME
#cmakedefine HAVE_GNUTLS
#cmakedefine HAVE_LIBBZ2
#cmakedefine HAVE_LIBLZMA
#cmakedefine HAVE_LIBZSTD
#cmakedefine HAVE_LOCALTIME_R
#cmakedefine HAVE_MBEDTLS
#cmakedefine HAVE_MKSTEMP
#cmakedefine HAVE_NULLABLE
#cmakedefine HAVE_OPENSSL
#cmakedefine HAVE_SETMODE
#cmakedefine HAVE_STRCASECMP
#cmakedefine HAVE_STRDUP
#cmakedefine HAVE_STRICMP
#cmakedefine HAVE_STRTOLL
#cmakedefine HAVE_STRTOULL
#cmakedefine HAVE_STRUCT_TM_TM_ZONE
#cmakedefine HAVE_STDBOOL_H
#cmakedefine HAVE_STRINGS_H
#cmakedefine HAVE_UNISTD_H
#cmakedefine HAVE_WINDOWS_CRYPTO
#cmakedefine SIZEOF_OFF_T ${SIZEOF_OFF_T}
#cmakedefine SIZEOF_SIZE_T ${SIZEOF_SIZE_T}
#cmakedefine HAVE_DIRENT_H
#cmakedefine HAVE_FTS_H
#cmakedefine HAVE_NDIR_H
#cmakedefine HAVE_SYS_DIR_H
#cmakedefine HAVE_SYS_NDIR_H
#cmakedefine WORDS_BIGENDIAN
#cmakedefine HAVE_SHARED
/* END DEFINES */
#define PACKAGE "@CMAKE_PROJECT_NAME@"
#define VERSION "@CMAKE_PROJECT_VERSION@"
#endif /* HAD_CONFIG_H */

View File

@ -0,0 +1,47 @@
#ifndef _HAD_ZIPCONF_H
#define _HAD_ZIPCONF_H
/*
zipconf.h -- platform specific include file
This file was generated automatically by CMake
based on ../cmake-zipconf.h.in.
*/
#define LIBZIP_VERSION "${libzip_VERSION}"
#define LIBZIP_VERSION_MAJOR ${libzip_VERSION_MAJOR}
#define LIBZIP_VERSION_MINOR ${libzip_VERSION_MINOR}
#define LIBZIP_VERSION_MICRO ${libzip_VERSION_PATCH}
#cmakedefine ZIP_STATIC
${ZIP_NULLABLE_DEFINES}
${LIBZIP_TYPES_INCLUDE}
typedef ${ZIP_INT8_T} zip_int8_t;
typedef ${ZIP_UINT8_T} zip_uint8_t;
typedef ${ZIP_INT16_T} zip_int16_t;
typedef ${ZIP_UINT16_T} zip_uint16_t;
typedef ${ZIP_INT32_T} zip_int32_t;
typedef ${ZIP_UINT32_T} zip_uint32_t;
typedef ${ZIP_INT64_T} zip_int64_t;
typedef ${ZIP_UINT64_T} zip_uint64_t;
#define ZIP_INT8_MIN (-ZIP_INT8_MAX-1)
#define ZIP_INT8_MAX 0x7f
#define ZIP_UINT8_MAX 0xff
#define ZIP_INT16_MIN (-ZIP_INT16_MAX-1)
#define ZIP_INT16_MAX 0x7fff
#define ZIP_UINT16_MAX 0xffff
#define ZIP_INT32_MIN (-ZIP_INT32_MAX-1L)
#define ZIP_INT32_MAX 0x7fffffffL
#define ZIP_UINT32_MAX 0xffffffffLU
#define ZIP_INT64_MIN (-ZIP_INT64_MAX-1LL)
#define ZIP_INT64_MAX 0x7fffffffffffffffLL
#define ZIP_UINT64_MAX 0xffffffffffffffffULL
#endif /* zipconf.h */

View File

@ -0,0 +1,83 @@
# Copyright (C) 2020 Dieter Baron and Thomas Klausner
#
# The authors can be contacted at <libzip@nih.at>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#[=======================================================================[.rst:
Dist
-------
Provide ``dist`` and ``distcheck`` targets similar to
autoconf/automake functionality.
The ``dist`` target creates tarballs of the project in ``.tar.gz`` and
``.tar.xz`` formats.
The ``distcheck`` target extracts one of created tarballs, builds the
software using its defaults, and runs the tests.
Both targets use Unix shell commands.
The Dist target takes one argument, the file name (before the extension).
The ``distcheck`` target creates (and removes) ``${ARCHIVE_NAME}-build``
and ``${ARCHIVE_NAME}-dest``.
#]=======================================================================]
function(Dist ARCHIVE_NAME)
if(NOT TARGET dist AND NOT TARGET distcheck)
add_custom_target(dist
COMMAND git config tar.tar.xz.command "xz -c"
COMMAND git archive --prefix=${ARCHIVE_NAME}/ -o ${ARCHIVE_NAME}.tar.gz HEAD
COMMAND git archive --prefix=${ARCHIVE_NAME}/ -o ${ARCHIVE_NAME}.tar.xz HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
add_custom_target(distcheck
COMMAND chmod -R u+w ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest 2>/dev/null || true
COMMAND rm -rf ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
COMMAND ${CMAKE_COMMAND} -E tar xf ${ARCHIVE_NAME}.tar.gz
COMMAND chmod -R u-w ${ARCHIVE_NAME}
COMMAND mkdir ${ARCHIVE_NAME}-build
COMMAND mkdir ${ARCHIVE_NAME}-dest
COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${ARCHIVE_NAME}-dest ${ARCHIVE_NAME} -B ${ARCHIVE_NAME}-build
COMMAND make -C ${ARCHIVE_NAME}-build -j4
COMMAND make -C ${ARCHIVE_NAME}-build test
COMMAND make -C ${ARCHIVE_NAME}-build install
# COMMAND make -C ${ARCHIVE_NAME}-build uninstall
# COMMAND if [ `find ${ARCHIVE_NAME}-dest ! -type d | wc -l` -ne 0 ]; then echo leftover files in ${ARCHIVE_NAME}-dest; false; fi
COMMAND make -C ${ARCHIVE_NAME}-build clean
COMMAND chmod -R u+w ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
COMMAND rm -rf ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest
COMMAND echo "${ARCHIVE_NAME}.tar.gz is ready for distribution."
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
add_dependencies(distcheck dist)
endif()
endfunction()

View File

@ -0,0 +1,132 @@
# Copyright (C) 2020 Dieter Baron and Thomas Klausner
#
# The authors can be contacted at <libzip@nih.at>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#[=======================================================================[.rst:
FindMbedTLS
-------
Finds the Mbed TLS library.
Imported Targets
^^^^^^^^^^^^^^^^
This module provides the following imported targets, if found:
``MbedTLS::MbedTLS``
The Mbed TLS library
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``MbedTLS_FOUND``
True if the system has the Mbed TLS library.
``MbedTLS_VERSION``
The version of the Mbed TLS library which was found.
``MbedTLS_INCLUDE_DIRS``
Include directories needed to use Mbed TLS.
``MbedTLS_LIBRARIES``
Libraries needed to link to Mbed TLS.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``MbedTLS_INCLUDE_DIR``
The directory containing ``mbedtls/aes.h``.
``MbedTLS_LIBRARY``
The path to the Mbed TLS library.
#]=======================================================================]
# I'm not aware of a pkg-config file for mbedtls as of 2020/07/08.
#find_package(PkgConfig)
#pkg_check_modules(PC_MbedTLS QUIET mbedtls)
find_path(MbedTLS_INCLUDE_DIR
NAMES mbedtls/aes.h
# PATHS ${PC_MbedTLS_INCLUDE_DIRS}
)
find_library(MbedTLS_LIBRARY
NAMES mbedcrypto
# PATHS ${PC_MbedTLS_LIBRARY_DIRS}
)
# Extract version information from the header file
if(MbedTLS_INCLUDE_DIR)
if(EXISTS ${MbedTLS_INCLUDE_DIR}/mbedtls/version.h)
file(STRINGS ${MbedTLS_INCLUDE_DIR}/mbedtls/version.h _ver_line
REGEX "^#define MBEDTLS_VERSION_STRING *\"[0-9]+\\.[0-9]+\\.[0-9]+\""
LIMIT_COUNT 1)
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+"
MbedTLS_VERSION "${_ver_line}")
unset(_ver_line)
else()
if(PC_MbedTLS_VERSION)
set(MbedTLS_VERSION ${PC_MbedTLS_VERSION})
else()
# version unknown
set(MbedTLS_VERSION "0.0")
endif()
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MbedTLS
FOUND_VAR MbedTLS_FOUND
REQUIRED_VARS
MbedTLS_LIBRARY
MbedTLS_INCLUDE_DIR
VERSION_VAR MbedTLS_VERSION
)
if(MbedTLS_FOUND)
set(MbedTLS_LIBRARIES ${MbedTLS_LIBRARY})
set(MbedTLS_INCLUDE_DIRS ${MbedTLS_INCLUDE_DIR})
# set(MbedTLS_DEFINITIONS ${PC_MbedTLS_CFLAGS_OTHER})
endif()
if(MbedTLS_FOUND AND NOT TARGET MbedTLS::MbedTLS)
add_library(MbedTLS::MbedTLS UNKNOWN IMPORTED)
set_target_properties(MbedTLS::MbedTLS PROPERTIES
IMPORTED_LOCATION "${MbedTLS_LIBRARY}"
# INTERFACE_COMPILE_OPTIONS "${PC_MbedTLS_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${MbedTLS_INCLUDE_DIR}"
)
endif()
mark_as_advanced(
MbedTLS_INCLUDE_DIR
MbedTLS_LIBRARY
)

View File

@ -0,0 +1,141 @@
# Copyright (C) 2020 Dieter Baron and Thomas Klausner
#
# The authors can be contacted at <libzip@nih.at>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#[=======================================================================[.rst:
FindNettle
-------
Finds the Nettle library.
Imported Targets
^^^^^^^^^^^^^^^^
This module provides the following imported targets, if found:
``Nettle::Nettle``
The Nettle library
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Nettle_FOUND``
True if the system has the Nettle library.
``Nettle_VERSION``
The version of the Nettle library which was found.
``Nettle_INCLUDE_DIRS``
Include directories needed to use Nettle.
``Nettle_LIBRARIES``
Libraries needed to link to Nettle.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``Nettle_INCLUDE_DIR``
The directory containing ``nettle/aes.h``.
``Nettle_LIBRARY``
The path to the Nettle library.
#]=======================================================================]
find_package(PkgConfig)
pkg_check_modules(PC_Nettle QUIET nettle)
find_path(Nettle_INCLUDE_DIR
NAMES nettle/aes.h nettle/md5.h nettle/pbkdf2.h nettle/ripemd160.h nettle/sha.h
PATHS ${PC_Nettle_INCLUDE_DIRS}
)
find_library(Nettle_LIBRARY
NAMES nettle
PATHS ${PC_Nettle_LIBRARY_DIRS}
)
# Extract version information from the header file
if(Nettle_INCLUDE_DIR)
# This file only exists in nettle>=3.0
if(EXISTS ${Nettle_INCLUDE_DIR}/nettle/version.h)
file(STRINGS ${Nettle_INCLUDE_DIR}/nettle/version.h _ver_major_line
REGEX "^#define NETTLE_VERSION_MAJOR *[0-9]+"
LIMIT_COUNT 1)
string(REGEX MATCH "[0-9]+"
Nettle_MAJOR_VERSION "${_ver_major_line}")
file(STRINGS ${Nettle_INCLUDE_DIR}/nettle/version.h _ver_minor_line
REGEX "^#define NETTLE_VERSION_MINOR *[0-9]+"
LIMIT_COUNT 1)
string(REGEX MATCH "[0-9]+"
Nettle_MINOR_VERSION "${_ver_minor_line}")
set(Nettle_VERSION "${Nettle_MAJOR_VERSION}.${Nettle_MINOR_VERSION}")
unset(_ver_major_line)
unset(_ver_minor_line)
else()
if(PC_Nettle_VERSION)
set(Nettle_VERSION ${PC_Nettle_VERSION})
else()
set(Nettle_VERSION "1.0")
endif()
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Nettle
FOUND_VAR Nettle_FOUND
REQUIRED_VARS
Nettle_LIBRARY
Nettle_INCLUDE_DIR
VERSION_VAR Nettle_VERSION
)
if(Nettle_FOUND)
set(Nettle_LIBRARIES ${Nettle_LIBRARY})
set(Nettle_INCLUDE_DIRS ${Nettle_INCLUDE_DIR})
set(Nettle_DEFINITIONS ${PC_Nettle_CFLAGS_OTHER})
endif()
if(Nettle_FOUND AND NOT TARGET Nettle::Nettle)
add_library(Nettle::Nettle UNKNOWN IMPORTED)
set_target_properties(Nettle::Nettle PROPERTIES
IMPORTED_LOCATION "${Nettle_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PC_Nettle_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${Nettle_INCLUDE_DIR}"
)
endif()
mark_as_advanced(
Nettle_INCLUDE_DIR
Nettle_LIBRARY
)
# compatibility variables
set(Nettle_VERSION_STRING ${Nettle_VERSION})

View File

@ -0,0 +1,135 @@
# Copyright (C) 2020 Dieter Baron and Thomas Klausner
#
# The authors can be contacted at <libzip@nih.at>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. The names of the authors may not be used to endorse or promote
# products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#[=======================================================================[.rst:
FindZstd
-------
Finds the Zstandard (zstd) library.
Imported Targets
^^^^^^^^^^^^^^^^
This module provides the following imported targets, if found:
``Zstd::Zstd``
The Zstandard library
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Zstd_FOUND``
True if the system has the Zstandard library.
``Zstd_VERSION``
The version of the Zstandard library which was found.
``Zstd_INCLUDE_DIRS``
Include directories needed to use Zstandard.
``Zstd_LIBRARIES``
Libraries needed to link to Zstandard.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``Zstd_INCLUDE_DIR``
The directory containing ``zstd.h``.
``Zstd_LIBRARY``
The path to the Zstandard library.
#]=======================================================================]
find_package(PkgConfig)
pkg_check_modules(PC_Zstd QUIET zstd)
find_path(Zstd_INCLUDE_DIR
NAMES zstd.h
PATHS ${PC_Zstd_INCLUDE_DIRS}
)
find_library(Zstd_LIBRARY
NAMES zstd
PATHS ${PC_Zstd_LIBRARY_DIRS}
)
# Extract version information from the header file
if(Zstd_INCLUDE_DIR)
file(STRINGS ${Zstd_INCLUDE_DIR}/zstd.h _ver_major_line
REGEX "^#define ZSTD_VERSION_MAJOR *[0-9]+"
LIMIT_COUNT 1)
string(REGEX MATCH "[0-9]+"
Zstd_MAJOR_VERSION "${_ver_major_line}")
file(STRINGS ${Zstd_INCLUDE_DIR}/zstd.h _ver_minor_line
REGEX "^#define ZSTD_VERSION_MINOR *[0-9]+"
LIMIT_COUNT 1)
string(REGEX MATCH "[0-9]+"
Zstd_MINOR_VERSION "${_ver_minor_line}")
file(STRINGS ${Zstd_INCLUDE_DIR}/zstd.h _ver_release_line
REGEX "^#define ZSTD_VERSION_RELEASE *[0-9]+"
LIMIT_COUNT 1)
string(REGEX MATCH "[0-9]+"
Zstd_RELEASE_VERSION "${_ver_release_line}")
set(Zstd_VERSION "${Zstd_MAJOR_VERSION}.${Zstd_MINOR_VERSION}.${Zstd_RELEASE_VERSION}")
unset(_ver_major_line)
unset(_ver_minor_line)
unset(_ver_release_line)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Zstd
FOUND_VAR Zstd_FOUND
REQUIRED_VARS
Zstd_LIBRARY
Zstd_INCLUDE_DIR
VERSION_VAR Zstd_VERSION
)
if(Zstd_FOUND)
set(Zstd_LIBRARIES ${Zstd_LIBRARY})
set(Zstd_INCLUDE_DIRS ${Zstd_INCLUDE_DIR})
set(Zstd_DEFINITIONS ${PC_Zstd_CFLAGS_OTHER})
endif()
if(Zstd_FOUND AND NOT TARGET Zstd::Zstd)
add_library(Zstd::Zstd UNKNOWN IMPORTED)
set_target_properties(Zstd::Zstd PROPERTIES
IMPORTED_LOCATION "${Zstd_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PC_Zstd_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${Zstd_INCLUDE_DIR}"
)
endif()
mark_as_advanced(
Zstd_INCLUDE_DIR
Zstd_LIBRARY
)

View File

@ -1,99 +0,0 @@
/* Config header for Android */
/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
*/
/* #undef HAVE_DECL_TZNAME */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 0
/* Define to 1 if you have the `fseeko' function. */
#define HAVE_FSEEKO 0
/* Define to 1 if you have the `ftello' function. */
#define HAVE_FTELLO 0
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 0
/* Define to 1 if you have the `z' library (-lz). */
#define HAVE_LIBZ 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 0
/* Define to 1 if you have the `mkstemp' function. */
#define HAVE_MKSTEMP 0
/* Define to 1 if you have the `MoveFileExA' function. */
/* #undef HAVE_MOVEFILEEXA */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
#ifndef _WIN32
/* Define to 1 if `tm_zone' is a member of `struct tm'. */
#define HAVE_STRUCT_TM_TM_ZONE 1
#endif
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
`HAVE_STRUCT_TM_TM_ZONE' instead. */
#define HAVE_TM_ZONE 1
/* Define to 1 if you don't have `tm_zone' but do have the external array
`tzname'. */
/* #undef HAVE_TZNAME */
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */
/* Name of package */
#define PACKAGE "libzip"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "libzip@nih.at"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libzip"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libzip 0.9.3"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libzip"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.9.3"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */
/* Version number of package */
#define VERSION "0.9.3"

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>PACKAGE_VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFPlugInDynamicRegisterFunction</key>
<string></string>
<key>CFPlugInDynamicRegistration</key>
<string>NO</string>
<key>CFPlugInFactories</key>
<dict>
<key>00000000-0000-0000-0000-000000000000</key>
<string>MyFactoryFunction</string>
</dict>
<key>CFPlugInTypes</key>
<dict>
<key>00000000-0000-0000-0000-000000000000</key>
<array>
<string>00000000-0000-0000-0000-000000000000</string>
</array>
</dict>
<key>CFPlugInUnloadFunction</key>
<string></string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2014 Dieter Baron and Thomas Klausner</string>
</dict>
</plist>

View File

@ -0,0 +1,6 @@
This Xcode project is for development only, it is not meant to
compile production builds.
It is used internally to develop libzip and to run Xcode's diagnostic
tools on the source, and is not always kept up-to-date. Please use
the standard build method instead.

View File

@ -0,0 +1,94 @@
#ifndef HAD_CONFIG_H
#define HAD_CONFIG_H
#ifndef _HAD_ZIPCONF_H
#include "zipconf.h"
#endif
/* BEGIN DEFINES */
/* #undef HAVE___PROGNAME */
/* #undef HAVE__CHMOD */
/* #undef HAVE__CLOSE */
/* #undef HAVE__DUP */
/* #undef HAVE__FDOPEN */
/* #undef HAVE__FILENO */
/* #undef HAVE__OPEN */
/* #undef HAVE__SETMODE */
/* #undef HAVE__SNPRINTF */
/* #undef HAVE__STRDUP */
/* #undef HAVE__STRICMP */
/* #undef HAVE__STRTOI64 */
/* #undef HAVE__STRTOUI64 */
/* #undef HAVE__UMASK */
/* #undef HAVE__UNLINK */
#define HAVE_ARC4RANDOM
#define HAVE_CLONEFILE
#define HAVE_COMMONCRYPTO
#define HAVE_CRYPTO
/* #undef HAVE_FICLONERANGE */
#define HAVE_FILENO
#define HAVE_FSEEKO
#define HAVE_FTELLO
#define HAVE_GETPROGNAME
/* #undef HAVE_GNUTLS */
#define HAVE_LIBBZ2
#define HAVE_LIBLZMA
#define HAVE_LOCALTIME_R
/* #undef HAVE_MBEDTLS */
/* #undef HAVE_MKSTEMP */
#define HAVE_NULLABLE
#define HAVE_OPEN
/* #undef HAVE_OPENSSL */
#define HAVE_SETMODE
#define HAVE_SSIZE_T_LIBZIP
#define HAVE_STRCASECMP
#define HAVE_STRDUP
/* #undef HAVE_STRICMP */
#define HAVE_STRTOLL
#define HAVE_STRTOULL
/* #undef HAVE_STRUCT_TM_TM_ZONE */
#define HAVE_STDBOOL_H
#define HAVE_STRINGS_H
#define HAVE_UNISTD_H
/* #undef HAVE_WINDOWS_CRYPTO */
/* #undef __INT8_LIBZIP */
#define INT8_T_LIBZIP 1
#define UINT8_T_LIBZIP 1
/* #undef __INT16_LIBZIP */
#define INT16_T_LIBZIP 2
#define UINT16_T_LIBZIP 2
/* #undef __INT32_LIBZIP */
#define INT32_T_LIBZIP 4
#define UINT32_T_LIBZIP 4
/* #undef __INT64_LIBZIP */
#define INT64_T_LIBZIP 8
#define UINT64_T_LIBZIP 8
#define SHORT_LIBZIP 2
#define INT_LIBZIP 4
#define LONG_LIBZIP 8
#define LONG_LONG_LIBZIP 8
#define SIZEOF_OFF_T 8
#define SIZE_T_LIBZIP 8
#define SSIZE_T_LIBZIP 8
/* #undef HAVE_DIRENT_H */
#define HAVE_FTS_H
/* #undef HAVE_NDIR_H */
/* #undef HAVE_SYS_DIR_H */
/* #undef HAVE_SYS_NDIR_H */
/* #undef WORDS_BIGENDIAN */
#define HAVE_SHARED
/* END DEFINES */
#define PACKAGE "libzip"
#define VERSION "1.5.2a"
#ifndef HAVE_SSIZE_T_LIBZIP
#if SIZE_T_LIBZIP == INT_LIBZIP
typedef int ssize_t;
#elif SIZE_T_LIBZIP == LONG_LIBZIP
typedef long ssize_t;
#elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP
typedef long long ssize_t;
#else
#error no suitable type for ssize_t found
#endif
#endif
#endif /* HAD_CONFIG_H */

View File

@ -0,0 +1,20 @@
#!/bin/sh
# Replace the value for PLIST_KEY with the resolved definition from the header file that was passed in.
SOURCE_HEADER_FILE_PATH=$1
SOURCE_PLIST_PATH=$2
PLIST_KEY="CFBundleShortVersionString"
VERSION_KEY=`/usr/libexec/PlistBuddy -c "Print :${PLIST_KEY}" "${SOURCE_PLIST_PATH}"`
#echo "Key: ${VERSION_KEY}"
VERSION_NUM=`cat "${SOURCE_HEADER_FILE_PATH}" | sed -n "s|#define ${VERSION_KEY} \"\(.*\)\".*|\1|p"`
#echo "Value: ${VERSION_NUM}"
TARGET_PLIST_PATH="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Set :${PLIST_KEY} ${VERSION_NUM}" "${TARGET_PLIST_PATH}"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:libzip.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,12 @@
#!/bin/sh
DIR=tmp.$$
mkdir -p $DIR/32 $DIR/64
(cd $DIR/32; ../../../configure CFLAGS=-m32)
(cd $DIR/64; ../../../configure CFLAGS=-m64)
diff -D __LP64__ $DIR/32/config.h $DIR/64/config.h > config.h
rm -r $DIR

View File

@ -1,12 +1,10 @@
/*
This file was generated automatically by ./make_zip_err_str.sh
from ./zip.h; make changes there.
*/
This file was generated automatically by CMake
from zip.h; make changes there.
*/
#include "zipint.h"
const char * const _zip_err_str[] = {
"No error",
"Multi-disk zip archives not supported",
@ -25,13 +23,22 @@ const char * const _zip_err_str[] = {
"Malloc failure",
"Entry has been changed",
"Compression method not supported",
"Premature EOF",
"Premature end of file",
"Invalid argument",
"Not a zip archive",
"Internal error",
"Zip archive inconsistent",
"Can't remove file",
"Entry has been deleted",
"Encryption method not supported",
"Read-only archive",
"No password provided",
"Wrong password provided",
"Operation not supported",
"Resource still in use",
"Tell error",
"Compressed data invalid",
"Operation cancelled",
};
const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
@ -65,4 +72,13 @@ const int _zip_err_type[] = {
N,
S,
N,
N,
N,
N,
N,
N,
N,
S,
N,
N,
};

View File

@ -0,0 +1,47 @@
#ifndef _HAD_ZIPCONF_H
#define _HAD_ZIPCONF_H
/*
zipconf.h -- platform specific include file
This file was generated automatically by CMake
based on ../cmake-zipconf.h.in.
*/
#define LIBZIP_VERSION "1.5.2a"
#define LIBZIP_VERSION_MAJOR 1
#define LIBZIP_VERSION_MINOR 5
#define LIBZIP_VERSION_MICRO 2a
/* #undef ZIP_STATIC */
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
typedef int8_t zip_int8_t;
typedef uint8_t zip_uint8_t;
typedef int16_t zip_int16_t;
typedef uint16_t zip_uint16_t;
typedef int32_t zip_int32_t;
typedef uint32_t zip_uint32_t;
typedef int64_t zip_int64_t;
typedef uint64_t zip_uint64_t;
#define ZIP_INT8_MIN (-ZIP_INT8_MAX - 1)
#define ZIP_INT8_MAX 0x7f
#define ZIP_UINT8_MAX 0xff
#define ZIP_INT16_MIN (-ZIP_INT16_MAX - 1)
#define ZIP_INT16_MAX 0x7fff
#define ZIP_UINT16_MAX 0xffff
#define ZIP_INT32_MIN (-ZIP_INT32_MAX - 1L)
#define ZIP_INT32_MAX 0x7fffffffL
#define ZIP_UINT32_MAX 0xffffffffLU
#define ZIP_INT64_MIN (-ZIP_INT64_MAX - 1LL)
#define ZIP_INT64_MAX 0x7fffffffffffffffLL
#define ZIP_UINT64_MAX 0xffffffffffffffffULL
#endif /* zipconf.h */

View File

@ -0,0 +1,3 @@
add_executable(in-memory in-memory.c)
target_link_libraries(in-memory zip)
target_include_directories(in-memory PRIVATE ${PROJECT_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR})

View File

@ -0,0 +1,217 @@
/*
in-memory.c -- modify zip file in memory
Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <zip.h>
static int
get_data(void **datap, size_t *sizep, const char *archive) {
/* example implementation that reads data from file */
struct stat st;
FILE *fp;
if ((fp = fopen(archive, "rb")) == NULL) {
if (errno != ENOENT) {
fprintf(stderr, "can't open %s: %s\n", archive, strerror(errno));
return -1;
}
*datap = NULL;
*sizep = 0;
return 0;
}
if (fstat(fileno(fp), &st) < 0) {
fprintf(stderr, "can't stat %s: %s\n", archive, strerror(errno));
fclose(fp);
return -1;
}
if ((*datap = malloc((size_t)st.st_size)) == NULL) {
fprintf(stderr, "can't allocate buffer\n");
fclose(fp);
return -1;
}
if (fread(*datap, 1, (size_t)st.st_size, fp) < (size_t)st.st_size) {
fprintf(stderr, "can't read %s: %s\n", archive, strerror(errno));
free(*datap);
fclose(fp);
return -1;
}
fclose(fp);
*sizep = (size_t)st.st_size;
return 0;
}
static int
modify_archive(zip_t *za) {
/* modify the archive */
return 0;
}
static int
use_data(void *data, size_t size, const char *archive) {
/* example implementation that writes data to file */
FILE *fp;
if (data == NULL) {
if (remove(archive) < 0 && errno != ENOENT) {
fprintf(stderr, "can't remove %s: %s\n", archive, strerror(errno));
return -1;
}
return 0;
}
if ((fp = fopen(archive, "wb")) == NULL) {
fprintf(stderr, "can't open %s: %s\n", archive, strerror(errno));
return -1;
}
if (fwrite(data, 1, size, fp) < size) {
fprintf(stderr, "can't write %s: %s\n", archive, strerror(errno));
fclose(fp);
return -1;
}
if (fclose(fp) < 0) {
fprintf(stderr, "can't write %s: %s\n", archive, strerror(errno));
return -1;
}
return 0;
}
int
main(int argc, char *argv[]) {
const char *archive;
zip_source_t *src;
zip_t *za;
zip_error_t error;
void *data;
size_t size;
if (argc < 2) {
fprintf(stderr, "usage: %s archive\n", argv[0]);
return 1;
}
archive = argv[1];
/* get buffer with zip archive inside */
if (get_data(&data, &size, archive) < 0) {
return 1;
}
zip_error_init(&error);
/* create source from buffer */
if ((src = zip_source_buffer_create(data, size, 1, &error)) == NULL) {
fprintf(stderr, "can't create source: %s\n", zip_error_strerror(&error));
free(data);
zip_error_fini(&error);
return 1;
}
/* open zip archive from source */
if ((za = zip_open_from_source(src, 0, &error)) == NULL) {
fprintf(stderr, "can't open zip from source: %s\n", zip_error_strerror(&error));
zip_source_free(src);
zip_error_fini(&error);
return 1;
}
zip_error_fini(&error);
/* we'll want to read the data back after zip_close */
zip_source_keep(src);
/* modify archive */
modify_archive(za);
/* close archive */
if (zip_close(za) < 0) {
fprintf(stderr, "can't close zip archive '%s': %s\n", archive, zip_strerror(za));
return 1;
}
/* copy new archive to buffer */
if (zip_source_is_deleted(src)) {
/* new archive is empty, thus no data */
data = NULL;
}
else {
zip_stat_t zst;
if (zip_source_stat(src, &zst) < 0) {
fprintf(stderr, "can't stat source: %s\n", zip_error_strerror(zip_source_error(src)));
return 1;
}
size = zst.size;
if (zip_source_open(src) < 0) {
fprintf(stderr, "can't open source: %s\n", zip_error_strerror(zip_source_error(src)));
return 1;
}
if ((data = malloc(size)) == NULL) {
fprintf(stderr, "malloc failed: %s\n", strerror(errno));
zip_source_close(src);
return 1;
}
if ((zip_uint64_t)zip_source_read(src, data, size) < size) {
fprintf(stderr, "can't read data from source: %s\n", zip_error_strerror(zip_source_error(src)));
zip_source_close(src);
free(data);
return 1;
}
zip_source_close(src);
}
/* we're done with src */
zip_source_free(src);
/* use new data */
use_data(data, size, archive);
free(data);
return 0;
}

View File

@ -0,0 +1,60 @@
/*
windows-open.c -- open zip archive using Windows UTF-16/Unicode file name
Copyright (C) 2015-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <zip.h>
zip_t *
windows_open(const wchar_t *name, int flags) {
zip_source_t *src;
zip_t *za;
zip_error_t error;
zip_error_init(&error);
/* create source from buffer */
if ((src = zip_source_win32w_create(name, 0, -1, &error)) == NULL) {
fprintf(stderr, "can't create source: %s\n", zip_error_strerror(&error));
zip_error_fini(&error);
return NULL;
}
/* open zip archive from source */
if ((za = zip_open_from_source(src, flags, &error)) == NULL) {
fprintf(stderr, "can't open zip from source: %s\n", zip_error_strerror(&error));
zip_source_free(src);
zip_error_fini(&error);
return NULL;
}
zip_error_fini(&error);
return za;
}

View File

@ -0,0 +1,228 @@
include(CheckFunctionExists)
set(CMAKE_C_VISIBILITY_PRESET hidden)
add_library(zip
zip_add.c
zip_add_dir.c
zip_add_entry.c
zip_algorithm_deflate.c
zip_buffer.c
zip_close.c
zip_delete.c
zip_dir_add.c
zip_dirent.c
zip_discard.c
zip_entry.c
zip_error.c
zip_error_clear.c
zip_error_get.c
zip_error_get_sys_type.c
zip_error_strerror.c
zip_error_to_str.c
zip_extra_field.c
zip_extra_field_api.c
zip_fclose.c
zip_fdopen.c
zip_file_add.c
zip_file_error_clear.c
zip_file_error_get.c
zip_file_get_comment.c
zip_file_get_external_attributes.c
zip_file_get_offset.c
zip_file_rename.c
zip_file_replace.c
zip_file_set_comment.c
zip_file_set_encryption.c
zip_file_set_external_attributes.c
zip_file_set_mtime.c
zip_file_strerror.c
zip_fopen.c
zip_fopen_encrypted.c
zip_fopen_index.c
zip_fopen_index_encrypted.c
zip_fread.c
zip_fseek.c
zip_ftell.c
zip_get_archive_comment.c
zip_get_archive_flag.c
zip_get_encryption_implementation.c
zip_get_file_comment.c
zip_get_name.c
zip_get_num_entries.c
zip_get_num_files.c
zip_hash.c
zip_io_util.c
zip_libzip_version.c
zip_memdup.c
zip_name_locate.c
zip_new.c
zip_open.c
zip_pkware.c
zip_progress.c
zip_rename.c
zip_replace.c
zip_set_archive_comment.c
zip_set_archive_flag.c
zip_set_default_password.c
zip_set_file_comment.c
zip_set_file_compression.c
zip_set_name.c
zip_source_accept_empty.c
zip_source_begin_write.c
zip_source_begin_write_cloning.c
zip_source_buffer.c
zip_source_call.c
zip_source_close.c
zip_source_commit_write.c
zip_source_compress.c
zip_source_crc.c
zip_source_error.c
zip_source_file_common.c
zip_source_file_stdio.c
zip_source_free.c
zip_source_function.c
zip_source_get_file_attributes.c
zip_source_is_deleted.c
zip_source_layered.c
zip_source_open.c
zip_source_pkware_decode.c
zip_source_pkware_encode.c
zip_source_read.c
zip_source_remove.c
zip_source_rollback_write.c
zip_source_seek.c
zip_source_seek_write.c
zip_source_stat.c
zip_source_supports.c
zip_source_tell.c
zip_source_tell_write.c
zip_source_window.c
zip_source_write.c
zip_source_zip.c
zip_source_zip_new.c
zip_stat.c
zip_stat_index.c
zip_stat_init.c
zip_strerror.c
zip_string.c
zip_unchange.c
zip_unchange_all.c
zip_unchange_archive.c
zip_unchange_data.c
zip_utf-8.c
${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c
)
add_library(libzip::zip ALIAS zip)
if(WIN32)
target_sources(zip PRIVATE
zip_source_file_win32.c
zip_source_file_win32_named.c
zip_source_file_win32_utf16.c
zip_source_file_win32_utf8.c
)
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
target_sources(zip PRIVATE zip_random_uwp.c)
else()
target_sources(zip PRIVATE zip_source_file_win32_ansi.c zip_random_win32.c)
target_link_libraries(zip PRIVATE advapi32)
endif()
else(WIN32)
target_sources(zip PRIVATE
zip_mkstempm.c
zip_source_file_stdio_named.c
zip_random_unix.c
)
endif(WIN32)
if(HAVE_LIBBZ2)
target_sources(zip PRIVATE zip_algorithm_bzip2.c)
target_link_libraries(zip PRIVATE BZip2::BZip2)
endif()
if(HAVE_LIBLZMA)
target_sources(zip PRIVATE zip_algorithm_xz.c)
target_link_libraries(zip PRIVATE LibLZMA::LibLZMA)
endif()
if(HAVE_LIBZSTD)
target_sources(zip PRIVATE zip_algorithm_zstd.c)
target_link_libraries(zip PRIVATE Zstd::Zstd)
endif()
if(HAVE_COMMONCRYPTO)
target_sources(zip PRIVATE zip_crypto_commoncrypto.c)
elseif(HAVE_WINDOWS_CRYPTO)
target_sources(zip PRIVATE zip_crypto_win.c)
target_link_libraries(zip PRIVATE bcrypt)
elseif(HAVE_GNUTLS)
target_sources(zip PRIVATE zip_crypto_gnutls.c)
target_link_libraries(zip PRIVATE GnuTLS::GnuTLS Nettle::Nettle)
elseif(HAVE_OPENSSL)
target_sources(zip PRIVATE zip_crypto_openssl.c)
target_link_libraries(zip PRIVATE OpenSSL::Crypto)
elseif(HAVE_MBEDTLS)
target_sources(zip PRIVATE zip_crypto_mbedtls.c)
target_link_libraries(zip PRIVATE MbedTLS::MbedTLS)
endif()
if(HAVE_CRYPTO)
target_sources(zip PRIVATE zip_winzip_aes.c zip_source_winzip_aes_decode.c zip_source_winzip_aes_encode.c)
endif()
if(SHARED_LIB_VERSIONNING)
set_target_properties(zip PROPERTIES VERSION 5.3 SOVERSION 5)
endif()
target_link_libraries(zip PRIVATE ZLIB::ZLIB)
target_include_directories(zip
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/lib>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
if(LIBZIP_DO_INSTALL)
install(TARGETS zip
EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES zip.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()
# create zip_err_str.h from zip.h
file(READ ${PROJECT_SOURCE_DIR}/lib/zip.h zip_h)
string(REGEX MATCHALL "#define ZIP_ER_([A-Z_]+) ([0-9]+)[ \t]+/([-*0-9a-zA-Z ']*)/" zip_h_err ${zip_h})
set(zip_err_str [=[
/*
This file was generated automatically by CMake
from zip.h\; make changes there.
*/
#include "zipint.h"
const char * const _zip_err_str[] = {
]=])
set(zip_err_type)
foreach(errln ${zip_h_err})
string(REGEX MATCH "#define ZIP_ER_([A-Z_]+) ([0-9]+)[ \t]+/([-*0-9a-zA-Z ']*)/" err_t_tt ${errln})
string(REGEX MATCH "([N|S|Z]+) ([-0-9a-zA-Z ']*)" err_t_tt "${CMAKE_MATCH_3}")
string(APPEND zip_err_type " ${CMAKE_MATCH_1},\n")
string(STRIP "${CMAKE_MATCH_2}" err_t_tt)
string(APPEND zip_err_str " \"${err_t_tt}\",\n")
endforeach()
string(APPEND zip_err_str [=[}\;
const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0])\;
#define N ZIP_ET_NONE
#define S ZIP_ET_SYS
#define Z ZIP_ET_ZLIB
const int _zip_err_type[] = {
]=])
string(APPEND zip_err_str "${zip_err_type}}\;\n")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c ${zip_err_str})

View File

@ -0,0 +1,194 @@
#ifndef _HAD_LIBZIP_COMPAT_H
#define _HAD_LIBZIP_COMPAT_H
/*
compat.h -- compatibility defines.
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipconf.h"
#include "config.h"
/* to have *_MAX definitions for all types when compiling with g++ */
#define __STDC_LIMIT_MACROS
#ifdef _WIN32
#ifndef ZIP_EXTERN
#ifndef ZIP_STATIC
#define ZIP_EXTERN __declspec(dllexport)
#endif
#endif
/* for dup(), close(), etc. */
#include <io.h>
#endif
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#else
typedef char bool;
#define true 1
#define false 0
#endif
#include <errno.h>
/* at least MinGW does not provide EOPNOTSUPP, see
* http://sourceforge.net/p/mingw/bugs/263/
*/
#ifndef EOPNOTSUPP
#define EOPNOTSUPP EINVAL
#endif
/* at least MinGW does not provide EOVERFLOW, see
* http://sourceforge.net/p/mingw/bugs/242/
*/
#ifndef EOVERFLOW
#define EOVERFLOW EFBIG
#endif
/* not supported on at least Windows */
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
#ifdef _WIN32
#if defined(HAVE__CLOSE)
#define close _close
#endif
#if defined(HAVE__DUP)
#define dup _dup
#endif
/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */
#if defined(HAVE__FDOPEN)
#define fdopen _fdopen
#endif
#if !defined(HAVE_FILENO) && defined(HAVE__FILENO)
#define fileno _fileno
#endif
#if defined(HAVE__SNPRINTF)
#define snprintf _snprintf
#endif
#if defined(HAVE__STRDUP)
#if !defined(HAVE_STRDUP) || defined(_WIN32)
#undef strdup
#define strdup _strdup
#endif
#endif
#if !defined(HAVE__SETMODE) && defined(HAVE_SETMODE)
#define _setmode setmode
#endif
#if !defined(HAVE_STRTOLL) && defined(HAVE__STRTOI64)
#define strtoll _strtoi64
#endif
#if !defined(HAVE_STRTOULL) && defined(HAVE__STRTOUI64)
#define strtoull _strtoui64
#endif
#if defined(HAVE__UNLINK)
#define unlink _unlink
#endif
#endif
#ifndef HAVE_FSEEKO
#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
#endif
#ifndef HAVE_FTELLO
#define ftello(s) ((long)ftell((s)))
#endif
#if !defined(HAVE_STRCASECMP)
#if defined(HAVE__STRICMP)
#define strcasecmp _stricmp
#elif defined(HAVE_STRICMP)
#define strcasecmp stricmp
#endif
#endif
#if SIZEOF_OFF_T == 8
#define ZIP_OFF_MAX ZIP_INT64_MAX
#define ZIP_OFF_MIN ZIP_INT64_MIN
#elif SIZEOF_OFF_T == 4
#define ZIP_OFF_MAX ZIP_INT32_MAX
#define ZIP_OFF_MIN ZIP_INT32_MIN
#elif SIZEOF_OFF_T == 2
#define ZIP_OFF_MAX ZIP_INT16_MAX
#define ZIP_OFF_MIN ZIP_INT16_MIN
#else
#error unsupported size of off_t
#endif
#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
#define ZIP_FSEEK_MAX ZIP_OFF_MAX
#define ZIP_FSEEK_MIN ZIP_OFF_MIN
#else
#include <limits.h>
#define ZIP_FSEEK_MAX LONG_MAX
#define ZIP_FSEEK_MIN LONG_MIN
#endif
#ifndef SIZE_MAX
#if SIZEOF_SIZE_T == 8
#define SIZE_MAX ZIP_INT64_MAX
#elif SIZEOF_SIZE_T == 4
#define SIZE_MAX ZIP_INT32_MAX
#elif SIZEOF_SIZE_T == 2
#define SIZE_MAX ZIP_INT16_MAX
#else
#error unsupported size of size_t
#endif
#endif
#ifndef PRId64
#ifdef _MSC_VER
#define PRId64 "I64d"
#else
#define PRId64 "lld"
#endif
#endif
#ifndef PRIu64
#ifdef _MSC_VER
#define PRIu64 "I64u"
#else
#define PRIu64 "llu"
#endif
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
#endif
#endif /* compat.h */

481
core/deps/libzip/lib/zip.h Normal file
View File

@ -0,0 +1,481 @@
#ifndef _HAD_ZIP_H
#define _HAD_ZIP_H
/*
zip.h -- exported declarations.
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __cplusplus
extern "C" {
#if 0
} /* fix autoindent */
#endif
#endif
#include <zipconf.h>
#ifndef ZIP_EXTERN
#ifndef ZIP_STATIC
#ifdef _WIN32
#define ZIP_EXTERN __declspec(dllimport)
#elif defined(__GNUC__) && __GNUC__ >= 4
#define ZIP_EXTERN __attribute__((visibility("default")))
#else
#define ZIP_EXTERN
#endif
#else
#define ZIP_EXTERN
#endif
#endif
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
/* flags for zip_open */
#define ZIP_CREATE 1
#define ZIP_EXCL 2
#define ZIP_CHECKCONS 4
#define ZIP_TRUNCATE 8
#define ZIP_RDONLY 16
/* flags for zip_name_locate, zip_fopen, zip_stat, ... */
#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */
#define ZIP_FL_NODIR 2u /* ignore directory component */
#define ZIP_FL_COMPRESSED 4u /* read compressed data */
#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */
#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */
#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */
#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */
#define ZIP_FL_ENC_RAW 64u /* get unmodified string */
#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */
#define ZIP_FL_LOCAL 256u /* in local header */
#define ZIP_FL_CENTRAL 512u /* in central directory */
/* 1024u reserved for internal use */
#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */
#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */
#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */
/* archive global flags flags */
#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */
/* create a new extra field */
#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX
#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX
/* libzip error codes */
#define ZIP_ER_OK 0 /* N No error */
#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */
#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */
#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */
#define ZIP_ER_SEEK 4 /* S Seek error */
#define ZIP_ER_READ 5 /* S Read error */
#define ZIP_ER_WRITE 6 /* S Write error */
#define ZIP_ER_CRC 7 /* N CRC error */
#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */
#define ZIP_ER_NOENT 9 /* N No such file */
#define ZIP_ER_EXISTS 10 /* N File already exists */
#define ZIP_ER_OPEN 11 /* S Can't open file */
#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */
#define ZIP_ER_ZLIB 13 /* Z Zlib error */
#define ZIP_ER_MEMORY 14 /* N Malloc failure */
#define ZIP_ER_CHANGED 15 /* N Entry has been changed */
#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */
#define ZIP_ER_EOF 17 /* N Premature end of file */
#define ZIP_ER_INVAL 18 /* N Invalid argument */
#define ZIP_ER_NOZIP 19 /* N Not a zip archive */
#define ZIP_ER_INTERNAL 20 /* N Internal error */
#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */
#define ZIP_ER_REMOVE 22 /* S Can't remove file */
#define ZIP_ER_DELETED 23 /* N Entry has been deleted */
#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */
#define ZIP_ER_RDONLY 25 /* N Read-only archive */
#define ZIP_ER_NOPASSWD 26 /* N No password provided */
#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */
#define ZIP_ER_OPNOTSUPP 28 /* N Operation not supported */
#define ZIP_ER_INUSE 29 /* N Resource still in use */
#define ZIP_ER_TELL 30 /* S Tell error */
#define ZIP_ER_COMPRESSED_DATA 31 /* N Compressed data invalid */
#define ZIP_ER_CANCELLED 32 /* N Operation cancelled */
/* type of system error value */
#define ZIP_ET_NONE 0 /* sys_err unused */
#define ZIP_ET_SYS 1 /* sys_err is errno */
#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */
/* compression methods */
#define ZIP_CM_DEFAULT -1 /* better of deflate or store */
#define ZIP_CM_STORE 0 /* stored (uncompressed) */
#define ZIP_CM_SHRINK 1 /* shrunk */
#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */
#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */
#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */
#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */
#define ZIP_CM_IMPLODE 6 /* imploded */
/* 7 - Reserved for Tokenizing compression algorithm */
#define ZIP_CM_DEFLATE 8 /* deflated */
#define ZIP_CM_DEFLATE64 9 /* deflate64 */
#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */
/* 11 - Reserved by PKWARE */
#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */
/* 13 - Reserved by PKWARE */
#define ZIP_CM_LZMA 14 /* LZMA (EFS) */
/* 15-17 - Reserved by PKWARE */
#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */
#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
/* 20 - old value for Zstandard */
#define ZIP_CM_LZMA2 33
#define ZIP_CM_ZSTD 93 /* Zstandard compressed data */
#define ZIP_CM_XZ 95 /* XZ compressed data */
#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */
#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */
#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */
/* encryption methods */
#define ZIP_EM_NONE 0 /* not encrypted */
#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */
#if 0 /* Strong Encryption Header not parsed yet */
#define ZIP_EM_DES 0x6601 /* strong encryption: DES */
#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */
#define ZIP_EM_3DES_168 0x6603
#define ZIP_EM_3DES_112 0x6609
#define ZIP_EM_PKZIP_AES_128 0x660e
#define ZIP_EM_PKZIP_AES_192 0x660f
#define ZIP_EM_PKZIP_AES_256 0x6610
#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */
#define ZIP_EM_RC4 0x6801
#endif
#define ZIP_EM_AES_128 0x0101 /* Winzip AES encryption */
#define ZIP_EM_AES_192 0x0102
#define ZIP_EM_AES_256 0x0103
#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */
#define ZIP_OPSYS_DOS 0x00u
#define ZIP_OPSYS_AMIGA 0x01u
#define ZIP_OPSYS_OPENVMS 0x02u
#define ZIP_OPSYS_UNIX 0x03u
#define ZIP_OPSYS_VM_CMS 0x04u
#define ZIP_OPSYS_ATARI_ST 0x05u
#define ZIP_OPSYS_OS_2 0x06u
#define ZIP_OPSYS_MACINTOSH 0x07u
#define ZIP_OPSYS_Z_SYSTEM 0x08u
#define ZIP_OPSYS_CPM 0x09u
#define ZIP_OPSYS_WINDOWS_NTFS 0x0au
#define ZIP_OPSYS_MVS 0x0bu
#define ZIP_OPSYS_VSE 0x0cu
#define ZIP_OPSYS_ACORN_RISC 0x0du
#define ZIP_OPSYS_VFAT 0x0eu
#define ZIP_OPSYS_ALTERNATE_MVS 0x0fu
#define ZIP_OPSYS_BEOS 0x10u
#define ZIP_OPSYS_TANDEM 0x11u
#define ZIP_OPSYS_OS_400 0x12u
#define ZIP_OPSYS_OS_X 0x13u
#define ZIP_OPSYS_DEFAULT ZIP_OPSYS_UNIX
enum zip_source_cmd {
ZIP_SOURCE_OPEN, /* prepare for reading */
ZIP_SOURCE_READ, /* read data */
ZIP_SOURCE_CLOSE, /* reading is done */
ZIP_SOURCE_STAT, /* get meta information */
ZIP_SOURCE_ERROR, /* get error information */
ZIP_SOURCE_FREE, /* cleanup and free resources */
ZIP_SOURCE_SEEK, /* set position for reading */
ZIP_SOURCE_TELL, /* get read position */
ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */
ZIP_SOURCE_COMMIT_WRITE, /* writing is done */
ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */
ZIP_SOURCE_WRITE, /* write data */
ZIP_SOURCE_SEEK_WRITE, /* set position for writing */
ZIP_SOURCE_TELL_WRITE, /* get write position */
ZIP_SOURCE_SUPPORTS, /* check whether source supports command */
ZIP_SOURCE_REMOVE, /* remove file */
ZIP_SOURCE_RESERVED_1, /* previously used internally */
ZIP_SOURCE_BEGIN_WRITE_CLONING, /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */
ZIP_SOURCE_ACCEPT_EMPTY, /* whether empty files are valid archives */
ZIP_SOURCE_GET_FILE_ATTRIBUTES /* get additional file attributes */
};
typedef enum zip_source_cmd zip_source_cmd_t;
#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd))
/* clang-format off */
#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_CLOSE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_STAT) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ERROR) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_FREE))
#define ZIP_SOURCE_SUPPORTS_SEEKABLE (ZIP_SOURCE_SUPPORTS_READABLE \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS))
#define ZIP_SOURCE_SUPPORTS_WRITABLE (ZIP_SOURCE_SUPPORTS_SEEKABLE \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_COMMIT_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ROLLBACK_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE))
/* clang-format on */
/* for use by sources */
struct zip_source_args_seek {
zip_int64_t offset;
int whence;
};
typedef struct zip_source_args_seek zip_source_args_seek_t;
#define ZIP_SOURCE_GET_ARGS(type, data, len, error) ((len) < sizeof(type) ? zip_error_set((error), ZIP_ER_INVAL, 0), (type *)NULL : (type *)(data))
/* error information */
/* use zip_error_*() to access */
struct zip_error {
int zip_err; /* libzip error code (ZIP_ER_*) */
int sys_err; /* copy of errno (E*) or zlib error code */
char *_Nullable str; /* string representation or NULL */
};
#define ZIP_STAT_NAME 0x0001u
#define ZIP_STAT_INDEX 0x0002u
#define ZIP_STAT_SIZE 0x0004u
#define ZIP_STAT_COMP_SIZE 0x0008u
#define ZIP_STAT_MTIME 0x0010u
#define ZIP_STAT_CRC 0x0020u
#define ZIP_STAT_COMP_METHOD 0x0040u
#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u
#define ZIP_STAT_FLAGS 0x0100u
struct zip_stat {
zip_uint64_t valid; /* which fields have valid values */
const char *_Nullable name; /* name of the file */
zip_uint64_t index; /* index within archive */
zip_uint64_t size; /* size of file (uncompressed) */
zip_uint64_t comp_size; /* size of file (compressed) */
time_t mtime; /* modification time */
zip_uint32_t crc; /* crc of file data */
zip_uint16_t comp_method; /* compression method used */
zip_uint16_t encryption_method; /* encryption method used */
zip_uint32_t flags; /* reserved for future use */
};
struct zip_buffer_fragment {
zip_uint8_t *_Nonnull data;
zip_uint64_t length;
};
struct zip_file_attributes {
zip_uint64_t valid; /* which fields have valid values */
zip_uint8_t version; /* version of this struct, currently 1 */
zip_uint8_t host_system; /* host system on which file was created */
zip_uint8_t ascii; /* flag whether file is ASCII text */
zip_uint8_t version_needed; /* minimum version needed to extract file */
zip_uint32_t external_file_attributes; /* external file attributes (host-system specific) */
zip_uint16_t general_purpose_bit_flags; /* general purpose big flags, only some bits are honored */
zip_uint16_t general_purpose_bit_mask; /* which bits in general_purpose_bit_flags are valid */
};
#define ZIP_FILE_ATTRIBUTES_HOST_SYSTEM 0x0001u
#define ZIP_FILE_ATTRIBUTES_ASCII 0x0002u
#define ZIP_FILE_ATTRIBUTES_VERSION_NEEDED 0x0004u
#define ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES 0x0008u
#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS 0x0010u
struct zip;
struct zip_file;
struct zip_source;
typedef struct zip zip_t;
typedef struct zip_error zip_error_t;
typedef struct zip_file zip_file_t;
typedef struct zip_file_attributes zip_file_attributes_t;
typedef struct zip_source zip_source_t;
typedef struct zip_stat zip_stat_t;
typedef struct zip_buffer_fragment zip_buffer_fragment_t;
typedef zip_uint32_t zip_flags_t;
typedef zip_int64_t (*zip_source_callback)(void *_Nullable, void *_Nullable, zip_uint64_t, zip_source_cmd_t);
typedef void (*zip_progress_callback)(zip_t *_Nonnull, double, void *_Nullable);
typedef int (*zip_cancel_callback)(zip_t *_Nonnull, void *_Nullable);
#ifndef ZIP_DISABLE_DEPRECATED
typedef void (*zip_progress_callback_t)(double);
ZIP_EXTERN void zip_register_progress_callback(zip_t *_Nonnull, zip_progress_callback_t _Nullable); /* use zip_register_progress_callback_with_state */
ZIP_EXTERN zip_int64_t zip_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull); /* use zip_file_add */
ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *_Nonnull, const char *_Nonnull); /* use zip_dir_add */
ZIP_EXTERN const char *_Nullable zip_get_file_comment(zip_t *_Nonnull, zip_uint64_t, int *_Nullable, int); /* use zip_file_get_comment */
ZIP_EXTERN int zip_get_num_files(zip_t *_Nonnull); /* use zip_get_num_entries instead */
ZIP_EXTERN int zip_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull); /* use zip_file_rename */
ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull); /* use zip_file_replace */
ZIP_EXTERN int zip_set_file_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, int); /* use zip_file_set_comment */
ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */
ZIP_EXTERN void zip_error_get(zip_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
ZIP_EXTERN int zip_error_to_str(char *_Nonnull, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */
ZIP_EXTERN void zip_file_error_get(zip_file_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
#endif
ZIP_EXTERN int zip_close(zip_t *_Nonnull);
ZIP_EXTERN int zip_delete(zip_t *_Nonnull, zip_uint64_t);
ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN void zip_discard(zip_t *_Nonnull);
ZIP_EXTERN zip_error_t *_Nonnull zip_get_error(zip_t *_Nonnull);
ZIP_EXTERN void zip_error_clear(zip_t *_Nonnull);
ZIP_EXTERN int zip_error_code_zip(const zip_error_t *_Nonnull);
ZIP_EXTERN int zip_error_code_system(const zip_error_t *_Nonnull);
ZIP_EXTERN void zip_error_fini(zip_error_t *_Nonnull);
ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull);
ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int);
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int);
ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull);
ZIP_EXTERN int zip_error_system_type(const zip_error_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *_Nonnull, void *_Nonnull, zip_uint64_t);
ZIP_EXTERN int zip_fclose(zip_file_t *_Nonnull);
ZIP_EXTERN zip_t *_Nullable zip_fdopen(int, int, int *_Nullable);
ZIP_EXTERN zip_int64_t zip_file_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull, zip_flags_t);
ZIP_EXTERN void zip_file_attributes_init(zip_file_attributes_t *_Nonnull);
ZIP_EXTERN void zip_file_error_clear(zip_file_t *_Nonnull);
ZIP_EXTERN int zip_file_extra_field_delete(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_extra_field_set(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *_Nullable, zip_uint16_t, zip_flags_t);
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_uint16_t *_Nullable, zip_flags_t);
ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_flags_t);
ZIP_EXTERN const char *_Nullable zip_file_get_comment(zip_t *_Nonnull, zip_uint64_t, zip_uint32_t *_Nullable, zip_flags_t);
ZIP_EXTERN zip_error_t *_Nonnull zip_file_get_error(zip_file_t *_Nonnull);
ZIP_EXTERN int zip_file_get_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t *_Nullable, zip_uint32_t *_Nullable);
ZIP_EXTERN int zip_file_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN int zip_file_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull, zip_flags_t);
ZIP_EXTERN int zip_file_set_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_set_dostime(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_set_encryption(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, const char *_Nullable);
ZIP_EXTERN int zip_file_set_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
ZIP_EXTERN int zip_file_set_mtime(zip_t *_Nonnull, zip_uint64_t, time_t, zip_flags_t);
ZIP_EXTERN const char *_Nonnull zip_file_strerror(zip_file_t *_Nonnull);
ZIP_EXTERN zip_file_t *_Nullable zip_fopen(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN zip_file_t *_Nullable zip_fopen_encrypted(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, const char *_Nullable);
ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index_encrypted(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, const char *_Nullable);
ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *_Nonnull, void *_Nonnull, zip_uint64_t);
ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t *_Nonnull, zip_int64_t, int);
ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t *_Nonnull);
ZIP_EXTERN const char *_Nullable zip_get_archive_comment(zip_t *_Nonnull, int *_Nullable, zip_flags_t);
ZIP_EXTERN int zip_get_archive_flag(zip_t *_Nonnull, zip_flags_t, zip_flags_t);
ZIP_EXTERN const char *_Nullable zip_get_name(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *_Nonnull, zip_flags_t);
ZIP_EXTERN const char *_Nonnull zip_libzip_version(void);
ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN zip_t *_Nullable zip_open(const char *_Nonnull, int, int *_Nullable);
ZIP_EXTERN zip_t *_Nullable zip_open_from_source(zip_source_t *_Nonnull, int, zip_error_t *_Nullable);
ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *_Nonnull, double, zip_progress_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable);
ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t *_Nonnull, zip_cancel_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable);
ZIP_EXTERN int zip_set_archive_comment(zip_t *_Nonnull, const char *_Nullable, zip_uint16_t);
ZIP_EXTERN int zip_set_archive_flag(zip_t *_Nonnull, zip_flags_t, int);
ZIP_EXTERN int zip_set_default_password(zip_t *_Nonnull, const char *_Nullable);
ZIP_EXTERN int zip_set_file_compression(zip_t *_Nonnull, zip_uint64_t, zip_int32_t, zip_uint32_t);
ZIP_EXTERN int zip_source_begin_write(zip_source_t *_Nonnull);
ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t *_Nonnull, zip_uint64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer(zip_t *_Nonnull, const void *_Nullable, zip_uint64_t, int);
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_create(const void *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable);
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment(zip_t *_Nonnull, const zip_buffer_fragment_t *_Nonnull, zip_uint64_t, int);
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable);
ZIP_EXTERN int zip_source_close(zip_source_t *_Nonnull);
ZIP_EXTERN int zip_source_commit_write(zip_source_t *_Nonnull);
ZIP_EXTERN zip_error_t *_Nonnull zip_source_error(zip_source_t *_Nonnull);
ZIP_EXTERN zip_source_t *_Nullable zip_source_file(zip_t *_Nonnull, const char *_Nonnull, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_file_create(const char *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
ZIP_EXTERN zip_source_t *_Nullable zip_source_filep(zip_t *_Nonnull, FILE *_Nonnull, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_filep_create(FILE *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
ZIP_EXTERN void zip_source_free(zip_source_t *_Nullable);
ZIP_EXTERN zip_source_t *_Nullable zip_source_function(zip_t *_Nonnull, zip_source_callback _Nonnull, void *_Nullable);
ZIP_EXTERN zip_source_t *_Nullable zip_source_function_create(zip_source_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable);
ZIP_EXTERN int zip_source_get_file_attributes(zip_source_t *_Nonnull, zip_file_attributes_t *_Nonnull);
ZIP_EXTERN int zip_source_is_deleted(zip_source_t *_Nonnull);
ZIP_EXTERN void zip_source_keep(zip_source_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...);
ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *_Nonnull, void *_Nonnull, zip_uint64_t);
ZIP_EXTERN void zip_source_rollback_write(zip_source_t *_Nonnull);
ZIP_EXTERN int zip_source_seek(zip_source_t *_Nonnull, zip_int64_t, int);
ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *_Nonnull, zip_uint64_t, zip_error_t *_Nullable);
ZIP_EXTERN int zip_source_seek_write(zip_source_t *_Nonnull, zip_int64_t, int);
ZIP_EXTERN int zip_source_stat(zip_source_t *_Nonnull, zip_stat_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *_Nonnull);
#ifdef _WIN32
ZIP_EXTERN zip_source_t *zip_source_win32a(zip_t *, const char *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32a_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
ZIP_EXTERN zip_source_t *zip_source_win32handle(zip_t *, void *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip_int64_t, zip_error_t *);
ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *);
#endif
ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
ZIP_EXTERN int zip_stat(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, zip_stat_t *_Nonnull);
ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull);
ZIP_EXTERN void zip_stat_init(zip_stat_t *_Nonnull);
ZIP_EXTERN const char *_Nonnull zip_strerror(zip_t *_Nonnull);
ZIP_EXTERN int zip_unchange(zip_t *_Nonnull, zip_uint64_t);
ZIP_EXTERN int zip_unchange_all(zip_t *_Nonnull);
ZIP_EXTERN int zip_unchange_archive(zip_t *_Nonnull);
ZIP_EXTERN int zip_compression_method_supported(zip_int32_t method, int compress);
ZIP_EXTERN int zip_encryption_method_supported(zip_uint16_t method, int encode);
#ifdef __cplusplus
}
#endif
#endif /* _HAD_ZIP_H */

View File

@ -1,6 +1,6 @@
/*
zip_add.c -- add file via callback function
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,19 +31,19 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN int
zip_add(struct zip *za, const char *name, struct zip_source *source)
{
if (name == NULL || source == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
return _zip_replace(za, -1, name, source);
/*
NOTE: Return type is signed so we can return -1 on error.
The index can not be larger than ZIP_INT64_MAX since the size
of the central directory cannot be larger than
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
*/
ZIP_EXTERN zip_int64_t
zip_add(zip_t *za, const char *name, zip_source_t *source) {
return zip_file_add(za, name, source, 0);
}

View File

@ -1,6 +1,6 @@
/*
zip_source_free.c -- free zip data source
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
zip_add_dir.c -- add directory
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,21 +31,14 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN void
zip_source_free(struct zip_source *source)
{
if (source == NULL)
return;
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
(void)source->f(source->ud, NULL, 0, ZIP_SOURCE_FREE);
free(source);
ZIP_EXTERN zip_int64_t
zip_add_dir(zip_t *za, const char *name) {
return zip_dir_add(za, name, 0);
}

View File

@ -0,0 +1,80 @@
/*
zip_add_entry.c -- create and init struct zip_entry
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
zip_int64_t
_zip_add_entry(zip_t *za) {
zip_uint64_t idx;
if (za->nentry + 1 >= za->nentry_alloc) {
zip_entry_t *rentries;
zip_uint64_t nalloc = za->nentry_alloc;
zip_uint64_t additional_entries = 2 * nalloc;
zip_uint64_t realloc_size;
if (additional_entries < 16) {
additional_entries = 16;
}
else if (additional_entries > 1024) {
additional_entries = 1024;
}
/* neither + nor * overflows can happen: nentry_alloc * sizeof(struct zip_entry) < UINT64_MAX */
nalloc += additional_entries;
realloc_size = sizeof(struct zip_entry) * (size_t)nalloc;
if (sizeof(struct zip_entry) * (size_t)za->nentry_alloc > realloc_size) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc);
if (!rentries) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
za->entry = rentries;
za->nentry_alloc = nalloc;
}
idx = za->nentry++;
_zip_entry_init(za->entry + idx);
return (zip_int64_t)idx;
}

View File

@ -0,0 +1,285 @@
/*
zip_algorithm_bzip2.c -- bzip2 (de)compression routines
Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
#include <bzlib.h>
#include <limits.h>
#include <stdlib.h>
struct ctx {
zip_error_t *error;
bool compress;
int compression_flags;
bool end_of_input;
bz_stream zstr;
};
static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
zip_uint64_t compressed_size = (zip_uint64_t)((double)uncompressed_size * 1.006);
if (compressed_size < uncompressed_size) {
return ZIP_UINT64_MAX;
}
return compressed_size;
}
static void *
allocate(bool compress, int compression_flags, zip_error_t *error) {
struct ctx *ctx;
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
return NULL;
}
ctx->error = error;
ctx->compress = compress;
ctx->compression_flags = compression_flags;
if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
ctx->compression_flags = 9;
}
ctx->end_of_input = false;
ctx->zstr.bzalloc = NULL;
ctx->zstr.bzfree = NULL;
ctx->zstr.opaque = NULL;
return ctx;
}
static void *
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(true, compression_flags, error);
}
static void *
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(false, compression_flags, error);
}
static void
deallocate(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
free(ctx);
}
static zip_uint16_t
general_purpose_bit_flags(void *ud) {
return 0;
}
static int
map_error(int ret) {
switch (ret) {
case BZ_FINISH_OK:
case BZ_FLUSH_OK:
case BZ_OK:
case BZ_RUN_OK:
case BZ_STREAM_END:
return ZIP_ER_OK;
case BZ_DATA_ERROR:
case BZ_DATA_ERROR_MAGIC:
case BZ_UNEXPECTED_EOF:
return ZIP_ER_COMPRESSED_DATA;
case BZ_MEM_ERROR:
return ZIP_ER_MEMORY;
case BZ_PARAM_ERROR:
return ZIP_ER_INVAL;
case BZ_CONFIG_ERROR: /* actually, bzip2 miscompiled */
case BZ_IO_ERROR:
case BZ_OUTBUFF_FULL:
case BZ_SEQUENCE_ERROR:
return ZIP_ER_INTERNAL;
default:
return ZIP_ER_INTERNAL;
}
}
static bool
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
struct ctx *ctx = (struct ctx *)ud;
int ret;
ctx->zstr.avail_in = 0;
ctx->zstr.next_in = NULL;
ctx->zstr.avail_out = 0;
ctx->zstr.next_out = NULL;
if (ctx->compress) {
ret = BZ2_bzCompressInit(&ctx->zstr, ctx->compression_flags, 0, 30);
}
else {
ret = BZ2_bzDecompressInit(&ctx->zstr, 0, 0);
}
if (ret != BZ_OK) {
zip_error_set(ctx->error, map_error(ret), 0);
return false;
}
return true;
}
static bool
end(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
int err;
if (ctx->compress) {
err = BZ2_bzCompressEnd(&ctx->zstr);
}
else {
err = BZ2_bzDecompressEnd(&ctx->zstr);
}
if (err != BZ_OK) {
zip_error_set(ctx->error, map_error(err), 0);
return false;
}
return true;
}
static bool
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
struct ctx *ctx = (struct ctx *)ud;
if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
return false;
}
ctx->zstr.avail_in = (unsigned int)length;
ctx->zstr.next_in = (char *)data;
return true;
}
static void
end_of_input(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
ctx->end_of_input = true;
}
static zip_compression_status_t
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
struct ctx *ctx = (struct ctx *)ud;
int ret;
if (ctx->zstr.avail_in == 0 && !ctx->end_of_input) {
*length = 0;
return ZIP_COMPRESSION_NEED_DATA;
}
ctx->zstr.avail_out = (unsigned int)ZIP_MIN(UINT_MAX, *length);
ctx->zstr.next_out = (char *)data;
if (ctx->compress) {
ret = BZ2_bzCompress(&ctx->zstr, ctx->end_of_input ? BZ_FINISH : BZ_RUN);
}
else {
ret = BZ2_bzDecompress(&ctx->zstr);
}
*length = *length - ctx->zstr.avail_out;
switch (ret) {
case BZ_FINISH_OK: /* compression */
return ZIP_COMPRESSION_OK;
case BZ_OK: /* decompression */
case BZ_RUN_OK: /* compression */
if (ctx->zstr.avail_in == 0) {
return ZIP_COMPRESSION_NEED_DATA;
}
return ZIP_COMPRESSION_OK;
case BZ_STREAM_END:
return ZIP_COMPRESSION_END;
default:
zip_error_set(ctx->error, map_error(ret), 0);
return ZIP_COMPRESSION_ERROR;
}
}
/* clang-format off */
zip_compression_algorithm_t zip_algorithm_bzip2_compress = {
maximum_compressed_size,
compress_allocate,
deallocate,
general_purpose_bit_flags,
46,
start,
end,
input,
end_of_input,
process
};
zip_compression_algorithm_t zip_algorithm_bzip2_decompress = {
maximum_compressed_size,
decompress_allocate,
deallocate,
general_purpose_bit_flags,
46,
start,
end,
input,
end_of_input,
process
};
/* clang-format on */

View File

@ -0,0 +1,265 @@
/*
zip_algorithm_deflate.c -- deflate (de)compression routines
Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
#include <limits.h>
#include <stdlib.h>
#include <zlib.h>
struct ctx {
zip_error_t *error;
bool compress;
int compression_flags;
bool end_of_input;
z_stream zstr;
};
static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
/* max deflate size increase: size + ceil(size/16k)*5+6 */
zip_uint64_t compressed_size = uncompressed_size + (uncompressed_size + 16383) / 16384 * 5 + 6;
if (compressed_size < uncompressed_size) {
return ZIP_UINT64_MAX;
}
return compressed_size;
}
static void *
allocate(bool compress, int compression_flags, zip_error_t *error) {
struct ctx *ctx;
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(error, ZIP_ET_SYS, errno);
return NULL;
}
ctx->error = error;
ctx->compress = compress;
ctx->compression_flags = compression_flags;
if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
ctx->compression_flags = Z_BEST_COMPRESSION;
}
ctx->end_of_input = false;
ctx->zstr.zalloc = Z_NULL;
ctx->zstr.zfree = Z_NULL;
ctx->zstr.opaque = NULL;
return ctx;
}
static void *
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(true, compression_flags, error);
}
static void *
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(false, compression_flags, error);
}
static void
deallocate(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
free(ctx);
}
static zip_uint16_t
general_purpose_bit_flags(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
if (!ctx->compress) {
return 0;
}
if (ctx->compression_flags < 3) {
return 2 << 1;
}
else if (ctx->compression_flags > 7) {
return 1 << 1;
}
return 0;
}
static bool
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
struct ctx *ctx = (struct ctx *)ud;
int ret;
ctx->zstr.avail_in = 0;
ctx->zstr.next_in = NULL;
ctx->zstr.avail_out = 0;
ctx->zstr.next_out = NULL;
if (ctx->compress) {
/* negative value to tell zlib not to write a header */
ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
}
else {
ret = inflateInit2(&ctx->zstr, -MAX_WBITS);
}
if (ret != Z_OK) {
zip_error_set(ctx->error, ZIP_ER_ZLIB, ret);
return false;
}
return true;
}
static bool
end(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
int err;
if (ctx->compress) {
err = deflateEnd(&ctx->zstr);
}
else {
err = inflateEnd(&ctx->zstr);
}
if (err != Z_OK) {
zip_error_set(ctx->error, ZIP_ER_ZLIB, err);
return false;
}
return true;
}
static bool
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
struct ctx *ctx = (struct ctx *)ud;
if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
return false;
}
ctx->zstr.avail_in = (uInt)length;
ctx->zstr.next_in = (Bytef *)data;
return true;
}
static void
end_of_input(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
ctx->end_of_input = true;
}
static zip_compression_status_t
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
struct ctx *ctx = (struct ctx *)ud;
int ret;
ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
ctx->zstr.next_out = (Bytef *)data;
if (ctx->compress) {
ret = deflate(&ctx->zstr, ctx->end_of_input ? Z_FINISH : 0);
}
else {
ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
}
*length = *length - ctx->zstr.avail_out;
switch (ret) {
case Z_OK:
return ZIP_COMPRESSION_OK;
case Z_STREAM_END:
return ZIP_COMPRESSION_END;
case Z_BUF_ERROR:
if (ctx->zstr.avail_in == 0) {
return ZIP_COMPRESSION_NEED_DATA;
}
/* fallthrough */
default:
zip_error_set(ctx->error, ZIP_ER_ZLIB, ret);
return ZIP_COMPRESSION_ERROR;
}
}
/* clang-format off */
zip_compression_algorithm_t zip_algorithm_deflate_compress = {
maximum_compressed_size,
compress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
zip_compression_algorithm_t zip_algorithm_deflate_decompress = {
maximum_compressed_size,
decompress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
/* clang-format on */

View File

@ -0,0 +1,407 @@
/*
zip_algorithm_xz.c -- LZMA/XZ (de)compression routines
Bazed on zip_algorithm_deflate.c -- deflate (de)compression routines
Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
#include <limits.h>
#include <lzma.h>
#include <stdlib.h>
#include <zlib.h>
enum header_state { INCOMPLETE, OUTPUT, DONE };
#define HEADER_BYTES_ZIP 9
#define HEADER_MAGIC_LENGTH 4
#define HEADER_MAGIC1_OFFSET 0
#define HEADER_MAGIC2_OFFSET 2
#define HEADER_SIZE_OFFSET 9
#define HEADER_SIZE_LENGTH 8
#define HEADER_PARAMETERS_LENGTH 5
#define HEADER_LZMA_ALONE_LENGTH (HEADER_PARAMETERS_LENGTH + HEADER_SIZE_LENGTH)
struct ctx {
zip_error_t *error;
bool compress;
zip_uint32_t compression_flags;
bool end_of_input;
lzma_stream zstr;
zip_uint16_t method;
/* header member is used for converting from zip to "lzma alone"
* format
*
* "lzma alone" file format starts with:
* 5 bytes lzma parameters
* 8 bytes uncompressed size
* compressed data
*
* zip archive on-disk format starts with
* 4 bytes magic (first two bytes vary, e.g. 0x0914 or 0x1002, next bytes are 0x0500)
* 5 bytes lzma parameters
* compressed data
*
* we read the data into a header of the form
* 4 bytes magic
* 5 bytes lzma parameters
* 8 bytes uncompressed size
*/
zip_uint8_t header[HEADER_MAGIC_LENGTH + HEADER_LZMA_ALONE_LENGTH];
zip_uint8_t header_bytes_offset;
enum header_state header_state;
zip_uint64_t uncompresssed_size;
};
static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
/*
According to https://sourceforge.net/p/sevenzip/discussion/45797/thread/b6bd62f8/
1) you can use
outSize = 1.10 * originalSize + 64 KB.
in most cases outSize is less then 1.02 from originalSize.
2) You can try LZMA2, where
outSize can be = 1.001 * originalSize + 1 KB.
*/
/* 13 bytes added for lzma alone header */
zip_uint64_t compressed_size = (zip_uint64_t)((double)uncompressed_size * 1.1) + 64 * 1024 + 13;
if (compressed_size < uncompressed_size) {
return ZIP_UINT64_MAX;
}
return compressed_size;
}
static void *
allocate(bool compress, int compression_flags, zip_error_t *error, zip_uint16_t method) {
struct ctx *ctx;
if (compression_flags < 0) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
ctx->error = error;
ctx->compress = compress;
ctx->compression_flags = (zip_uint32_t)compression_flags;
ctx->compression_flags |= LZMA_PRESET_EXTREME;
ctx->end_of_input = false;
memset(ctx->header, 0, sizeof(ctx->header));
ctx->header_bytes_offset = 0;
if (ZIP_CM_LZMA) {
ctx->header_state = INCOMPLETE;
}
else {
ctx->header_state = DONE;
}
memset(&ctx->zstr, 0, sizeof(ctx->zstr));
ctx->method = method;
return ctx;
}
static void *
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(true, compression_flags, error, method);
}
static void *
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(false, compression_flags, error, method);
}
static void
deallocate(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
free(ctx);
}
static zip_uint16_t
general_purpose_bit_flags(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
if (!ctx->compress) {
return 0;
}
if (ctx->method == ZIP_CM_LZMA) {
/* liblzma always returns an EOS/EOPM marker, see
* https://sourceforge.net/p/lzmautils/discussion/708858/thread/84c5dbb9/#a5e4/3764 */
return 1 << 1;
}
return 0;
}
static int
map_error(lzma_ret ret) {
switch (ret) {
case LZMA_DATA_ERROR:
case LZMA_UNSUPPORTED_CHECK:
return ZIP_ER_COMPRESSED_DATA;
case LZMA_MEM_ERROR:
return ZIP_ER_MEMORY;
case LZMA_OPTIONS_ERROR:
return ZIP_ER_INVAL;
default:
return ZIP_ER_INTERNAL;
}
}
static bool
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
struct ctx *ctx = (struct ctx *)ud;
lzma_ret ret;
lzma_options_lzma opt_lzma;
lzma_lzma_preset(&opt_lzma, ctx->compression_flags);
lzma_filter filters[] = {
{.id = (ctx->method == ZIP_CM_LZMA ? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2), .options = &opt_lzma},
{.id = LZMA_VLI_UNKNOWN, .options = NULL},
};
ctx->zstr.avail_in = 0;
ctx->zstr.next_in = NULL;
ctx->zstr.avail_out = 0;
ctx->zstr.next_out = NULL;
if (ctx->compress) {
if (ctx->method == ZIP_CM_LZMA)
ret = lzma_alone_encoder(&ctx->zstr, filters[0].options);
else
ret = lzma_stream_encoder(&ctx->zstr, filters, LZMA_CHECK_CRC64);
}
else {
if (ctx->method == ZIP_CM_LZMA)
ret = lzma_alone_decoder(&ctx->zstr, UINT64_MAX);
else
ret = lzma_stream_decoder(&ctx->zstr, UINT64_MAX, LZMA_CONCATENATED);
}
if (ret != LZMA_OK) {
zip_error_set(ctx->error, map_error(ret), 0);
return false;
}
/* If general purpose bits 1 & 2 are both zero, write real uncompressed size in header. */
if ((attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) && (attributes->general_purpose_bit_mask & 0x6) == 0x6 && (attributes->general_purpose_bit_flags & 0x06) == 0 && (st->valid & ZIP_STAT_SIZE)) {
ctx->uncompresssed_size = st->size;
}
else {
ctx->uncompresssed_size = ZIP_UINT64_MAX;
}
return true;
}
static bool
end(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
lzma_end(&ctx->zstr);
return true;
}
static bool
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
struct ctx *ctx = (struct ctx *)ud;
if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
return false;
}
/* For decompression of LZMA1: Have we read the full "lzma alone" header yet? */
if (ctx->method == ZIP_CM_LZMA && !ctx->compress && ctx->header_state == INCOMPLETE) {
/* if not, get more of the data */
zip_uint8_t got = ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, length);
memcpy(ctx->header + ctx->header_bytes_offset, data, got);
ctx->header_bytes_offset += got;
length -= got;
data += got;
/* Do we have a complete header now? */
if (ctx->header_bytes_offset == HEADER_BYTES_ZIP) {
Bytef empty_buffer[1];
zip_buffer_t *buffer;
/* check magic */
if (ctx->header[HEADER_MAGIC2_OFFSET] != 0x05 || ctx->header[HEADER_MAGIC2_OFFSET + 1] != 0x00) {
/* magic does not match */
zip_error_set(ctx->error, ZIP_ER_COMPRESSED_DATA, 0);
return false;
}
/* set size of uncompressed data in "lzma alone" header to "unknown" */
if ((buffer = _zip_buffer_new(ctx->header + HEADER_SIZE_OFFSET, HEADER_SIZE_LENGTH)) == NULL) {
zip_error_set(ctx->error, ZIP_ER_MEMORY, 0);
return false;
}
_zip_buffer_put_64(buffer, ctx->uncompresssed_size);
_zip_buffer_free(buffer);
/* Feed header into "lzma alone" decoder, for
* initialization; this should not produce output. */
ctx->zstr.next_in = (void *)(ctx->header + HEADER_MAGIC_LENGTH);
ctx->zstr.avail_in = HEADER_LZMA_ALONE_LENGTH;
ctx->zstr.total_in = 0;
ctx->zstr.next_out = empty_buffer;
ctx->zstr.avail_out = sizeof(*empty_buffer);
ctx->zstr.total_out = 0;
/* this just initializes the decoder and does not produce output, so it consumes the complete header */
if (lzma_code(&ctx->zstr, LZMA_RUN) != LZMA_OK || ctx->zstr.total_out > 0) {
zip_error_set(ctx->error, ZIP_ER_COMPRESSED_DATA, 0);
return false;
}
ctx->header_state = DONE;
}
}
ctx->zstr.avail_in = (uInt)length;
ctx->zstr.next_in = (Bytef *)data;
return true;
}
static void
end_of_input(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
ctx->end_of_input = true;
}
static zip_compression_status_t
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
struct ctx *ctx = (struct ctx *)ud;
lzma_ret ret;
/* for compression of LZMA1 */
if (ctx->method == ZIP_CM_LZMA && ctx->compress) {
if (ctx->header_state == INCOMPLETE) {
/* write magic to output buffer */
ctx->header[0] = 0x09;
ctx->header[1] = 0x14;
ctx->header[2] = 0x05;
ctx->header[3] = 0x00;
/* generate lzma parameters into output buffer */
ctx->zstr.avail_out = HEADER_LZMA_ALONE_LENGTH;
ctx->zstr.next_out = ctx->header + HEADER_MAGIC_LENGTH;
ret = lzma_code(&ctx->zstr, LZMA_RUN);
if (ret != LZMA_OK || ctx->zstr.avail_out != 0) {
/* assume that the whole header will be provided with the first call to lzma_code */
return ZIP_COMPRESSION_ERROR;
}
ctx->header_state = OUTPUT;
}
if (ctx->header_state == OUTPUT) {
/* write header */
zip_uint8_t write_len = ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, *length);
memcpy(data, ctx->header + ctx->header_bytes_offset, write_len);
ctx->header_bytes_offset += write_len;
*length = write_len;
if (ctx->header_bytes_offset == HEADER_BYTES_ZIP) {
ctx->header_state = DONE;
}
return ZIP_COMPRESSION_OK;
}
}
ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
ctx->zstr.next_out = (Bytef *)data;
ret = lzma_code(&ctx->zstr, ctx->end_of_input ? LZMA_FINISH : LZMA_RUN);
*length = *length - ctx->zstr.avail_out;
switch (ret) {
case LZMA_OK:
return ZIP_COMPRESSION_OK;
case LZMA_STREAM_END:
return ZIP_COMPRESSION_END;
case LZMA_BUF_ERROR:
if (ctx->zstr.avail_in == 0) {
return ZIP_COMPRESSION_NEED_DATA;
}
/* fallthrough */
default:
zip_error_set(ctx->error, map_error(ret), 0);
return ZIP_COMPRESSION_ERROR;
}
}
/* Version Required should be set to 63 (6.3) because this compression
method was only defined in appnote.txt version 6.3.8, but Winzip
does not unpack it if the value is not 20. */
/* clang-format off */
zip_compression_algorithm_t zip_algorithm_xz_compress = {
maximum_compressed_size,
compress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
zip_compression_algorithm_t zip_algorithm_xz_decompress = {
maximum_compressed_size,
decompress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
/* clang-format on */

View File

@ -0,0 +1,294 @@
/*
zip_algorithm_zstd.c -- zstd (de)compression routines
Copyright (C) 2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
#include <limits.h>
#include <stdlib.h>
#include <zstd.h>
#include <zstd_errors.h>
struct ctx {
zip_error_t *error;
bool compress;
int compression_flags;
bool end_of_input;
ZSTD_DStream *zdstream;
ZSTD_CStream *zcstream;
ZSTD_outBuffer out;
ZSTD_inBuffer in;
};
static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
return ZSTD_compressBound(uncompressed_size);
}
static void *
allocate(bool compress, int compression_flags, zip_error_t *error) {
struct ctx *ctx;
/* 0: let zstd choose */
if (compression_flags < 0 || compression_flags > 9) {
compression_flags = 0;
}
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
return NULL;
}
ctx->error = error;
ctx->compress = compress;
ctx->compression_flags = compression_flags;
ctx->end_of_input = false;
ctx->zdstream = NULL;
ctx->zcstream = NULL;
ctx->in.src = NULL;
ctx->in.pos = 0;
ctx->in.size = 0;
ctx->out.dst = NULL;
ctx->out.pos = 0;
ctx->out.size = 0;
return ctx;
}
static void *
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(true, compression_flags, error);
}
static void *
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(false, compression_flags, error);
}
static void
deallocate(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
free(ctx);
}
static zip_uint16_t
general_purpose_bit_flags(void *ud) {
/* struct ctx *ctx = (struct ctx *)ud; */
return 0;
}
static int
map_error(size_t ret) {
switch (ret) {
case ZSTD_error_no_error:
return ZIP_ER_OK;
case ZSTD_error_corruption_detected:
case ZSTD_error_checksum_wrong:
case ZSTD_error_dictionary_corrupted:
case ZSTD_error_dictionary_wrong:
return ZIP_ER_COMPRESSED_DATA;
case ZSTD_error_memory_allocation:
return ZIP_ER_MEMORY;
case ZSTD_error_parameter_unsupported:
case ZSTD_error_parameter_outOfBound:
return ZIP_ER_INVAL;
default:
return ZIP_ER_INTERNAL;
}
}
static bool
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
struct ctx *ctx = (struct ctx *)ud;
ctx->in.src = NULL;
ctx->in.pos = 0;
ctx->in.size = 0;
ctx->out.dst = NULL;
ctx->out.pos = 0;
ctx->out.size = 0;
if (ctx->compress) {
size_t ret;
ctx->zcstream = ZSTD_createCStream();
if (ctx->zcstream == NULL) {
zip_error_set(ctx->error, ZIP_ER_MEMORY, 0);
return false;
}
ret = ZSTD_initCStream(ctx->zcstream, ctx->compression_flags);
if (ZSTD_isError(ret)) {
zip_error_set(ctx->error, ZIP_ER_ZLIB, map_error(ret));
return false;
}
}
else {
ctx->zdstream = ZSTD_createDStream();
if (ctx->zdstream == NULL) {
zip_error_set(ctx->error, ZIP_ER_MEMORY, 0);
return false;
}
}
return true;
}
static bool
end(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
size_t ret;
if (ctx->compress) {
ret = ZSTD_freeCStream(ctx->zcstream);
ctx->zcstream = NULL;
}
else {
ret = ZSTD_freeDStream(ctx->zdstream);
ctx->zdstream = NULL;
}
if (ZSTD_isError(ret)) {
zip_error_set(ctx->error, map_error(ret), 0);
return false;
}
return true;
}
static bool
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
struct ctx *ctx = (struct ctx *)ud;
if (length > SIZE_MAX || ctx->in.pos != ctx->in.size) {
zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
return false;
}
ctx->in.src = (const void *)data;
ctx->in.size = (size_t)length;
ctx->in.pos = 0;
return true;
}
static void
end_of_input(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
ctx->end_of_input = true;
}
static zip_compression_status_t
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
struct ctx *ctx = (struct ctx *)ud;
size_t ret;
if (ctx->in.pos == ctx->in.size && !ctx->end_of_input) {
*length = 0;
return ZIP_COMPRESSION_NEED_DATA;
}
ctx->out.dst = data;
ctx->out.pos = 0;
ctx->out.size = ZIP_MIN(SIZE_MAX, *length);
if (ctx->compress) {
if (ctx->in.pos == ctx->in.size && ctx->end_of_input) {
ret = ZSTD_endStream(ctx->zcstream, &ctx->out);
if (ret == 0) {
*length = ctx->out.pos;
return ZIP_COMPRESSION_END;
}
}
else {
ret = ZSTD_compressStream(ctx->zcstream, &ctx->out, &ctx->in);
}
}
else {
ret = ZSTD_decompressStream(ctx->zdstream, &ctx->out, &ctx->in);
}
if (ZSTD_isError(ret)) {
zip_error_set(ctx->error, map_error(ret), 0);
return ZIP_COMPRESSION_ERROR;
}
*length = ctx->out.pos;
if (ctx->in.pos == ctx->in.size) {
return ZIP_COMPRESSION_NEED_DATA;
}
return ZIP_COMPRESSION_OK;
}
/* Version Required should be set to 63 (6.3) because this compression
method was only defined in appnote.txt version 6.3.7, but Winzip
does not unpack it if the value is not 20. */
/* clang-format off */
zip_compression_algorithm_t zip_algorithm_zstd_compress = {
maximum_compressed_size,
compress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
zip_compression_algorithm_t zip_algorithm_zstd_decompress = {
maximum_compressed_size,
decompress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
/* clang-format on */

View File

@ -0,0 +1,324 @@
/*
zip_buffer.c -- bounds checked access to memory buffer
Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
zip_uint8_t *
_zip_buffer_data(zip_buffer_t *buffer) {
return buffer->data;
}
void
_zip_buffer_free(zip_buffer_t *buffer) {
if (buffer == NULL) {
return;
}
if (buffer->free_data) {
free(buffer->data);
}
free(buffer);
}
bool
_zip_buffer_eof(zip_buffer_t *buffer) {
return buffer->ok && buffer->offset == buffer->size;
}
zip_uint8_t *
_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length) {
zip_uint8_t *data;
data = _zip_buffer_peek(buffer, length);
if (data != NULL) {
buffer->offset += length;
}
return data;
}
zip_uint16_t
_zip_buffer_get_16(zip_buffer_t *buffer) {
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
if (data == NULL) {
return 0;
}
return (zip_uint16_t)(data[0] + (data[1] << 8));
}
zip_uint32_t
_zip_buffer_get_32(zip_buffer_t *buffer) {
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
if (data == NULL) {
return 0;
}
return ((((((zip_uint32_t)data[3] << 8) + data[2]) << 8) + data[1]) << 8) + data[0];
}
zip_uint64_t
_zip_buffer_get_64(zip_buffer_t *buffer) {
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
if (data == NULL) {
return 0;
}
return ((zip_uint64_t)data[7] << 56) + ((zip_uint64_t)data[6] << 48) + ((zip_uint64_t)data[5] << 40) + ((zip_uint64_t)data[4] << 32) + ((zip_uint64_t)data[3] << 24) + ((zip_uint64_t)data[2] << 16) + ((zip_uint64_t)data[1] << 8) + (zip_uint64_t)data[0];
}
zip_uint8_t
_zip_buffer_get_8(zip_buffer_t *buffer) {
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
if (data == NULL) {
return 0;
}
return data[0];
}
zip_uint64_t
_zip_buffer_left(zip_buffer_t *buffer) {
return buffer->ok ? buffer->size - buffer->offset : 0;
}
zip_uint64_t
_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) {
if (_zip_buffer_left(buffer) < length) {
length = _zip_buffer_left(buffer);
}
memcpy(data, _zip_buffer_get(buffer, length), length);
return length;
}
zip_buffer_t *
_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) {
bool free_data = (data == NULL);
zip_buffer_t *buffer;
if (data == NULL) {
if ((data = (zip_uint8_t *)malloc(size)) == NULL) {
return NULL;
}
}
if ((buffer = (zip_buffer_t *)malloc(sizeof(*buffer))) == NULL) {
if (free_data) {
free(data);
}
return NULL;
}
buffer->ok = true;
buffer->data = data;
buffer->size = size;
buffer->offset = 0;
buffer->free_data = free_data;
return buffer;
}
zip_buffer_t *
_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error) {
zip_buffer_t *buffer;
if ((buffer = _zip_buffer_new(buf, size)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (_zip_read(src, buffer->data, size, error) < 0) {
_zip_buffer_free(buffer);
return NULL;
}
return buffer;
}
zip_uint64_t
_zip_buffer_offset(zip_buffer_t *buffer) {
return buffer->ok ? buffer->offset : 0;
}
bool
_zip_buffer_ok(zip_buffer_t *buffer) {
return buffer->ok;
}
zip_uint8_t *
_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length) {
zip_uint8_t *data;
if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
buffer->ok = false;
return NULL;
}
data = buffer->data + buffer->offset;
return data;
}
int
_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) {
zip_uint8_t *dst = _zip_buffer_get(buffer, length);
if (dst == NULL) {
return -1;
}
memcpy(dst, src, length);
return 0;
}
int
_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i) {
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
return 0;
}
int
_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i) {
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
return 0;
}
int
_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i) {
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
if (data == NULL) {
return -1;
}
data[0] = (zip_uint8_t)(i & 0xff);
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
data[4] = (zip_uint8_t)((i >> 32) & 0xff);
data[5] = (zip_uint8_t)((i >> 40) & 0xff);
data[6] = (zip_uint8_t)((i >> 48) & 0xff);
data[7] = (zip_uint8_t)((i >> 56) & 0xff);
return 0;
}
int
_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) {
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
if (data == NULL) {
return -1;
}
data[0] = i;
return 0;
}
int
_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
if (offset > buffer->size) {
buffer->ok = false;
return -1;
}
buffer->ok = true;
buffer->offset = offset;
return 0;
}
int
_zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) {
zip_uint64_t offset = buffer->offset + length;
if (offset < buffer->offset) {
buffer->ok = false;
return -1;
}
return _zip_buffer_set_offset(buffer, offset);
}
zip_uint64_t
_zip_buffer_size(zip_buffer_t *buffer) {
return buffer->size;
}

View File

@ -0,0 +1,700 @@
/*
zip_close.c -- close zip archive and update changes
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t);
static int copy_data(zip_t *, zip_uint64_t);
static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64);
ZIP_EXTERN int
zip_close(zip_t *za) {
zip_uint64_t i, j, survivors, unchanged_offset;
zip_int64_t off;
int error;
zip_filelist_t *filelist;
int changed;
if (za == NULL)
return -1;
changed = _zip_changed(za, &survivors);
/* don't create zip files with no entries */
if (survivors == 0) {
if ((za->open_flags & ZIP_TRUNCATE) || changed) {
if (zip_source_remove(za->src) < 0) {
if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
}
}
zip_discard(za);
return 0;
}
if (!changed) {
zip_discard(za);
return 0;
}
if (survivors > za->nentry) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
if ((filelist = (zip_filelist_t *)malloc(sizeof(filelist[0]) * (size_t)survivors)) == NULL)
return -1;
unchanged_offset = ZIP_UINT64_MAX;
/* create list of files with index into original archive */
for (i = j = 0; i < za->nentry; i++) {
if (za->entry[i].orig != NULL && ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) {
unchanged_offset = ZIP_MIN(unchanged_offset, za->entry[i].orig->offset);
}
if (za->entry[i].deleted) {
continue;
}
if (j >= survivors) {
free(filelist);
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
filelist[j].idx = i;
j++;
}
if (j < survivors) {
free(filelist);
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) {
unchanged_offset = 0;
}
else {
if (unchanged_offset == ZIP_UINT64_MAX) {
/* we're keeping all file data, find the end of the last one */
zip_uint64_t last_index = ZIP_UINT64_MAX;
unchanged_offset = 0;
for (i = 0; i < za->nentry; i++) {
if (za->entry[i].orig != NULL) {
if (za->entry[i].orig->offset >= unchanged_offset) {
unchanged_offset = za->entry[i].orig->offset;
last_index = i;
}
}
}
if (last_index != ZIP_UINT64_MAX) {
if ((unchanged_offset = _zip_file_get_end(za, last_index, &za->error)) == 0) {
free(filelist);
return -1;
}
}
}
if (unchanged_offset > 0) {
if (zip_source_begin_write_cloning(za->src, unchanged_offset) < 0) {
/* cloning not supported, need to copy everything */
unchanged_offset = 0;
}
}
}
if (unchanged_offset == 0) {
if (zip_source_begin_write(za->src) < 0) {
_zip_error_set_from_source(&za->error, za->src);
free(filelist);
return -1;
}
}
if (_zip_progress_start(za->progress) != 0) {
zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
zip_source_rollback_write(za->src);
free(filelist);
return -1;
}
error = 0;
for (j = 0; j < survivors; j++) {
int new_data;
zip_entry_t *entry;
zip_dirent_t *de;
if (_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors) != 0) {
zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
error = 1;
break;
}
i = filelist[j].idx;
entry = za->entry + i;
if (entry->orig != NULL && entry->orig->offset < unchanged_offset) {
/* already implicitly copied by cloning */
continue;
}
new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD));
/* create new local directory entry */
if (entry->changes == NULL) {
if ((entry->changes = _zip_dirent_clone(entry->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
error = 1;
break;
}
}
de = entry->changes;
if (_zip_read_local_ef(za, i) < 0) {
error = 1;
break;
}
if ((off = zip_source_tell_write(za->src)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
error = 1;
break;
}
de->offset = (zip_uint64_t)off;
if (new_data) {
zip_source_t *zs;
zs = NULL;
if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
if ((zs = _zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) {
error = 1;
break;
}
}
/* add_data writes dirent */
if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) {
error = 1;
if (zs)
zip_source_free(zs);
break;
}
if (zs)
zip_source_free(zs);
}
else {
zip_uint64_t offset;
if (de->encryption_method != ZIP_EM_TRAD_PKWARE) {
/* when copying data, all sizes are known -> no data descriptor needed */
/* except for PKWare encryption, where removing the data descriptor breaks password validation */
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
}
if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
error = 1;
break;
}
if ((offset = _zip_file_get_offset(za, i, &za->error)) == 0) {
error = 1;
break;
}
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
error = 1;
break;
}
if (copy_data(za, de->comp_size) < 0) {
error = 1;
break;
}
if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) {
error = 1;
break;
}
}
}
}
if (!error) {
if (write_cdir(za, filelist, survivors) < 0)
error = 1;
}
free(filelist);
if (!error) {
if (zip_source_commit_write(za->src) != 0) {
_zip_error_set_from_source(&za->error, za->src);
error = 1;
}
_zip_progress_end(za->progress);
}
if (error) {
zip_source_rollback_write(za->src);
return -1;
}
zip_discard(za);
return 0;
}
static int
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
zip_int64_t offstart, offdata, offend, data_length;
zip_stat_t st;
zip_file_attributes_t attributes;
zip_source_t *src_final, *src_tmp;
int ret;
int is_zip64;
zip_flags_t flags;
bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
if (zip_source_stat(src, &st) < 0) {
_zip_error_set_from_source(&za->error, src);
return -1;
}
if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
st.valid |= ZIP_STAT_COMP_METHOD;
st.comp_method = ZIP_CM_STORE;
}
if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
de->comp_method = st.comp_method;
else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
st.valid |= ZIP_STAT_COMP_SIZE;
st.comp_size = st.size;
}
else {
/* we'll recompress */
st.valid &= ~ZIP_STAT_COMP_SIZE;
}
if ((st.valid & ZIP_STAT_ENCRYPTION_METHOD) == 0) {
st.valid |= ZIP_STAT_ENCRYPTION_METHOD;
st.encryption_method = ZIP_EM_NONE;
}
flags = ZIP_EF_LOCAL;
if ((st.valid & ZIP_STAT_SIZE) == 0) {
flags |= ZIP_FL_FORCE_ZIP64;
data_length = -1;
}
else {
de->uncomp_size = st.size;
/* this is technically incorrect (copy_source counts compressed data), but it's the best we have */
data_length = (zip_int64_t)st.size;
if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) {
zip_uint64_t max_compressed_size;
zip_uint16_t compression_method = ZIP_CM_ACTUAL(de->comp_method);
if (compression_method == ZIP_CM_STORE) {
max_compressed_size = st.size;
}
else {
zip_compression_algorithm_t *algorithm = _zip_get_compression_algorithm(compression_method, true);
if (algorithm == NULL) {
max_compressed_size = ZIP_UINT64_MAX;
}
else {
max_compressed_size = algorithm->maximum_compressed_size(st.size);
}
}
if (max_compressed_size > 0xffffffffu) {
flags |= ZIP_FL_FORCE_ZIP64;
}
}
else {
de->comp_size = st.comp_size;
data_length = (zip_int64_t)st.comp_size;
}
}
if ((offstart = zip_source_tell_write(za->src)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
/* as long as we don't support non-seekable output, clear data descriptor bit */
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
if ((is_zip64 = _zip_dirent_write(za, de, flags)) < 0) {
return -1;
}
needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method);
needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE);
/* in these cases we can compute the CRC ourselves, so we do */
needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress;
needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE);
needs_reencrypt = needs_recompress || (de->changed & ZIP_DIRENT_PASSWORD) || (de->encryption_method != st.encryption_method);
needs_decrypt = needs_reencrypt && (st.encryption_method != ZIP_EM_NONE);
needs_encrypt = needs_reencrypt && (de->encryption_method != ZIP_EM_NONE);
src_final = src;
zip_source_keep(src_final);
if (needs_decrypt) {
zip_encryption_implementation impl;
if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) {
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
zip_source_free(src_final);
return -1;
}
if ((src_tmp = impl(za, src_final, st.encryption_method, ZIP_CODEC_DECODE, za->default_password)) == NULL) {
/* error set by impl */
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if (needs_decompress) {
if ((src_tmp = zip_source_decompress(za, src_final, st.comp_method)) == NULL) {
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if (needs_crc) {
if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) {
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if (needs_compress) {
if ((src_tmp = zip_source_compress(za, src_final, de->comp_method, de->compression_level)) == NULL) {
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if (needs_encrypt) {
zip_encryption_implementation impl;
const char *password = NULL;
if (de->password) {
password = de->password;
}
else if (za->default_password) {
password = za->default_password;
}
if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) {
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
zip_source_free(src_final);
return -1;
}
if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) {
/* error set by impl */
zip_source_free(src_final);
return -1;
}
if (de->encryption_method == ZIP_EM_TRAD_PKWARE) {
de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR;
}
zip_source_free(src_final);
src_final = src_tmp;
}
if ((offdata = zip_source_tell_write(za->src)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
ret = copy_source(za, src_final, data_length);
if (zip_source_stat(src_final, &st) < 0) {
_zip_error_set_from_source(&za->error, src_final);
ret = -1;
}
if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
_zip_error_set_from_source(&za->error, src_final);
ret = -1;
}
zip_source_free(src_final);
if (ret < 0) {
return -1;
}
if ((offend = zip_source_tell_write(za->src)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
if ((st.valid & (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
if (st.valid & ZIP_STAT_MTIME)
de->last_mod = st.mtime;
else
time(&de->last_mod);
}
de->comp_method = st.comp_method;
de->crc = st.crc;
de->uncomp_size = st.size;
de->comp_size = (zip_uint64_t)(offend - offdata);
_zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
if ((ret = _zip_dirent_write(za, de, flags)) < 0)
return -1;
if (is_zip64 != ret) {
/* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
if (write_data_descriptor(za, de, is_zip64) < 0) {
return -1;
}
}
return 0;
}
static int
copy_data(zip_t *za, zip_uint64_t len) {
DEFINE_BYTE_ARRAY(buf, BUFSIZE);
size_t n;
double total = (double)len;
if (!byte_array_init(buf, BUFSIZE)) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
while (len > 0) {
n = len > BUFSIZE ? BUFSIZE : len;
if (_zip_read(za->src, buf, n, &za->error) < 0) {
byte_array_fini(buf);
return -1;
}
if (_zip_write(za, buf, n) < 0) {
byte_array_fini(buf);
return -1;
}
len -= n;
if (_zip_progress_update(za->progress, (total - (double)len) / total) != 0) {
zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
return -1;
}
}
byte_array_fini(buf);
return 0;
}
static int
copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
DEFINE_BYTE_ARRAY(buf, BUFSIZE);
zip_int64_t n, current;
int ret;
if (zip_source_open(src) < 0) {
_zip_error_set_from_source(&za->error, src);
return -1;
}
if (!byte_array_init(buf, BUFSIZE)) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
ret = 0;
current = 0;
while ((n = zip_source_read(src, buf, BUFSIZE)) > 0) {
if (_zip_write(za, buf, (zip_uint64_t)n) < 0) {
ret = -1;
break;
}
if (n == BUFSIZE && za->progress && data_length > 0) {
current += n;
if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) {
zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
ret = -1;
break;
}
}
}
if (n < 0) {
_zip_error_set_from_source(&za->error, src);
ret = -1;
}
byte_array_fini(buf);
zip_source_close(src);
return ret;
}
static int
write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) {
zip_int64_t cd_start, end, size;
if ((cd_start = zip_source_tell_write(za->src)) < 0) {
return -1;
}
if ((size = _zip_cdir_write(za, filelist, survivors)) < 0) {
return -1;
}
if ((end = zip_source_tell_write(za->src)) < 0) {
return -1;
}
return 0;
}
int
_zip_changed(const zip_t *za, zip_uint64_t *survivorsp) {
int changed;
zip_uint64_t i, survivors;
changed = 0;
survivors = 0;
if (za->comment_changed || za->ch_flags != za->flags) {
changed = 1;
}
for (i = 0; i < za->nentry; i++) {
if (ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) {
changed = 1;
}
if (!za->entry[i].deleted) {
survivors++;
}
}
if (survivorsp) {
*survivorsp = survivors;
}
return changed;
}
static int
write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) {
zip_buffer_t *buffer = _zip_buffer_new(NULL, MAX_DATA_DESCRIPTOR_LENGTH);
int ret = 0;
if (buffer == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
_zip_buffer_put(buffer, DATADES_MAGIC, 4);
_zip_buffer_put_32(buffer, de->crc);
if (is_zip64) {
_zip_buffer_put_64(buffer, de->comp_size);
_zip_buffer_put_64(buffer, de->uncomp_size);
}
else {
_zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
_zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
}
if (!_zip_buffer_ok(buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
ret = -1;
}
else {
ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer));
}
_zip_buffer_free(buffer);
return ret;
}

View File

@ -0,0 +1,54 @@
/*
zip_crypto.h -- crypto definitions
Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HAD_ZIP_CRYPTO_H
#define HAD_ZIP_CRYPTO_H
#define ZIP_CRYPTO_SHA1_LENGTH 20
#define ZIP_CRYPTO_AES_BLOCK_LENGTH 16
#if defined(HAVE_WINDOWS_CRYPTO)
#include "zip_crypto_win.h"
#elif defined(HAVE_COMMONCRYPTO)
#include "zip_crypto_commoncrypto.h"
#elif defined(HAVE_GNUTLS)
#include "zip_crypto_gnutls.h"
#elif defined(HAVE_OPENSSL)
#include "zip_crypto_openssl.h"
#elif defined(HAVE_MBEDTLS)
#include "zip_crypto_mbedtls.h"
#else
#error "no crypto backend found"
#endif
#endif /* HAD_ZIP_CRYPTO_H */

View File

@ -0,0 +1,110 @@
/*
zip_crypto_commoncrypto.c -- CommonCrypto wrapper.
Copyright (C) 2018-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
#include "zip_crypto.h"
#include <fcntl.h>
#include <unistd.h>
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
CCCryptorRelease(aes);
}
bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
size_t len;
CCCryptorUpdate(aes, in, ZIP_CRYPTO_AES_BLOCK_LENGTH, out, ZIP_CRYPTO_AES_BLOCK_LENGTH, &len);
return true;
}
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
CCCryptorStatus ret;
ret = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES, kCCOptionECBMode, key, key_size / 8, NULL, &aes);
switch (ret) {
case kCCSuccess:
return aes;
case kCCMemoryFailure:
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
case kCCParamError:
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
default:
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return NULL;
}
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
return;
}
_zip_crypto_clear(hmac, sizeof(*hmac));
free(hmac);
}
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
_zip_crypto_hmac_t *hmac;
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
CCHmacInit(hmac, kCCHmacAlgSHA1, secret, secret_length);
return hmac;
}

View File

@ -0,0 +1,53 @@
/*
zip_crypto_commoncrypto.h -- definitions for CommonCrypto wrapper.
Copyright (C) 2018 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HAD_ZIP_CRYPTO_COMMONCRYPTO_H
#define HAD_ZIP_CRYPTO_COMMONCRYPTO_H
#include <CommonCrypto/CommonCrypto.h>
#define _zip_crypto_aes_t struct _CCCryptor
#define _zip_crypto_hmac_t CCHmacContext
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
#define _zip_crypto_hmac(hmac, data, length) (CCHmacUpdate((hmac), (data), (length)), true)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
#define _zip_crypto_hmac_output(hmac, data) (CCHmacFinal((hmac), (data)), true)
#define _zip_crypto_pbkdf2(key, key_length, salt, salt_length, iterations, output, output_length) (CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)(key), (key_length), (salt), (salt_length), kCCPRFHmacAlgSHA1, (iterations), (output), (output_length)) == kCCSuccess)
#endif /* HAD_ZIP_CRYPTO_COMMONCRYPTO_H */

View File

@ -0,0 +1,135 @@
/*
zip_crypto_gnutls.c -- GnuTLS wrapper.
Copyright (C) 2018-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
#include "zip_crypto.h"
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
if ((aes = (_zip_crypto_aes_t *)malloc(sizeof(*aes))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
aes->key_size = key_size;
switch (aes->key_size) {
case 128:
nettle_aes128_set_encrypt_key(&aes->ctx.ctx_128, key);
break;
case 192:
nettle_aes192_set_encrypt_key(&aes->ctx.ctx_192, key);
break;
case 256:
nettle_aes256_set_encrypt_key(&aes->ctx.ctx_256, key);
break;
default:
zip_error_set(error, ZIP_ER_INVAL, 0);
free(aes);
return NULL;
}
return aes;
}
bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
switch (aes->key_size) {
case 128:
nettle_aes128_encrypt(&aes->ctx.ctx_128, ZIP_CRYPTO_AES_BLOCK_LENGTH, out, in);
break;
case 192:
nettle_aes192_encrypt(&aes->ctx.ctx_192, ZIP_CRYPTO_AES_BLOCK_LENGTH, out, in);
break;
case 256:
nettle_aes256_encrypt(&aes->ctx.ctx_256, ZIP_CRYPTO_AES_BLOCK_LENGTH, out, in);
break;
}
return true;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
_zip_crypto_clear(aes, sizeof(*aes));
free(aes);
}
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
_zip_crypto_hmac_t *hmac;
int ret;
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if ((ret = gnutls_hmac_init(hmac, GNUTLS_MAC_SHA1, secret, secret_length)) < 0) {
/* TODO: set error */
free(hmac);
return NULL;
}
return hmac;
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
zip_uint8_t buf[ZIP_CRYPTO_SHA1_LENGTH];
if (hmac == NULL) {
return;
}
gnutls_hmac_deinit(*hmac, buf);
_zip_crypto_clear(hmac, sizeof(*hmac));
free(hmac);
}
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
return gnutls_rnd(GNUTLS_RND_KEY, buffer, length) == 0;
}

View File

@ -0,0 +1,68 @@
/*
zip_crypto_gnutls.h -- definitions for GnuTLS wrapper.
Copyright (C) 2018-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HAD_ZIP_CRYPTO_GNUTLS_H
#define HAD_ZIP_CRYPTO_GNUTLS_H
#define HAVE_SECURE_RANDOM
#include <nettle/aes.h>
#include <nettle/pbkdf2.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
typedef struct {
union {
struct aes128_ctx ctx_128;
struct aes192_ctx ctx_192;
struct aes256_ctx ctx_256;
} ctx;
zip_uint16_t key_size;
} _zip_crypto_aes_t;
#define _zip_crypto_hmac_t gnutls_hmac_hd_t
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
#define _zip_crypto_hmac(hmac, data, length) (gnutls_hmac(*(hmac), (data), (length)) == 0)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
#define _zip_crypto_hmac_output(hmac, data) (gnutls_hmac_output(*(hmac), (data)), true)
#define _zip_crypto_pbkdf2(key, key_length, salt, salt_length, iterations, output, output_length) (pbkdf2_hmac_sha1((key_length), (key), (iterations), (salt_length), (salt), (output_length), (output)), true)
#endif /* HAD_ZIP_CRYPTO_GNUTLS_H */

View File

@ -0,0 +1,162 @@
/*
zip_crypto_mbedtls.c -- mbed TLS wrapper
Copyright (C) 2018-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
#include "zip_crypto.h"
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/pkcs5.h>
#include <limits.h>
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
if ((aes = (_zip_crypto_aes_t *)malloc(sizeof(*aes))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
mbedtls_aes_init(aes);
mbedtls_aes_setkey_enc(aes, (const unsigned char *)key, (unsigned int)key_size);
return aes;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
mbedtls_aes_free(aes);
free(aes);
}
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
_zip_crypto_hmac_t *hmac;
if (secret_length > INT_MAX) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
mbedtls_md_init(hmac);
if (mbedtls_md_setup(hmac, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1) != 0) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
free(hmac);
return NULL;
}
if (mbedtls_md_hmac_starts(hmac, (const unsigned char *)secret, (size_t)secret_length) != 0) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
free(hmac);
return NULL;
}
return hmac;
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
return;
}
mbedtls_md_free(hmac);
free(hmac);
}
bool
_zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, int iterations, zip_uint8_t *output, zip_uint64_t output_length) {
mbedtls_md_context_t sha1_ctx;
bool ok = true;
mbedtls_md_init(&sha1_ctx);
if (mbedtls_md_setup(&sha1_ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1) != 0) {
ok = false;
}
if (ok && mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, (const unsigned char *)key, (size_t)key_length, (const unsigned char *)salt, (size_t)salt_length, (unsigned int)iterations, (uint32_t)output_length, (unsigned char *)output) != 0) {
ok = false;
}
mbedtls_md_free(&sha1_ctx);
return ok;
}
typedef struct {
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
} zip_random_context_t;
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
static zip_random_context_t *ctx = NULL;
const unsigned char *pers = "zip_crypto_mbedtls";
if (!ctx) {
ctx = (zip_random_context_t *)malloc(sizeof(zip_random_context_t));
if (!ctx) {
return false;
}
mbedtls_entropy_init(&ctx->entropy);
mbedtls_ctr_drbg_init(&ctx->ctr_drbg);
if (mbedtls_ctr_drbg_seed(&ctx->ctr_drbg, mbedtls_entropy_func, &ctx->entropy, pers, strlen(pers)) != 0) {
mbedtls_ctr_drbg_free(&ctx->ctr_drbg);
mbedtls_entropy_free(&ctx->entropy);
free(ctx);
ctx = NULL;
return false;
}
}
return mbedtls_ctr_drbg_random(&ctx->ctr_drbg, (unsigned char *)buffer, (size_t)length) == 0;
}

View File

@ -0,0 +1,56 @@
/*
zip_crypto_mbedtls.h -- definitions for mbedtls wrapper
Copyright (C) 2018-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HAD_ZIP_CRYPTO_MBEDTLS_H
#define HAD_ZIP_CRYPTO_MBEDTLS_H
#define HAVE_SECURE_RANDOM
#include <mbedtls/aes.h>
#include <mbedtls/md.h>
#define _zip_crypto_aes_t mbedtls_aes_context
#define _zip_crypto_hmac_t mbedtls_md_context_t
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
#define _zip_crypto_aes_encrypt_block(aes, in, out) (mbedtls_aes_crypt_ecb((aes), MBEDTLS_AES_ENCRYPT, (in), (out)) == 0)
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
#define _zip_crypto_hmac(hmac, data, length) (mbedtls_md_hmac_update((hmac), (data), (length)) == 0)
#define _zip_crypto_hmac_output(hmac, data) (mbedtls_md_hmac_finish((hmac), (data)) == 0)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
bool _zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, int iterations, zip_uint8_t *output, zip_uint64_t output_length);
#endif /* HAD_ZIP_CRYPTO_MBEDTLS_H */

View File

@ -0,0 +1,137 @@
/*
zip_crypto_openssl.c -- OpenSSL wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
#include "zip_crypto.h"
#include <limits.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
#define USE_OPENSSL_1_0_API
#endif
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
if ((aes = (_zip_crypto_aes_t *)malloc(sizeof(*aes))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
AES_set_encrypt_key(key, key_size, aes);
return aes;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
_zip_crypto_clear(aes, sizeof(*aes));
free(aes);
}
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
_zip_crypto_hmac_t *hmac;
if (secret_length > INT_MAX) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
#ifdef USE_OPENSSL_1_0_API
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
HMAC_CTX_init(hmac);
#else
if ((hmac = HMAC_CTX_new()) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
#endif
if (HMAC_Init_ex(hmac, secret, (int)secret_length, EVP_sha1(), NULL) != 1) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
#ifdef USE_OPENSSL_1_0_API
free(hmac);
#else
HMAC_CTX_free(hmac);
#endif
return NULL;
}
return hmac;
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
return;
}
#ifdef USE_OPENSSL_1_0_API
HMAC_CTX_cleanup(hmac);
_zip_crypto_clear(hmac, sizeof(*hmac));
free(hmac);
#else
HMAC_CTX_free(hmac);
#endif
}
bool
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
unsigned int length;
return HMAC_Final(hmac, data, &length) == 1;
}
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
return RAND_bytes(buffer, length) == 1;
}

View File

@ -0,0 +1,56 @@
/*
zip_crypto_openssl.h -- definitions for OpenSSL wrapper.
Copyright (C) 2018-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HAD_ZIP_CRYPTO_OPENSSL_H
#define HAD_ZIP_CRYPTO_OPENSSL_H
#define HAVE_SECURE_RANDOM
#include <openssl/aes.h>
#include <openssl/hmac.h>
#define _zip_crypto_aes_t AES_KEY
#define _zip_crypto_hmac_t HMAC_CTX
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
#define _zip_crypto_aes_encrypt_block(aes, in, out) (AES_encrypt((in), (out), (aes)), true)
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
#define _zip_crypto_hmac(hmac, data, length) (HMAC_Update((hmac), (data), (length)) == 1)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
bool _zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data);
#define _zip_crypto_pbkdf2(key, key_length, salt, salt_length, iterations, output, output_length) (PKCS5_PBKDF2_HMAC_SHA1((const char *)(key), (key_length), (salt), (salt_length), (iterations), (output_length), (output)))
#endif /* HAD_ZIP_CRYPTO_OPENSSL_H */

View File

@ -0,0 +1,495 @@
/*
zip_crypto_win.c -- Windows Crypto API wrapper.
Copyright (C) 2018-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <limits.h>
#include "zipint.h"
#include "zip_crypto.h"
#define WIN32_LEAN_AND_MEAN
#define NOCRYPT
#include <windows.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
/*
This code is using the Cryptography API: Next Generation (CNG)
https://docs.microsoft.com/en-us/windows/desktop/seccng/cng-portal
This API is supported on
- Windows Vista or later (client OS)
- Windows Server 2008 (server OS)
- Windows Embedded Compact 2013 (don't know about Windows Embedded Compact 7)
The code was developed for Windows Embedded Compact 2013 (WEC2013),
but should be working for all of the above mentioned OSes.
There are 2 restrictions for WEC2013, Windows Vista and Windows Server 2008:
1.) The function "BCryptDeriveKeyPBKDF2" is not available
I found some code which is implementing this function using the deprecated Crypto API here:
https://www.idrix.fr/Root/content/view/37/54/
I took this code and converted it to the newer CNG API. The original code was more
flexible, but this is not needed here so i refactored it a bit and just kept what is needed.
The define "HAS_BCRYPTDERIVEKEYPBKDF2" controls whether "BCryptDeriveKeyPBKDF2"
of the CNG API is used or not. This define must not be set if you are compiling for WEC2013 or Windows Vista.
2.) "BCryptCreateHash" can't manage the memory needed for the hash object internally
On Windows 7 or later it is possible to pass NULL for the hash object buffer.
This is not supported on WEC2013, so we have to handle the memory allocation/deallocation ourselves.
There is no #ifdef to control that, because this is working for all supported OSes.
*/
#if !defined(WINCE) && !defined(__MINGW32__)
#define HAS_BCRYPTDERIVEKEYPBKDF2
#endif
#ifdef HAS_BCRYPTDERIVEKEYPBKDF2
bool
_zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length) {
BCRYPT_ALG_HANDLE hAlgorithm = NULL;
bool result;
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG))) {
return false;
}
result = BCRYPT_SUCCESS(BCryptDeriveKeyPBKDF2(hAlgorithm, (PUCHAR)key, (ULONG)key_length, (PUCHAR)salt, salt_length, iterations, output, output_length, 0));
BCryptCloseAlgorithmProvider(hAlgorithm, 0);
return result;
}
#else
#include <math.h>
#define DIGEST_SIZE 20
#define BLOCK_SIZE 64
typedef struct {
BCRYPT_ALG_HANDLE hAlgorithm;
BCRYPT_HASH_HANDLE hInnerHash;
BCRYPT_HASH_HANDLE hOuterHash;
ULONG cbHashObject;
PUCHAR pbInnerHash;
PUCHAR pbOuterHash;
} PRF_CTX;
static void
hmacFree(PRF_CTX *pContext) {
if (pContext->hOuterHash)
BCryptDestroyHash(pContext->hOuterHash);
if (pContext->hInnerHash)
BCryptDestroyHash(pContext->hInnerHash);
free(pContext->pbOuterHash);
free(pContext->pbInnerHash);
if (pContext->hAlgorithm)
BCryptCloseAlgorithmProvider(pContext->hAlgorithm, 0);
}
static BOOL
hmacPrecomputeDigest(BCRYPT_HASH_HANDLE hHash, PUCHAR pbPassword, DWORD cbPassword, BYTE mask) {
BYTE buffer[BLOCK_SIZE];
DWORD i;
if (cbPassword > BLOCK_SIZE) {
return FALSE;
}
memset(buffer, mask, sizeof(buffer));
for (i = 0; i < cbPassword; ++i) {
buffer[i] = (char)(pbPassword[i] ^ mask);
}
return BCRYPT_SUCCESS(BCryptHashData(hHash, buffer, sizeof(buffer), 0));
}
static BOOL
hmacInit(PRF_CTX *pContext, PUCHAR pbPassword, DWORD cbPassword) {
BOOL bStatus = FALSE;
ULONG cbResult;
BYTE key[DIGEST_SIZE];
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&pContext->hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, 0)) || !BCRYPT_SUCCESS(BCryptGetProperty(pContext->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&pContext->cbHashObject, sizeof(pContext->cbHashObject), &cbResult, 0)) || ((pContext->pbInnerHash = malloc(pContext->cbHashObject)) == NULL) || ((pContext->pbOuterHash = malloc(pContext->cbHashObject)) == NULL) || !BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &pContext->hInnerHash, pContext->pbInnerHash, pContext->cbHashObject, NULL, 0, 0)) || !BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &pContext->hOuterHash, pContext->pbOuterHash, pContext->cbHashObject, NULL, 0, 0))) {
goto hmacInit_end;
}
if (cbPassword > BLOCK_SIZE) {
BCRYPT_HASH_HANDLE hHash = NULL;
PUCHAR pbHashObject = malloc(pContext->cbHashObject);
if (pbHashObject == NULL) {
goto hmacInit_end;
}
bStatus = BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &hHash, pbHashObject, pContext->cbHashObject, NULL, 0, 0)) && BCRYPT_SUCCESS(BCryptHashData(hHash, pbPassword, cbPassword, 0)) && BCRYPT_SUCCESS(BCryptGetProperty(hHash, BCRYPT_HASH_LENGTH, (PUCHAR)&cbPassword, sizeof(cbPassword), &cbResult, 0)) && BCRYPT_SUCCESS(BCryptFinishHash(hHash, key, cbPassword, 0));
if (hHash)
BCryptDestroyHash(hHash);
free(pbHashObject);
if (!bStatus) {
goto hmacInit_end;
}
pbPassword = key;
}
bStatus = hmacPrecomputeDigest(pContext->hInnerHash, pbPassword, cbPassword, 0x36) && hmacPrecomputeDigest(pContext->hOuterHash, pbPassword, cbPassword, 0x5C);
hmacInit_end:
if (bStatus == FALSE)
hmacFree(pContext);
return bStatus;
}
static BOOL
hmacCalculateInternal(BCRYPT_HASH_HANDLE hHashTemplate, PUCHAR pbData, DWORD cbData, PUCHAR pbOutput, DWORD cbOutput, DWORD cbHashObject) {
BOOL success = FALSE;
BCRYPT_HASH_HANDLE hHash = NULL;
PUCHAR pbHashObject = malloc(cbHashObject);
if (pbHashObject == NULL) {
return FALSE;
}
if (BCRYPT_SUCCESS(BCryptDuplicateHash(hHashTemplate, &hHash, pbHashObject, cbHashObject, 0))) {
success = BCRYPT_SUCCESS(BCryptHashData(hHash, pbData, cbData, 0)) && BCRYPT_SUCCESS(BCryptFinishHash(hHash, pbOutput, cbOutput, 0));
BCryptDestroyHash(hHash);
}
free(pbHashObject);
return success;
}
static BOOL
hmacCalculate(PRF_CTX *pContext, PUCHAR pbData, DWORD cbData, PUCHAR pbDigest) {
DWORD cbResult;
DWORD cbHashObject;
return BCRYPT_SUCCESS(BCryptGetProperty(pContext->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&cbHashObject, sizeof(cbHashObject), &cbResult, 0)) && hmacCalculateInternal(pContext->hInnerHash, pbData, cbData, pbDigest, DIGEST_SIZE, cbHashObject) && hmacCalculateInternal(pContext->hOuterHash, pbDigest, DIGEST_SIZE, pbDigest, DIGEST_SIZE, cbHashObject);
}
static void
myxor(LPBYTE ptr1, LPBYTE ptr2, DWORD dwLen) {
while (dwLen--)
*ptr1++ ^= *ptr2++;
}
BOOL
pbkdf2(PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, DWORD cIterations, PUCHAR pbDerivedKey, ULONG cbDerivedKey) {
BOOL bStatus = FALSE;
DWORD l, r, dwULen, i, j;
BYTE Ti[DIGEST_SIZE];
BYTE V[DIGEST_SIZE];
LPBYTE U = malloc(max((cbSalt + 4), DIGEST_SIZE));
PRF_CTX prfCtx = {0};
if (U == NULL) {
return FALSE;
}
if (pbPassword == NULL || cbPassword == 0 || pbSalt == NULL || cbSalt == 0 || cIterations == 0 || pbDerivedKey == NULL || cbDerivedKey == 0) {
free(U);
return FALSE;
}
if (!hmacInit(&prfCtx, pbPassword, cbPassword)) {
goto PBKDF2_end;
}
l = (DWORD)ceil((double)cbDerivedKey / (double)DIGEST_SIZE);
r = cbDerivedKey - (l - 1) * DIGEST_SIZE;
for (i = 1; i <= l; i++) {
ZeroMemory(Ti, DIGEST_SIZE);
for (j = 0; j < cIterations; j++) {
if (j == 0) {
/* construct first input for PRF */
memcpy(U, pbSalt, cbSalt);
U[cbSalt] = (BYTE)((i & 0xFF000000) >> 24);
U[cbSalt + 1] = (BYTE)((i & 0x00FF0000) >> 16);
U[cbSalt + 2] = (BYTE)((i & 0x0000FF00) >> 8);
U[cbSalt + 3] = (BYTE)((i & 0x000000FF));
dwULen = cbSalt + 4;
}
else {
memcpy(U, V, DIGEST_SIZE);
dwULen = DIGEST_SIZE;
}
if (!hmacCalculate(&prfCtx, U, dwULen, V)) {
goto PBKDF2_end;
}
myxor(Ti, V, DIGEST_SIZE);
}
if (i != l) {
memcpy(&pbDerivedKey[(i - 1) * DIGEST_SIZE], Ti, DIGEST_SIZE);
}
else {
/* Take only the first r bytes */
memcpy(&pbDerivedKey[(i - 1) * DIGEST_SIZE], Ti, r);
}
}
bStatus = TRUE;
PBKDF2_end:
hmacFree(&prfCtx);
free(U);
return bStatus;
}
bool
_zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length) {
return (key_length <= ZIP_UINT32_MAX) && pbkdf2((PUCHAR)key, (ULONG)key_length, (PUCHAR)salt, salt_length, iterations, output, output_length);
}
#endif
struct _zip_crypto_aes_s {
BCRYPT_ALG_HANDLE hAlgorithm;
BCRYPT_KEY_HANDLE hKey;
ULONG cbKeyObject;
PUCHAR pbKeyObject;
};
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes = (_zip_crypto_aes_t *)calloc(1, sizeof(*aes));
ULONG cbResult;
ULONG key_length = key_size / 8;
if (aes == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&aes->hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0))) {
_zip_crypto_aes_free(aes);
return NULL;
}
if (!BCRYPT_SUCCESS(BCryptSetProperty(aes->hAlgorithm, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0))) {
_zip_crypto_aes_free(aes);
return NULL;
}
if (!BCRYPT_SUCCESS(BCryptGetProperty(aes->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&aes->cbKeyObject, sizeof(aes->cbKeyObject), &cbResult, 0))) {
_zip_crypto_aes_free(aes);
return NULL;
}
aes->pbKeyObject = malloc(aes->cbKeyObject);
if (aes->pbKeyObject == NULL) {
_zip_crypto_aes_free(aes);
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (!BCRYPT_SUCCESS(BCryptGenerateSymmetricKey(aes->hAlgorithm, &aes->hKey, aes->pbKeyObject, aes->cbKeyObject, (PUCHAR)key, key_length, 0))) {
_zip_crypto_aes_free(aes);
return NULL;
}
return aes;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
if (aes->hKey != NULL) {
BCryptDestroyKey(aes->hKey);
}
if (aes->pbKeyObject != NULL) {
free(aes->pbKeyObject);
}
if (aes->hAlgorithm != NULL) {
BCryptCloseAlgorithmProvider(aes->hAlgorithm, 0);
}
free(aes);
}
bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
ULONG cbResult;
NTSTATUS status = BCryptEncrypt(aes->hKey, (PUCHAR)in, ZIP_CRYPTO_AES_BLOCK_LENGTH, NULL, NULL, 0, (PUCHAR)out, ZIP_CRYPTO_AES_BLOCK_LENGTH, &cbResult, 0);
return BCRYPT_SUCCESS(status);
}
struct _zip_crypto_hmac_s {
BCRYPT_ALG_HANDLE hAlgorithm;
BCRYPT_HASH_HANDLE hHash;
DWORD cbHashObject;
PUCHAR pbHashObject;
DWORD cbHash;
PUCHAR pbHash;
};
/* https://code.msdn.microsoft.com/windowsdesktop/Hmac-Computation-Sample-11fe8ec1/sourcecode?fileId=42820&pathId=283874677 */
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
NTSTATUS status;
ULONG cbResult;
_zip_crypto_hmac_t *hmac;
if (secret_length > INT_MAX) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
hmac = (_zip_crypto_hmac_t *)calloc(1, sizeof(*hmac));
if (hmac == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
status = BCryptOpenAlgorithmProvider(&hmac->hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG);
if (!BCRYPT_SUCCESS(status)) {
_zip_crypto_hmac_free(hmac);
return NULL;
}
status = BCryptGetProperty(hmac->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hmac->cbHashObject, sizeof(hmac->cbHashObject), &cbResult, 0);
if (!BCRYPT_SUCCESS(status)) {
_zip_crypto_hmac_free(hmac);
return NULL;
}
hmac->pbHashObject = malloc(hmac->cbHashObject);
if (hmac->pbHashObject == NULL) {
_zip_crypto_hmac_free(hmac);
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
status = BCryptGetProperty(hmac->hAlgorithm, BCRYPT_HASH_LENGTH, (PUCHAR)&hmac->cbHash, sizeof(hmac->cbHash), &cbResult, 0);
if (!BCRYPT_SUCCESS(status)) {
_zip_crypto_hmac_free(hmac);
return NULL;
}
hmac->pbHash = malloc(hmac->cbHash);
if (hmac->pbHash == NULL) {
_zip_crypto_hmac_free(hmac);
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
status = BCryptCreateHash(hmac->hAlgorithm, &hmac->hHash, hmac->pbHashObject, hmac->cbHashObject, (PUCHAR)secret, (ULONG)secret_length, 0);
if (!BCRYPT_SUCCESS(status)) {
_zip_crypto_hmac_free(hmac);
return NULL;
}
return hmac;
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
return;
}
if (hmac->hHash != NULL) {
BCryptDestroyHash(hmac->hHash);
}
if (hmac->pbHash != NULL) {
free(hmac->pbHash);
}
if (hmac->pbHashObject != NULL) {
free(hmac->pbHashObject);
}
if (hmac->hAlgorithm) {
BCryptCloseAlgorithmProvider(hmac->hAlgorithm, 0);
}
free(hmac);
}
bool
_zip_crypto_hmac(_zip_crypto_hmac_t *hmac, zip_uint8_t *data, zip_uint64_t length) {
if (hmac == NULL || length > ULONG_MAX) {
return false;
}
return BCRYPT_SUCCESS(BCryptHashData(hmac->hHash, data, (ULONG)length, 0));
}
bool
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
if (hmac == NULL) {
return false;
}
return BCRYPT_SUCCESS(BCryptFinishHash(hmac->hHash, data, hmac->cbHash, 0));
}
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
return BCRYPT_SUCCESS(BCryptGenRandom(NULL, buffer, length, BCRYPT_USE_SYSTEM_PREFERRED_RNG));
}

View File

@ -0,0 +1,53 @@
/*
zip_crypto_win.h -- Windows Crypto API wrapper.
Copyright (C) 2018-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HAD_ZIP_CRYPTO_WIN_H
#define HAD_ZIP_CRYPTO_WIN_H
#define HAVE_SECURE_RANDOM
typedef struct _zip_crypto_aes_s _zip_crypto_aes_t;
typedef struct _zip_crypto_hmac_s _zip_crypto_hmac_t;
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
bool _zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
bool _zip_crypto_hmac(_zip_crypto_hmac_t *hmac, zip_uint8_t *data, zip_uint64_t length);
bool _zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data);
#endif /* HAD_ZIP_CRYPTO_WIN_H */

View File

@ -1,6 +1,6 @@
/*
zip_delete.c -- delete file from zip archive
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,28 +31,38 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_delete(struct zip *za, int idx)
{
if (idx < 0 || idx >= za->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
zip_delete(zip_t *za, zip_uint64_t idx) {
const char *name;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if ((name = _zip_get_name(za, idx, 0, &za->error)) == NULL) {
return -1;
}
if (!_zip_hash_delete(za->names, (const zip_uint8_t *)name, &za->error)) {
return -1;
}
/* allow duplicate file names, because the file will
* be removed directly afterwards */
if (_zip_unchange(za, idx, 1) != 0)
return -1;
return -1;
za->entry[idx].state = ZIP_ST_DELETED;
za->entry[idx].deleted = 1;
return 0;
}

View File

@ -0,0 +1,92 @@
/*
zip_dir_add.c -- add directory
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
ZIP_EXTERN zip_int64_t
zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) {
size_t len;
zip_int64_t idx;
char *s;
zip_source_t *source;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (name == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
s = NULL;
len = strlen(name);
if (name[len - 1] != '/') {
if ((s = (char *)malloc(len + 2)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
strcpy(s, name);
s[len] = '/';
s[len + 1] = '\0';
}
if ((source = zip_source_buffer(za, NULL, 0, 0)) == NULL) {
free(s);
return -1;
}
idx = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags);
free(s);
if (idx < 0)
zip_source_free(source);
else {
if (zip_file_set_external_attributes(za, (zip_uint64_t)idx, 0, ZIP_OPSYS_DEFAULT, ZIP_EXT_ATTRIB_DEFAULT_DIR) < 0) {
zip_delete(za, (zip_uint64_t)idx);
return -1;
}
}
return idx;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
zip_free.c -- free struct zip
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
zip_discard.c -- discard and free struct zip
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,50 +31,49 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
/* _zip_free:
/* zip_discard:
frees the space allocated to a zipfile struct, and closes the
corresponding file. */
void
_zip_free(struct zip *za)
{
int i;
zip_discard(zip_t *za) {
zip_uint64_t i;
if (za == NULL)
return;
return;
if (za->zn)
free(za->zn);
if (za->src) {
zip_source_close(za->src);
zip_source_free(za->src);
}
if (za->zp)
fclose(za->zp);
free(za->default_password);
_zip_string_free(za->comment_orig);
_zip_string_free(za->comment_changes);
_zip_cdir_free(za->cdir);
_zip_hash_free(za->names);
if (za->entry) {
for (i=0; i<za->nentry; i++) {
_zip_entry_free(za->entry+i);
}
free(za->entry);
for (i = 0; i < za->nentry; i++)
_zip_entry_finalize(za->entry + i);
free(za->entry);
}
for (i=0; i<za->nfile; i++) {
if (za->file[i]->error.zip_err == ZIP_ER_OK) {
_zip_error_set(&za->file[i]->error, ZIP_ER_ZIPCLOSED, 0);
za->file[i]->za = NULL;
}
for (i = 0; i < za->nopen_source; i++) {
_zip_source_invalidate(za->open_source[i]);
}
free(za->open_source);
_zip_progress_free(za->progress);
zip_error_fini(&za->error);
free(za->file);
free(za);
return;

View File

@ -1,6 +1,6 @@
/*
zip_stat_init.c -- initialize struct zip_stat.
Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
zip_entry.c -- struct zip_entry helper functions
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,21 +31,21 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN void
zip_stat_init(struct zip_stat *st)
{
st->name = NULL;
st->index = -1;
st->crc = 0;
st->mtime = (time_t)-1;
st->size = -1;
st->comp_size = -1;
st->comp_method = ZIP_CM_STORE;
st->encryption_method = ZIP_EM_NONE;
void
_zip_entry_finalize(zip_entry_t *e) {
_zip_unchange_data(e);
_zip_dirent_free(e->orig);
_zip_dirent_free(e->changes);
}
void
_zip_entry_init(zip_entry_t *e) {
e->orig = NULL;
e->changes = NULL;
e->source = NULL;
e->deleted = 0;
}

View File

@ -0,0 +1,84 @@
/*
This file was generated automatically by CMake
from zip.h; make changes there.
*/
#include "zipint.h"
const char * const _zip_err_str[] = {
"No error",
"Multi-disk zip archives not supported",
"Renaming temporary file failed",
"Closing zip archive failed",
"Seek error",
"Read error",
"Write error",
"CRC error",
"Containing zip archive was closed",
"No such file",
"File already exists",
"Can't open file",
"Failure to create temporary file",
"Zlib error",
"Malloc failure",
"Entry has been changed",
"Compression method not supported",
"Premature end of file",
"Invalid argument",
"Not a zip archive",
"Internal error",
"Zip archive inconsistent",
"Can't remove file",
"Entry has been deleted",
"Encryption method not supported",
"Read-only archive",
"No password provided",
"Wrong password provided",
"Operation not supported",
"Resource still in use",
"Tell error",
"Compressed data invalid",
"Operation cancelled",
};
const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
#define N ZIP_ET_NONE
#define S ZIP_ET_SYS
#define Z ZIP_ET_ZLIB
const int _zip_err_type[] = {
N,
N,
S,
S,
S,
S,
S,
N,
N,
N,
N,
S,
S,
Z,
N,
N,
N,
N,
N,
N,
N,
N,
S,
N,
N,
N,
N,
N,
N,
N,
S,
N,
N,
};

View File

@ -0,0 +1,150 @@
/*
zip_error.c -- zip_error_t helper functions
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN int
zip_error_code_system(const zip_error_t *error) {
return error->sys_err;
}
ZIP_EXTERN int
zip_error_code_zip(const zip_error_t *error) {
return error->zip_err;
}
ZIP_EXTERN void
zip_error_fini(zip_error_t *err) {
free(err->str);
err->str = NULL;
}
ZIP_EXTERN void
zip_error_init(zip_error_t *err) {
err->zip_err = ZIP_ER_OK;
err->sys_err = 0;
err->str = NULL;
}
ZIP_EXTERN void
zip_error_init_with_code(zip_error_t *error, int ze) {
zip_error_init(error);
error->zip_err = ze;
switch (zip_error_system_type(error)) {
case ZIP_ET_SYS:
error->sys_err = errno;
break;
default:
error->sys_err = 0;
break;
}
}
ZIP_EXTERN int
zip_error_system_type(const zip_error_t *error) {
if (error->zip_err < 0 || error->zip_err >= _zip_nerr_str)
return ZIP_ET_NONE;
return _zip_err_type[error->zip_err];
}
void
_zip_error_clear(zip_error_t *err) {
if (err == NULL)
return;
err->zip_err = ZIP_ER_OK;
err->sys_err = 0;
}
void
_zip_error_copy(zip_error_t *dst, const zip_error_t *src) {
if (dst == NULL) {
return;
}
dst->zip_err = src->zip_err;
dst->sys_err = src->sys_err;
}
void
_zip_error_get(const zip_error_t *err, int *zep, int *sep) {
if (zep)
*zep = err->zip_err;
if (sep) {
if (zip_error_system_type(err) != ZIP_ET_NONE)
*sep = err->sys_err;
else
*sep = 0;
}
}
void
zip_error_set(zip_error_t *err, int ze, int se) {
if (err) {
err->zip_err = ze;
err->sys_err = se;
}
}
void
_zip_error_set_from_source(zip_error_t *err, zip_source_t *src) {
_zip_error_copy(err, zip_source_error(src));
}
zip_int64_t
zip_error_to_data(const zip_error_t *error, void *data, zip_uint64_t length) {
int *e = (int *)data;
if (length < sizeof(int) * 2) {
return -1;
}
e[0] = zip_error_code_zip(error);
e[1] = zip_error_code_system(error);
return sizeof(int) * 2;
}

View File

@ -1,6 +1,6 @@
/*
zip_error_clear.c -- clear zip error
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,14 +31,14 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN void
zip_error_clear(struct zip *za)
{
zip_error_clear(zip_t *za) {
if (za == NULL)
return;
_zip_error_clear(&za->error);
}

View File

@ -1,6 +1,6 @@
/*
zip_error_get.c -- get zip error
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,14 +31,24 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN void
zip_error_get(struct zip *za, int *zep, int *sep)
{
zip_error_get(zip_t *za, int *zep, int *sep) {
_zip_error_get(&za->error, zep, sep);
}
ZIP_EXTERN zip_error_t *
zip_get_error(zip_t *za) {
return &za->error;
}
ZIP_EXTERN zip_error_t *
zip_file_get_error(zip_file_t *f) {
return &f->error;
}

View File

@ -1,6 +1,6 @@
/*
zip_error_get_sys_type.c -- return type of system error code
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,17 +31,14 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN int
zip_error_get_sys_type(int ze)
{
zip_error_get_sys_type(int ze) {
if (ze < 0 || ze >= _zip_nerr_str)
return 0;
return 0;
return _zip_err_type[ze];
}

View File

@ -1,6 +1,6 @@
/*
zip_error_sterror.c -- get string representation of struct zip_error
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,60 +31,53 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include "zipint.h"
const char *
_zip_error_strerror(struct zip_error *err)
{
ZIP_EXTERN const char *
zip_error_strerror(zip_error_t *err) {
const char *zs, *ss;
char buf[128], *s;
_zip_error_fini(err);
zip_error_fini(err);
if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) {
sprintf(buf, "Unknown error %d", err->zip_err);
zs = NULL;
ss = buf;
sprintf(buf, "Unknown error %d", err->zip_err);
zs = NULL;
ss = buf;
}
else {
zs = _zip_err_str[err->zip_err];
switch (_zip_err_type[err->zip_err]) {
case ZIP_ET_SYS:
ss = strerror(err->sys_err);
break;
zs = _zip_err_str[err->zip_err];
case ZIP_ET_ZLIB:
ss = zError(err->sys_err);
break;
switch (_zip_err_type[err->zip_err]) {
case ZIP_ET_SYS:
ss = strerror(err->sys_err);
break;
default:
ss = NULL;
}
case ZIP_ET_ZLIB:
ss = zError(err->sys_err);
break;
default:
ss = NULL;
}
}
if (ss == NULL)
return zs;
return zs;
else {
if ((s=(char *)malloc(strlen(ss)
+ (zs ? strlen(zs)+2 : 0) + 1)) == NULL)
return _zip_err_str[ZIP_ER_MEMORY];
sprintf(s, "%s%s%s",
(zs ? zs : ""),
(zs ? ": " : ""),
ss);
err->str = s;
if ((s = (char *)malloc(strlen(ss) + (zs ? strlen(zs) + 2 : 0) + 1)) == NULL)
return _zip_err_str[ZIP_ER_MEMORY];
return s;
sprintf(s, "%s%s%s", (zs ? zs : ""), (zs ? ": " : ""), ss);
err->str = s;
return s;
}
}

View File

@ -1,6 +1,6 @@
/*
zip_error_to_str.c -- get string representation of zip error code
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,40 +31,36 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN int
zip_error_to_str(char *buf, size_t len, int ze, int se)
{
zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) {
const char *zs, *ss;
if (ze < 0 || ze >= _zip_nerr_str)
return snprintf(buf, len, "Unknown error %d", ze);
return snprintf(buf, len, "Unknown error %d", ze);
zs = _zip_err_str[ze];
switch (_zip_err_type[ze]) {
case ZIP_ET_SYS:
ss = strerror(se);
break;
ss = strerror(se);
break;
case ZIP_ET_ZLIB:
ss = zError(se);
break;
ss = zError(se);
break;
default:
ss = NULL;
ss = NULL;
}
return snprintf(buf, len, "%s%s%s",
zs, (ss ? ": " : ""), (ss ? ss : ""));
return snprintf(buf, len, "%s%s%s", zs, (ss ? ": " : ""), (ss ? ss : ""));
}

View File

@ -0,0 +1,426 @@
/*
zip_extra_field.c -- manipulate extra fields
Copyright (C) 2012-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
zip_extra_field_t *
_zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error) {
zip_extra_field_t *head, *prev, *def;
head = prev = NULL;
while (ef) {
if ((def = _zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
_zip_ef_free(head);
return NULL;
}
if (head == NULL)
head = def;
if (prev)
prev->next = def;
prev = def;
ef = ef->next;
}
return head;
}
zip_extra_field_t *
_zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags) {
zip_extra_field_t *head, *prev;
int i;
i = 0;
head = ef;
prev = NULL;
for (; ef; ef = (prev ? prev->next : head)) {
if ((ef->flags & flags & ZIP_EF_BOTH) && ((ef->id == id) || (id == ZIP_EXTRA_FIELD_ALL))) {
if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) {
ef->flags &= ~(flags & ZIP_EF_BOTH);
if ((ef->flags & ZIP_EF_BOTH) == 0) {
if (prev)
prev->next = ef->next;
else
head = ef->next;
ef->next = NULL;
_zip_ef_free(ef);
if (id_idx == ZIP_EXTRA_FIELD_ALL)
continue;
}
}
i++;
if (i > id_idx)
break;
}
prev = ef;
}
return head;
}
void
_zip_ef_free(zip_extra_field_t *ef) {
zip_extra_field_t *ef2;
while (ef) {
ef2 = ef->next;
free(ef->data);
free(ef);
ef = ef2;
}
}
const zip_uint8_t *
_zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, zip_error_t *error) {
static const zip_uint8_t empty[1] = {'\0'};
int i;
i = 0;
for (; ef; ef = ef->next) {
if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) {
if (i < id_idx) {
i++;
continue;
}
if (lenp)
*lenp = ef->size;
if (ef->size > 0)
return ef->data;
else
return empty;
}
}
zip_error_set(error, ZIP_ER_NOENT, 0);
return NULL;
}
zip_extra_field_t *
_zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from) {
zip_extra_field_t *ef2, *tt, *tail;
int duplicate;
if (to == NULL)
return from;
for (tail = to; tail->next; tail = tail->next)
;
for (; from; from = ef2) {
ef2 = from->next;
duplicate = 0;
for (tt = to; tt; tt = tt->next) {
if (tt->id == from->id && tt->size == from->size && (tt->size == 0 || memcmp(tt->data, from->data, tt->size) == 0)) {
tt->flags |= (from->flags & ZIP_EF_BOTH);
duplicate = 1;
break;
}
}
from->next = NULL;
if (duplicate)
_zip_ef_free(from);
else
tail = tail->next = from;
}
return to;
}
zip_extra_field_t *
_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags) {
zip_extra_field_t *ef;
if ((ef = (zip_extra_field_t *)malloc(sizeof(*ef))) == NULL)
return NULL;
ef->next = NULL;
ef->flags = flags;
ef->id = id;
ef->size = size;
if (size > 0) {
if ((ef->data = (zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) {
free(ef);
return NULL;
}
}
else
ef->data = NULL;
return ef;
}
bool
_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_extra_field_t **ef_head_p, zip_error_t *error) {
zip_buffer_t *buffer;
zip_extra_field_t *ef, *ef2, *ef_head;
if ((buffer = _zip_buffer_new((zip_uint8_t *)data, len)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return false;
}
ef_head = ef = NULL;
while (_zip_buffer_ok(buffer) && _zip_buffer_left(buffer) >= 4) {
zip_uint16_t fid, flen;
zip_uint8_t *ef_data;
fid = _zip_buffer_get_16(buffer);
flen = _zip_buffer_get_16(buffer);
ef_data = _zip_buffer_get(buffer, flen);
if (ef_data == NULL) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(buffer);
_zip_ef_free(ef_head);
return false;
}
if ((ef2 = _zip_ef_new(fid, flen, ef_data, flags)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
_zip_buffer_free(buffer);
_zip_ef_free(ef_head);
return false;
}
if (ef_head) {
ef->next = ef2;
ef = ef2;
}
else
ef_head = ef = ef2;
}
if (!_zip_buffer_eof(buffer)) {
/* Android APK files align stored file data with padding in extra fields; ignore. */
/* see https://android.googlesource.com/platform/build/+/master/tools/zipalign/ZipAlign.cpp */
size_t glen = _zip_buffer_left(buffer);
zip_uint8_t *garbage;
garbage = _zip_buffer_get(buffer, glen);
if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(buffer);
_zip_ef_free(ef_head);
return false;
}
}
_zip_buffer_free(buffer);
if (ef_head_p) {
*ef_head_p = ef_head;
}
else {
_zip_ef_free(ef_head);
}
return true;
}
zip_extra_field_t *
_zip_ef_remove_internal(zip_extra_field_t *ef) {
zip_extra_field_t *ef_head;
zip_extra_field_t *prev, *next;
ef_head = ef;
prev = NULL;
while (ef) {
if (ZIP_EF_IS_INTERNAL(ef->id)) {
next = ef->next;
if (ef_head == ef)
ef_head = next;
ef->next = NULL;
_zip_ef_free(ef);
if (prev)
prev->next = next;
ef = next;
}
else {
prev = ef;
ef = ef->next;
}
}
return ef_head;
}
zip_uint16_t
_zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags) {
zip_uint16_t size;
size = 0;
for (; ef; ef = ef->next) {
if (ef->flags & flags & ZIP_EF_BOTH)
size = (zip_uint16_t)(size + 4 + ef->size);
}
return size;
}
int
_zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags) {
zip_uint8_t b[4];
zip_buffer_t *buffer = _zip_buffer_new(b, sizeof(b));
if (buffer == NULL) {
return -1;
}
for (; ef; ef = ef->next) {
if (ef->flags & flags & ZIP_EF_BOTH) {
_zip_buffer_set_offset(buffer, 0);
_zip_buffer_put_16(buffer, ef->id);
_zip_buffer_put_16(buffer, ef->size);
if (!_zip_buffer_ok(buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(buffer);
return -1;
}
if (_zip_write(za, b, 4) < 0) {
_zip_buffer_free(buffer);
return -1;
}
if (ef->size > 0) {
if (_zip_write(za, ef->data, ef->size) < 0) {
_zip_buffer_free(buffer);
return -1;
}
}
}
}
_zip_buffer_free(buffer);
return 0;
}
int
_zip_read_local_ef(zip_t *za, zip_uint64_t idx) {
zip_entry_t *e;
unsigned char b[4];
zip_buffer_t *buffer;
zip_uint16_t fname_len, ef_len;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
e = za->entry + idx;
if (e->orig == NULL || e->orig->local_extra_fields_read)
return 0;
if (e->orig->offset + 26 > ZIP_INT64_MAX) {
zip_error_set(&za->error, ZIP_ER_SEEK, EFBIG);
return -1;
}
if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
return -1;
}
if ((buffer = _zip_buffer_new_from_source(za->src, sizeof(b), b, &za->error)) == NULL) {
return -1;
}
fname_len = _zip_buffer_get_16(buffer);
ef_len = _zip_buffer_get_16(buffer);
if (!_zip_buffer_eof(buffer)) {
_zip_buffer_free(buffer);
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
return -1;
}
_zip_buffer_free(buffer);
if (ef_len > 0) {
zip_extra_field_t *ef;
zip_uint8_t *ef_raw;
if (zip_source_seek(za->src, fname_len, SEEK_CUR) < 0) {
zip_error_set(&za->error, ZIP_ER_SEEK, errno);
return -1;
}
ef_raw = _zip_read_data(NULL, za->src, ef_len, 0, &za->error);
if (ef_raw == NULL)
return -1;
if (!_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &ef, &za->error)) {
free(ef_raw);
return -1;
}
free(ef_raw);
if (ef) {
ef = _zip_ef_remove_internal(ef);
e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef);
}
}
e->orig->local_extra_fields_read = 1;
if (e->changes && e->changes->local_extra_fields_read == 0) {
e->changes->extra_fields = e->orig->extra_fields;
e->changes->local_extra_fields_read = 1;
}
return 0;
}

View File

@ -0,0 +1,355 @@
/*
zip_extra_field_api.c -- public extra fields API functions
Copyright (C) 2012-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN int
zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags) {
zip_dirent_t *de;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
return -1;
de = za->entry[idx].changes;
de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags);
return 0;
}
ZIP_EXTERN int
zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags) {
zip_dirent_t *de;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
return -1;
de = za->entry[idx].changes;
de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
return 0;
}
ZIP_EXTERN const zip_uint8_t *
zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags) {
static const zip_uint8_t empty[1] = {'\0'};
zip_dirent_t *de;
zip_extra_field_t *ef;
int i;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
return NULL;
if (flags & ZIP_FL_LOCAL)
if (_zip_read_local_ef(za, idx) < 0)
return NULL;
i = 0;
for (ef = de->extra_fields; ef; ef = ef->next) {
if (ef->flags & flags & ZIP_EF_BOTH) {
if (i < ef_idx) {
i++;
continue;
}
if (idp)
*idp = ef->id;
if (lenp)
*lenp = ef->size;
if (ef->size > 0)
return ef->data;
else
return empty;
}
}
zip_error_set(&za->error, ZIP_ER_NOENT, 0);
return NULL;
}
ZIP_EXTERN const zip_uint8_t *
zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags) {
zip_dirent_t *de;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
return NULL;
if (flags & ZIP_FL_LOCAL)
if (_zip_read_local_ef(za, idx) < 0)
return NULL;
return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
}
ZIP_EXTERN zip_int16_t
zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags) {
zip_dirent_t *de;
zip_extra_field_t *ef;
zip_uint16_t n;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
return -1;
if (flags & ZIP_FL_LOCAL)
if (_zip_read_local_ef(za, idx) < 0)
return -1;
n = 0;
for (ef = de->extra_fields; ef; ef = ef->next)
if (ef->flags & flags & ZIP_EF_BOTH)
n++;
return (zip_int16_t)n;
}
ZIP_EXTERN zip_int16_t
zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags) {
zip_dirent_t *de;
zip_extra_field_t *ef;
zip_uint16_t n;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
return -1;
if (flags & ZIP_FL_LOCAL)
if (_zip_read_local_ef(za, idx) < 0)
return -1;
n = 0;
for (ef = de->extra_fields; ef; ef = ef->next)
if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
n++;
return (zip_int16_t)n;
}
ZIP_EXTERN int
zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags) {
zip_dirent_t *de;
zip_uint16_t ls, cs;
zip_extra_field_t *ef, *ef_prev, *ef_new;
int i, found, new_len;
if ((flags & ZIP_EF_BOTH) == 0) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (ZIP_EF_IS_INTERNAL(ef_id)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
return -1;
de = za->entry[idx].changes;
ef = de->extra_fields;
ef_prev = NULL;
i = 0;
found = 0;
for (; ef; ef = ef->next) {
if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) {
if (i == ef_idx) {
found = 1;
break;
}
i++;
}
ef_prev = ef;
}
if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (flags & ZIP_EF_LOCAL)
ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL);
else
ls = 0;
if (flags & ZIP_EF_CENTRAL)
cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL);
else
cs = 0;
new_len = ls > cs ? ls : cs;
if (found)
new_len -= ef->size + 4;
new_len += len + 4;
if (new_len > ZIP_UINT16_MAX) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((ef_new = _zip_ef_new(ef_id, len, data, flags)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
if (found) {
if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
ef_new->next = ef->next;
ef->next = NULL;
_zip_ef_free(ef);
if (ef_prev)
ef_prev->next = ef_new;
else
de->extra_fields = ef_new;
}
else {
ef->flags &= ~(flags & ZIP_EF_BOTH);
ef_new->next = ef->next;
ef->next = ef_new;
}
}
else if (ef_prev) {
ef_new->next = ef_prev->next;
ef_prev->next = ef_new;
}
else
de->extra_fields = ef_new;
return 0;
}
int
_zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx) {
zip_entry_t *e;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
e = za->entry + idx;
if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD))
return 0;
if (e->orig) {
if (_zip_read_local_ef(za, idx) < 0)
return -1;
}
if (e->changes == NULL) {
if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
if (e->orig && e->orig->extra_fields) {
if ((e->changes->extra_fields = _zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL)
return -1;
}
e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD;
return 0;
}

View File

@ -1,6 +1,6 @@
/*
zip_fclose.c -- close file in zip archive
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,41 +31,24 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
ZIP_EXTERN int
zip_fclose(struct zip_file *zf)
{
int i, ret;
if (zf->zstr)
inflateEnd(zf->zstr);
free(zf->buffer);
free(zf->zstr);
zip_fclose(zip_file_t *zf) {
int ret;
for (i=0; i<zf->za->nfile; i++) {
if (zf->za->file[i] == zf) {
zf->za->file[i] = zf->za->file[zf->za->nfile-1];
zf->za->nfile--;
break;
}
}
if (zf->src)
zip_source_free(zf->src);
ret = 0;
if (zf->error.zip_err)
ret = zf->error.zip_err;
else if ((zf->flags & ZIP_ZF_CRC) && (zf->flags & ZIP_ZF_EOF)) {
/* if EOF, compare CRC */
if (zf->crc_orig != zf->crc)
ret = ZIP_ER_CRC;
}
ret = zf->error.zip_err;
zip_error_fini(&zf->error);
free(zf);
return ret;
}

View File

@ -1,6 +1,6 @@
/*
zip_entry_new.c -- create and init struct zip_entry
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
zip_fdopen.c -- open read-only archive from file descriptor
Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,48 +31,56 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include "zipint.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
struct zip_entry *
_zip_entry_new(struct zip *za)
{
struct zip_entry *ze;
if (!za) {
ze = (struct zip_entry *)malloc(sizeof(struct zip_entry));
if (!ze) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
}
else {
if (za->nentry >= za->nentry_alloc-1) {
za->nentry_alloc += 16;
za->entry = (struct zip_entry *)realloc(za->entry,
sizeof(struct zip_entry)
* za->nentry_alloc);
if (!za->entry) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
}
ze = za->entry+za->nentry;
ZIP_EXTERN zip_t *
zip_fdopen(int fd_orig, int _flags, int *zep) {
int fd;
FILE *fp;
zip_t *za;
zip_source_t *src;
struct zip_error error;
if (_flags < 0 || (_flags & ~(ZIP_CHECKCONS | ZIP_RDONLY))) {
_zip_set_open_error(zep, NULL, ZIP_ER_INVAL);
return NULL;
}
ze->state = ZIP_ST_UNCHANGED;
/* We dup() here to avoid messing with the passed in fd.
We could not restore it to the original state in case of error. */
ze->ch_filename = NULL;
ze->ch_comment = NULL;
ze->ch_comment_len = -1;
ze->source = NULL;
if ((fd = dup(fd_orig)) < 0) {
_zip_set_open_error(zep, NULL, ZIP_ER_OPEN);
return NULL;
}
if (za)
za->nentry++;
if ((fp = fdopen(fd, "rb")) == NULL) {
close(fd);
_zip_set_open_error(zep, NULL, ZIP_ER_OPEN);
return NULL;
}
return ze;
zip_error_init(&error);
if ((src = zip_source_filep_create(fp, 0, -1, &error)) == NULL) {
fclose(fp);
_zip_set_open_error(zep, &error, 0);
zip_error_fini(&error);
return NULL;
}
if ((za = zip_open_from_source(src, _flags, &error)) == NULL) {
zip_source_free(src);
_zip_set_open_error(zep, &error, 0);
zip_error_fini(&error);
return NULL;
}
zip_error_fini(&error);
close(fd_orig);
return za;
}

View File

@ -0,0 +1,52 @@
/*
zip_file_add.c -- add file via callback function
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
/*
NOTE: Return type is signed so we can return -1 on error.
The index can not be larger than ZIP_INT64_MAX since the size
of the central directory cannot be larger than
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
*/
ZIP_EXTERN zip_int64_t
zip_file_add(zip_t *za, const char *name, zip_source_t *source, zip_flags_t flags) {
if (name == NULL || source == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
return _zip_file_replace(za, ZIP_UINT64_MAX, name, source, flags);
}

View File

@ -1,6 +1,6 @@
/*
zip_file_error_clear.c -- clear zip file error
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,14 +31,14 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN void
zip_file_error_clear(struct zip_file *zf)
{
zip_file_error_clear(zip_file_t *zf) {
if (zf == NULL)
return;
_zip_error_clear(&zf->error);
}

View File

@ -1,6 +1,6 @@
/*
zip_file_error_get.c -- get zip file error
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,14 +31,11 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"
ZIP_EXTERN void
zip_file_error_get(struct zip_file *zf, int *zep, int *sep)
{
zip_file_error_get(zip_file_t *zf, int *zep, int *sep) {
_zip_error_get(&zf->error, zep, sep);
}

View File

@ -0,0 +1,55 @@
/*
zip_file_get_comment.c -- get file comment
Copyright (C) 2006-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
/* lenp is 32 bit because converted comment can be longer than ZIP_UINT16_MAX */
ZIP_EXTERN const char *
zip_file_get_comment(zip_t *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags) {
zip_dirent_t *de;
zip_uint32_t len;
const zip_uint8_t *str;
if ((de = _zip_get_dirent(za, idx, flags, NULL)) == NULL)
return NULL;
if ((str = _zip_string_get(de->comment, &len, flags, &za->error)) == NULL)
return NULL;
if (lenp)
*lenp = len;
return (const char *)str;
}

View File

@ -0,0 +1,50 @@
/*
zip_file_get_external_attributes.c -- get opsys/external attributes
Copyright (C) 2013-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
int
zip_file_get_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes) {
zip_dirent_t *de;
if ((de = _zip_get_dirent(za, idx, flags, NULL)) == NULL)
return -1;
if (opsys)
*opsys = (zip_uint8_t)((de->version_madeby >> 8) & 0xff);
if (attributes)
*attributes = de->ext_attrib;
return 0;
}

View File

@ -0,0 +1,117 @@
/*
zip_file_get_offset.c -- get offset of file data in archive.
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include "zipint.h"
/* _zip_file_get_offset(za, ze):
Returns the offset of the file data for entry ze.
On error, fills in za->error and returns 0.
*/
zip_uint64_t
_zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error) {
zip_uint64_t offset;
zip_int32_t size;
if (za->entry[idx].orig == NULL) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return 0;
}
offset = za->entry[idx].orig->offset;
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
_zip_error_set_from_source(error, za->src);
return 0;
}
/* TODO: cache? */
if ((size = _zip_dirent_size(za->src, ZIP_EF_LOCAL, error)) < 0)
return 0;
if (offset + (zip_uint32_t)size > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return 0;
}
return offset + (zip_uint32_t)size;
}
zip_uint64_t
_zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error) {
zip_uint64_t offset;
zip_dirent_t *entry;
if ((offset = _zip_file_get_offset(za, index, error)) == 0) {
return 0;
}
entry = za->entry[index].orig;
if (offset + entry->comp_size < offset || offset + entry->comp_size > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return 0;
}
offset += entry->comp_size;
if (entry->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
zip_uint8_t buf[4];
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
_zip_error_set_from_source(error, za->src);
return 0;
}
if (zip_source_read(za->src, buf, 4) != 4) {
_zip_error_set_from_source(error, za->src);
return 0;
}
if (memcmp(buf, DATADES_MAGIC, 4) == 0) {
offset += 4;
}
offset += 12;
if (_zip_dirent_needs_zip64(entry, 0)) {
offset += 8;
}
if (offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
return 0;
}
}
return offset;
}

View File

@ -1,6 +1,6 @@
/*
zip_set_name.c -- rename helper function
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
zip_file_rename.c -- rename file in zip archive
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -17,7 +17,7 @@
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -31,45 +31,37 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "zipint.h"
int
_zip_set_name(struct zip *za, int idx, const char *name)
{
char *s;
int i;
if (idx < 0 || idx >= za->nentry || name == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
ZIP_EXTERN int
zip_file_rename(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) {
const char *old_name;
int old_is_dir, new_is_dir;
if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) {
_zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
return -1;
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
/* no effective name change */
if (i == idx)
return 0;
if ((s=strdup(name)) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
if ((old_name = zip_get_name(za, idx, 0)) == NULL)
return -1;
new_is_dir = (name != NULL && name[strlen(name) - 1] == '/');
old_is_dir = (old_name[strlen(old_name) - 1] == '/');
if (new_is_dir != old_is_dir) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (za->entry[idx].state == ZIP_ST_UNCHANGED)
za->entry[idx].state = ZIP_ST_RENAMED;
free(za->entry[idx].ch_filename);
za->entry[idx].ch_filename = s;
return 0;
return _zip_set_name(za, idx, name, flags);
}

Some files were not shown because too many files have changed in this diff Show More