VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/BootEncryption.cpp2
-rw-r--r--src/Common/Dlgcode.c32
-rw-r--r--src/Common/Dlgcode.h4
-rw-r--r--src/Common/Random.c346
-rw-r--r--src/Common/Tcdefs.h2
-rw-r--r--src/Common/Zip.vcxproj1
-rw-r--r--src/Common/Zip.vcxproj.filters3
-rw-r--r--src/Common/libzip/NEWS.md17
-rw-r--r--src/Common/libzip/compat.h78
-rw-r--r--src/Common/libzip/config.h6
-rw-r--r--src/Common/libzip/zip.h6
-rw-r--r--src/Common/libzip/zip_add.c2
-rw-r--r--src/Common/libzip/zip_add_dir.c2
-rw-r--r--src/Common/libzip/zip_add_entry.c4
-rw-r--r--src/Common/libzip/zip_algorithm_bzip2.c2
-rw-r--r--src/Common/libzip/zip_algorithm_deflate.c2
-rw-r--r--src/Common/libzip/zip_algorithm_xz.c2
-rw-r--r--src/Common/libzip/zip_algorithm_zstd.c2
-rw-r--r--src/Common/libzip/zip_buffer.c5
-rw-r--r--src/Common/libzip/zip_close.c45
-rw-r--r--src/Common/libzip/zip_crypto.h2
-rw-r--r--src/Common/libzip/zip_crypto_commoncrypto.c2
-rw-r--r--src/Common/libzip/zip_crypto_commoncrypto.h2
-rw-r--r--src/Common/libzip/zip_crypto_gnutls.c2
-rw-r--r--src/Common/libzip/zip_crypto_gnutls.h2
-rw-r--r--src/Common/libzip/zip_crypto_mbedtls.c2
-rw-r--r--src/Common/libzip/zip_crypto_mbedtls.h2
-rw-r--r--src/Common/libzip/zip_crypto_openssl.c13
-rw-r--r--src/Common/libzip/zip_crypto_openssl.h2
-rw-r--r--src/Common/libzip/zip_crypto_win.c5
-rw-r--r--src/Common/libzip/zip_crypto_win.h2
-rw-r--r--src/Common/libzip/zip_delete.c2
-rw-r--r--src/Common/libzip/zip_dir_add.c2
-rw-r--r--src/Common/libzip/zip_dirent.c202
-rw-r--r--src/Common/libzip/zip_discard.c2
-rw-r--r--src/Common/libzip/zip_entry.c2
-rw-r--r--src/Common/libzip/zip_err_str.c6
-rw-r--r--src/Common/libzip/zip_error.c2
-rw-r--r--src/Common/libzip/zip_error_clear.c2
-rw-r--r--src/Common/libzip/zip_error_get.c2
-rw-r--r--src/Common/libzip/zip_error_get_sys_type.c2
-rw-r--r--src/Common/libzip/zip_error_strerror.c14
-rw-r--r--src/Common/libzip/zip_error_to_str.c2
-rw-r--r--src/Common/libzip/zip_extra_field.c2
-rw-r--r--src/Common/libzip/zip_extra_field_api.c6
-rw-r--r--src/Common/libzip/zip_fclose.c2
-rw-r--r--src/Common/libzip/zip_fdopen.c2
-rw-r--r--src/Common/libzip/zip_file_add.c2
-rw-r--r--src/Common/libzip/zip_file_error_clear.c2
-rw-r--r--src/Common/libzip/zip_file_error_get.c2
-rw-r--r--src/Common/libzip/zip_file_get_comment.c2
-rw-r--r--src/Common/libzip/zip_file_get_external_attributes.c2
-rw-r--r--src/Common/libzip/zip_file_get_offset.c2
-rw-r--r--src/Common/libzip/zip_file_rename.c2
-rw-r--r--src/Common/libzip/zip_file_replace.c8
-rw-r--r--src/Common/libzip/zip_file_set_comment.c2
-rw-r--r--src/Common/libzip/zip_file_set_encryption.c2
-rw-r--r--src/Common/libzip/zip_file_set_external_attributes.c2
-rw-r--r--src/Common/libzip/zip_file_set_mtime.c40
-rw-r--r--src/Common/libzip/zip_file_strerror.c2
-rw-r--r--src/Common/libzip/zip_fopen.c2
-rw-r--r--src/Common/libzip/zip_fopen_encrypted.c2
-rw-r--r--src/Common/libzip/zip_fopen_index.c2
-rw-r--r--src/Common/libzip/zip_fopen_index_encrypted.c2
-rw-r--r--src/Common/libzip/zip_fread.c8
-rw-r--r--src/Common/libzip/zip_fseek.c10
-rw-r--r--src/Common/libzip/zip_ftell.c8
-rw-r--r--src/Common/libzip/zip_get_archive_comment.c2
-rw-r--r--src/Common/libzip/zip_get_archive_flag.c2
-rw-r--r--src/Common/libzip/zip_get_encryption_implementation.c2
-rw-r--r--src/Common/libzip/zip_get_file_comment.c2
-rw-r--r--src/Common/libzip/zip_get_name.c2
-rw-r--r--src/Common/libzip/zip_get_num_entries.c2
-rw-r--r--src/Common/libzip/zip_get_num_files.c2
-rw-r--r--src/Common/libzip/zip_hash.c2
-rw-r--r--src/Common/libzip/zip_io_util.c10
-rw-r--r--src/Common/libzip/zip_libzip_version.c2
-rw-r--r--src/Common/libzip/zip_memdup.c4
-rw-r--r--src/Common/libzip/zip_new.c5
-rw-r--r--src/Common/libzip/zip_open.c491
-rw-r--r--src/Common/libzip/zip_pkware.c2
-rw-r--r--src/Common/libzip/zip_progress.c4
-rw-r--r--src/Common/libzip/zip_random_unix.c2
-rw-r--r--src/Common/libzip/zip_random_uwp.c2
-rw-r--r--src/Common/libzip/zip_random_win32.c2
-rw-r--r--src/Common/libzip/zip_rename.c2
-rw-r--r--src/Common/libzip/zip_replace.c2
-rw-r--r--src/Common/libzip/zip_set_archive_comment.c2
-rw-r--r--src/Common/libzip/zip_set_archive_flag.c2
-rw-r--r--src/Common/libzip/zip_set_default_password.c2
-rw-r--r--src/Common/libzip/zip_set_file_comment.c2
-rw-r--r--src/Common/libzip/zip_set_file_compression.c2
-rw-r--r--src/Common/libzip/zip_set_name.c2
-rw-r--r--src/Common/libzip/zip_source_accept_empty.c2
-rw-r--r--src/Common/libzip/zip_source_begin_write.c2
-rw-r--r--src/Common/libzip/zip_source_begin_write_cloning.c2
-rw-r--r--src/Common/libzip/zip_source_buffer.c2
-rw-r--r--src/Common/libzip/zip_source_call.c2
-rw-r--r--src/Common/libzip/zip_source_close.c2
-rw-r--r--src/Common/libzip/zip_source_commit_write.c2
-rw-r--r--src/Common/libzip/zip_source_compress.c2
-rw-r--r--src/Common/libzip/zip_source_crc.c2
-rw-r--r--src/Common/libzip/zip_source_error.c2
-rw-r--r--src/Common/libzip/zip_source_file.h7
-rw-r--r--src/Common/libzip/zip_source_file_common.c2
-rw-r--r--src/Common/libzip/zip_source_file_stdio.c12
-rw-r--r--src/Common/libzip/zip_source_file_stdio.h2
-rw-r--r--src/Common/libzip/zip_source_file_stdio_named.c14
-rw-r--r--src/Common/libzip/zip_source_file_win32.c2
-rw-r--r--src/Common/libzip/zip_source_file_win32.h11
-rw-r--r--src/Common/libzip/zip_source_file_win32_ansi.c69
-rw-r--r--src/Common/libzip/zip_source_file_win32_named.c29
-rw-r--r--src/Common/libzip/zip_source_file_win32_utf16.c65
-rw-r--r--src/Common/libzip/zip_source_file_win32_utf8.c2
-rw-r--r--src/Common/libzip/zip_source_free.c2
-rw-r--r--src/Common/libzip/zip_source_get_dostime.c72
-rw-r--r--src/Common/libzip/zip_source_get_file_attributes.c2
-rw-r--r--src/Common/libzip/zip_source_is_deleted.c2
-rw-r--r--src/Common/libzip/zip_source_layered.c2
-rw-r--r--src/Common/libzip/zip_source_open.c2
-rw-r--r--src/Common/libzip/zip_source_pass_to_lower_layer.c4
-rw-r--r--src/Common/libzip/zip_source_pkware_decode.c43
-rw-r--r--src/Common/libzip/zip_source_pkware_encode.c63
-rw-r--r--src/Common/libzip/zip_source_read.c2
-rw-r--r--src/Common/libzip/zip_source_remove.c2
-rw-r--r--src/Common/libzip/zip_source_rollback_write.c2
-rw-r--r--src/Common/libzip/zip_source_seek.c2
-rw-r--r--src/Common/libzip/zip_source_seek_write.c2
-rw-r--r--src/Common/libzip/zip_source_stat.c2
-rw-r--r--src/Common/libzip/zip_source_supports.c2
-rw-r--r--src/Common/libzip/zip_source_tell.c2
-rw-r--r--src/Common/libzip/zip_source_tell_write.c2
-rw-r--r--src/Common/libzip/zip_source_window.c30
-rw-r--r--src/Common/libzip/zip_source_winzip_aes_decode.c2
-rw-r--r--src/Common/libzip/zip_source_winzip_aes_encode.c2
-rw-r--r--src/Common/libzip/zip_source_write.c2
-rw-r--r--src/Common/libzip/zip_source_zip.c2
-rw-r--r--src/Common/libzip/zip_source_zip_new.c11
-rw-r--r--src/Common/libzip/zip_stat.c2
-rw-r--r--src/Common/libzip/zip_stat_index.c12
-rw-r--r--src/Common/libzip/zip_stat_init.c2
-rw-r--r--src/Common/libzip/zip_strerror.c2
-rw-r--r--src/Common/libzip/zip_string.c22
-rw-r--r--src/Common/libzip/zip_unchange_all.c2
-rw-r--r--src/Common/libzip/zip_unchange_archive.c2
-rw-r--r--src/Common/libzip/zip_unchange_data.c2
-rw-r--r--src/Common/libzip/zip_utf-8.c146
-rw-r--r--src/Common/libzip/zip_winzip_aes.c2
-rw-r--r--src/Common/libzip/zipconf.h6
-rw-r--r--src/Common/libzip/zipint.h54
-rw-r--r--src/Common/lzma/7zTypes.h14
-rw-r--r--src/Common/lzma/Alloc.c174
-rw-r--r--src/Common/lzma/Alloc.h15
-rw-r--r--src/Common/lzma/Compiler.h91
-rw-r--r--src/Common/lzma/CpuArch.c217
-rw-r--r--src/Common/lzma/CpuArch.h177
-rw-r--r--src/Common/lzma/LzFind.c127
-rw-r--r--src/Common/lzma/LzFind.h5
-rw-r--r--src/Common/lzma/LzFindMt.c58
-rw-r--r--src/Common/lzma/LzFindMt.h9
-rw-r--r--src/Common/lzma/LzmaEnc.c40
-rw-r--r--src/Common/lzma/Precomp.h123
-rw-r--r--src/Common/lzma/Threads.c53
-rw-r--r--src/Common/lzma/Threads.h20
-rw-r--r--src/Common/lzma/lzma-history.txt74
-rw-r--r--src/Common/lzma/lzma-sdk.txt17
166 files changed, 2412 insertions, 1061 deletions
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index e6e36f12..6a36a60f 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -3202,7 +3202,7 @@ namespace VeraCrypt
void BootEncryption::UpdateSetupConfigFile (bool bForInstall)
{
// starting from Windows 10 1607 (Build 14393), ReflectDrivers in Setupconfig.ini is supported
- if (IsOSVersionAtLeast (WIN_10, 0) && CurrentOSBuildNumber >= 14393)
+ if (IsWin10BuildAtLeast(WIN_10_1607_BUILD))
{
wchar_t szInstallPath [TC_MAX_PATH];
wchar_t szSetupconfigLocation [TC_MAX_PATH + 20];
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index ee3630c0..dcdcb3a4 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -311,12 +311,12 @@ static unsigned char gpbSha512CodeSignCertFingerprint[64] = {
};
static unsigned char gpbSha512MSCodeSignCertFingerprint[64] = {
- 0xEB, 0x76, 0x2E, 0xD3, 0x5B, 0x4A, 0xB1, 0x0E, 0xF5, 0x3B, 0x99, 0x4E,
- 0xC1, 0xF7, 0x48, 0x88, 0xF6, 0xA0, 0xE9, 0xAC, 0x32, 0x69, 0xCF, 0x20,
- 0xE1, 0x60, 0xC4, 0x0C, 0xEF, 0x01, 0x1F, 0xCB, 0x41, 0x95, 0x72, 0xB9,
- 0xED, 0x63, 0x0C, 0x6B, 0xB9, 0xE9, 0xA2, 0x72, 0xA6, 0x78, 0x96, 0x4C,
- 0x69, 0x9F, 0x90, 0x3F, 0xB1, 0x3C, 0x64, 0xF2, 0xAB, 0xCF, 0x14, 0x1D,
- 0xEC, 0x7C, 0xB0, 0xC7
+ 0x17, 0x8C, 0x1B, 0x37, 0x70, 0xBF, 0x8B, 0xDF, 0x84, 0x55, 0xC5, 0x18,
+ 0x13, 0x64, 0xE9, 0x65, 0x6D, 0x67, 0xCA, 0x0C, 0xD6, 0x3B, 0x9E, 0x7B,
+ 0x9B, 0x6A, 0x63, 0xD6, 0x19, 0xAE, 0xD7, 0xBA, 0xBE, 0x5C, 0xCB, 0xD1,
+ 0x07, 0x89, 0x07, 0xFB, 0x12, 0xC0, 0x2C, 0x94, 0x86, 0xEB, 0x67, 0x0B,
+ 0x9C, 0x97, 0xEB, 0x20, 0x38, 0x13, 0x9C, 0x0F, 0x56, 0x93, 0x1B, 0x19,
+ 0x6F, 0x8F, 0x6A, 0x39
};
/* Windows dialog class */
@@ -1046,6 +1046,20 @@ BOOL IsOSVersionAtLeast (OSVersionEnum reqMinOS, int reqMinServicePack)
>= (major << 16 | minor << 8 | reqMinServicePack));
}
+BOOL IsWin10BuildAtLeast(DWORD minBuild)
+{
+ // Must first be recognized as Windows 10 or higher
+ if (nCurrentOS < WIN_10)
+ return FALSE;
+
+ // If we’re on Windows 10, check build number
+ if (nCurrentOS == WIN_10 && CurrentOSBuildNumber < minBuild)
+ return FALSE;
+
+ // If we are on a higher version of Windows, we are good to go
+ return TRUE;
+}
+
#ifdef SETUP_DLL
static BOOL GetWindowVersionFromFile(DWORD* pdwMajor, DWORD* pdwMinor, DWORD* pdwBuildNumber)
{
@@ -3611,10 +3625,10 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
InitOSVersionInfo();
- if (!IsOSAtLeast (WIN_10))
+ if (!IsWin10BuildAtLeast(WIN_10_1809_BUILD))
{
- // abort using a message that says that VeraCrypt can run only on Windows 10 and later
- AbortProcessDirect(L"VeraCrypt requires at least Windows 10 to run.");
+ // abort using a message that says that VeraCrypt can run only on Windows 10 version 1809 or later
+ AbortProcessDirect(L"VeraCrypt requires at least Windows 10 version 1809 (October 2018 Update) to run.");
}
if (!Is64BitOs())
diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h
index 4dfae20f..9ffb5c9d 100644
--- a/src/Common/Dlgcode.h
+++ b/src/Common/Dlgcode.h
@@ -286,6 +286,9 @@ typedef NTSTATUS (WINAPI *NtQuerySystemInformationFn)(
#define ISO_BURNER_TOOL L"isoburn.exe"
#define PRINT_TOOL L"notepad.exe"
+#define WIN_10_1607_BUILD 14393 // Windows 10 version 1607 corresponds to build 14393
+#define WIN_10_1809_BUILD 17763 // Windows 10 version 1809 corresponds to build 17763
+
void InitGlobalLocks ();
void FinalizeGlobalLocks ();
void cleanup ( void );
@@ -500,6 +503,7 @@ void Debug (char *format, ...);
void DebugMsgBox (char *format, ...);
BOOL IsOSAtLeast (OSVersionEnum reqMinOS);
BOOL IsOSVersionAtLeast (OSVersionEnum reqMinOS, int reqMinServicePack);
+BOOL IsWin10BuildAtLeast(DWORD minBuild);
BOOL IsSupportedOS ();
BOOL Is64BitOs ();
BOOL IsARM();
diff --git a/src/Common/Random.c b/src/Common/Random.c
index 0cd6bfa0..00a00729 100644
--- a/src/Common/Random.c
+++ b/src/Common/Random.c
@@ -20,6 +20,8 @@
#include "Crypto\rdrand.h"
#include <Strsafe.h>
#include <bcrypt.h>
+#include <pdh.h>
+#include <pdhmsg.h>
static unsigned __int8 buffer[RNG_POOL_SIZE];
static unsigned char *pRandPool = NULL;
@@ -82,15 +84,45 @@ DWORD ProcessedMouseEventsCounter = 0;
CRITICAL_SECTION critRandProt; /* The critical section */
BOOL volatile bThreadTerminate = FALSE; /* This variable is shared among thread's so its made volatile */
-/* Network library handle for the SlowPoll function */
-HANDLE hNetAPI32 = NULL;
-
// CryptoAPI
DWORD CryptoAPILastError = ERROR_SUCCESS;
typedef DWORD (WINAPI *RtlNtStatusToDosError_t)(NTSTATUS);
RtlNtStatusToDosError_t pRtlNtStatusToDosError = NULL;
+static HMODULE hPdhLib = NULL;
+
+typedef PDH_STATUS (WINAPI *PfnPdhOpenQueryW)(LPCWSTR, DWORD_PTR, PDH_HQUERY *);
+typedef PDH_STATUS (WINAPI *PfnPdhAddCounterW)(PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER *);
+typedef PDH_STATUS (WINAPI *PfnPdhCollectQueryData)(PDH_HQUERY);
+typedef PDH_STATUS (WINAPI *PfnPdhGetFormattedCounterValue)(PDH_HCOUNTER, DWORD, LPDWORD, PPDH_FMT_COUNTERVALUE);
+typedef PDH_STATUS (WINAPI *PfnPdhCloseQuery)(PDH_HQUERY);
+
+static PfnPdhOpenQueryW pfnPdhOpenQuery = NULL;
+static PfnPdhAddCounterW pfnPdhAddCounter = NULL;
+static PfnPdhCollectQueryData pfnPdhCollectQueryData = NULL;
+static PfnPdhGetFormattedCounterValue pfnPdhGetFormattedCounterValue = NULL;
+static PfnPdhCloseQuery pfnPdhCloseQuery = NULL;
+
+static BOOL LoadPdhDll()
+{
+ if (!hPdhLib)
+ {
+ hPdhLib = LoadLibraryExW(L"pdh.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (!hPdhLib)
+ return FALSE;
+
+ pfnPdhOpenQuery = (PfnPdhOpenQueryW) GetProcAddress(hPdhLib, "PdhOpenQueryW");
+ pfnPdhAddCounter = (PfnPdhAddCounterW) GetProcAddress(hPdhLib, "PdhAddCounterW");
+ pfnPdhCollectQueryData = (PfnPdhCollectQueryData) GetProcAddress(hPdhLib, "PdhCollectQueryData");
+ pfnPdhGetFormattedCounterValue = (PfnPdhGetFormattedCounterValue) GetProcAddress(hPdhLib, "PdhGetFormattedCounterValue");
+ pfnPdhCloseQuery = (PfnPdhCloseQuery) GetProcAddress(hPdhLib, "PdhCloseQuery");
+ }
+
+ return (pfnPdhOpenQuery && pfnPdhAddCounter && pfnPdhCollectQueryData &&
+ pfnPdhGetFormattedCounterValue && pfnPdhCloseQuery);
+}
+
/* Init the random number generator, setup the hooks, and start the thread */
int RandinitWithCheck ( int* pAlreadyInitialized)
{
@@ -191,12 +223,6 @@ void RandStop (BOOL freePool)
if (PeriodicFastPollThreadHandle)
WaitForSingleObject (PeriodicFastPollThreadHandle, INFINITE);
- if (hNetAPI32 != 0)
- {
- FreeLibrary (hNetAPI32);
- hNetAPI32 = NULL;
- }
-
hMouse = NULL;
hKeyboard = NULL;
@@ -254,7 +280,7 @@ BOOL Randmix ()
if (bRandmixEnabled)
{
unsigned char hashOutputBuffer [MAX_DIGESTSIZE];
- #ifndef WOLFCRYPT_BACKEND
+ #ifndef WOLFCRYPT_BACKEND
WHIRLPOOL_CTX wctx;
blake2s_state bctx;
STREEBOG_CTX stctx;
@@ -273,11 +299,11 @@ BOOL Randmix ()
digestSize = SHA256_DIGESTSIZE;
break;
- #ifndef WOLFCRYPT_BACKEND
+ #ifndef WOLFCRYPT_BACKEND
case BLAKE2S:
digestSize = BLAKE2S_DIGESTSIZE;
break;
-
+
case WHIRLPOOL:
digestSize = WHIRLPOOL_DIGESTSIZE;
break;
@@ -640,142 +666,192 @@ static unsigned __stdcall PeriodicFastPollThreadProc (void *dummy)
}
}
-/* Type definitions for function pointers to call NetAPI32 functions */
-typedef
- DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
- DWORD dwLevel, DWORD dwOptions,
- LPBYTE * lpBuffer);
-typedef
- DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
-typedef
- DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
+/* -------------------------------------------------------------------------------------
+ GetDiskStatistics: This function uses the Windows Performance Data Helper (PDH) API
+ to collect disk statistics. The function collects the number of disk reads and writes
+ per second for all physical disks. The function also collects high-resolution
+ timestamps before and after the PDH query. The function then adds the collected data
+ to the random pool.
+ The code waits a short random interval between the two PDH samples to ensures that
+ the performance counters have time to accumulate measurable changes and produce more
+ varied data.
+ -------------------------------------------------------------------------------------
-NETSTATISTICSGET pNetStatisticsGet = NULL;
-NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
-NETAPIBUFFERFREE pNetApiBufferFree = NULL;
+*/
+void GetDiskStatistics()
+{
+ if (!LoadPdhDll())
+ return;
+ PDH_STATUS status;
+ PDH_HQUERY query = NULL;
+ PDH_HCOUNTER counterReads = NULL, counterWrites = NULL;
+ PDH_FMT_COUNTERVALUE counterValue;
+ DWORD dwType;
+ LONGLONG llReads = 0, llWrites = 0;
+ DWORDLONG tstampBefore = 0, tstampAfter = 0;
+ LARGE_INTEGER perfCounterBefore, perfCounterAfter;
+
+ // High-resolution timestamps
+ if (!QueryPerformanceCounter(&perfCounterBefore))
+ return;
+ tstampBefore = GetTickCount64();
+
+ // Open PDH query
+ status = pfnPdhOpenQuery(NULL, 0, &query);
+ if (status != ERROR_SUCCESS)
+ goto error;
+
+ // Add counters for disk reads and writes (all physical disks).
+ status = pfnPdhAddCounter(query, L"\\PhysicalDisk(*)\\Disk Reads/sec", 0, &counterReads);
+ if (status != ERROR_SUCCESS)
+ goto error;
+
+ status = pfnPdhAddCounter(query, L"\\PhysicalDisk(*)\\Disk Writes/sec", 0, &counterWrites);
+ if (status != ERROR_SUCCESS)
+ goto error;
+
+ // First sample
+ status = pfnPdhCollectQueryData(query);
+ if (status != ERROR_SUCCESS)
+ goto error;
+
+ // Wait a short random interval
+ Sleep(10 + (GetCurrentProcessId() % 40));
+
+ // Second sample
+ status = pfnPdhCollectQueryData(query);
+ if (status != ERROR_SUCCESS)
+ goto error;
+
+ // Format counters in PDH_FMT_LARGE
+ status = pfnPdhGetFormattedCounterValue(counterReads, PDH_FMT_LARGE, &dwType, &counterValue);
+ if (status == ERROR_SUCCESS)
+ llReads = counterValue.largeValue;
+
+ status = pfnPdhGetFormattedCounterValue(counterWrites, PDH_FMT_LARGE, &dwType, &counterValue);
+ if (status == ERROR_SUCCESS)
+ llWrites = counterValue.largeValue;
+
+ // Another high-resolution timestamp
+ if (!QueryPerformanceCounter(&perfCounterAfter))
+ goto error;
+ tstampAfter = GetTickCount64();
+ // Close PDH query
+ pfnPdhCloseQuery(query);
+ query = NULL;
-/* This is the slowpoll function which gathers up network/hard drive
- performance data for the random pool */
-BOOL SlowPoll (void)
+ // Collect results into the random pool
+ RandaddBuf(&llReads, sizeof(llReads));
+ RandaddBuf(&llWrites, sizeof(llWrites));
+ RandaddBuf(&tstampBefore, sizeof(tstampBefore));
+ RandaddBuf(&tstampAfter, sizeof(tstampAfter));
+ RandaddBuf(&perfCounterBefore.QuadPart, sizeof(perfCounterBefore.QuadPart));
+ RandaddBuf(&perfCounterAfter.QuadPart, sizeof(perfCounterAfter.QuadPart));
+
+error:
+ if (query)
+ pfnPdhCloseQuery(query);
+}
+
+
+/* -------------------------------------------------------------------------------------
+ GetNetworkStatistics: This function uses the Windows Performance Data Helper (PDH) API
+ to collect network statistics. The function collects the number of bytes sent and
+ received per second for all network interfaces. The function also collects
+ high-resolution timestamps before and after the PDH query. The function then adds the
+ collected data to the random pool.
+ The code waits a short random interval between the two PDH samples to ensures that
+ the performance counters have time to accumulate measurable changes and produce more
+ varied data.
+*/
+void GetNetworkStatistics()
{
- static int isWorkstation = -1;
- static int cbPerfData = 0x10000;
- HANDLE hDevice;
- LPBYTE lpBuffer;
- DWORD dwSize, status;
- LPWSTR lpszLanW, lpszLanS;
- int nDrive;
- NTSTATUS bStatus = 0;
+ if (!LoadPdhDll())
+ return;
+ PDH_STATUS status;
+ PDH_HQUERY query = NULL;
+ PDH_HCOUNTER counterBytesSent = NULL, counterBytesReceived = NULL;
+ PDH_FMT_COUNTERVALUE counterValue;
+ DWORD dwType;
+ LONGLONG llBytesSent = 0, llBytesReceived = 0;
+ DWORDLONG tstampBefore = 0, tstampAfter = 0;
+ LARGE_INTEGER perfCounterBefore, perfCounterAfter;
+
+ // High-resolution timestamps
+ if (!QueryPerformanceCounter(&perfCounterBefore))
+ return;
+ tstampBefore = GetTickCount64();
- /* Find out whether this is an NT server or workstation if necessary */
- if (isWorkstation == -1)
- {
- HKEY hKey;
+ // Open PDH query
+ status = pfnPdhOpenQuery(NULL, 0, &query);
+ if (status != ERROR_SUCCESS)
+ goto error;
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
- 0, KEY_READ, &hKey) == ERROR_SUCCESS)
- {
- wchar_t szValue[32];
- dwSize = sizeof (szValue);
+ // Add counters for network bytes sent and received
+ status = pfnPdhAddCounter(query, L"\\Network Interface(*)\\Bytes Sent/sec", 0, &counterBytesSent);
+ if (status != ERROR_SUCCESS)
+ goto error;
- isWorkstation = TRUE;
- status = RegQueryValueEx (hKey, L"ProductType", 0, NULL,
- (LPBYTE) szValue, &dwSize);
+ status = pfnPdhAddCounter(query, L"\\Network Interface(*)\\Bytes Received/sec", 0, &counterBytesReceived);
+ if (status != ERROR_SUCCESS)
+ goto error;
- if (status == ERROR_SUCCESS && _wcsicmp (szValue, L"WinNT"))
- /* Note: There are (at least) three cases for
- ProductType: WinNT = NT Workstation,
- ServerNT = NT Server, LanmanNT = NT Server
- acting as a Domain Controller */
- isWorkstation = FALSE;
+ // First sample
+ status = pfnPdhCollectQueryData(query);
+ if (status != ERROR_SUCCESS)
+ goto error;
- RegCloseKey (hKey);
- }
- }
- /* Initialize the NetAPI32 function pointers if necessary */
- if (hNetAPI32 == NULL)
- {
- /* Obtain a handle to the module containing the Lan Manager
- functions */
- wchar_t dllPath[MAX_PATH];
- if (GetSystemDirectory (dllPath, MAX_PATH))
- {
- StringCchCatW(dllPath, ARRAYSIZE(dllPath), L"\\NETAPI32.DLL");
- }
- else
- StringCchCopyW(dllPath, ARRAYSIZE(dllPath), L"C:\\Windows\\System32\\NETAPI32.DLL");
+ // Wait short, dynamic interval
+ Sleep(10 + (GetCurrentProcessId() % 40));
- hNetAPI32 = LoadLibrary (dllPath);
- if (hNetAPI32 != NULL)
- {
- /* Now get pointers to the functions */
- pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
- "NetStatisticsGet");
- pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
- "NetApiBufferSize");
- pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
- "NetApiBufferFree");
-
- /* Make sure we got valid pointers for every NetAPI32
- function */
- if (pNetStatisticsGet == NULL ||
- pNetApiBufferSize == NULL ||
- pNetApiBufferFree == NULL)
- {
- /* Free the library reference and reset the
- static handle */
- FreeLibrary (hNetAPI32);
- hNetAPI32 = NULL;
- }
- }
- }
+ // Second sample
+ status = pfnPdhCollectQueryData(query);
+ if (status != ERROR_SUCCESS)
+ goto error;
- /* Get network statistics. Note: Both NT Workstation and NT Server
- by default will be running both the workstation and server
- services. The heuristic below is probably useful though on the
- assumption that the majority of the network traffic will be via
- the appropriate service */
- lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
- lpszLanS = (LPWSTR) WIDE ("LanmanServer");
- if (hNetAPI32 &&
- pNetStatisticsGet (NULL,
- isWorkstation ? lpszLanW : lpszLanS,
- 0, 0, &lpBuffer) == 0)
- {
- pNetApiBufferSize (lpBuffer, &dwSize);
- RandaddBuf ((unsigned char *) lpBuffer, dwSize);
- pNetApiBufferFree (lpBuffer);
- }
+ // Format counters
+ status = pfnPdhGetFormattedCounterValue(counterBytesSent, PDH_FMT_LARGE, &dwType, &counterValue);
+ if (status == ERROR_SUCCESS)
+ llBytesSent = counterValue.largeValue;
- /* Get disk I/O statistics for all the hard drives */
- for (nDrive = 0;; nDrive++)
- {
- DISK_PERFORMANCE diskPerformance;
- wchar_t szDevice[24];
-
- /* Check whether we can access this device */
- StringCchPrintfW (szDevice, ARRAYSIZE(szDevice), L"\\\\.\\PhysicalDrive%d", nDrive);
- hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, 0, NULL);
- if (hDevice == INVALID_HANDLE_VALUE)
- break;
+ status = pfnPdhGetFormattedCounterValue(counterBytesReceived, PDH_FMT_LARGE, &dwType, &counterValue);
+ if (status == ERROR_SUCCESS)
+ llBytesReceived = counterValue.largeValue;
+ if (!QueryPerformanceCounter(&perfCounterAfter))
+ goto error;
+ tstampAfter = GetTickCount64();
- /* Note: This only works if you have turned on the disk
- performance counters with 'diskperf -y'. These counters
- are off by default */
- if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
- &diskPerformance, sizeof (DISK_PERFORMANCE),
- &dwSize, NULL))
- {
- RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
- }
- CloseHandle (hDevice);
- }
+ // Close PDH query
+ pfnPdhCloseQuery(query);
+ query = NULL;
+ // Collect results into our random pool
+ RandaddBuf(&llBytesSent, sizeof(llBytesSent));
+ RandaddBuf(&llBytesReceived, sizeof(llBytesReceived));
+ RandaddBuf(&tstampBefore, sizeof(tstampBefore));
+ RandaddBuf(&tstampAfter, sizeof(tstampAfter));
+ RandaddBuf(&perfCounterBefore.QuadPart, sizeof(perfCounterBefore.QuadPart));
+ RandaddBuf(&perfCounterAfter.QuadPart, sizeof(perfCounterAfter.QuadPart));
+
+error:
+ if (query)
+ pfnPdhCloseQuery(query);
+}
+
+/* This is the slowpoll function which gathers up network/hard drive
+ performance data for the random pool */
+BOOL SlowPoll (void)
+{
+ NTSTATUS bStatus = 0;
+
+ // Gather disk stats via PDH
+ GetDiskStatistics();
+
+ // Gather network stats via PDH
+ GetNetworkStatistics();
bStatus = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (NT_SUCCESS(bStatus))
@@ -803,7 +879,7 @@ BOOL SlowPoll (void)
}
// use RDSEED or RDRAND from CPU as source of entropy if present
- if ( IsCpuRngEnabled() &&
+ if ( IsCpuRngEnabled() &&
( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer)))
|| (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer)))
))
@@ -812,6 +888,8 @@ BOOL SlowPoll (void)
}
burn(buffer, sizeof (buffer));
+
+ /* Mix the pool */
Randmix();
return TRUE;
@@ -934,7 +1012,7 @@ BOOL FastPoll (void)
}
// use RDSEED or RDRAND from CPU as source of entropy if enabled
- if ( IsCpuRngEnabled() &&
+ if ( IsCpuRngEnabled() &&
( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer)))
|| (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer)))
))
diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h
index 0051dba2..48fc12b6 100644
--- a/src/Common/Tcdefs.h
+++ b/src/Common/Tcdefs.h
@@ -261,7 +261,7 @@ void ThrowFatalException(int line);
extern ULONG AllocTag;
-#define TCalloc(size) ((void *) ExAllocatePool2( POOL_FLAG_NON_PAGED, size, AllocTag ))
+#define TCalloc(size) ((void *) ExAllocatePoolUninitialized( NonPagedPoolNx , size, AllocTag ))
#define TCfree(memblock) ExFreePoolWithTag( memblock, AllocTag )
#define DEVICE_DRIVER
diff --git a/src/Common/Zip.vcxproj b/src/Common/Zip.vcxproj
index 6674ef34..a8fbf1eb 100644
--- a/src/Common/Zip.vcxproj
+++ b/src/Common/Zip.vcxproj
@@ -114,6 +114,7 @@
<ClCompile Include="libzip\zip_source_file_win32_utf8.c" />
<ClCompile Include="libzip\zip_source_free.c" />
<ClCompile Include="libzip\zip_source_function.c" />
+ <ClCompile Include="libzip\zip_source_get_dostime.c" />
<ClCompile Include="libzip\zip_source_get_file_attributes.c" />
<ClCompile Include="libzip\zip_source_is_deleted.c" />
<ClCompile Include="libzip\zip_source_layered.c" />
diff --git a/src/Common/Zip.vcxproj.filters b/src/Common/Zip.vcxproj.filters
index 92bcf493..eb88a358 100644
--- a/src/Common/Zip.vcxproj.filters
+++ b/src/Common/Zip.vcxproj.filters
@@ -399,6 +399,9 @@
<ClCompile Include="libzip\zip_source_pass_to_lower_layer.c">
<Filter>zlib</Filter>
</ClCompile>
+ <ClCompile Include="libzip\zip_source_get_dostime.c">
+ <Filter>libzip</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="libzip\compat.h">
diff --git a/src/Common/libzip/NEWS.md b/src/Common/libzip/NEWS.md
index e117422d..d2b1e73d 100644
--- a/src/Common/libzip/NEWS.md
+++ b/src/Common/libzip/NEWS.md
@@ -1,3 +1,20 @@
+# 1.11.2 [2024-10-31]
+
+* Fix performance regression in `zip_stat` introduced in 1.11.
+
+# 1.11.1 [2024-09-19]
+
+* Fix zipconf.h for version number with missing third component.
+
+# 1.11 [2024-09-19]
+
+* Stop searching after finding acceptable central directory, even if it contains inconsistencies.
+* Only write Zip64 EOCD if fields don't fit in normal EOCD. Previously libzip also wrote it when any directory entry required Zip64.
+* Allow bytes from 0x00-0x1F as UTF-8.
+* Add new error code `ZIP_ER_TRUNCATED_ZIP` for files that start with a valid local header signature.
+* `zipcmp`: add `-T` option for comparing timestamps.
+* `zip_file_replace` now removes the target's extra field information.
+
# 1.10.1 [2023-08-23]
* Add `ZIP_LENGTH_TO_END` and `ZIP_LENGTH_UNCHECKED`. Unless `ZIP_LENGTH_UNCHECKED` is used as `length`, it is an error for a file to shrink between the time when the source is created and when its data is read.
diff --git a/src/Common/libzip/compat.h b/src/Common/libzip/compat.h
index 296ee59e..2cbc19f8 100644
--- a/src/Common/libzip/compat.h
+++ b/src/Common/libzip/compat.h
@@ -3,7 +3,7 @@
/*
compat.h -- compatibility defines.
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -126,14 +126,65 @@ typedef char bool;
#endif
#endif
-#ifndef HAVE_FSEEKO
-#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
+
+#if defined(HAVE__FSEEKI64) && defined(HAVE__FSTAT64) && defined(HAVE__FTELLI64)
+/* Windows API using int64 */
+typedef zip_int64_t zip_off_t;
+typedef struct _stat64 zip_os_stat_t;
+#define zip_os_stat _stat64
+#define zip_os_fstat _fstat64
+#define zip_os_fseek _fseeki64
+#define zip_os_ftell _ftelli64
+#define ZIP_FSEEK_MAX ZIP_INT64_MAX
+#define ZIP_FSEEK_MIN ZIP_INT64_MIN
+#else
+
+/* Normal API */
+#include <sys/stat.h>
+typedef struct stat zip_os_stat_t;
+#define zip_os_fstat fstat
+#define zip_os_stat stat
+
+#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
+/* Using off_t */
+typedef off_t zip_off_t;
+#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
+
+#define ZIP_FSEEK_MAX ZIP_OFF_MAX
+#define ZIP_FSEEK_MIN ZIP_OFF_MIN
+
+#define zip_os_fseek fseeko
+#define zip_os_ftell ftello
+#else
+
+/* Using long */
+typedef long zip_off_t;
+#include <limits.h>
+#define ZIP_FSEEK_MAX LONG_MAX
+#define ZIP_FSEEK_MIN LONG_MIN
+
+#define zip_os_fseek fseek
+#define zip_os_ftell ftell
+#endif
+
#endif
#ifndef HAVE_FTELLO
#define ftello(s) ((long)ftell((s)))
#endif
+
#ifdef HAVE_LOCALTIME_S
#ifdef _WIN32
/* Windows is incompatible to the C11 standard, hurray! */
@@ -182,27 +233,6 @@ typedef char bool;
#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
diff --git a/src/Common/libzip/config.h b/src/Common/libzip/config.h
index 2976249c..5edc625f 100644
--- a/src/Common/libzip/config.h
+++ b/src/Common/libzip/config.h
@@ -10,6 +10,9 @@
#define HAVE__DUP
#define HAVE__FDOPEN
#define HAVE__FILENO
+#define HAVE__FSEEKI64
+#define HAVE__FSTAT64
+#define HAVE__FTELLI64
#define HAVE__SETMODE
#if defined(_MSC_VER) && _MSC_VER < 1900
#define HAVE__SNPRINTF
@@ -18,6 +21,7 @@
#endif
#define HAVE__SNPRINTF_S
#define HAVE__SNWPRINTF_S
+#define HAVE__STAT64
#define HAVE__STRDUP
#define HAVE__STRICMP
#define HAVE__STRTOI64
@@ -88,6 +92,6 @@
#define HAVE_SHARED
/* END DEFINES */
#define PACKAGE "libzip"
-#define VERSION "1.10.1"
+#define VERSION "1.11.2"
#endif /* HAD_CONFIG_H */
diff --git a/src/Common/libzip/zip.h b/src/Common/libzip/zip.h
index dc3751c8..da57ea56 100644
--- a/src/Common/libzip/zip.h
+++ b/src/Common/libzip/zip.h
@@ -3,7 +3,7 @@
/*
zip.h -- exported declarations.
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -158,6 +158,7 @@ extern "C" {
#define ZIP_ER_CANCELLED 32 /* N Operation cancelled */
#define ZIP_ER_DATA_LENGTH 33 /* N Unexpected length of data */
#define ZIP_ER_NOT_ALLOWED 34 /* N Not allowed in torrentzip */
+#define ZIP_ER_TRUNCATED_ZIP 35 /* N Possibly truncated or corrupted zip archive */
/* type of system error value */
@@ -260,7 +261,8 @@ enum zip_source_cmd {
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 */
- ZIP_SOURCE_SUPPORTS_REOPEN /* allow reading from changed entry */
+ ZIP_SOURCE_SUPPORTS_REOPEN, /* allow reading from changed entry */
+ ZIP_SOURCE_GET_DOS_TIME /* get last modification time in DOS format */
};
typedef enum zip_source_cmd zip_source_cmd_t;
diff --git a/src/Common/libzip/zip_add.c b/src/Common/libzip/zip_add.c
index 9770139d..a426a579 100644
--- a/src/Common/libzip/zip_add.c
+++ b/src/Common/libzip/zip_add.c
@@ -1,6 +1,6 @@
/*
zip_add.c -- add file via callback function
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_add_dir.c b/src/Common/libzip/zip_add_dir.c
index c31fea36..2faaa1a6 100644
--- a/src/Common/libzip/zip_add_dir.c
+++ b/src/Common/libzip/zip_add_dir.c
@@ -1,6 +1,6 @@
/*
zip_add_dir.c -- add directory
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_add_entry.c b/src/Common/libzip/zip_add_entry.c
index bf12dd54..e8beaa81 100644
--- a/src/Common/libzip/zip_add_entry.c
+++ b/src/Common/libzip/zip_add_entry.c
@@ -1,6 +1,6 @@
/*
zip_add_entry.c -- create and init struct zip_entry
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -64,7 +64,7 @@ _zip_add_entry(zip_t *za) {
return -1;
}
rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc);
- if (!rentries) {
+ if (rentries == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
diff --git a/src/Common/libzip/zip_algorithm_bzip2.c b/src/Common/libzip/zip_algorithm_bzip2.c
index f25be143..1818039e 100644
--- a/src/Common/libzip/zip_algorithm_bzip2.c
+++ b/src/Common/libzip/zip_algorithm_bzip2.c
@@ -1,6 +1,6 @@
/*
zip_algorithm_bzip2.c -- bzip2 (de)compression routines
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_algorithm_deflate.c b/src/Common/libzip/zip_algorithm_deflate.c
index 3c85e204..5ab879df 100644
--- a/src/Common/libzip/zip_algorithm_deflate.c
+++ b/src/Common/libzip/zip_algorithm_deflate.c
@@ -1,6 +1,6 @@
/*
zip_algorithm_deflate.c -- deflate (de)compression routines
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_algorithm_xz.c b/src/Common/libzip/zip_algorithm_xz.c
index d7a7142d..b0413e01 100644
--- a/src/Common/libzip/zip_algorithm_xz.c
+++ b/src/Common/libzip/zip_algorithm_xz.c
@@ -1,7 +1,7 @@
/*
zip_algorithm_xz.c -- LZMA/XZ (de)compression routines
Bazed on zip_algorithm_deflate.c -- deflate (de)compression routines
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_algorithm_zstd.c b/src/Common/libzip/zip_algorithm_zstd.c
index d005da9d..b2aa2132 100644
--- a/src/Common/libzip/zip_algorithm_zstd.c
+++ b/src/Common/libzip/zip_algorithm_zstd.c
@@ -1,6 +1,6 @@
/*
zip_algorithm_zstd.c -- zstd (de)compression routines
- Copyright (C) 2020-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2020-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_buffer.c b/src/Common/libzip/zip_buffer.c
index e2103f04..de22bab1 100644
--- a/src/Common/libzip/zip_buffer.c
+++ b/src/Common/libzip/zip_buffer.c
@@ -1,6 +1,6 @@
/*
zip_buffer.c -- bounds checked access to memory buffer
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -306,8 +306,7 @@ _zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) {
}
-int
-_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
+int _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
if (offset > buffer->size) {
buffer->ok = false;
return -1;
diff --git a/src/Common/libzip/zip_close.c b/src/Common/libzip/zip_close.c
index ddc2c245..4313592c 100644
--- a/src/Common/libzip/zip_close.c
+++ b/src/Common/libzip/zip_close.c
@@ -1,6 +1,6 @@
/*
zip_close.c -- close zip archive and update changes
- Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -44,7 +44,7 @@
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 copy_source(zip_t *, zip_source_t *, zip_source_t *, zip_int64_t);
static int torrentzip_compare_names(const void *a, const void *b);
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);
@@ -468,11 +468,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
/* PKWare encryption uses last_mod, make sure it gets the right value. */
if (de->changed & ZIP_DIRENT_LAST_MOD) {
- zip_stat_t st_mtime;
- zip_stat_init(&st_mtime);
- st_mtime.valid = ZIP_STAT_MTIME;
- st_mtime.mtime = de->last_mod;
- if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, 0, NULL, NULL, 0, true, &za->error)) == NULL) {
+ if ((src_tmp = _zip_source_window_new(src_final, 0, -1, NULL, 0, NULL, &de->last_mod, NULL, 0, true, &za->error)) == NULL) {
zip_source_free(src_final);
return -1;
}
@@ -495,7 +491,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
return -1;
}
- ret = copy_source(za, src_final, data_length);
+ ret = copy_source(za, src_final, src, data_length);
if (zip_source_stat(src_final, &st) < 0) {
zip_error_set_from_source(&za->error, src_final);
@@ -529,10 +525,23 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
}
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
- if (st.valid & ZIP_STAT_MTIME)
- de->last_mod = st.mtime;
- else
- time(&de->last_mod);
+ int ret2 = zip_source_get_dos_time(src, &de->last_mod);
+ if (ret2 < 0) {
+ zip_error_set_from_source(&za->error, src);
+ return -1;
+ }
+ if (ret2 == 0) {
+ time_t mtime;
+ if (st.valid & ZIP_STAT_MTIME) {
+ mtime = st.mtime;
+ }
+ else {
+ time(&mtime);
+ }
+ if (_zip_u2d_time(mtime, &de->last_mod, &za->error) < 0) {
+ return -1;
+ }
+ }
}
de->comp_method = st.comp_method;
de->crc = st.crc;
@@ -605,7 +614,7 @@ copy_data(zip_t *za, zip_uint64_t len) {
static int
-copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
+copy_source(zip_t *za, zip_source_t *src, zip_source_t *src_for_length, zip_int64_t data_length) {
DEFINE_BYTE_ARRAY(buf, BUFSIZE);
zip_int64_t n, current;
int ret;
@@ -628,7 +637,13 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
break;
}
if (n == BUFSIZE && za->progress && data_length > 0) {
- current += n;
+ zip_int64_t t;
+ t = zip_source_tell(src_for_length);
+ if (t >= 0) {
+ current = t;
+ } else {
+ 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;
@@ -742,4 +757,4 @@ static int torrentzip_compare_names(const void *a, const void *b) {
}
return strcasecmp(aname, bname);
-} \ No newline at end of file
+}
diff --git a/src/Common/libzip/zip_crypto.h b/src/Common/libzip/zip_crypto.h
index 0d74d1a4..805af52f 100644
--- a/src/Common/libzip/zip_crypto.h
+++ b/src/Common/libzip/zip_crypto.h
@@ -1,6 +1,6 @@
/*
zip_crypto.h -- crypto definitions
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_crypto_commoncrypto.c b/src/Common/libzip/zip_crypto_commoncrypto.c
index b198be56..e6cb72d3 100644
--- a/src/Common/libzip/zip_crypto_commoncrypto.c
+++ b/src/Common/libzip/zip_crypto_commoncrypto.c
@@ -1,6 +1,6 @@
/*
zip_crypto_commoncrypto.c -- CommonCrypto wrapper.
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_crypto_commoncrypto.h b/src/Common/libzip/zip_crypto_commoncrypto.h
index 01828cc6..82dafdb4 100644
--- a/src/Common/libzip/zip_crypto_commoncrypto.h
+++ b/src/Common/libzip/zip_crypto_commoncrypto.h
@@ -1,6 +1,6 @@
/*
zip_crypto_commoncrypto.h -- definitions for CommonCrypto wrapper.
- Copyright (C) 2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_crypto_gnutls.c b/src/Common/libzip/zip_crypto_gnutls.c
index 1a25aa12..fcc7fdfd 100644
--- a/src/Common/libzip/zip_crypto_gnutls.c
+++ b/src/Common/libzip/zip_crypto_gnutls.c
@@ -1,6 +1,6 @@
/*
zip_crypto_gnutls.c -- GnuTLS wrapper.
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_crypto_gnutls.h b/src/Common/libzip/zip_crypto_gnutls.h
index dc8b97a4..a6fa508a 100644
--- a/src/Common/libzip/zip_crypto_gnutls.h
+++ b/src/Common/libzip/zip_crypto_gnutls.h
@@ -1,6 +1,6 @@
/*
zip_crypto_gnutls.h -- definitions for GnuTLS wrapper.
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_crypto_mbedtls.c b/src/Common/libzip/zip_crypto_mbedtls.c
index 84544a82..0ed66c0d 100644
--- a/src/Common/libzip/zip_crypto_mbedtls.c
+++ b/src/Common/libzip/zip_crypto_mbedtls.c
@@ -1,6 +1,6 @@
/*
zip_crypto_mbedtls.c -- mbed TLS wrapper
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_crypto_mbedtls.h b/src/Common/libzip/zip_crypto_mbedtls.h
index 1151fff7..30ce21c9 100644
--- a/src/Common/libzip/zip_crypto_mbedtls.h
+++ b/src/Common/libzip/zip_crypto_mbedtls.h
@@ -1,6 +1,6 @@
/*
zip_crypto_mbedtls.h -- definitions for mbedtls wrapper
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_crypto_openssl.c b/src/Common/libzip/zip_crypto_openssl.c
index 7f1da10e..9e9e8e7c 100644
--- a/src/Common/libzip/zip_crypto_openssl.c
+++ b/src/Common/libzip/zip_crypto_openssl.c
@@ -1,6 +1,6 @@
/*
zip_crypto_openssl.c -- OpenSSL wrapper.
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -126,8 +126,9 @@ _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) {
- int len;
- if (EVP_EncryptUpdate(aes, out, &len, in, ZIP_CRYPTO_AES_BLOCK_LENGTH) != 1) {
+ int len = 0;
+ if (EVP_EncryptUpdate(aes, out, &len, in, ZIP_CRYPTO_AES_BLOCK_LENGTH) != 1
+ || len != ZIP_CRYPTO_AES_BLOCK_LENGTH) {
return false;
}
return true;
@@ -214,11 +215,11 @@ _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
bool
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
#ifdef USE_OPENSSL_3_API
- size_t length;
+ size_t length = 0;
return EVP_MAC_final(hmac->ctx, data, &length, ZIP_CRYPTO_SHA1_LENGTH) == 1 && length == ZIP_CRYPTO_SHA1_LENGTH;
#else
- unsigned int length;
- return HMAC_Final(hmac, data, &length) == 1;
+ unsigned int length = 0;
+ return HMAC_Final(hmac, data, &length) == 1 && length == ZIP_CRYPTO_SHA1_LENGTH;
#endif
}
diff --git a/src/Common/libzip/zip_crypto_openssl.h b/src/Common/libzip/zip_crypto_openssl.h
index 198a9071..e593ec55 100644
--- a/src/Common/libzip/zip_crypto_openssl.h
+++ b/src/Common/libzip/zip_crypto_openssl.h
@@ -1,6 +1,6 @@
/*
zip_crypto_openssl.h -- definitions for OpenSSL wrapper.
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_crypto_win.c b/src/Common/libzip/zip_crypto_win.c
index ee3ccc30..6d923038 100644
--- a/src/Common/libzip/zip_crypto_win.c
+++ b/src/Common/libzip/zip_crypto_win.c
@@ -1,6 +1,6 @@
/*
zip_crypto_win.c -- Windows Crypto API wrapper.
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -37,9 +37,6 @@
#include "zip_crypto.h"
-#define WIN32_LEAN_AND_MEAN
-#define NOCRYPT
-
#include <windows.h>
#include <bcrypt.h>
diff --git a/src/Common/libzip/zip_crypto_win.h b/src/Common/libzip/zip_crypto_win.h
index a533fe2d..3f05b621 100644
--- a/src/Common/libzip/zip_crypto_win.h
+++ b/src/Common/libzip/zip_crypto_win.h
@@ -1,6 +1,6 @@
/*
zip_crypto_win.h -- Windows Crypto API wrapper.
- Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_delete.c b/src/Common/libzip/zip_delete.c
index 676c16bf..4eefdd97 100644
--- a/src/Common/libzip/zip_delete.c
+++ b/src/Common/libzip/zip_delete.c
@@ -1,6 +1,6 @@
/*
zip_delete.c -- delete file from zip archive
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_dir_add.c b/src/Common/libzip/zip_dir_add.c
index c0108191..01d8ec9d 100644
--- a/src/Common/libzip/zip_dir_add.c
+++ b/src/Common/libzip/zip_dir_add.c
@@ -1,6 +1,6 @@
/*
zip_dir_add.c -- add directory
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_dirent.c b/src/Common/libzip/zip_dirent.c
index 45a2a6a2..24bc6abf 100644
--- a/src/Common/libzip/zip_dirent.c
+++ b/src/Common/libzip/zip_dirent.c
@@ -1,6 +1,6 @@
/*
zip_dirent.c -- read directory entry (local or central), clean dirent
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -41,7 +41,7 @@
#include "zipint.h"
-static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
+static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str, bool check_consistency);
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);
@@ -50,8 +50,9 @@ void
_zip_cdir_free(zip_cdir_t *cd) {
zip_uint64_t i;
- if (!cd)
+ if (cd == NULL) {
return;
+ }
for (i = 0; i < cd->nentry; i++)
_zip_entry_finalize(cd->entry + i);
@@ -62,7 +63,7 @@ _zip_cdir_free(zip_cdir_t *cd) {
zip_cdir_t *
-_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) {
+_zip_cdir_new(zip_error_t *error) {
zip_cdir_t *cd;
if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
@@ -76,11 +77,6 @@ _zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) {
cd->comment = NULL;
cd->is_zip64 = false;
- if (!_zip_cdir_grow(cd, nentry, error)) {
- _zip_cdir_free(cd);
- return NULL;
- }
-
return cd;
}
@@ -126,8 +122,6 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
zip_buffer_t *buffer;
zip_int64_t off;
zip_uint64_t i;
- bool is_zip64;
- int ret;
zip_uint32_t cdir_crc;
if ((off = zip_source_tell_write(za->src)) < 0) {
@@ -136,8 +130,6 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
}
offset = (zip_uint64_t)off;
- is_zip64 = false;
-
if (ZIP_WANT_TORRENTZIP(za)) {
cdir_crc = (zip_uint32_t)crc32(0, NULL, 0);
za->write_crc = &cdir_crc;
@@ -146,10 +138,10 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
for (i = 0; i < survivors; i++) {
zip_entry_t *entry = za->entry + filelist[i].idx;
- if ((ret = _zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0)
+ if (_zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL) < 0) {
+ za->write_crc = NULL;
return -1;
- if (ret)
- is_zip64 = true;
+ }
}
za->write_crc = NULL;
@@ -160,16 +152,12 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor
}
size = (zip_uint64_t)off - offset;
- if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) {
- is_zip64 = true;
- }
-
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
- if (is_zip64) {
+ if (survivors > ZIP_UINT16_MAX || offset > ZIP_UINT32_MAX || size > ZIP_UINT32_MAX) {
_zip_buffer_put(buffer, EOCD64_MAGIC, 4);
_zip_buffer_put_64(buffer, EOCD64LEN - 12);
_zip_buffer_put_16(buffer, 45);
@@ -294,11 +282,13 @@ _zip_dirent_init(zip_dirent_t *de) {
de->cloned = 0;
de->crc_valid = true;
+ de->last_mod_mtime_valid = false;
de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8);
de->version_needed = 10; /* 1.0 */
de->bitflags = 0;
de->comp_method = ZIP_CM_DEFAULT;
- de->last_mod = 0;
+ de->last_mod.date = 0;
+ de->last_mod.time = 0;
de->crc = 0;
de->comp_size = 0;
de->uncomp_size = 0;
@@ -336,7 +326,7 @@ _zip_dirent_new(void) {
}
-/* _zip_dirent_read(zde, fp, bufp, left, localp, error):
+/*
Fills the zip directory entry zde.
If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.
@@ -347,11 +337,12 @@ _zip_dirent_new(void) {
*/
zip_int64_t
-_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error) {
+_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_uint64_t central_compressed_size, bool check_consistency, zip_error_t *error) {
zip_uint8_t buf[CDENTRYSIZE];
- zip_uint16_t dostime, dosdate;
zip_uint32_t size, variable_size;
zip_uint16_t filename_len, comment_len, ef_len;
+ zip_string_t *utf8_string;
+ bool is_zip64 = false;
bool from_buffer = (buffer != NULL);
@@ -389,9 +380,8 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
zde->comp_method = _zip_buffer_get_16(buffer);
/* convert to time_t */
- dostime = _zip_buffer_get_16(buffer);
- dosdate = _zip_buffer_get_16(buffer);
- zde->last_mod = _zip_d2u_time(dostime, dosdate);
+ zde->last_mod.time = _zip_buffer_get_16(buffer);
+ zde->last_mod.date = _zip_buffer_get_16(buffer);
zde->crc = _zip_buffer_get_32(buffer);
zde->comp_size = _zip_buffer_get_32(buffer);
@@ -458,7 +448,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
if (filename_len) {
zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
- if (!zde->filename) {
+ if (zde->filename == NULL) {
if (zip_error_code_zip(error) == ZIP_ER_EOF) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW);
}
@@ -502,7 +492,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
if (comment_len) {
zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
- if (!zde->comment) {
+ if (zde->comment == NULL) {
if (!from_buffer) {
_zip_buffer_free(buffer);
}
@@ -519,8 +509,24 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
}
}
- zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
- zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
+ if ((utf8_string = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename, check_consistency)) == NULL && zde->filename != NULL) {
+ zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_UTF8_FILENAME_MISMATCH);
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
+ }
+ zde->filename = utf8_string;
+ if (!local) {
+ if ((utf8_string = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment, check_consistency)) == NULL && zde->comment != NULL) {
+ zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_UTF8_COMMENT_MISMATCH);
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
+ }
+ zde->comment = utf8_string;
+ }
/* Zip64 */
@@ -535,6 +541,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1;
}
}
+ is_zip64 = true;
}
@@ -545,10 +552,40 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
}
return -1;
}
+
if (!from_buffer) {
_zip_buffer_free(buffer);
}
+ if (local && zde->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
+ zip_uint32_t df_crc;
+ zip_uint64_t df_comp_size, df_uncomp_size;
+ if (zip_source_seek(src, central_compressed_size, SEEK_CUR) != 0 || (buffer = _zip_buffer_new_from_source(src, MAX_DATA_DESCRIPTOR_LENGTH, buf, error)) == NULL) {
+ return -1;
+ }
+ if (memcmp(_zip_buffer_peek(buffer, MAGIC_LEN), DATADES_MAGIC, MAGIC_LEN) == 0) {
+ _zip_buffer_skip(buffer, MAGIC_LEN);
+ }
+ df_crc = _zip_buffer_get_32(buffer);
+ df_comp_size = is_zip64 ? _zip_buffer_get_64(buffer) : _zip_buffer_get_32(buffer);
+ df_uncomp_size = is_zip64 ? _zip_buffer_get_64(buffer) : _zip_buffer_get_32(buffer);
+
+ if (!_zip_buffer_ok(buffer)) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ _zip_buffer_free(buffer);
+ return -1;
+ }
+ _zip_buffer_free(buffer);
+
+ if ((zde->crc != 0 && zde->crc != df_crc) || (zde->comp_size != 0 && zde->comp_size != df_comp_size) || (zde->uncomp_size != 0 && zde->uncomp_size != df_uncomp_size)) {
+ zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_DATA_DESCRIPTOR_MISMATCH);
+ return -1;
+ }
+ zde->crc = df_crc;
+ zde->comp_size = df_comp_size;
+ zde->uncomp_size = df_uncomp_size;
+ }
+
/* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
if (zde->offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
@@ -564,7 +601,8 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return (zip_int64_t)size + (zip_int64_t)variable_size;
}
-bool zip_dirent_process_ef_zip64(zip_dirent_t* zde, const zip_uint8_t* ef, zip_uint64_t got_len, bool local, zip_error_t* error) {
+bool
+zip_dirent_process_ef_zip64(zip_dirent_t *zde, const zip_uint8_t *ef, zip_uint64_t got_len, bool local, zip_error_t *error) {
zip_buffer_t *ef_buffer;
if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
@@ -625,7 +663,7 @@ bool zip_dirent_process_ef_zip64(zip_dirent_t* zde, const zip_uint8_t* ef, zip_u
static zip_string_t *
-_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) {
+_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str, bool check_consistency) {
zip_uint16_t ef_len;
zip_uint32_t ef_crc;
zip_buffer_t *buffer;
@@ -648,6 +686,14 @@ _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string
zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);
if (ef_str != NULL) {
+ if (check_consistency) {
+ if (!_zip_string_equal(str, ef_str) && _zip_string_is_ascii(ef_str)) {
+ _zip_string_free(ef_str);
+ _zip_buffer_free(buffer);
+ return NULL;
+ }
+ }
+
_zip_string_free(str);
str = ef_str;
}
@@ -688,18 +734,18 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
crc_valid = true;
switch (_zip_buffer_get_16(buffer)) {
- case 1:
- break;
+ case 1:
+ break;
- case 2:
- crc_valid = false;
- /* TODO: When checking consistency, check that crc is 0. */
- break;
-
- default:
- zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
- _zip_buffer_free(buffer);
- return false;
+ case 2:
+ crc_valid = false;
+ /* TODO: When checking consistency, check that crc is 0. */
+ break;
+
+ default:
+ zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
+ _zip_buffer_free(buffer);
+ return false;
}
/* vendor */
@@ -787,7 +833,7 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) {
int
_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
- zip_uint16_t dostime, dosdate;
+ zip_dostime_t dostime;
zip_encoding_type_t com_enc, name_enc;
zip_extra_field_t *ef;
zip_extra_field_t *ef64;
@@ -926,14 +972,14 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
}
if (ZIP_WANT_TORRENTZIP(za)) {
- dostime = 0xbc00;
- dosdate = 0x2198;
+ dostime.time = 0xbc00;
+ dostime.date = 0x2198;
}
else {
- _zip_u2d_time(de->last_mod, &dostime, &dosdate);
+ dostime = de->last_mod;
}
- _zip_buffer_put_16(buffer, dostime);
- _zip_buffer_put_16(buffer, dosdate);
+ _zip_buffer_put_16(buffer, dostime.time);
+ _zip_buffer_put_16(buffer, dostime.date);
if (is_winzip_aes && de->uncomp_size < 20) {
_zip_buffer_put_32(buffer, 0);
@@ -1034,7 +1080,7 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
time_t
-_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) {
+_zip_d2u_time(const zip_dostime_t *dtime) {
struct tm tm;
memset(&tm, 0, sizeof(tm));
@@ -1042,13 +1088,13 @@ _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) {
/* let mktime decide if DST is in effect */
tm.tm_isdst = -1;
- tm.tm_year = ((ddate >> 9) & 127) + 1980 - 1900;
- tm.tm_mon = ((ddate >> 5) & 15) - 1;
- tm.tm_mday = ddate & 31;
+ tm.tm_year = ((dtime->date >> 9) & 127) + 1980 - 1900;
+ tm.tm_mon = ((dtime->date >> 5) & 15) - 1;
+ tm.tm_mday = dtime->date & 31;
- tm.tm_hour = (dtime >> 11) & 31;
- tm.tm_min = (dtime >> 5) & 63;
- tm.tm_sec = (dtime << 1) & 62;
+ tm.tm_hour = (dtime->time >> 11) & 31;
+ tm.tm_min = (dtime->time >> 5) & 63;
+ tm.tm_sec = (dtime->time << 1) & 62;
return mktime(&tm);
}
@@ -1119,23 +1165,28 @@ _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *err
}
-void
-_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
+int
+_zip_u2d_time(time_t intime, zip_dostime_t *dtime, zip_error_t *ze) {
struct tm *tpm;
struct tm tm;
tpm = zip_localtime(&intime, &tm);
if (tpm == NULL) {
/* if localtime fails, return an arbitrary date (1980-01-01 00:00:00) */
- *ddate = (1 << 5) + 1;
- *dtime = 0;
- return;
+ dtime->date = (1 << 5) + 1;
+ dtime->time = 0;
+ if (ze) {
+ zip_error_set(ze, ZIP_ER_INVAL, errno);
+ }
+ return -1;
}
if (tpm->tm_year < 80) {
tpm->tm_year = 80;
}
- *ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
- *dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
+ dtime->date = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
+ dtime->time = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
+
+ return 0;
}
@@ -1192,10 +1243,11 @@ _zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes
Set values suitable for torrentzip.
*/
-void zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
+void
+zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
de->version_madeby = 0;
de->version_needed = 20; /* 2.0 */
- de->bitflags = 2; /* maximum compression */
+ de->bitflags = 2; /* maximum compression */
de->comp_method = ZIP_CM_DEFLATE;
de->compression_level = TORRENTZIP_COMPRESSION_FLAGS;
de->disk_number = 0;
@@ -1203,5 +1255,21 @@ void zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
de->ext_attrib = 0;
/* last_mod, extra_fields, and comment are normalized in zip_dirent_write() directly */
+}
+int
+zip_dirent_check_consistency(zip_dirent_t *dirent) {
+ if (dirent->comp_method == ZIP_CM_STORE && dirent->comp_size != dirent->uncomp_size) {
+ return ZIP_ER_DETAIL_STORED_SIZE_MISMATCH;
+ }
+ return 0;
}
+
+time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de) {
+ if (!de->last_mod_mtime_valid) {
+ de->last_mod_mtime = _zip_d2u_time(&de->last_mod);
+ de->last_mod_mtime_valid = true;
+ }
+
+ return de->last_mod_mtime;
+} \ No newline at end of file
diff --git a/src/Common/libzip/zip_discard.c b/src/Common/libzip/zip_discard.c
index d1dc4f8b..841a80e2 100644
--- a/src/Common/libzip/zip_discard.c
+++ b/src/Common/libzip/zip_discard.c
@@ -1,6 +1,6 @@
/*
zip_discard.c -- discard and free struct zip
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_entry.c b/src/Common/libzip/zip_entry.c
index 35a36e4a..dd25e61f 100644
--- a/src/Common/libzip/zip_entry.c
+++ b/src/Common/libzip/zip_entry.c
@@ -1,6 +1,6 @@
/*
zip_entry.c -- struct zip_entry helper functions
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_err_str.c b/src/Common/libzip/zip_err_str.c
index 28af773b..fb4b69fa 100644
--- a/src/Common/libzip/zip_err_str.c
+++ b/src/Common/libzip/zip_err_str.c
@@ -49,6 +49,7 @@ const struct _zip_err_info _zip_err_str[] = {
{ N, "Operation cancelled" },
{ N, "Unexpected length of data" },
{ N, "Not allowed in torrentzip" },
+ { N, "Possibly truncated or corrupted zip archive" },
};
const int _zip_err_str_count = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
@@ -74,6 +75,11 @@ const struct _zip_err_info _zip_err_details[] = {
{ E, "garbage at end of extra fields" },
{ E, "extra field length is invalid" },
{ E, "file length in header doesn't match actual file length" },
+ { E, "compressed and uncompressed sizes don't match for stored file" },
+ { E, "local header and data descriptor do not match" },
+ { G, "EOCD64 and EOCD64 locator do not match" },
+ { E, "UTF-8 filename is ASCII and doesn't match filename" },
+ { E, "UTF-8 comment is ASCII and doesn't match comment" },
};
const int _zip_err_details_count = sizeof(_zip_err_details)/sizeof(_zip_err_details[0]);
diff --git a/src/Common/libzip/zip_error.c b/src/Common/libzip/zip_error.c
index c498e086..da910d44 100644
--- a/src/Common/libzip/zip_error.c
+++ b/src/Common/libzip/zip_error.c
@@ -1,6 +1,6 @@
/*
zip_error.c -- zip_error_t helper functions
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_error_clear.c b/src/Common/libzip/zip_error_clear.c
index 94ff5062..04062719 100644
--- a/src/Common/libzip/zip_error_clear.c
+++ b/src/Common/libzip/zip_error_clear.c
@@ -1,6 +1,6 @@
/*
zip_error_clear.c -- clear zip error
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_error_get.c b/src/Common/libzip/zip_error_get.c
index c0418f0d..2a5b3eaf 100644
--- a/src/Common/libzip/zip_error_get.c
+++ b/src/Common/libzip/zip_error_get.c
@@ -1,6 +1,6 @@
/*
zip_error_get.c -- get zip error
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_error_get_sys_type.c b/src/Common/libzip/zip_error_get_sys_type.c
index a22ffb03..973d26c0 100644
--- a/src/Common/libzip/zip_error_get_sys_type.c
+++ b/src/Common/libzip/zip_error_get_sys_type.c
@@ -1,6 +1,6 @@
/*
zip_error_get_sys_type.c -- return type of system error code
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_error_strerror.c b/src/Common/libzip/zip_error_strerror.c
index fe04cbb4..5be54b38 100644
--- a/src/Common/libzip/zip_error_strerror.c
+++ b/src/Common/libzip/zip_error_strerror.c
@@ -1,6 +1,6 @@
/*
zip_error_sterror.c -- get string representation of struct zip_error
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -49,6 +49,9 @@ zip_error_strerror(zip_error_t *err) {
if (err->zip_err < 0 || err->zip_err >= _zip_err_str_count) {
system_error_buffer = (char *)malloc(128);
+ if (system_error_buffer == NULL) {
+ return _zip_err_str[ZIP_ER_MEMORY].description;
+ }
snprintf_s(system_error_buffer, 128, "Unknown error %d", err->zip_err);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
zip_error_string = NULL;
@@ -61,6 +64,9 @@ zip_error_strerror(zip_error_t *err) {
case ZIP_ET_SYS: {
size_t len = strerrorlen_s(err->sys_err) + 1;
system_error_buffer = malloc(len);
+ if (system_error_buffer == NULL) {
+ return _zip_err_str[ZIP_ER_MEMORY].description;
+ }
strerror_s(system_error_buffer, len, err->sys_err);
system_error_string = system_error_buffer;
break;
@@ -79,12 +85,18 @@ zip_error_strerror(zip_error_t *err) {
}
else if (error >= _zip_err_details_count) {
system_error_buffer = (char *)malloc(128);
+ if (system_error_buffer == NULL) {
+ return _zip_err_str[ZIP_ER_MEMORY].description;
+ }
snprintf_s(system_error_buffer, 128, "invalid detail error %u", error);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
system_error_string = system_error_buffer;
}
else if (_zip_err_details[error].type == ZIP_DETAIL_ET_ENTRY && index < MAX_DETAIL_INDEX) {
system_error_buffer = (char *)malloc(128);
+ if (system_error_buffer == NULL) {
+ return _zip_err_str[ZIP_ER_MEMORY].description;
+ }
snprintf_s(system_error_buffer, 128, "entry %d: %s", index, _zip_err_details[error].description);
system_error_buffer[128 - 1] = '\0'; /* make sure string is NUL-terminated */
system_error_string = system_error_buffer;
diff --git a/src/Common/libzip/zip_error_to_str.c b/src/Common/libzip/zip_error_to_str.c
index b60b7881..4186e3a4 100644
--- a/src/Common/libzip/zip_error_to_str.c
+++ b/src/Common/libzip/zip_error_to_str.c
@@ -1,6 +1,6 @@
/*
zip_error_to_str.c -- get string representation of zip error code
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_extra_field.c b/src/Common/libzip/zip_extra_field.c
index 7aed12ad..52837046 100644
--- a/src/Common/libzip/zip_extra_field.c
+++ b/src/Common/libzip/zip_extra_field.c
@@ -1,6 +1,6 @@
/*
zip_extra_field.c -- manipulate extra fields
- Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_extra_field_api.c b/src/Common/libzip/zip_extra_field_api.c
index 560c71bb..6f2b4596 100644
--- a/src/Common/libzip/zip_extra_field_api.c
+++ b/src/Common/libzip/zip_extra_field_api.c
@@ -1,6 +1,6 @@
/*
zip_extra_field_api.c -- public extra fields API functions
- Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -56,10 +56,6 @@ zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zi
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
- if (ZIP_WANT_TORRENTZIP(za)) {
- zip_error_set(&za->error, ZIP_ER_NOT_ALLOWED, 0);
- return -1;
- }
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
return -1;
diff --git a/src/Common/libzip/zip_fclose.c b/src/Common/libzip/zip_fclose.c
index b820d98b..2ef579a0 100644
--- a/src/Common/libzip/zip_fclose.c
+++ b/src/Common/libzip/zip_fclose.c
@@ -1,6 +1,6 @@
/*
zip_fclose.c -- close file in zip archive
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_fdopen.c b/src/Common/libzip/zip_fdopen.c
index e72c55dc..94fe6c7c 100644
--- a/src/Common/libzip/zip_fdopen.c
+++ b/src/Common/libzip/zip_fdopen.c
@@ -1,6 +1,6 @@
/*
zip_fdopen.c -- open read-only archive from file descriptor
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_add.c b/src/Common/libzip/zip_file_add.c
index c2c41e15..5959d504 100644
--- a/src/Common/libzip/zip_file_add.c
+++ b/src/Common/libzip/zip_file_add.c
@@ -1,6 +1,6 @@
/*
zip_file_add.c -- add file via callback function
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_error_clear.c b/src/Common/libzip/zip_file_error_clear.c
index a10bff80..eb9a614e 100644
--- a/src/Common/libzip/zip_file_error_clear.c
+++ b/src/Common/libzip/zip_file_error_clear.c
@@ -1,6 +1,6 @@
/*
zip_file_error_clear.c -- clear zip file error
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_error_get.c b/src/Common/libzip/zip_file_error_get.c
index b93117bb..679aeefb 100644
--- a/src/Common/libzip/zip_file_error_get.c
+++ b/src/Common/libzip/zip_file_error_get.c
@@ -1,6 +1,6 @@
/*
zip_file_error_get.c -- get zip file error
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_get_comment.c b/src/Common/libzip/zip_file_get_comment.c
index fa998f02..ca04042a 100644
--- a/src/Common/libzip/zip_file_get_comment.c
+++ b/src/Common/libzip/zip_file_get_comment.c
@@ -1,6 +1,6 @@
/*
zip_file_get_comment.c -- get file comment
- Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_get_external_attributes.c b/src/Common/libzip/zip_file_get_external_attributes.c
index a79bb3ed..483557f0 100644
--- a/src/Common/libzip/zip_file_get_external_attributes.c
+++ b/src/Common/libzip/zip_file_get_external_attributes.c
@@ -1,6 +1,6 @@
/*
zip_file_get_external_attributes.c -- get opsys/external attributes
- Copyright (C) 2013-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2013-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_get_offset.c b/src/Common/libzip/zip_file_get_offset.c
index 72f4880e..c50def54 100644
--- a/src/Common/libzip/zip_file_get_offset.c
+++ b/src/Common/libzip/zip_file_get_offset.c
@@ -1,6 +1,6 @@
/*
zip_file_get_offset.c -- get offset of file data in archive.
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_rename.c b/src/Common/libzip/zip_file_rename.c
index 9ac25814..03101e43 100644
--- a/src/Common/libzip/zip_file_rename.c
+++ b/src/Common/libzip/zip_file_rename.c
@@ -1,6 +1,6 @@
/*
zip_file_rename.c -- rename file in zip archive
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_replace.c b/src/Common/libzip/zip_file_replace.c
index 4262d453..ce457ed1 100644
--- a/src/Common/libzip/zip_file_replace.c
+++ b/src/Common/libzip/zip_file_replace.c
@@ -1,6 +1,6 @@
/*
zip_file_replace.c -- replace file via callback function
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -83,6 +83,12 @@ _zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *s
return -1;
}
+ /* delete all extra fields - these are usually data that are
+ * strongly coupled with the original data */
+ if (zip_file_extra_field_delete(za, idx, ZIP_EXTRA_FIELD_ALL, ZIP_FL_CENTRAL | ZIP_FL_LOCAL) < 0) {
+ return -1;
+ }
+
/* does not change any name related data, so we can do it here;
* needed for a double add of the same file name */
_zip_unchange_data(za->entry + idx);
diff --git a/src/Common/libzip/zip_file_set_comment.c b/src/Common/libzip/zip_file_set_comment.c
index 570f8e82..fb7b9edd 100644
--- a/src/Common/libzip/zip_file_set_comment.c
+++ b/src/Common/libzip/zip_file_set_comment.c
@@ -1,6 +1,6 @@
/*
zip_file_set_comment.c -- set comment for file in archive
- Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_set_encryption.c b/src/Common/libzip/zip_file_set_encryption.c
index 1cdcd4ab..7bb6cdc7 100644
--- a/src/Common/libzip/zip_file_set_encryption.c
+++ b/src/Common/libzip/zip_file_set_encryption.c
@@ -1,6 +1,6 @@
/*
zip_file_set_encryption.c -- set encryption for file in archive
- Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2016-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_set_external_attributes.c b/src/Common/libzip/zip_file_set_external_attributes.c
index 2e0429b8..2f9d30f9 100644
--- a/src/Common/libzip/zip_file_set_external_attributes.c
+++ b/src/Common/libzip/zip_file_set_external_attributes.c
@@ -1,6 +1,6 @@
/*
zip_file_set_external_attributes.c -- set external attributes for entry
- Copyright (C) 2013-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2013-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_file_set_mtime.c b/src/Common/libzip/zip_file_set_mtime.c
index 4126f5a1..e60f7a9a 100644
--- a/src/Common/libzip/zip_file_set_mtime.c
+++ b/src/Common/libzip/zip_file_set_mtime.c
@@ -1,6 +1,6 @@
/*
zip_file_set_mtime.c -- set modification time of entry.
- Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -33,19 +33,12 @@
#include "zipint.h"
-ZIP_EXTERN int
-zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) {
- time_t mtime;
- mtime = _zip_d2u_time(dtime, ddate);
- return zip_file_set_mtime(za, idx, mtime, flags);
-}
-
-ZIP_EXTERN int
-zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
+static int zip_file_set_time(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags, time_t *mtime) {
zip_entry_t *e;
- if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
+ 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);
@@ -70,8 +63,31 @@ zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
}
}
- e->changes->last_mod = mtime;
+ e->changes->last_mod.time = dtime;
+ e->changes->last_mod.date = ddate;
+ if (mtime != NULL) {
+ e->changes->last_mod_mtime = *mtime;
+ e->changes->last_mod_mtime_valid = true;
+ }
+ else {
+ e->changes->last_mod_mtime_valid = false;
+ }
e->changes->changed |= ZIP_DIRENT_LAST_MOD;
return 0;
}
+
+ZIP_EXTERN int zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) {
+ return zip_file_set_time(za, idx, dtime, ddate, flags, NULL);
+}
+
+
+ZIP_EXTERN int zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) {
+ zip_dostime_t dostime;
+
+ if (_zip_u2d_time(mtime, &dostime, &za->error) < 0) {
+ return -1;
+ }
+
+ return zip_file_set_time(za, idx, dostime.time, dostime.date, flags, &mtime);
+}
diff --git a/src/Common/libzip/zip_file_strerror.c b/src/Common/libzip/zip_file_strerror.c
index 5b5a0092..5e896b4c 100644
--- a/src/Common/libzip/zip_file_strerror.c
+++ b/src/Common/libzip/zip_file_strerror.c
@@ -1,6 +1,6 @@
/*
zip_file_sterror.c -- get string representation of zip file error
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_fopen.c b/src/Common/libzip/zip_fopen.c
index e3cde9be..93217f3d 100644
--- a/src/Common/libzip/zip_fopen.c
+++ b/src/Common/libzip/zip_fopen.c
@@ -1,6 +1,6 @@
/*
zip_fopen.c -- open file in zip archive for reading
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_fopen_encrypted.c b/src/Common/libzip/zip_fopen_encrypted.c
index d5880dcb..78143afe 100644
--- a/src/Common/libzip/zip_fopen_encrypted.c
+++ b/src/Common/libzip/zip_fopen_encrypted.c
@@ -1,6 +1,6 @@
/*
zip_fopen_encrypted.c -- open file for reading with password
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_fopen_index.c b/src/Common/libzip/zip_fopen_index.c
index a449b83a..b6676b7d 100644
--- a/src/Common/libzip/zip_fopen_index.c
+++ b/src/Common/libzip/zip_fopen_index.c
@@ -1,6 +1,6 @@
/*
zip_fopen_index.c -- open file in zip archive for reading by index
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_fopen_index_encrypted.c b/src/Common/libzip/zip_fopen_index_encrypted.c
index 40483709..86d69774 100644
--- a/src/Common/libzip/zip_fopen_index_encrypted.c
+++ b/src/Common/libzip/zip_fopen_index_encrypted.c
@@ -1,6 +1,6 @@
/*
zip_fopen_index_encrypted.c -- open file for reading by index w/ password
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_fread.c b/src/Common/libzip/zip_fread.c
index 5b7da46a..17cec4fb 100644
--- a/src/Common/libzip/zip_fread.c
+++ b/src/Common/libzip/zip_fread.c
@@ -1,6 +1,6 @@
/*
zip_fread.c -- read from file
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -39,11 +39,13 @@ ZIP_EXTERN zip_int64_t
zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) {
zip_int64_t n;
- if (!zf)
+ if (zf == NULL) {
return -1;
+ }
- if (zf->error.zip_err != 0)
+ if (zf->error.zip_err != 0) {
return -1;
+ }
if (toread > ZIP_INT64_MAX) {
zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
diff --git a/src/Common/libzip/zip_fseek.c b/src/Common/libzip/zip_fseek.c
index e68ffd36..107a6f73 100644
--- a/src/Common/libzip/zip_fseek.c
+++ b/src/Common/libzip/zip_fseek.c
@@ -1,6 +1,6 @@
/*
zip_fseek.c -- seek in file
- Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2016-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -36,11 +36,13 @@
ZIP_EXTERN zip_int8_t
zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) {
- if (!zf)
+ if (zf == NULL) {
return -1;
+ }
- if (zf->error.zip_err != 0)
+ if (zf->error.zip_err != 0) {
return -1;
+ }
if (zip_source_seek(zf->src, offset, whence) < 0) {
zip_error_set_from_source(&zf->error, zf->src);
@@ -53,7 +55,7 @@ zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) {
ZIP_EXTERN int
zip_file_is_seekable(zip_file_t *zfile) {
- if (!zfile) {
+ if (zfile == NULL) {
return -1;
}
diff --git a/src/Common/libzip/zip_ftell.c b/src/Common/libzip/zip_ftell.c
index bf3b03d3..6299b2da 100644
--- a/src/Common/libzip/zip_ftell.c
+++ b/src/Common/libzip/zip_ftell.c
@@ -1,6 +1,6 @@
/*
zip_ftell.c -- tell position in file
- Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2016-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -38,11 +38,13 @@ ZIP_EXTERN zip_int64_t
zip_ftell(zip_file_t *zf) {
zip_int64_t res;
- if (!zf)
+ if (zf == NULL) {
return -1;
+ }
- if (zf->error.zip_err != 0)
+ if (zf->error.zip_err != 0) {
return -1;
+ }
res = zip_source_tell(zf->src);
if (res < 0) {
diff --git a/src/Common/libzip/zip_get_archive_comment.c b/src/Common/libzip/zip_get_archive_comment.c
index ea9a00ab..b83e6bcf 100644
--- a/src/Common/libzip/zip_get_archive_comment.c
+++ b/src/Common/libzip/zip_get_archive_comment.c
@@ -1,6 +1,6 @@
/*
zip_get_archive_comment.c -- get archive comment
- Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_get_archive_flag.c b/src/Common/libzip/zip_get_archive_flag.c
index fc200bdc..80d59914 100644
--- a/src/Common/libzip/zip_get_archive_flag.c
+++ b/src/Common/libzip/zip_get_archive_flag.c
@@ -1,6 +1,6 @@
/*
zip_get_archive_flag.c -- get archive global flag
- Copyright (C) 2008-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2008-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_get_encryption_implementation.c b/src/Common/libzip/zip_get_encryption_implementation.c
index 72e48fe8..28ad3297 100644
--- a/src/Common/libzip/zip_get_encryption_implementation.c
+++ b/src/Common/libzip/zip_get_encryption_implementation.c
@@ -1,6 +1,6 @@
/*
zip_get_encryption_implementation.c -- get encryption implementation
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_get_file_comment.c b/src/Common/libzip/zip_get_file_comment.c
index d58e22ba..0284aecd 100644
--- a/src/Common/libzip/zip_get_file_comment.c
+++ b/src/Common/libzip/zip_get_file_comment.c
@@ -1,6 +1,6 @@
/*
zip_get_file_comment.c -- get file comment
- Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_get_name.c b/src/Common/libzip/zip_get_name.c
index 4828d781..d1c94532 100644
--- a/src/Common/libzip/zip_get_name.c
+++ b/src/Common/libzip/zip_get_name.c
@@ -1,6 +1,6 @@
/*
zip_get_name.c -- get filename for a file in zip file
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_get_num_entries.c b/src/Common/libzip/zip_get_num_entries.c
index 667dc511..b2595dec 100644
--- a/src/Common/libzip/zip_get_num_entries.c
+++ b/src/Common/libzip/zip_get_num_entries.c
@@ -1,6 +1,6 @@
/*
zip_get_num_entries.c -- get number of entries in archive
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_get_num_files.c b/src/Common/libzip/zip_get_num_files.c
index 140e34f9..16d7754b 100644
--- a/src/Common/libzip/zip_get_num_files.c
+++ b/src/Common/libzip/zip_get_num_files.c
@@ -1,6 +1,6 @@
/*
zip_get_num_files.c -- get number of files in archive
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_hash.c b/src/Common/libzip/zip_hash.c
index d3a954ec..8479bec1 100644
--- a/src/Common/libzip/zip_hash.c
+++ b/src/Common/libzip/zip_hash.c
@@ -1,6 +1,6 @@
/*
zip_hash.c -- hash table string -> uint64
- Copyright (C) 2015-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2015-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_io_util.c b/src/Common/libzip/zip_io_util.c
index 9fcd10b4..6ae8aac6 100644
--- a/src/Common/libzip/zip_io_util.c
+++ b/src/Common/libzip/zip_io_util.c
@@ -1,6 +1,6 @@
/*
zip_io_util.c -- I/O helper functions
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -69,8 +69,14 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp
return NULL;
}
+// VS2022: Workaround an Internal compiler error for Release ARM (32-bit) build.
+#if _MSC_VER >= 1940 && _MSC_VER < 1950 && defined(_M_ARM) && defined(NDEBUG)
+ size_t l = length + (nulp ? 1 : 0);
+ r = (zip_uint8_t *)malloc(l);
+#else
r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0));
- if (!r) {
+#endif
+ if (r == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
diff --git a/src/Common/libzip/zip_libzip_version.c b/src/Common/libzip/zip_libzip_version.c
index 4200727f..139b250f 100644
--- a/src/Common/libzip/zip_libzip_version.c
+++ b/src/Common/libzip/zip_libzip_version.c
@@ -1,6 +1,6 @@
/*
zip_libzip_version.c -- return run-time version of library
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_memdup.c b/src/Common/libzip/zip_memdup.c
index 75d72c61..6ac9a5a2 100644
--- a/src/Common/libzip/zip_memdup.c
+++ b/src/Common/libzip/zip_memdup.c
@@ -1,6 +1,6 @@
/*
zip_memdup.c -- internal zip function, "strdup" with len
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -45,7 +45,7 @@ _zip_memdup(const void *mem, size_t len, zip_error_t *error) {
return NULL;
ret = malloc(len);
- if (!ret) {
+ if (ret == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
diff --git a/src/Common/libzip/zip_new.c b/src/Common/libzip/zip_new.c
index 4f69c8a2..68e1588f 100644
--- a/src/Common/libzip/zip_new.c
+++ b/src/Common/libzip/zip_new.c
@@ -1,6 +1,6 @@
/*
zip_new.c -- create and init struct zip
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -46,7 +46,7 @@ _zip_new(zip_error_t *error) {
zip_t *za;
za = (zip_t *)malloc(sizeof(struct zip));
- if (!za) {
+ if (za == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
@@ -68,6 +68,7 @@ _zip_new(zip_error_t *error) {
za->nopen_source = za->nopen_source_alloc = 0;
za->open_source = NULL;
za->progress = NULL;
+ za->torrent_mtime = 0;
return za;
}
diff --git a/src/Common/libzip/zip_open.c b/src/Common/libzip/zip_open.c
index ee7e9dec..9dccad61 100644
--- a/src/Common/libzip/zip_open.c
+++ b/src/Common/libzip/zip_open.c
@@ -1,6 +1,6 @@
/*
zip_open.c -- open zip archive by name
- Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -31,7 +31,6 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -39,17 +38,30 @@
#include "zipint.h"
-typedef enum { EXISTS_ERROR = -1, EXISTS_NOT = 0, EXISTS_OK } exists_t;
+typedef enum {
+ EXISTS_ERROR = -1,
+ EXISTS_NOT = 0,
+ EXISTS_OK
+} exists_t;
+typedef enum {
+ CDIR_OK,
+ CDIR_INVALID,
+ CDIR_NOT_FOUND
+
+} cdir_status_t;
+
+static bool check_eocd(zip_cdir_t *cd, unsigned int flags, zip_error_t *error);
+static bool check_magic(zip_uint64_t offset, zip_buffer_t *buffer, zip_uint64_t buffer_offset, zip_source_t *src, const char* magic);
static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error);
static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error);
static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir);
static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);
static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error);
static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *);
-static const unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t);
-static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error);
-static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
-static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
+static bool _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_cdir_t **cdirp, zip_error_t *error);
+static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error);
+static cdir_status_t _zip_read_eocd64(zip_cdir_t *cdir, zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
+static const unsigned char *find_eocd(zip_buffer_t *buffer, const unsigned char *last);
ZIP_EXTERN zip_t *
@@ -144,6 +156,27 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) {
}
+static bool
+_is_truncated_zip(zip_source_t *src) {
+ unsigned char data[4];
+ /* check if the source is a truncated zip archive: true if yes, no
+ if not or can't be determined */
+ if (zip_source_seek(src, 0, SEEK_SET) < 0) {
+ return false;
+ }
+
+ if (zip_source_read(src, data, 4) != 4) {
+ return false;
+ }
+
+ if (memcmp(data, LOCAL_MAGIC, 4) == 0) {
+ /* file starts with a ZIP local header signature */
+ return true;
+ }
+ return false;
+}
+
+
zip_t *
_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
zip_t *za;
@@ -174,6 +207,12 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) {
if ((cdir = _zip_find_central_dir(za, len)) == NULL) {
_zip_error_copy(error, &za->error);
+ if (zip_error_code_zip(error) == ZIP_ER_NOZIP) {
+ /* not a zip - find out if it's truncated */
+ if (_is_truncated_zip(src)) {
+ zip_error_set(error, ZIP_ER_TRUNCATED_ZIP, 0);
+ }
+ }
/* keep src so discard does not get rid of it */
zip_source_keep(src);
zip_discard(za);
@@ -228,14 +267,14 @@ void
_zip_set_open_error(int *zep, const zip_error_t *err, int ze) {
if (err) {
ze = zip_error_code_zip(err);
- switch (zip_error_system_type(err)) {
- case ZIP_ET_SYS:
- case ZIP_ET_LIBZIP:
- errno = zip_error_code_system(err);
- break;
-
- default:
- break;
+ switch (zip_error_system_type(err)) {
+ case ZIP_ET_SYS:
+ case ZIP_ET_LIBZIP:
+ errno = zip_error_code_system(err);
+ break;
+
+ default:
+ break;
}
}
@@ -250,37 +289,67 @@ _zip_set_open_error(int *zep, const zip_error_t *err, int ze) {
Returns a struct zip_cdir which contains the central directory
entries, or NULL if unsuccessful. */
-static zip_cdir_t *
-_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error) {
+static bool _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_cdir_t **cdirp, zip_error_t *error) {
zip_cdir_t *cd;
zip_uint16_t comment_len;
zip_uint64_t i, left;
zip_uint64_t eocd_offset = _zip_buffer_offset(buffer);
zip_buffer_t *cd_buffer;
+ bool eocd64_found = false;
- if (_zip_buffer_left(buffer) < EOCDLEN) {
- /* not enough bytes left for comment */
- zip_error_set(error, ZIP_ER_NOZIP, 0);
- return NULL;
- }
+ *cdirp = NULL;
- /* check for end-of-central-dir magic */
- if (memcmp(_zip_buffer_get(buffer, 4), EOCD_MAGIC, 4) != 0) {
- zip_error_set(error, ZIP_ER_NOZIP, 0);
- return NULL;
+ if ((cd = _zip_read_eocd(buffer, buf_offset, error)) == NULL) {
+ return false;
}
if (eocd_offset >= EOCD64LOCLEN && memcmp(_zip_buffer_data(buffer) + eocd_offset - EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) {
+ eocd64_found = true;
_zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN);
- cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error);
+ switch (_zip_read_eocd64(cd, za->src, buffer, buf_offset, za->flags, error)) {
+ case CDIR_OK:
+ break;
+
+ case CDIR_INVALID:
+ _zip_cdir_free(cd);
+ return true;
+
+ case CDIR_NOT_FOUND:
+ _zip_cdir_free(cd);
+ return false;
+ }
}
- else {
- _zip_buffer_set_offset(buffer, eocd_offset);
- cd = _zip_read_eocd(buffer, buf_offset, za->flags, error);
+
+ if ((cd->eocd_disk != 0 || cd->this_disk != 0) && !eocd64_found && cd->eocd_disk != cd->this_disk) {
+ /* If the central directory doesn't start on this disk, we can't check that offset is valid. Check as much as we can instead. */
+ if (cd->this_disk < cd->eocd_disk) {
+ /* Disks before the start of the central directory don't contain an EOCD. */
+ _zip_cdir_free(cd);
+ return false;
+ }
+ if (cd->size <= cd->eocd_offset) {
+ /* The complete central directory would fit on this disk. */
+ _zip_cdir_free(cd);
+ return false;
+ }
}
- if (cd == NULL)
- return NULL;
+ if (!eocd64_found) {
+ if (cd->this_disk == 0 && cd->eocd_disk == 0 && cd->eocd_offset == 0 && cd->offset == 0 && cd->num_entries == 0) {
+ /* An empty archive doesn't contain central directory entries. */
+ }
+ else if (!check_magic(cd->offset, buffer, buf_offset, za->src, CENTRAL_MAGIC)) {
+ _zip_cdir_free(cd);
+ return false;
+ }
+ }
+
+ /* We accept this EOCD as valid and won't search for an earlier one if it is unusable. */
+
+ if (!check_eocd(cd, za->flags, error)) {
+ _zip_cdir_free(cd);
+ return true;
+ }
_zip_buffer_set_offset(buffer, eocd_offset + 20);
comment_len = _zip_buffer_get_16(buffer);
@@ -289,7 +358,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
/* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
if (comment_len || (za->open_flags & ZIP_CHECKCONS)) {
@@ -298,16 +367,21 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
_zip_buffer_set_offset(buffer, eocd_offset + EOCDLEN);
tail_len = _zip_buffer_left(buffer);
- if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) {
- zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID);
- _zip_cdir_free(cd);
- return NULL;
+ if (tail_len != comment_len) {
+ if (za->open_flags & ZIP_CHECKCONS) {
+ zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID);
+ _zip_cdir_free(cd);
+ return true;
+ }
+ if (tail_len < comment_len) {
+ comment_len = tail_len;
+ }
}
if (comment_len) {
if ((cd->comment = _zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) {
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
}
}
@@ -320,12 +394,12 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
}
else {
@@ -334,17 +408,22 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) {
zip_error_set_from_source(error, za->src);
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
/* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */
if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) {
zip_error_set(error, ZIP_ER_NOZIP, 0);
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
}
+ if (!_zip_cdir_grow(cd, cd->num_entries, error)) {
+ _zip_cdir_free(cd);
+ _zip_buffer_free(cd_buffer);
+ return true;
+ }
left = (zip_uint64_t)cd->size;
i = 0;
while (left > 0) {
@@ -362,31 +441,32 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
if (!_zip_cdir_grow(cd, 0x10000, error)) {
_zip_cdir_free(cd);
_zip_buffer_free(cd_buffer);
- return NULL;
+ return true;
}
grown = true;
}
- if ((cd->entry[i].orig = _zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) {
- if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
- zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
- }
- else if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) {
+ if ((cd->entry[i].orig = _zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, 0, za->open_flags & ZIP_CHECKCONS, error)) < 0) {
+ if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
+ zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
+ }
+ else if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) {
zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_CDIR_ENTRY_INVALID, i));
}
_zip_cdir_free(cd);
_zip_buffer_free(cd_buffer);
- return NULL;
+ return true;
}
i++;
left -= (zip_uint64_t)entry_size;
}
+ /* If we didn't fill all we grew, cd->num_entries was wrong. */
if (i != cd->nentry || left > 0) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_WRONG_ENTRIES_COUNT);
_zip_buffer_free(cd_buffer);
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
if (za->open_flags & ZIP_CHECKCONS) {
@@ -401,7 +481,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
if (offset < 0) {
zip_error_set_from_source(error, za->src);
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
ok = ((zip_uint64_t)offset == cd->offset + cd->size);
}
@@ -410,12 +490,32 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
_zip_buffer_free(cd_buffer);
_zip_cdir_free(cd);
- return NULL;
+ return true;
}
}
_zip_buffer_free(cd_buffer);
- return cd;
+ *cdirp = cd;
+ return true;
+}
+
+
+static bool check_magic(zip_uint64_t offset, zip_buffer_t *buffer, zip_uint64_t buffer_offset, zip_source_t *src, const char* magic) {
+ if (buffer_offset <= offset) {
+ zip_uint8_t* data;
+ if (_zip_buffer_set_offset(buffer, offset - buffer_offset) < 0 || (data = _zip_buffer_get(buffer, MAGIC_LEN)) == NULL) {
+ return false;
+ }
+ return memcmp(data, magic, MAGIC_LEN) == 0;
+ }
+ else {
+ zip_uint8_t data[MAGIC_LEN];
+
+ if (zip_source_seek(src, offset, SEEK_SET) < 0 || zip_source_read(src, data, MAGIC_LEN) != MAGIC_LEN) {
+ return false;
+ }
+ return memcmp(data, magic, MAGIC_LEN) == 0;
+ }
}
@@ -430,6 +530,7 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
zip_uint64_t i;
zip_uint64_t min, max, j;
struct zip_dirent temp;
+ int detail;
_zip_dirent_init(&temp);
if (cd->nentry) {
@@ -460,10 +561,10 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
return -1;
}
- if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) {
- if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
- zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
- }
+ if (_zip_dirent_read(&temp, za->src, NULL, true, cd->entry[i].orig->comp_size, true, error) == -1) {
+ if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
+ zip_error_set(error, ZIP_ER_INCONS, ADD_INDEX_TO_DETAIL(zip_error_code_system(error), i));
+ }
_zip_dirent_finalize(&temp);
return -1;
}
@@ -479,6 +580,11 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
temp.extra_fields = NULL;
_zip_dirent_finalize(&temp);
+
+ if ((detail = zip_dirent_check_consistency(cd->entry[i].orig)) != 0) {
+ zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(detail, i));
+ return -1;
+ }
}
return (max - min) < ZIP_INT64_MAX ? (zip_int64_t)(max - min) : ZIP_INT64_MAX;
@@ -497,25 +603,23 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) {
and global headers for the bitflags */
|| (central->bitflags != local->bitflags)
#endif
- || (central->comp_method != local->comp_method) || (central->last_mod != local->last_mod) || !_zip_string_equal(central->filename, local->filename))
+ || (central->comp_method != local->comp_method) || (central->last_mod.time != local->last_mod.time) || (central->last_mod.date != local->last_mod.date) || !_zip_string_equal(central->filename, local->filename))
return -1;
if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) {
/* InfoZip stores valid values in local header even when data descriptor is used.
This is in violation of the appnote.
- macOS Archive sets the compressed size even when data descriptor is used ( but not the others),
- also in violation of the appnote.
- */
- /* if data descriptor is not used, the values must match */
+ macOS Archive sets the compressed size even when data descriptor is used ( but not the others),
+ also in violation of the appnote.
+ */
+ /* if data descriptor is not used, the values must match */
if ((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0) {
return -1;
- }
- /* when using a data descriptor, the local header value must be zero or match */
- if ((local->crc != 0 && central->crc != local->crc) ||
- (local->comp_size != 0 && central->comp_size != local->comp_size) ||
- (local->uncomp_size != 0 && central->uncomp_size != local->uncomp_size)) {
- return -1;
- }
+ }
+ /* when using a data descriptor, the local header value must be zero or match */
+ if ((local->crc != 0 && central->crc != local->crc) || (local->comp_size != 0 && central->comp_size != local->comp_size) || (local->uncomp_size != 0 && central->uncomp_size != local->uncomp_size)) {
+ return -1;
+ }
}
return 0;
@@ -568,12 +672,10 @@ _zip_file_exists(zip_source_t *src, zip_error_t *error) {
static zip_cdir_t *
_zip_find_central_dir(zip_t *za, zip_uint64_t len) {
- zip_cdir_t *cdir, *cdirnew;
+ zip_cdir_t *cdir;
const zip_uint8_t *match;
zip_int64_t buf_offset;
zip_uint64_t buflen;
- zip_int64_t a;
- zip_int64_t best;
zip_error_t error;
zip_buffer_t *buffer;
@@ -600,7 +702,6 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) {
return NULL;
}
- best = -1;
cdir = NULL;
if (buflen >= CDBUFSIZE) {
/* EOCD64 locator is before EOCD, so leave place for it */
@@ -608,165 +709,139 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) {
}
zip_error_set(&error, ZIP_ER_NOZIP, 0);
- match = _zip_buffer_get(buffer, 0);
- /* The size of buffer never greater than CDBUFSIZE. */
- while (_zip_buffer_left(buffer) >= EOCDLEN && (match = _zip_memmem(match, (size_t)_zip_buffer_left(buffer) - (EOCDLEN - 4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) {
+ match = NULL;
+ while ((match = find_eocd(buffer, match)) != NULL) {
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
- if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) {
- if (cdir) {
- if (best <= 0) {
- best = _zip_checkcons(za, cdir, &error);
- }
-
- a = _zip_checkcons(za, cdirnew, &error);
- if (best < a) {
- _zip_cdir_free(cdir);
- cdir = cdirnew;
- best = a;
- }
- else {
- _zip_cdir_free(cdirnew);
- }
+ if (_zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &cdir, &error)) {
+ if (cdir != NULL && (za->open_flags & ZIP_CHECKCONS) && _zip_checkcons(za, cdir, &error) < 0) {
+ _zip_cdir_free(cdir);
+ cdir = NULL;
}
- else {
- cdir = cdirnew;
- if (za->open_flags & ZIP_CHECKCONS)
- best = _zip_checkcons(za, cdir, &error);
- else {
- best = 0;
- }
- }
- cdirnew = NULL;
+ break;
}
-
- match++;
- _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
}
_zip_buffer_free(buffer);
- if (best < 0) {
+ if (cdir == NULL) {
_zip_error_copy(&za->error, &error);
- _zip_cdir_free(cdir);
- return NULL;
}
-
return cdir;
}
-static const unsigned char *_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) {
+static const unsigned char *
+find_eocd(zip_buffer_t *buffer, const unsigned char *last) {
+ const unsigned char *data = _zip_buffer_data(buffer);
const unsigned char *p;
- if (littlelen == 0) {
- return big;
+ if (last == NULL) {
+ last = data + _zip_buffer_size(buffer) - MAGIC_LEN;
}
-
- if (biglen < littlelen) {
+ else if (last == _zip_buffer_data(buffer)) {
return NULL;
}
+ else {
+ last -= 1;
+ }
- p = big;
- while (true) {
- p = (const unsigned char *)memchr(p, little[0], biglen - (littlelen - 1) - (size_t)(p - big));
- if (p == NULL) {
- return NULL;
- }
- if (memcmp(p + 1, little + 1, littlelen - 1) == 0) {
- return p;
+ for (p = last; p >= data; p -= 1) {
+ if (*p == EOCD_MAGIC[0]) {
+ if (memcmp(p, EOCD_MAGIC, MAGIC_LEN) == 0) {
+ return p;
+ }
}
- p += 1;
}
+
+ return NULL;
}
static zip_cdir_t *
-_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) {
+_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error) {
zip_cdir_t *cd;
- zip_uint64_t i, nentry, size, offset, eocd_offset;
if (_zip_buffer_left(buffer) < EOCDLEN) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD_LENGTH_INVALID);
return NULL;
}
- eocd_offset = _zip_buffer_offset(buffer);
-
- _zip_buffer_get(buffer, 4); /* magic already verified */
-
- if (_zip_buffer_get_32(buffer) != 0) {
- zip_error_set(error, ZIP_ER_MULTIDISK, 0);
+ if ((cd = _zip_cdir_new(error)) == NULL) {
return NULL;
}
+ cd->eocd_offset = buf_offset + _zip_buffer_offset(buffer);
+ /* This function is only called where EOCD magic was found, so no need to check that here. */
+ _zip_buffer_skip(buffer, MAGIC_LEN);
+ cd->is_zip64 = false;
+ cd->this_disk = _zip_buffer_get_16(buffer);
+ cd->eocd_disk = _zip_buffer_get_16(buffer);
+
/* number of cdir-entries on this disk */
- i = _zip_buffer_get_16(buffer);
+ cd->disk_entries = _zip_buffer_get_16(buffer);
/* number of cdir-entries */
- nentry = _zip_buffer_get_16(buffer);
-
- if (nentry != i) {
- zip_error_set(error, ZIP_ER_NOZIP, 0);
- return NULL;
- }
+ cd->num_entries = _zip_buffer_get_16(buffer);
+ cd->size = _zip_buffer_get_32(buffer);
+ cd->offset = _zip_buffer_get_32(buffer);
- size = _zip_buffer_get_32(buffer);
- offset = _zip_buffer_get_32(buffer);
+ return cd;
+}
- if (offset + size < offset) {
- zip_error_set(error, ZIP_ER_SEEK, EFBIG);
- return NULL;
+static bool
+check_eocd(zip_cdir_t *cd, unsigned int flags, zip_error_t *error) {
+ if (cd->disk_entries != cd->num_entries || cd->this_disk != 0 || cd->eocd_disk != 0) {
+ zip_error_set(error, ZIP_ER_MULTIDISK, 0);
+ return false;
}
- if (offset + size > buf_offset + eocd_offset) {
- /* cdir spans past EOCD record */
- zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
- return NULL;
+ if (cd->offset + cd->size < cd->offset) {
+ zip_error_set(error, ZIP_ER_SEEK, EFBIG);
+ return false;
}
-
- if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) {
+ if ((flags & ZIP_CHECKCONS) && cd->offset + cd->size != cd->eocd_offset) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
- return NULL;
+ return false;
}
- if ((cd = _zip_cdir_new(nentry, error)) == NULL)
- return NULL;
-
- cd->is_zip64 = false;
- cd->size = size;
- cd->offset = offset;
-
- return cd;
+ return true;
}
-static zip_cdir_t *
-_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) {
- zip_cdir_t *cd;
+cdir_status_t _zip_read_eocd64(zip_cdir_t *cdir, zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) {
zip_uint64_t offset;
zip_uint8_t eocd[EOCD64LEN];
zip_uint64_t eocd_offset;
zip_uint64_t size, nentry, i, eocdloc_offset;
bool free_buffer;
- zip_uint32_t num_disks, num_disks64, eocd_disk, eocd_disk64;
+ zip_uint32_t num_disks, eocd_disk, this_disk;
eocdloc_offset = _zip_buffer_offset(buffer);
_zip_buffer_get(buffer, 4); /* magic already verified */
- num_disks = _zip_buffer_get_16(buffer);
- eocd_disk = _zip_buffer_get_16(buffer);
+ eocd_disk = _zip_buffer_get_32(buffer);
eocd_offset = _zip_buffer_get_64(buffer);
+ num_disks = _zip_buffer_get_32(buffer);
+
+ if (!check_magic(eocd_offset, buffer, buf_offset, src, EOCD64_MAGIC)) {
+ return CDIR_NOT_FOUND;
+ }
+
+ if (num_disks != 1) {
+ zip_error_set(error, ZIP_ER_MULTIDISK, 0);
+ return CDIR_INVALID;
+ }
/* valid seek value for start of EOCD */
if (eocd_offset > ZIP_INT64_MAX) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
- return NULL;
+ return CDIR_INVALID;
}
/* does EOCD fit before EOCD locator? */
if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_OVERLAPS_EOCD);
- return NULL;
+ return CDIR_INVALID;
}
/* make sure current position of buffer is beginning of EOCD */
@@ -777,10 +852,10 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
else {
if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) {
zip_error_set_from_source(error, src);
- return NULL;
+ return CDIR_INVALID;
}
if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) {
- return NULL;
+ return CDIR_INVALID;
}
free_buffer = true;
}
@@ -790,7 +865,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
if (free_buffer) {
_zip_buffer_free(buffer);
}
- return NULL;
+ return CDIR_INVALID;
}
/* size of EOCD */
@@ -802,47 +877,29 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
if (free_buffer) {
_zip_buffer_free(buffer);
}
- return NULL;
+ return CDIR_INVALID;
}
_zip_buffer_get(buffer, 4); /* skip version made by/needed */
- num_disks64 = _zip_buffer_get_32(buffer);
- eocd_disk64 = _zip_buffer_get_32(buffer);
-
- /* if eocd values are 0xffff, we have to use eocd64 values.
- otherwise, if the values are not the same, it's inconsistent;
- in any case, if the value is not 0, we don't support it */
- if (num_disks == 0xffff) {
- num_disks = num_disks64;
- }
- if (eocd_disk == 0xffff) {
- eocd_disk = eocd_disk64;
- }
- if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) {
- zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_MISMATCH);
+ this_disk = _zip_buffer_get_32(buffer);
+ if (_zip_buffer_get_32(buffer) != eocd_disk) {
+ zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_LOCATOR_MISMATCH);
if (free_buffer) {
_zip_buffer_free(buffer);
}
- return NULL;
- }
- if (num_disks != 0 || eocd_disk != 0) {
- zip_error_set(error, ZIP_ER_MULTIDISK, 0);
- if (free_buffer) {
- _zip_buffer_free(buffer);
- }
- return NULL;
+ return CDIR_INVALID;
}
- nentry = _zip_buffer_get_64(buffer);
i = _zip_buffer_get_64(buffer);
+ nentry = _zip_buffer_get_64(buffer);
if (nentry != i) {
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
if (free_buffer) {
_zip_buffer_free(buffer);
}
- return NULL;
+ return CDIR_INVALID;
}
size = _zip_buffer_get_64(buffer);
@@ -854,7 +911,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
if (free_buffer) {
_zip_buffer_free(buffer);
}
- return NULL;
+ return CDIR_INVALID;
}
if (free_buffer) {
@@ -863,35 +920,33 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
if (offset > ZIP_INT64_MAX || offset + size < offset) {
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
- return NULL;
- }
- if (offset + size > buf_offset + eocd_offset) {
- /* cdir spans past EOCD record */
- zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
- return NULL;
- }
- if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) {
- zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
- return NULL;
+ return CDIR_INVALID;
}
if (nentry > size / CDENTRYSIZE) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_INVALID);
- return NULL;
+ return CDIR_INVALID;
}
- if ((cd = _zip_cdir_new(nentry, error)) == NULL)
- return NULL;
+ if ((cdir->size != 0xffffffff && cdir->size != size) || (cdir->offset != 0xffffffff && cdir->offset != offset) || (cdir->num_entries != 0xffff && cdir->num_entries != nentry) || (cdir->disk_entries != 0xffff && cdir->disk_entries != i) || (cdir->this_disk != 0xffff && cdir->this_disk != this_disk) || (cdir->eocd_disk != 0xffff && cdir->eocd_disk != eocd_disk)) {
+ zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_MISMATCH);
+ return CDIR_INVALID;
+ }
- cd->is_zip64 = true;
- cd->size = size;
- cd->offset = offset;
+ cdir->is_zip64 = true;
+ cdir->size = size;
+ cdir->offset = offset;
+ cdir->disk_entries = i;
+ cdir->num_entries = nentry;
+ cdir->this_disk = this_disk;
+ cdir->eocd_disk = eocd_disk;
- return cd;
+ return CDIR_OK;
}
-static int decode_hex(char c) {
+static int
+decode_hex(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
@@ -906,17 +961,17 @@ static int decode_hex(char c) {
/* _zip_check_torrentzip:
check whether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */
-static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
+static void
+zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
zip_uint32_t crc_should;
- char buf[8+1];
+ char buf[8 + 1];
size_t i;
if (cdir == NULL) {
return;
}
- if (_zip_string_length(cdir->comment) != TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH
- || strncmp((const char *)cdir->comment->raw, TORRENTZIP_SIGNATURE, TORRENTZIP_SIGNATURE_LENGTH) != 0)
+ if (_zip_string_length(cdir->comment) != TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH || strncmp((const char *)cdir->comment->raw, TORRENTZIP_SIGNATURE, TORRENTZIP_SIGNATURE_LENGTH) != 0)
return;
memcpy(buf, cdir->comment->raw + TORRENTZIP_SIGNATURE_LENGTH, TORRENTZIP_CRC_LENGTH);
@@ -934,8 +989,8 @@ static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
{
zip_stat_t st;
- zip_source_t* src_window;
- zip_source_t* src_crc;
+ zip_source_t *src_window;
+ zip_source_t *src_crc;
zip_uint8_t buffer[512];
zip_int64_t ret;
@@ -943,7 +998,7 @@ static void zip_check_torrentzip(zip_t *za, const zip_cdir_t *cdir) {
st.valid |= ZIP_STAT_SIZE | ZIP_STAT_CRC;
st.size = cdir->size;
st.crc = crc_should;
- if ((src_window = _zip_source_window_new(za->src, cdir->offset, cdir->size, &st, 0, NULL, NULL, 0, false, NULL)) == NULL) {
+ if ((src_window = _zip_source_window_new(za->src, cdir->offset, cdir->size, &st, 0, NULL, NULL, NULL, 0, false, NULL)) == NULL) {
return;
}
if ((src_crc = zip_source_crc_create(src_window, 1, NULL)) == NULL) {
diff --git a/src/Common/libzip/zip_pkware.c b/src/Common/libzip/zip_pkware.c
index 6a8c9fcd..ef3a30bb 100644
--- a/src/Common/libzip/zip_pkware.c
+++ b/src/Common/libzip/zip_pkware.c
@@ -1,6 +1,6 @@
/*
zip_pkware.c -- Traditional PKWARE de/encryption backend routines
- Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_progress.c b/src/Common/libzip/zip_progress.c
index e080514b..5693d7a5 100644
--- a/src/Common/libzip/zip_progress.c
+++ b/src/Common/libzip/zip_progress.c
@@ -1,6 +1,6 @@
/*
zip_progress.c -- progress reporting
- Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -191,7 +191,7 @@ _zip_progress_update(zip_progress_t *progress, double sub_current) {
if (progress->callback_progress != NULL) {
current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start;
- if (current - progress->last_update > progress->precision) {
+ if (current - progress->last_update > progress->precision || (progress->last_update < 1 && current == 1)) {
progress->callback_progress(progress->za, current, progress->ud_progress);
progress->last_update = current;
}
diff --git a/src/Common/libzip/zip_random_unix.c b/src/Common/libzip/zip_random_unix.c
index 867df790..9446ca92 100644
--- a/src/Common/libzip/zip_random_unix.c
+++ b/src/Common/libzip/zip_random_unix.c
@@ -1,6 +1,6 @@
/*
zip_random_unix.c -- fill the user's buffer with random stuff (Unix version)
- Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2016-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_random_uwp.c b/src/Common/libzip/zip_random_uwp.c
index 0883ce45..7accdeb2 100644
--- a/src/Common/libzip/zip_random_uwp.c
+++ b/src/Common/libzip/zip_random_uwp.c
@@ -1,6 +1,6 @@
/*
zip_random_uwp.c -- fill the user's buffer with random stuff (UWP version)
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_random_win32.c b/src/Common/libzip/zip_random_win32.c
index 789b9c20..209ca4b8 100644
--- a/src/Common/libzip/zip_random_win32.c
+++ b/src/Common/libzip/zip_random_win32.c
@@ -1,6 +1,6 @@
/*
zip_random_win32.c -- fill the user's buffer with random stuff (Windows version)
- Copyright (C) 2016-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2016-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_rename.c b/src/Common/libzip/zip_rename.c
index c89b06c9..b356de45 100644
--- a/src/Common/libzip/zip_rename.c
+++ b/src/Common/libzip/zip_rename.c
@@ -1,6 +1,6 @@
/*
zip_rename.c -- rename file in zip archive
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_replace.c b/src/Common/libzip/zip_replace.c
index 96c083c3..549306a0 100644
--- a/src/Common/libzip/zip_replace.c
+++ b/src/Common/libzip/zip_replace.c
@@ -1,6 +1,6 @@
/*
zip_replace.c -- replace file via callback function
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_set_archive_comment.c b/src/Common/libzip/zip_set_archive_comment.c
index 7d06688e..2c75bda6 100644
--- a/src/Common/libzip/zip_set_archive_comment.c
+++ b/src/Common/libzip/zip_set_archive_comment.c
@@ -1,6 +1,6 @@
/*
zip_set_archive_comment.c -- set archive comment
- Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_set_archive_flag.c b/src/Common/libzip/zip_set_archive_flag.c
index 834ef5ba..7533ac50 100644
--- a/src/Common/libzip/zip_set_archive_flag.c
+++ b/src/Common/libzip/zip_set_archive_flag.c
@@ -1,6 +1,6 @@
/*
zip_get_archive_flag.c -- set archive global flag
- Copyright (C) 2008-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2008-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_set_default_password.c b/src/Common/libzip/zip_set_default_password.c
index 4bab513f..07b3a06e 100644
--- a/src/Common/libzip/zip_set_default_password.c
+++ b/src/Common/libzip/zip_set_default_password.c
@@ -1,6 +1,6 @@
/*
zip_set_default_password.c -- set default password for decryption
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_set_file_comment.c b/src/Common/libzip/zip_set_file_comment.c
index 5d2b0b8a..b587ae95 100644
--- a/src/Common/libzip/zip_set_file_comment.c
+++ b/src/Common/libzip/zip_set_file_comment.c
@@ -1,6 +1,6 @@
/*
zip_set_file_comment.c -- set comment for file in archive
- Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_set_file_compression.c b/src/Common/libzip/zip_set_file_compression.c
index a193bb77..cee099d5 100644
--- a/src/Common/libzip/zip_set_file_compression.c
+++ b/src/Common/libzip/zip_set_file_compression.c
@@ -1,6 +1,6 @@
/*
zip_set_file_compression.c -- set compression for file in archive
- Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_set_name.c b/src/Common/libzip/zip_set_name.c
index f1bf703e..0087af1a 100644
--- a/src/Common/libzip/zip_set_name.c
+++ b/src/Common/libzip/zip_set_name.c
@@ -1,6 +1,6 @@
/*
zip_set_name.c -- rename helper function
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_accept_empty.c b/src/Common/libzip/zip_source_accept_empty.c
index e772aeea..be319434 100644
--- a/src/Common/libzip/zip_source_accept_empty.c
+++ b/src/Common/libzip/zip_source_accept_empty.c
@@ -1,6 +1,6 @@
/*
zip_source_accept_empty.c -- if empty source is a valid archive
- Copyright (C) 2019-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2019-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_begin_write.c b/src/Common/libzip/zip_source_begin_write.c
index 4a9d5d5d..2724335d 100644
--- a/src/Common/libzip/zip_source_begin_write.c
+++ b/src/Common/libzip/zip_source_begin_write.c
@@ -1,6 +1,6 @@
/*
zip_source_begin_write.c -- start a new file for writing
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_begin_write_cloning.c b/src/Common/libzip/zip_source_begin_write_cloning.c
index df195fcd..67d3475b 100644
--- a/src/Common/libzip/zip_source_begin_write_cloning.c
+++ b/src/Common/libzip/zip_source_begin_write_cloning.c
@@ -1,6 +1,6 @@
/*
zip_source_begin_write_cloning.c -- clone part of file for writing
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_buffer.c b/src/Common/libzip/zip_source_buffer.c
index 44159536..bdd522d6 100644
--- a/src/Common/libzip/zip_source_buffer.c
+++ b/src/Common/libzip/zip_source_buffer.c
@@ -1,6 +1,6 @@
/*
zip_source_buffer.c -- create zip data source from buffer
- Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_call.c b/src/Common/libzip/zip_source_call.c
index 8c98fc2e..bc13c3b0 100644
--- a/src/Common/libzip/zip_source_call.c
+++ b/src/Common/libzip/zip_source_call.c
@@ -1,6 +1,6 @@
/*
zip_source_call.c -- invoke callback command on zip_source
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_close.c b/src/Common/libzip/zip_source_close.c
index f4f3ff2b..f1ae6f3e 100644
--- a/src/Common/libzip/zip_source_close.c
+++ b/src/Common/libzip/zip_source_close.c
@@ -1,6 +1,6 @@
/*
zip_source_close.c -- close zip_source (stop reading)
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_commit_write.c b/src/Common/libzip/zip_source_commit_write.c
index d7f567b8..ca7563ce 100644
--- a/src/Common/libzip/zip_source_commit_write.c
+++ b/src/Common/libzip/zip_source_commit_write.c
@@ -1,6 +1,6 @@
/*
zip_source_commit_write.c -- commit changes to file
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_compress.c b/src/Common/libzip/zip_source_compress.c
index 3cf709ff..54387eca 100644
--- a/src/Common/libzip/zip_source_compress.c
+++ b/src/Common/libzip/zip_source_compress.c
@@ -1,6 +1,6 @@
/*
zip_source_compress.c -- (de)compression routines
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_crc.c b/src/Common/libzip/zip_source_crc.c
index 435a084b..931a729c 100644
--- a/src/Common/libzip/zip_source_crc.c
+++ b/src/Common/libzip/zip_source_crc.c
@@ -1,6 +1,6 @@
/*
zip_source_crc.c -- pass-through source that calculates CRC32 and size
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_error.c b/src/Common/libzip/zip_source_error.c
index dc7fa20c..774eec0a 100644
--- a/src/Common/libzip/zip_source_error.c
+++ b/src/Common/libzip/zip_source_error.c
@@ -1,6 +1,6 @@
/*
zip_source_error.c -- get last error from zip_source
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_file.h b/src/Common/libzip/zip_source_file.h
index cca9fd2b..de07aecc 100644
--- a/src/Common/libzip/zip_source_file.h
+++ b/src/Common/libzip/zip_source_file.h
@@ -1,6 +1,9 @@
+#ifndef _HAD_ZIP_SOURCE_FILE_H
+#define _HAD_ZIP_SOURCE_FILE_H
+
/*
zip_source_file.h -- header for common file operations
- Copyright (C) 2020-2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 2020-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -88,3 +91,5 @@ struct zip_source_file_operations {
};
zip_source_t *zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error);
+
+#endif /* _HAD_ZIP_SOURCE_FILE_H */
diff --git a/src/Common/libzip/zip_source_file_common.c b/src/Common/libzip/zip_source_file_common.c
index 6c58320f..99f893eb 100644
--- a/src/Common/libzip/zip_source_file_common.c
+++ b/src/Common/libzip/zip_source_file_common.c
@@ -1,6 +1,6 @@
/*
zip_source_file_common.c -- create data source from file
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_file_stdio.c b/src/Common/libzip/zip_source_file_stdio.c
index 6dcc5639..fd16f392 100644
--- a/src/Common/libzip/zip_source_file_stdio.c
+++ b/src/Common/libzip/zip_source_file_stdio.c
@@ -1,6 +1,6 @@
/*
zip_source_file_stdio.c -- read-only stdio file source implementation
- Copyright (C) 2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 2020-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -120,7 +120,7 @@ _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset,
}
#endif
- if (fseeko((FILE *)f, (off_t)offset, whence) < 0) {
+ if (zip_os_fseek((FILE *)f, (zip_off_t)offset, whence) < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
return false;
}
@@ -130,15 +130,15 @@ _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset,
bool
_zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
- struct stat sb;
+ zip_os_stat_t sb;
int ret;
if (ctx->fname) {
- ret = stat(ctx->fname, &sb);
+ ret = zip_os_stat(ctx->fname, &sb);
}
else {
- ret = fstat(fileno((FILE *)ctx->f), &sb);
+ ret = zip_os_fstat(fileno((FILE *)ctx->f), &sb);
}
if (ret < 0) {
@@ -168,7 +168,7 @@ _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
zip_int64_t
_zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) {
- off_t offset = ftello((FILE *)f);
+ zip_off_t offset = zip_os_ftell((FILE *)f);
if (offset < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
diff --git a/src/Common/libzip/zip_source_file_stdio.h b/src/Common/libzip/zip_source_file_stdio.h
index 802e6071..417a28c0 100644
--- a/src/Common/libzip/zip_source_file_stdio.h
+++ b/src/Common/libzip/zip_source_file_stdio.h
@@ -3,7 +3,7 @@
/*
zip_source_file_stdio.h -- common header for stdio file implementation
- Copyright (C) 2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 2020-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_file_stdio_named.c b/src/Common/libzip/zip_source_file_stdio_named.c
index 1495d7dd..1a5ca226 100644
--- a/src/Common/libzip/zip_source_file_stdio_named.c
+++ b/src/Common/libzip/zip_source_file_stdio_named.c
@@ -1,6 +1,6 @@
/*
zip_source_file_stdio_named.c -- source for stdio file opened by name
- Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -178,9 +178,9 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin
{
int fd;
struct file_clone_range range;
- struct stat st;
+ zip_os_stat_t st;
- if (fstat(fileno(ctx->f), &st) < 0) {
+ if (zip_os_fstat(fileno(ctx->f), &st) < 0) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
return -1;
}
@@ -223,7 +223,7 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin
ctx->tmpname = NULL;
return -1;
}
- if (fseeko(tfp, (off_t)offset, SEEK_SET) < 0) {
+ if (zip_os_fseek(tfp, (zip_off_t)offset, SEEK_SET) < 0) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
(void)fclose(tfp);
(void)remove(ctx->tmpname);
@@ -290,11 +290,11 @@ _zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64
static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) {
char *temp;
int mode;
- struct stat st;
+ zip_os_stat_t st;
int fd = 0;
char *start, *end;
- if (stat(ctx->fname, &st) == 0) {
+ if (zip_os_stat(ctx->fname, &st) == 0) {
mode = st.st_mode;
}
else {
@@ -344,7 +344,7 @@ static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) {
}
}
else {
- if (stat(temp, &st) < 0) {
+ if (zip_os_stat(temp, &st) < 0) {
if (errno == ENOENT) {
break;
}
diff --git a/src/Common/libzip/zip_source_file_win32.c b/src/Common/libzip/zip_source_file_win32.c
index 624860b1..aa669766 100644
--- a/src/Common/libzip/zip_source_file_win32.c
+++ b/src/Common/libzip/zip_source_file_win32.c
@@ -1,6 +1,6 @@
/*
zip_source_file_win32.c -- read-only Windows file source implementation
- Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_file_win32.h b/src/Common/libzip/zip_source_file_win32.h
index d86069ec..da691f0a 100644
--- a/src/Common/libzip/zip_source_file_win32.h
+++ b/src/Common/libzip/zip_source_file_win32.h
@@ -3,7 +3,7 @@
/*
zip_source_file_win32.h -- common header for Windows file implementation
- Copyright (C) 2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 2020-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -59,6 +59,7 @@ struct zip_win32_file_operations {
BOOL(__stdcall *move_file)(const void *from, const void *to, DWORD flags);
BOOL(__stdcall *set_file_attributes)(const void *name, DWORD attributes);
char *(*string_duplicate)(const char *string);
+ HANDLE(__stdcall *find_first_file)(const void *name, void *data);
};
typedef struct zip_win32_file_operations zip_win32_file_operations_t;
@@ -73,12 +74,4 @@ zip_int64_t _zip_win32_op_tell(zip_source_file_context_t *ctx, void *f);
bool _zip_filetime_to_time_t(FILETIME ft, time_t *t);
int _zip_win32_error_to_errno(DWORD win32err);
-#ifdef __clang__
-#define DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wincompatible-function-pointer-types\"")
-#define DONT_WARN_INCOMPATIBLE_FN_PTR_END _Pragma("GCC diagnostic pop")
-#else
-#define DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
-#define DONT_WARN_INCOMPATIBLE_FN_PTR_END
-#endif
-
#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */
diff --git a/src/Common/libzip/zip_source_file_win32_ansi.c b/src/Common/libzip/zip_source_file_win32_ansi.c
index 58034cc2..f10f8ae3 100644
--- a/src/Common/libzip/zip_source_file_win32_ansi.c
+++ b/src/Common/libzip/zip_source_file_win32_ansi.c
@@ -1,6 +1,6 @@
/*
zip_source_file_win32_ansi.c -- source for Windows file opened by ANSI name
- Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -34,24 +34,28 @@
#include "zip_source_file_win32.h"
static char *ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp);
+static HANDLE __stdcall ansi_create_file(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
+static BOOL __stdcall ansi_delete_file(const void *name);
+static DWORD __stdcall ansi_get_file_attributes(const void *name);
+static BOOL __stdcall ansi_get_file_attributes_ex(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information);
static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
+static BOOL __stdcall ansi_move_file(const void *from, const void *to, DWORD flags);
+static BOOL __stdcall ansi_set_file_attributes(const void *name, DWORD attributes);
+static HANDLE __stdcall ansi_find_first_file(const void *name, void* data);
/* clang-format off */
-DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
-
zip_win32_file_operations_t ops_ansi = {
ansi_allocate_tempname,
- CreateFileA,
- DeleteFileA,
- GetFileAttributesA,
- GetFileAttributesExA,
+ ansi_create_file,
+ ansi_delete_file,
+ ansi_get_file_attributes,
+ ansi_get_file_attributes_ex,
ansi_make_tempname,
- MoveFileExA,
- SetFileAttributesA,
- strdup
+ ansi_move_file,
+ ansi_set_file_attributes,
+ strdup,
+ ansi_find_first_file,
};
-
-DONT_WARN_INCOMPATIBLE_FN_PTR_END
/* clang-format on */
ZIP_EXTERN zip_source_t *
@@ -80,8 +84,49 @@ ansi_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) {
return (char *)malloc(*lengthp);
}
+static HANDLE __stdcall
+ansi_create_file(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file)
+{
+ return CreateFileA((const char *)name, access, share_mode, security_attributes, creation_disposition, file_attributes, template_file);
+}
+
+static BOOL __stdcall
+ansi_delete_file(const void *name)
+{
+ return DeleteFileA((const char *)name);
+}
+
+static DWORD __stdcall
+ansi_get_file_attributes(const void *name)
+{
+ return GetFileAttributesA((const char *)name);
+}
+
+static BOOL __stdcall
+ansi_get_file_attributes_ex(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information)
+{
+ return GetFileAttributesExA((const char *)name, info_level, information);
+}
static void
ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
snprintf_s(buf, len, "%s.%08x", name, i);
}
+
+static BOOL __stdcall
+ansi_move_file(const void *from, const void *to, DWORD flags)
+{
+ return MoveFileExA((const char *)from, (const char *)to, flags);
+}
+
+static BOOL __stdcall
+ansi_set_file_attributes(const void *name, DWORD attributes)
+{
+ return SetFileAttributesA((const char *)name, attributes);
+}
+
+static HANDLE __stdcall
+ansi_find_first_file(const void *name, void *data)
+{
+ return FindFirstFileA((const char *)name, data);
+}
diff --git a/src/Common/libzip/zip_source_file_win32_named.c b/src/Common/libzip/zip_source_file_win32_named.c
index 855e605a..ae72db19 100644
--- a/src/Common/libzip/zip_source_file_win32_named.c
+++ b/src/Common/libzip/zip_source_file_win32_named.c
@@ -1,6 +1,6 @@
/*
zip_source_file_win32_named.c -- source for Windows file opened by name
- Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -33,6 +33,13 @@
#include "zip_source_file_win32.h"
+/* ACL is not available when targeting the games API partition */
+#if defined(WINAPI_FAMILY_PARTITION) && defined(WINAPI_PARTITION_GAMES)
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)
+#define ACL_UNSUPPORTED
+#endif
+#endif
+
static zip_int64_t _zip_win32_named_op_commit_write(zip_source_file_context_t *ctx);
static zip_int64_t _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx);
static bool _zip_win32_named_op_open(zip_source_file_context_t *ctx);
@@ -110,7 +117,11 @@ _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx) {
if ((HANDLE)ctx->f != INVALID_HANDLE_VALUE && GetFileType((HANDLE)ctx->f) == FILE_TYPE_DISK) {
si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
+ #ifdef ACL_UNSUPPORTED
+ success = ERROR_NOT_SUPPORTED;
+ #else
success = GetSecurityInfo((HANDLE)ctx->f, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd);
+ #endif
if (success == ERROR_SUCCESS) {
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
@@ -210,8 +221,20 @@ _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t
st->regular_file = false;
if (file_attributes.dwFileAttributes != INVALID_FILE_ATTRIBUTES) {
- if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) == 0) {
- st->regular_file = true;
+ if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0) {
+ if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+#ifdef IO_REPARSE_TAG_DEDUP // Not defined in WinSDK 7.1 or before (VS2010).
+ WIN32_FIND_DATA find_data;
+ /* Deduplication on Windows replaces files with reparse points;
+ * accept them as regular files. */
+ if (file_ops->find_first_file(ctx->fname, &find_data) != INVALID_HANDLE_VALUE) {
+ st->regular_file = (find_data.dwReserved0 == IO_REPARSE_TAG_DEDUP);
+ }
+#endif
+ }
+ else {
+ st->regular_file = true;
+ }
}
}
diff --git a/src/Common/libzip/zip_source_file_win32_utf16.c b/src/Common/libzip/zip_source_file_win32_utf16.c
index 8f07d021..73e25666 100644
--- a/src/Common/libzip/zip_source_file_win32_utf16.c
+++ b/src/Common/libzip/zip_source_file_win32_utf16.c
@@ -1,6 +1,6 @@
/*
zip_source_file_win32_utf16.c -- source for Windows file opened by UTF-16 name
- Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -34,26 +34,30 @@
#include "zip_source_file_win32.h"
static char *utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp);
-static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
+static HANDLE __stdcall utf16_create_file(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
+static BOOL __stdcall utf16_delete_file(const void *name);
+static DWORD __stdcall utf16_get_file_attributes(const void *name);
+static BOOL __stdcall utf16_get_file_attributes_ex(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information);
static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
+static BOOL __stdcall utf16_move_file(const void *from, const void *to, DWORD flags);
+static BOOL __stdcall utf16_set_file_attributes(const void *name, DWORD attributes);
static char *utf16_strdup(const char *string);
+static HANDLE __stdcall utf16_find_first_file(const void *name, void* data);
-/* clang-format off */
-DONT_WARN_INCOMPATIBLE_FN_PTR_BEGIN
+/* clang-format off */
zip_win32_file_operations_t ops_utf16 = {
utf16_allocate_tempname,
utf16_create_file,
- DeleteFileW,
- GetFileAttributesW,
- GetFileAttributesExW,
+ utf16_delete_file,
+ utf16_get_file_attributes,
+ utf16_get_file_attributes_ex,
utf16_make_tempname,
- MoveFileExW,
- SetFileAttributesW,
- utf16_strdup
+ utf16_move_file,
+ utf16_set_file_attributes,
+ utf16_strdup,
+ utf16_find_first_file
};
-
-DONT_WARN_INCOMPATIBLE_FN_PTR_END
/* clang-format on */
ZIP_EXTERN zip_source_t *
@@ -84,7 +88,7 @@ utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) {
}
-static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file) {
+static HANDLE __stdcall utf16_create_file(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file) {
#ifdef MS_UWP
CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
extParams.dwFileAttributes = file_attributes;
@@ -100,14 +104,49 @@ static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD
#endif
}
+static BOOL __stdcall
+utf16_delete_file(const void *name)
+{
+ return DeleteFileW((const wchar_t *)name);
+}
+
+static DWORD __stdcall
+utf16_get_file_attributes(const void *name)
+{
+ return GetFileAttributesW((const wchar_t *)name);
+}
+
+static BOOL __stdcall
+utf16_get_file_attributes_ex(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information)
+{
+ return GetFileAttributesExW((const wchar_t *)name, info_level, information);
+}
static void
utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
_snwprintf_s((wchar_t *)buf, len, len, L"%s.%08x", (const wchar_t *)name, i);
}
+static BOOL __stdcall
+utf16_move_file(const void *from, const void *to, DWORD flags)
+{
+ return MoveFileExW((const wchar_t *)from, (const wchar_t *)to, flags);
+}
+
+static BOOL __stdcall
+utf16_set_file_attributes(const void *name, DWORD attributes)
+{
+ return SetFileAttributesW((const wchar_t *)name, attributes);
+}
static char *
utf16_strdup(const char *string) {
return (char *)_wcsdup((const wchar_t *)string);
}
+
+
+static HANDLE __stdcall
+utf16_find_first_file(const void *name, void* data)
+{
+ return FindFirstFileW((const wchar_t *)name, data);
+}
diff --git a/src/Common/libzip/zip_source_file_win32_utf8.c b/src/Common/libzip/zip_source_file_win32_utf8.c
index d154f97a..5c27df92 100644
--- a/src/Common/libzip/zip_source_file_win32_utf8.c
+++ b/src/Common/libzip/zip_source_file_win32_utf8.c
@@ -1,6 +1,6 @@
/*
zip_source_file_win32_ansi.c -- source for Windows file opened by UTF-8 name
- Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_free.c b/src/Common/libzip/zip_source_free.c
index 1a800405..df4b08d8 100644
--- a/src/Common/libzip/zip_source_free.c
+++ b/src/Common/libzip/zip_source_free.c
@@ -1,6 +1,6 @@
/*
zip_source_free.c -- free zip data source
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_get_dostime.c b/src/Common/libzip/zip_source_get_dostime.c
new file mode 100644
index 00000000..17f652bb
--- /dev/null
+++ b/src/Common/libzip/zip_source_get_dostime.c
@@ -0,0 +1,72 @@
+/*
+ zip_source_get_dostime.c -- get modification time in DOS format from source
+ Copyright (C) 2024 Dieter Baron and Thomas Klausner
+
+ This file is part of libzip, a library to manipulate ZIP archives.
+ The authors can be contacted at <info@libzip.org>
+
+ 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"
+
+/* Returns -1 on error, 0 on no dostime available, 1 for dostime returned */
+int
+zip_source_get_dos_time(zip_source_t *src, zip_dostime_t *dos_time) {
+ if (src->source_closed) {
+ return -1;
+ }
+ if (dos_time == NULL) {
+ zip_error_set(&src->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
+ zip_error_set(&src->error, ZIP_ER_READ, ENOENT);
+ }
+
+ if (zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_DOS_TIME)) {
+ zip_int64_t n = _zip_source_call(src, dos_time, sizeof(*dos_time), ZIP_SOURCE_GET_DOS_TIME);
+
+ if (n < 0) {
+ return -1;
+ }
+ else if (n == 0) {
+ return 0;
+ }
+ else if (n == sizeof(*dos_time)) {
+ return 1;
+ }
+ else {
+ zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+ }
+ else {
+ return 0;
+ }
+}
diff --git a/src/Common/libzip/zip_source_get_file_attributes.c b/src/Common/libzip/zip_source_get_file_attributes.c
index 4771dc16..209e39f5 100644
--- a/src/Common/libzip/zip_source_get_file_attributes.c
+++ b/src/Common/libzip/zip_source_get_file_attributes.c
@@ -1,6 +1,6 @@
/*
zip_source_get_file_attributes.c -- get attributes for file from source
- Copyright (C) 2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 2020-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_is_deleted.c b/src/Common/libzip/zip_source_is_deleted.c
index 838aa909..d6016a02 100644
--- a/src/Common/libzip/zip_source_is_deleted.c
+++ b/src/Common/libzip/zip_source_is_deleted.c
@@ -1,6 +1,6 @@
/*
zip_source_is_deleted.c -- was archive was removed?
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_layered.c b/src/Common/libzip/zip_source_layered.c
index 62b78e68..be428190 100644
--- a/src/Common/libzip/zip_source_layered.c
+++ b/src/Common/libzip/zip_source_layered.c
@@ -1,6 +1,6 @@
/*
zip_source_layered.c -- create layered source
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_open.c b/src/Common/libzip/zip_source_open.c
index b34fa2c6..9e42d0a9 100644
--- a/src/Common/libzip/zip_source_open.c
+++ b/src/Common/libzip/zip_source_open.c
@@ -1,6 +1,6 @@
/*
zip_source_open.c -- open zip_source (prepare for reading)
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_pass_to_lower_layer.c b/src/Common/libzip/zip_source_pass_to_lower_layer.c
index 4a98222e..391729e4 100644
--- a/src/Common/libzip/zip_source_pass_to_lower_layer.c
+++ b/src/Common/libzip/zip_source_pass_to_lower_layer.c
@@ -1,6 +1,6 @@
/*
zip_source_pass_to_lower_layer.c -- pass command to lower layer
- Copyright (C) 2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 2022-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -47,12 +47,12 @@ zip_int64_t zip_source_pass_to_lower_layer(zip_source_t *src, void *data, zip_ui
case ZIP_SOURCE_ACCEPT_EMPTY:
case ZIP_SOURCE_ERROR:
+ case ZIP_SOURCE_GET_DOS_TIME:
case ZIP_SOURCE_READ:
case ZIP_SOURCE_SEEK:
case ZIP_SOURCE_TELL:
return _zip_source_call(src, data, length, command);
-
case ZIP_SOURCE_BEGIN_WRITE:
case ZIP_SOURCE_BEGIN_WRITE_CLONING:
case ZIP_SOURCE_COMMIT_WRITE:
diff --git a/src/Common/libzip/zip_source_pkware_decode.c b/src/Common/libzip/zip_source_pkware_decode.c
index b4c482b3..9c22a069 100644
--- a/src/Common/libzip/zip_source_pkware_decode.c
+++ b/src/Common/libzip/zip_source_pkware_decode.c
@@ -1,6 +1,6 @@
/*
zip_source_pkware_decode.c -- Traditional PKWARE decryption routines
- Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -80,9 +80,9 @@ zip_source_pkware_decode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flag
static int
decrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
zip_uint8_t header[ZIP_CRYPTO_PKWARE_HEADERLEN];
- struct zip_stat st;
+ zip_stat_t st;
+ zip_dostime_t dostime;
zip_int64_t n;
- bool ok = false;
if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) {
zip_error_set_from_source(&ctx->error, src);
@@ -96,36 +96,35 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
_zip_pkware_decrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN);
- if (zip_source_stat(src, &st)) {
- /* stat failed, skip password validation */
+ if (zip_source_stat(src, &st) < 0 || (st.valid & ZIP_STAT_CRC) == 0) {
+ /* skip password validation */
return 0;
}
- /* password verification - two ways:
- * mtime - InfoZIP way, to avoid computing complete CRC before encrypting data
- * CRC - old PKWare way
- */
-
- if (st.valid & ZIP_STAT_MTIME) {
- unsigned short dostime, dosdate;
- _zip_u2d_time(st.mtime, &dostime, &dosdate);
- if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime >> 8) {
- ok = true;
+ if (zip_source_get_dos_time(src, &dostime) <= 0) {
+ if ((st.valid & ZIP_STAT_MTIME) == 0) {
+ /* no date available, skip password validation */
+ return 0;
}
- }
- if (st.valid & ZIP_STAT_CRC) {
- if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == st.crc >> 24) {
- ok = true;
+ if (_zip_u2d_time(st.mtime, &dostime, &ctx->error) < 0) {
+ return -1;
}
}
- if (!ok && ((st.valid & (ZIP_STAT_MTIME | ZIP_STAT_CRC)) != 0)) {
+ /*
+ password verification - two ways:
+ - mtime - InfoZIP way, to avoid computing complete CRC before encrypting data
+ - CRC - old PKWare way
+ */
+ if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime.time >> 8
+ || header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == st.crc >> 24) {
+ return 0;
+ }
+ else {
zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0);
return -1;
}
-
- return 0;
}
diff --git a/src/Common/libzip/zip_source_pkware_encode.c b/src/Common/libzip/zip_source_pkware_encode.c
index d89b9f4e..fed76115 100644
--- a/src/Common/libzip/zip_source_pkware_encode.c
+++ b/src/Common/libzip/zip_source_pkware_encode.c
@@ -1,6 +1,6 @@
/*
zip_source_pkware_encode.c -- Traditional PKWARE encryption routines
- Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -42,8 +42,7 @@ struct trad_pkware {
zip_pkware_keys_t keys;
zip_buffer_t *buffer;
bool eof;
- bool mtime_set;
- time_t mtime;
+ zip_dostime_t dostime;
zip_error_t error;
};
@@ -52,7 +51,6 @@ static int encrypt_header(zip_source_t *, struct trad_pkware *);
static zip_int64_t pkware_encrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
static void trad_pkware_free(struct trad_pkware *);
static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error);
-static void set_mtime(struct trad_pkware* ctx, zip_stat_t* st);
zip_source_t *
zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) {
@@ -69,9 +67,24 @@ zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flag
}
if ((ctx = trad_pkware_new(password, &za->error)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
+ if (zip_source_get_dos_time(src, &ctx->dostime) <= 0) {
+ zip_stat_t st;
+
+ if (zip_source_stat(src, &st) < 0) {
+ zip_error_set_from_source(&za->error, src);
+ trad_pkware_free(ctx);
+ return NULL;
+ }
+ if (_zip_u2d_time((st.valid & ZIP_STAT_MTIME) ? st.mtime : time(NULL), &ctx->dostime, &za->error) < 0) {
+ trad_pkware_free(ctx);
+ return NULL;
+ }
+ }
+
if ((s2 = zip_source_layered(za, src, pkware_encrypt, ctx)) == NULL) {
trad_pkware_free(ctx);
return NULL;
@@ -83,20 +96,8 @@ zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flag
static int
encrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
- unsigned short dostime, dosdate;
zip_uint8_t *header;
- if (!ctx->mtime_set) {
- struct zip_stat st;
- if (zip_source_stat(src, &st) != 0) {
- zip_error_set_from_source(&ctx->error, src);
- return -1;
- }
- set_mtime(ctx, &st);
- }
-
- _zip_u2d_time(ctx->mtime, &dostime, &dosdate);
-
if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
@@ -112,7 +113,7 @@ encrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
ctx->buffer = NULL;
return -1;
}
- header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] = (zip_uint8_t)((dostime >> 8) & 0xff);
+ header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] = (zip_uint8_t)((ctx->dostime.time >> 8) & 0xff);
_zip_pkware_encrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN);
@@ -187,9 +188,6 @@ pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip
if (st->valid & ZIP_STAT_COMP_SIZE) {
st->comp_size += ZIP_CRYPTO_PKWARE_HEADERLEN;
}
- set_mtime(ctx, st);
- st->mtime = ctx->mtime;
- st->valid |= ZIP_STAT_MTIME;
return 0;
}
@@ -206,8 +204,16 @@ pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip
return 0;
}
+ case ZIP_SOURCE_GET_DOS_TIME:
+ if (length < sizeof(ctx->dostime)) {
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+ (void)memcpy_s(data, sizeof(ctx->dostime), &ctx->dostime, sizeof(ctx->dostime));
+ return sizeof(ctx->dostime);
+
case ZIP_SOURCE_SUPPORTS:
- return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
+ return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_GET_DOS_TIME, -1);
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, length);
@@ -237,8 +243,6 @@ trad_pkware_new(const char *password, zip_error_t *error) {
return NULL;
}
ctx->buffer = NULL;
- ctx->mtime_set = false;
- ctx->mtime = 0;
zip_error_init(&ctx->error);
return ctx;
@@ -256,16 +260,3 @@ trad_pkware_free(struct trad_pkware *ctx) {
zip_error_fini(&ctx->error);
free(ctx);
}
-
-
-static void set_mtime(struct trad_pkware* ctx, zip_stat_t* st) {
- if (!ctx->mtime_set) {
- if (st->valid & ZIP_STAT_MTIME) {
- ctx->mtime = st->mtime;
- }
- else {
- time(&ctx->mtime);
- }
- ctx->mtime_set = true;
- }
-}
diff --git a/src/Common/libzip/zip_source_read.c b/src/Common/libzip/zip_source_read.c
index 0938fcb0..910d4c3e 100644
--- a/src/Common/libzip/zip_source_read.c
+++ b/src/Common/libzip/zip_source_read.c
@@ -1,6 +1,6 @@
/*
zip_source_read.c -- read data from zip_source
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_remove.c b/src/Common/libzip/zip_source_remove.c
index c1d73ab9..06325b72 100644
--- a/src/Common/libzip/zip_source_remove.c
+++ b/src/Common/libzip/zip_source_remove.c
@@ -1,6 +1,6 @@
/*
zip_source_remove.c -- remove empty archive
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_rollback_write.c b/src/Common/libzip/zip_source_rollback_write.c
index ea1a1510..51613252 100644
--- a/src/Common/libzip/zip_source_rollback_write.c
+++ b/src/Common/libzip/zip_source_rollback_write.c
@@ -1,6 +1,6 @@
/*
zip_source_rollback_write.c -- discard changes
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_seek.c b/src/Common/libzip/zip_source_seek.c
index e3baad5a..42d6b0d2 100644
--- a/src/Common/libzip/zip_source_seek.c
+++ b/src/Common/libzip/zip_source_seek.c
@@ -1,6 +1,6 @@
/*
zip_source_seek.c -- seek to offset
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_seek_write.c b/src/Common/libzip/zip_source_seek_write.c
index 34ae2f5a..9e87fa4d 100644
--- a/src/Common/libzip/zip_source_seek_write.c
+++ b/src/Common/libzip/zip_source_seek_write.c
@@ -1,6 +1,6 @@
/*
zip_source_seek_write.c -- seek to offset for writing
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_stat.c b/src/Common/libzip/zip_source_stat.c
index 05dcb84d..7c8bacac 100644
--- a/src/Common/libzip/zip_source_stat.c
+++ b/src/Common/libzip/zip_source_stat.c
@@ -1,6 +1,6 @@
/*
zip_source_stat.c -- get meta information from zip_source
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_supports.c b/src/Common/libzip/zip_source_supports.c
index 8fea2ae9..e30ee757 100644
--- a/src/Common/libzip/zip_source_supports.c
+++ b/src/Common/libzip/zip_source_supports.c
@@ -1,6 +1,6 @@
/*
zip_source_supports.c -- check for supported functions
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_tell.c b/src/Common/libzip/zip_source_tell.c
index 49057ce5..33ec475e 100644
--- a/src/Common/libzip/zip_source_tell.c
+++ b/src/Common/libzip/zip_source_tell.c
@@ -1,6 +1,6 @@
/*
zip_source_tell.c -- report current offset
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_tell_write.c b/src/Common/libzip/zip_source_tell_write.c
index a5b0e531..6912af9e 100644
--- a/src/Common/libzip/zip_source_tell_write.c
+++ b/src/Common/libzip/zip_source_tell_write.c
@@ -1,6 +1,6 @@
/*
zip_source_tell_write.c -- report current offset for writing
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_window.c b/src/Common/libzip/zip_source_window.c
index 524e27c8..eac27c39 100644
--- a/src/Common/libzip/zip_source_window.c
+++ b/src/Common/libzip/zip_source_window.c
@@ -1,6 +1,6 @@
/*
zip_source_window.c -- return part of lower source
- Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -51,6 +51,8 @@ struct window {
zip_stat_t stat;
zip_uint64_t stat_invalid;
zip_file_attributes_t attributes;
+ zip_dostime_t dostime;
+ bool dostime_valid;
zip_error_t error;
zip_int64_t supports;
bool needs_seek;
@@ -61,12 +63,12 @@ static zip_int64_t window_read(zip_source_t *, void *, void *, zip_uint64_t, zip
ZIP_EXTERN zip_source_t *
zip_source_window_create(zip_source_t *src, zip_uint64_t start, zip_int64_t len, zip_error_t *error) {
- return _zip_source_window_new(src, start, len, NULL, 0, NULL, NULL, 0, false, error);
+ return _zip_source_window_new(src, start, len, NULL, 0, NULL, NULL, NULL, 0, false, error);
}
zip_source_t *
-_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_uint64_t st_invalid, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, bool take_ownership, zip_error_t *error) {
+_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_uint64_t st_invalid, zip_file_attributes_t *attributes, zip_dostime_t *dostime, zip_t *source_archive, zip_uint64_t source_index, bool take_ownership, zip_error_t *error) {
zip_source_t* window_source;
struct window *ctx;
@@ -103,10 +105,17 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length
else {
zip_file_attributes_init(&ctx->attributes);
}
+ if (dostime != NULL) {
+ ctx->dostime = *dostime;
+ ctx->dostime_valid = true;
+ }
+ else {
+ ctx->dostime_valid = false;
+ }
ctx->source_archive = source_archive;
ctx->source_index = source_index;
zip_error_init(&ctx->error);
- ctx->supports = (zip_source_supports(src) & (ZIP_SOURCE_SUPPORTS_SEEKABLE | ZIP_SOURCE_SUPPORTS_REOPEN)) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, ZIP_SOURCE_FREE, -1));
+ ctx->supports = (zip_source_supports(src) & (ZIP_SOURCE_SUPPORTS_SEEKABLE | ZIP_SOURCE_SUPPORTS_REOPEN)) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_GET_DOS_TIME, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, ZIP_SOURCE_FREE, -1));
ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false;
if (st) {
@@ -309,6 +318,19 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
(void)memcpy_s(data, sizeof(ctx->attributes), &ctx->attributes, sizeof(ctx->attributes));
return sizeof(ctx->attributes);
+ case ZIP_SOURCE_GET_DOS_TIME:
+ if (len < sizeof(ctx->dostime)) {
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+ if (ctx->dostime_valid) {
+ (void)memcpy_s(data, sizeof(ctx->dostime), &ctx->dostime, sizeof(ctx->dostime));
+ return sizeof(ctx->dostime);
+ }
+ else {
+ return 0;
+ }
+
case ZIP_SOURCE_SUPPORTS:
return ctx->supports;
diff --git a/src/Common/libzip/zip_source_winzip_aes_decode.c b/src/Common/libzip/zip_source_winzip_aes_decode.c
index ee53fb41..8830a005 100644
--- a/src/Common/libzip/zip_source_winzip_aes_decode.c
+++ b/src/Common/libzip/zip_source_winzip_aes_decode.c
@@ -1,6 +1,6 @@
/*
zip_source_winzip_aes_decode.c -- Winzip AES decryption routines
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_winzip_aes_encode.c b/src/Common/libzip/zip_source_winzip_aes_encode.c
index 87e2865a..c704b123 100644
--- a/src/Common/libzip/zip_source_winzip_aes_encode.c
+++ b/src/Common/libzip/zip_source_winzip_aes_encode.c
@@ -1,6 +1,6 @@
/*
zip_source_winzip_aes_encode.c -- Winzip AES encryption routines
- Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2009-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_write.c b/src/Common/libzip/zip_source_write.c
index 24dde9b2..20ca361c 100644
--- a/src/Common/libzip/zip_source_write.c
+++ b/src/Common/libzip/zip_source_write.c
@@ -1,6 +1,6 @@
/*
zip_source_write.c -- start a new file for writing
- Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_zip.c b/src/Common/libzip/zip_source_zip.c
index faabf0d2..07819865 100644
--- a/src/Common/libzip/zip_source_zip.c
+++ b/src/Common/libzip/zip_source_zip.c
@@ -1,6 +1,6 @@
/*
zip_source_zip.c -- create data source from zip file
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2023 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_source_zip_new.c b/src/Common/libzip/zip_source_zip_new.c
index ecccdd68..3eb8a4c2 100644
--- a/src/Common/libzip/zip_source_zip_new.c
+++ b/src/Common/libzip/zip_source_zip_new.c
@@ -1,6 +1,6 @@
/*
zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip
- Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -200,7 +200,7 @@ ZIP_EXTERN zip_source_t *zip_source_zip_file_create(zip_t *srcza, zip_uint64_t s
st2.valid |= ZIP_STAT_MTIME;
}
- if ((src = _zip_source_window_new(src, start, data_len, &st2, ZIP_STAT_NAME, &attributes, source_archive, source_index, take_ownership, error)) == NULL) {
+ if ((src = _zip_source_window_new(src, start, data_len, &st2, ZIP_STAT_NAME, &attributes, &de->last_mod, source_archive, source_index, take_ownership, error)) == NULL) {
return NULL;
}
}
@@ -219,7 +219,7 @@ ZIP_EXTERN zip_source_t *zip_source_zip_file_create(zip_t *srcza, zip_uint64_t s
attributes and to have a source that positions the read
offset properly before each read for multiple zip_file_t
referring to the same underlying source */
- if ((src = _zip_source_window_new(srcza->src, 0, (zip_int64_t)st.comp_size, &st, ZIP_STAT_NAME, &attributes, srcza, srcidx, take_ownership, error)) == NULL) {
+ if ((src = _zip_source_window_new(srcza->src, 0, (zip_int64_t)st.comp_size, &st, ZIP_STAT_NAME, &attributes, &de->last_mod, srcza, srcidx, take_ownership, error)) == NULL) {
return NULL;
}
}
@@ -235,7 +235,7 @@ ZIP_EXTERN zip_source_t *zip_source_zip_file_create(zip_t *srcza, zip_uint64_t s
attributes and to have a source that positions the read
offset properly before each read for multiple zip_file_t
referring to the same underlying source */
- if ((src = _zip_source_window_new(src, 0, data_len, &st, ZIP_STAT_NAME, &attributes, NULL, 0, take_ownership, error)) == NULL) {
+ if ((src = _zip_source_window_new(src, 0, data_len, &st, ZIP_STAT_NAME, &attributes, &de->last_mod, NULL, 0, take_ownership, error)) == NULL) {
return NULL;
}
}
@@ -253,6 +253,7 @@ ZIP_EXTERN zip_source_t *zip_source_zip_file_create(zip_t *srcza, zip_uint64_t s
zip_encryption_implementation enc_impl;
if ((enc_impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) {
+ zip_source_free(src);
zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
return NULL;
}
@@ -289,7 +290,7 @@ ZIP_EXTERN zip_source_t *zip_source_zip_file_create(zip_t *srcza, zip_uint64_t s
st2.valid = ZIP_STAT_SIZE;
st2.size = (zip_uint64_t)data_len;
}
- s2 = _zip_source_window_new(src, start, data_len, &st2, ZIP_STAT_NAME, NULL, NULL, 0, true, error);
+ s2 = _zip_source_window_new(src, start, data_len, &st2, ZIP_STAT_NAME, NULL, NULL, NULL, 0, true, error);
if (s2 == NULL) {
zip_source_free(src);
return NULL;
diff --git a/src/Common/libzip/zip_stat.c b/src/Common/libzip/zip_stat.c
index 51d8026d..74fc5c37 100644
--- a/src/Common/libzip/zip_stat.c
+++ b/src/Common/libzip/zip_stat.c
@@ -1,6 +1,6 @@
/*
zip_stat.c -- get information about file by name
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_stat_index.c b/src/Common/libzip/zip_stat_index.c
index da33c09e..af9f0e5f 100644
--- a/src/Common/libzip/zip_stat_index.c
+++ b/src/Common/libzip/zip_stat_index.c
@@ -1,6 +1,6 @@
/*
zip_stat_index.c -- get information about file by index
- Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -77,7 +77,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
}
if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_LAST_MOD) {
- st->mtime = de->last_mod;
+ st->mtime = zip_dirent_get_last_mod_mtime(de);
st->valid |= ZIP_STAT_MTIME;
}
}
@@ -86,7 +86,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
st->crc = de->crc;
st->size = de->uncomp_size;
- st->mtime = de->last_mod;
+ st->mtime = zip_dirent_get_last_mod_mtime(de);
st->comp_size = de->comp_size;
st->comp_method = (zip_uint16_t)de->comp_method;
st->encryption_method = de->encryption_method;
@@ -97,8 +97,12 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st)
}
if ((za->ch_flags & ZIP_AFL_WANT_TORRENTZIP) && (flags & ZIP_FL_UNCHANGED) == 0) {
+ if (za->torrent_mtime == 0) {
+ zip_dostime_t dostime = {0xbc00, 0x2198};
+ za->torrent_mtime = _zip_d2u_time(&dostime);
+ }
st->comp_method = ZIP_CM_DEFLATE;
- st->mtime = _zip_d2u_time(0xbc00, 0x2198);
+ st->mtime = za->torrent_mtime;
st->valid |= ZIP_STAT_MTIME | ZIP_STAT_COMP_METHOD;
st->valid &= ~ZIP_STAT_COMP_SIZE;
}
diff --git a/src/Common/libzip/zip_stat_init.c b/src/Common/libzip/zip_stat_init.c
index 9c6088a7..bd83565b 100644
--- a/src/Common/libzip/zip_stat_init.c
+++ b/src/Common/libzip/zip_stat_init.c
@@ -1,6 +1,6 @@
/*
zip_stat_init.c -- initialize struct zip_stat.
- Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_strerror.c b/src/Common/libzip/zip_strerror.c
index 7d827931..681024a3 100644
--- a/src/Common/libzip/zip_strerror.c
+++ b/src/Common/libzip/zip_strerror.c
@@ -1,6 +1,6 @@
/*
zip_sterror.c -- get string representation of zip error
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_string.c b/src/Common/libzip/zip_string.c
index 1c964491..bb06c1d6 100644
--- a/src/Common/libzip/zip_string.c
+++ b/src/Common/libzip/zip_string.c
@@ -1,6 +1,6 @@
/*
zip_string.c -- string handling (with encoding)
- Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2012-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -88,8 +88,10 @@ _zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip
if ((flags & ZIP_FL_ENC_RAW) == 0) {
/* start guessing */
- if (string->encoding == ZIP_ENCODING_UNKNOWN)
- _zip_guess_encoding(string, ZIP_ENCODING_UNKNOWN);
+ if (string->encoding == ZIP_ENCODING_UNKNOWN) {
+ /* guess encoding, sets string->encoding */
+ (void)_zip_guess_encoding(string, ZIP_ENCODING_UNKNOWN);
+ }
if (((flags & ZIP_FL_ENC_STRICT) && string->encoding != ZIP_ENCODING_ASCII && string->encoding != ZIP_ENCODING_UTF8_KNOWN) || (string->encoding == ZIP_ENCODING_CP437)) {
if (string->converted == NULL) {
@@ -107,6 +109,20 @@ _zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip
return string->raw;
}
+bool _zip_string_is_ascii(const zip_string_t *string) {
+ if (string->encoding != ZIP_ENCODING_ASCII) {
+ zip_uint16_t i;
+
+ for (i = 0; i < string->length; i++) {
+ if (string->raw[i] & 0x80) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
zip_uint16_t
_zip_string_length(const zip_string_t *s) {
diff --git a/src/Common/libzip/zip_unchange_all.c b/src/Common/libzip/zip_unchange_all.c
index 34f3702e..0b22c803 100644
--- a/src/Common/libzip/zip_unchange_all.c
+++ b/src/Common/libzip/zip_unchange_all.c
@@ -1,6 +1,6 @@
/*
zip_unchange.c -- undo changes to all files in zip archive
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_unchange_archive.c b/src/Common/libzip/zip_unchange_archive.c
index 56a8e31f..ddd617bc 100644
--- a/src/Common/libzip/zip_unchange_archive.c
+++ b/src/Common/libzip/zip_unchange_archive.c
@@ -1,6 +1,6 @@
/*
zip_unchange_archive.c -- undo global changes to ZIP archive
- Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_unchange_data.c b/src/Common/libzip/zip_unchange_data.c
index 6bdecd18..30a7be7b 100644
--- a/src/Common/libzip/zip_unchange_data.c
+++ b/src/Common/libzip/zip_unchange_data.c
@@ -1,6 +1,6 @@
/*
zip_unchange_data.c -- undo helper function
- Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zip_utf-8.c b/src/Common/libzip/zip_utf-8.c
index 678912f6..7d671f60 100644
--- a/src/Common/libzip/zip_utf-8.c
+++ b/src/Common/libzip/zip_utf-8.c
@@ -1,6 +1,6 @@
/*
zip_utf-8.c -- UTF-8 support functions for libzip
- Copyright (C) 2011-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2011-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -101,70 +101,124 @@ _zip_guess_encoding(zip_string_t *str, zip_encoding_type_t expected_encoding) {
zip_encoding_type_t enc;
const zip_uint8_t *name;
zip_uint32_t i, j, ulen;
+ bool can_be_ascii = true;
+ bool can_be_utf8 = true;
+ bool has_control_characters = false;
- if (str == NULL)
+ if (str == NULL) {
return ZIP_ENCODING_ASCII;
+ }
name = str->raw;
- if (str->encoding != ZIP_ENCODING_UNKNOWN)
- enc = str->encoding;
- else {
- enc = ZIP_ENCODING_ASCII;
- for (i = 0; i < str->length; i++) {
- if ((name[i] > 31 && name[i] < 128) || name[i] == '\r' || name[i] == '\n' || name[i] == '\t')
- continue;
-
- enc = ZIP_ENCODING_UTF8_GUESSED;
- if ((name[i] & UTF_8_LEN_2_MASK) == UTF_8_LEN_2_MATCH)
- ulen = 1;
- else if ((name[i] & UTF_8_LEN_3_MASK) == UTF_8_LEN_3_MATCH)
- ulen = 2;
- else if ((name[i] & UTF_8_LEN_4_MASK) == UTF_8_LEN_4_MATCH)
- ulen = 3;
- else {
- enc = ZIP_ENCODING_CP437;
- break;
- }
+ if (str->encoding != ZIP_ENCODING_UNKNOWN) {
+ return str->encoding;
+ }
- if (i + ulen >= str->length) {
- enc = ZIP_ENCODING_CP437;
- break;
+ for (i = 0; i < str->length; i++) {
+ if (name[i] < 128) {
+ if (name[i] < 32 && name[i] != '\r' && name[i] != '\n' && name[i] != '\t') {
+ has_control_characters = true;
}
+ continue;
+ }
+
+ can_be_ascii = false;
+ if ((name[i] & UTF_8_LEN_2_MASK) == UTF_8_LEN_2_MATCH) {
+ ulen = 1;
+ }
+ else if ((name[i] & UTF_8_LEN_3_MASK) == UTF_8_LEN_3_MATCH) {
+ ulen = 2;
+ }
+ else if ((name[i] & UTF_8_LEN_4_MASK) == UTF_8_LEN_4_MATCH) {
+ ulen = 3;
+ }
+ else {
+ can_be_utf8 = false;
+ break;
+ }
- for (j = 1; j <= ulen; j++) {
- if ((name[i + j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) {
- enc = ZIP_ENCODING_CP437;
- goto done;
- }
+ if (i + ulen >= str->length) {
+ can_be_utf8 = false;
+ break;
+ }
+
+ for (j = 1; j <= ulen; j++) {
+ if ((name[i + j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) {
+ can_be_utf8 = false;
+ goto done;
}
- i += ulen;
}
+ i += ulen;
}
-done:
- str->encoding = enc;
+ done:
+ enc = ZIP_ENCODING_CP437;
+
+ switch (expected_encoding) {
+ case ZIP_ENCODING_UTF8_KNOWN:
+ case ZIP_ENCODING_UTF8_GUESSED:
+ if (can_be_utf8) {
+ enc = ZIP_ENCODING_UTF8_KNOWN;
+ }
+ else {
+ enc = ZIP_ENCODING_ERROR;
+ }
+ break;
- if (expected_encoding != ZIP_ENCODING_UNKNOWN) {
- if (expected_encoding == ZIP_ENCODING_UTF8_KNOWN && enc == ZIP_ENCODING_UTF8_GUESSED)
- str->encoding = enc = ZIP_ENCODING_UTF8_KNOWN;
+ case ZIP_ENCODING_ASCII:
+ if (can_be_ascii && !has_control_characters) {
+ enc = ZIP_ENCODING_ASCII;
+ }
+ else {
+ enc = ZIP_ENCODING_ERROR;
+ }
+ break;
- if (expected_encoding != enc && enc != ZIP_ENCODING_ASCII)
- return ZIP_ENCODING_ERROR;
+ case ZIP_ENCODING_CP437:
+ enc = ZIP_ENCODING_CP437;
+ break;
+
+ case ZIP_ENCODING_UNKNOWN:
+ if (can_be_ascii && !has_control_characters) {
+ /* only bytes from 0x20-0x7F */
+ enc = ZIP_ENCODING_ASCII;
+ }
+ else if (can_be_ascii && has_control_characters) {
+ /* only bytes from 0x00-0x7F */
+ enc = ZIP_ENCODING_CP437;
+ }
+ else if (can_be_utf8) {
+ /* contains bytes from 0x80-0xFF and is valid UTF-8 */
+ enc = ZIP_ENCODING_UTF8_GUESSED;
+ }
+ else {
+ /* fallback */
+ enc = ZIP_ENCODING_CP437;
+ }
+ break;
+ case ZIP_ENCODING_ERROR:
+ /* invalid, shouldn't happen */
+ enc = ZIP_ENCODING_ERROR;
+ break;
}
+ str->encoding = enc;
return enc;
}
static zip_uint32_t
_zip_unicode_to_utf8_len(zip_uint32_t codepoint) {
- if (codepoint < 0x0080)
+ if (codepoint < 0x0080) {
return 1;
- if (codepoint < 0x0800)
+ }
+ if (codepoint < 0x0800) {
return 2;
- if (codepoint < 0x10000)
+ }
+ if (codepoint < 0x10000) {
return 3;
+ }
return 4;
}
@@ -201,14 +255,16 @@ _zip_cp437_to_utf8(const zip_uint8_t *const _cp437buf, zip_uint32_t len, zip_uin
zip_uint32_t buflen, i, offset;
if (len == 0) {
- if (utf8_lenp)
+ if (utf8_lenp) {
*utf8_lenp = 0;
+ }
return NULL;
}
buflen = 1;
- for (i = 0; i < len; i++)
+ for (i = 0; i < len; i++) {
buflen += _zip_unicode_to_utf8_len(_cp437_to_unicode[cp437buf[i]]);
+ }
if ((utf8buf = (zip_uint8_t *)malloc(buflen)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
@@ -216,11 +272,13 @@ _zip_cp437_to_utf8(const zip_uint8_t *const _cp437buf, zip_uint32_t len, zip_uin
}
offset = 0;
- for (i = 0; i < len; i++)
+ for (i = 0; i < len; i++) {
offset += _zip_unicode_to_utf8(_cp437_to_unicode[cp437buf[i]], utf8buf + offset);
+ }
utf8buf[buflen - 1] = 0;
- if (utf8_lenp)
+ if (utf8_lenp) {
*utf8_lenp = buflen - 1;
+ }
return utf8buf;
}
diff --git a/src/Common/libzip/zip_winzip_aes.c b/src/Common/libzip/zip_winzip_aes.c
index ce269036..2c9874b0 100644
--- a/src/Common/libzip/zip_winzip_aes.c
+++ b/src/Common/libzip/zip_winzip_aes.c
@@ -1,6 +1,6 @@
/*
zip_winzip_aes.c -- Winzip AES de/encryption backend routines
- Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2022 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
diff --git a/src/Common/libzip/zipconf.h b/src/Common/libzip/zipconf.h
index 472e06c1..28954780 100644
--- a/src/Common/libzip/zipconf.h
+++ b/src/Common/libzip/zipconf.h
@@ -8,10 +8,10 @@
based on ../cmake-zipconf.h.in.
*/
-#define LIBZIP_VERSION "1.10.1"
+#define LIBZIP_VERSION "1.11.2"
#define LIBZIP_VERSION_MAJOR 1
-#define LIBZIP_VERSION_MINOR 10
-#define LIBZIP_VERSION_MICRO 1
+#define LIBZIP_VERSION_MINOR 11
+#define LIBZIP_VERSION_MICRO 2
/* #undef ZIP_STATIC */
diff --git a/src/Common/libzip/zipint.h b/src/Common/libzip/zipint.h
index 4887b6c5..e22d74c2 100644
--- a/src/Common/libzip/zipint.h
+++ b/src/Common/libzip/zipint.h
@@ -3,7 +3,7 @@
/*
zipint.h -- internal declarations.
- Copyright (C) 1999-2022 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2024 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <info@libzip.org>
@@ -56,6 +56,7 @@
#define DATADES_MAGIC "PK\7\10"
#define EOCD64LOC_MAGIC "PK\6\7"
#define EOCD64_MAGIC "PK\6\6"
+#define MAGIC_LEN 4
#define CDENTRYSIZE 46u
#define LENTRYSIZE 30
#define MAXCOMLEN 65536
@@ -229,12 +230,17 @@ extern const int _zip_err_details_count;
#define ZIP_ER_DETAIL_CDIR_INVALID 11 /* G invalid value in central directory */
#define ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW 12 /* E variable size fields overflow header */
#define ZIP_ER_DETAIL_INVALID_UTF8_IN_FILENAME 13 /* E invalid UTF-8 in filename */
-#define ZIP_ER_DETAIL_INVALID_UTF8_IN_COMMENT 13 /* E invalid UTF-8 in comment */
-#define ZIP_ER_DETAIL_INVALID_ZIP64_EF 14 /* E invalid Zip64 extra field */
-#define ZIP_ER_DETAIL_INVALID_WINZIPAES_EF 14 /* E invalid WinZip AES extra field */
-#define ZIP_ER_DETAIL_EF_TRAILING_GARBAGE 15 /* E garbage at end of extra fields */
-#define ZIP_ER_DETAIL_INVALID_EF_LENGTH 16 /* E extra field length is invalid */
-#define ZIP_ER_DETAIL_INVALID_FILE_LENGTH 17 /* E file length in header doesn't match actual file length */
+#define ZIP_ER_DETAIL_INVALID_UTF8_IN_COMMENT 14 /* E invalid UTF-8 in comment */
+#define ZIP_ER_DETAIL_INVALID_ZIP64_EF 15 /* E invalid Zip64 extra field */
+#define ZIP_ER_DETAIL_INVALID_WINZIPAES_EF 16 /* E invalid WinZip AES extra field */
+#define ZIP_ER_DETAIL_EF_TRAILING_GARBAGE 17 /* E garbage at end of extra fields */
+#define ZIP_ER_DETAIL_INVALID_EF_LENGTH 18 /* E extra field length is invalid */
+#define ZIP_ER_DETAIL_INVALID_FILE_LENGTH 19 /* E file length in header doesn't match actual file length */
+#define ZIP_ER_DETAIL_STORED_SIZE_MISMATCH 20 /* E compressed and uncompressed sizes don't match for stored file */
+#define ZIP_ER_DETAIL_DATA_DESCRIPTOR_MISMATCH 21 /* E local header and data descriptor do not match */
+#define ZIP_ER_DETAIL_EOCD64_LOCATOR_MISMATCH 22 /* G EOCD64 and EOCD64 locator do not match */
+#define ZIP_ER_DETAIL_UTF8_FILENAME_MISMATCH 23 /* E UTF-8 filename is ASCII and doesn't match filename */
+#define ZIP_ER_DETAIL_UTF8_COMMENT_MISMATCH 24 /* E UTF-8 comment is ASCII and doesn't match comment */
/* directory entry: general purpose bit flags */
@@ -270,6 +276,7 @@ struct zip_hash;
struct zip_progress;
typedef struct zip_cdir zip_cdir_t;
+typedef struct zip_dostime zip_dostime_t;
typedef struct zip_dirent zip_dirent_t;
typedef struct zip_entry zip_entry_t;
typedef struct zip_extra_field zip_extra_field_t;
@@ -307,6 +314,7 @@ struct zip {
zip_progress_t *progress; /* progress callback for zip_close() */
zip_uint32_t* write_crc; /* have _zip_write() compute CRC */
+ time_t torrent_mtime;
};
/* file in zip archive, part of API */
@@ -328,18 +336,24 @@ struct zip_file {
#define ZIP_DIRENT_PASSWORD 0x0080u
#define ZIP_DIRENT_ALL ZIP_UINT32_MAX
+struct zip_dostime {
+ zip_uint16_t time;
+ zip_uint16_t date;
+};
+
struct zip_dirent {
zip_uint32_t changed;
bool local_extra_fields_read; /* whether we already read in local header extra fields */
bool cloned; /* whether this instance is cloned, and thus shares non-changed strings */
bool crc_valid; /* if CRC is valid (sometimes not for encrypted archives) */
+ bool last_mod_mtime_valid;
zip_uint16_t version_madeby; /* (c) version of creator */
zip_uint16_t version_needed; /* (cl) version needed to extract */
zip_uint16_t bitflags; /* (cl) general purpose bit flag */
zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */
- time_t last_mod; /* (cl) time of last modification */
+ zip_dostime_t last_mod; /* (cl) time of last modification */
zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */
zip_uint64_t comp_size; /* (cl) size of compressed data */
zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */
@@ -354,6 +368,8 @@ struct zip_dirent {
zip_uint32_t compression_level; /* level of compression to use (never valid in orig) */
zip_uint16_t encryption_method; /* encryption method, computed from other fields */
char *password; /* file specific encryption password */
+
+ time_t last_mod_mtime; /* cached last_mod in Unix time format */
};
/* zip archive central directory */
@@ -363,8 +379,13 @@ struct zip_cdir {
zip_uint64_t nentry; /* number of entries */
zip_uint64_t nentry_alloc; /* number of entries allocated */
+ zip_uint32_t this_disk;
+ zip_uint32_t eocd_disk;
+ zip_uint64_t disk_entries; /* number of entries on this disk */
+ zip_uint64_t num_entries; /* number of entries on all disks */
zip_uint64_t size; /* size of central directory */
zip_uint64_t offset; /* offset of central directory in file */
+ zip_uint64_t eocd_offset; /* offset of EOCD in file */
zip_string_t *comment; /* zip archive comment */
bool is_zip64; /* central directory in zip64 format */
};
@@ -526,20 +547,22 @@ zip_uint64_t _zip_buffer_size(zip_buffer_t *buffer);
void _zip_cdir_free(zip_cdir_t *);
bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error);
-zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *);
+zip_cdir_t *_zip_cdir_new(zip_error_t *);
zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors);
-time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
+time_t _zip_d2u_time(const zip_dostime_t*);
void _zip_deregister_source(zip_t *za, zip_source_t *src);
void _zip_dirent_apply_attributes(zip_dirent_t *, zip_file_attributes_t *, bool, zip_uint32_t);
+int zip_dirent_check_consistency(zip_dirent_t *dirent);
zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *);
void _zip_dirent_free(zip_dirent_t *);
void _zip_dirent_finalize(zip_dirent_t *);
+time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de);
void _zip_dirent_init(zip_dirent_t *);
bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t);
zip_dirent_t *_zip_dirent_new(void);
bool zip_dirent_process_ef_zip64(zip_dirent_t * zde, const zip_uint8_t * ef, zip_uint64_t got_len, bool local, zip_error_t * error);
-zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error);
+zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_uint64_t central_compressed_size, bool check_consistency, zip_error_t *error);
void _zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64);
void zip_dirent_torrentzip_normalize(zip_dirent_t *de);
@@ -611,18 +634,21 @@ void _zip_set_open_error(int *zep, const zip_error_t *err, int ze);
bool zip_source_accept_empty(zip_source_t *src);
zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command);
bool _zip_source_eof(zip_source_t *);
+int zip_source_get_dos_time(zip_source_t *src, zip_dostime_t *dos_time);
+
zip_source_t *_zip_source_file_or_p(const char *, FILE *, zip_uint64_t, zip_int64_t, const zip_stat_t *, zip_error_t *error);
bool _zip_source_had_error(zip_source_t *);
void _zip_source_invalidate(zip_source_t *src);
zip_source_t *_zip_source_new(zip_error_t *error);
int _zip_source_set_source_archive(zip_source_t *, zip_t *);
-zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_uint64_t st_invalid, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, bool take_ownership, zip_error_t *error);
+zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_int64_t length, zip_stat_t *st, zip_uint64_t st_invalid, zip_file_attributes_t *attributes, zip_dostime_t *dostime, zip_t *source_archive, zip_uint64_t source_index, bool take_ownership, zip_error_t *error);
int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error);
int _zip_string_equal(const zip_string_t *a, const zip_string_t *b);
void _zip_string_free(zip_string_t *string);
zip_uint32_t _zip_string_crc32(const zip_string_t *string);
const zip_uint8_t *_zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip_error_t *error);
+bool _zip_string_is_ascii(const zip_string_t *string);
zip_uint16_t _zip_string_length(const zip_string_t *string);
zip_string_t *_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, zip_error_t *error);
int _zip_string_write(zip_t *za, const zip_string_t *string);
@@ -647,9 +673,9 @@ zip_t *_zip_new(zip_error_t *);
zip_int64_t _zip_file_replace(zip_t *, zip_uint64_t, const char *, zip_source_t *, zip_flags_t);
int _zip_set_name(zip_t *, zip_uint64_t, const char *, zip_flags_t);
-void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *);
+int _zip_u2d_time(time_t, zip_dostime_t *, zip_error_t *);
int _zip_unchange(zip_t *, zip_uint64_t, int);
void _zip_unchange_data(zip_entry_t *);
int _zip_write(zip_t *za, const void *data, zip_uint64_t length);
-#endif /* zipint.h */
+#endif /* _HAD_ZIPINT_H */
diff --git a/src/Common/lzma/7zTypes.h b/src/Common/lzma/7zTypes.h
index 1fcb2473..5b77420a 100644
--- a/src/Common/lzma/7zTypes.h
+++ b/src/Common/lzma/7zTypes.h
@@ -1,5 +1,5 @@
/* 7zTypes.h -- Basic types
-2023-04-02 : Igor Pavlov : Public domain */
+2024-01-24 : Igor Pavlov : Public domain */
#ifndef ZIP7_7Z_TYPES_H
#define ZIP7_7Z_TYPES_H
@@ -530,20 +530,20 @@ struct ISzAlloc
#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m)
*/
#if defined (__clang__) || defined(__GNUC__)
-#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL \
+#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
-#define Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL \
+#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL \
_Pragma("GCC diagnostic pop")
#else
-#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL
-#define Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL
+#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL
+#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL
#endif
#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \
- Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL \
+ Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \
type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \
- Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL
+ Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL
#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p)
diff --git a/src/Common/lzma/Alloc.c b/src/Common/lzma/Alloc.c
index d841bf20..63e1a121 100644
--- a/src/Common/lzma/Alloc.c
+++ b/src/Common/lzma/Alloc.c
@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions
-2023-04-02 : Igor Pavlov : Public domain */
+2024-02-18 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -10,19 +10,18 @@
#include "Alloc.h"
-#ifdef _WIN32
-#ifdef Z7_LARGE_PAGES
-#if defined(__clang__) || defined(__GNUC__)
-typedef void (*Z7_voidFunction)(void);
-#define MY_CAST_FUNC (Z7_voidFunction)
-#elif defined(_MSC_VER) && _MSC_VER > 1920
-#define MY_CAST_FUNC (void *)
-// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()'
-#else
-#define MY_CAST_FUNC
+#if defined(Z7_LARGE_PAGES) && defined(_WIN32) && \
+ (!defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0502) // < Win2003 (xp-64)
+ #define Z7_USE_DYN_GetLargePageMinimum
+#endif
+
+// for debug:
+#if 0
+#if defined(__CHERI__) && defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16)
+// #pragma message("=== Z7_ALLOC_NO_OFFSET_ALLOCATOR === ")
+#define Z7_ALLOC_NO_OFFSET_ALLOCATOR
+#endif
#endif
-#endif // Z7_LARGE_PAGES
-#endif // _WIN32
// #define SZ_ALLOC_DEBUG
/* #define SZ_ALLOC_DEBUG */
@@ -146,7 +145,9 @@ static void PrintAddr(void *p)
#define PRINT_FREE(name, cnt, ptr)
#define Print(s)
#define PrintLn()
+#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR
#define PrintHex(v, align)
+#endif
#define PrintAddr(p)
#endif
@@ -246,9 +247,9 @@ void MidFree(void *address)
#ifdef Z7_LARGE_PAGES
#ifdef MEM_LARGE_PAGES
- #define MY__MEM_LARGE_PAGES MEM_LARGE_PAGES
+ #define MY_MEM_LARGE_PAGES MEM_LARGE_PAGES
#else
- #define MY__MEM_LARGE_PAGES 0x20000000
+ #define MY_MEM_LARGE_PAGES 0x20000000
#endif
extern
@@ -258,19 +259,23 @@ typedef SIZE_T (WINAPI *Func_GetLargePageMinimum)(VOID);
void SetLargePageSize(void)
{
- #ifdef Z7_LARGE_PAGES
SIZE_T size;
+#ifdef Z7_USE_DYN_GetLargePageMinimum
+Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
+
const
Func_GetLargePageMinimum fn =
- (Func_GetLargePageMinimum) MY_CAST_FUNC GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
+ (Func_GetLargePageMinimum) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
"GetLargePageMinimum");
if (!fn)
return;
size = fn();
+#else
+ size = GetLargePageMinimum();
+#endif
if (size == 0 || (size & (size - 1)) != 0)
return;
g_LargePageSize = size;
- #endif
}
#endif // Z7_LARGE_PAGES
@@ -292,7 +297,7 @@ void *BigAlloc(size_t size)
size2 = (size + ps) & ~ps;
if (size2 >= size)
{
- void *p = VirtualAlloc(NULL, size2, MEM_COMMIT | MY__MEM_LARGE_PAGES, PAGE_READWRITE);
+ void *p = VirtualAlloc(NULL, size2, MEM_COMMIT | MY_MEM_LARGE_PAGES, PAGE_READWRITE);
if (p)
{
PRINT_ALLOC("Alloc-BM ", g_allocCountMid, size2, p)
@@ -328,20 +333,7 @@ const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
#endif
-/*
- uintptr_t : <stdint.h> C99 (optional)
- : unsupported in VS6
-*/
-
-#ifdef _WIN32
- typedef UINT_PTR UIntPtr;
-#else
- /*
- typedef uintptr_t UIntPtr;
- */
- typedef ptrdiff_t UIntPtr;
-#endif
-
+#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR
#define ADJUST_ALLOC_SIZE 0
/*
@@ -352,14 +344,36 @@ const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
MyAlloc() can return address that is NOT multiple of sizeof(void *).
*/
-
/*
-#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1))))
+ uintptr_t : <stdint.h> C99 (optional)
+ : unsupported in VS6
*/
-#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1))))
+typedef
+ #ifdef _WIN32
+ UINT_PTR
+ #elif 1
+ uintptr_t
+ #else
+ ptrdiff_t
+ #endif
+ MY_uintptr_t;
+
+#if 0 \
+ || (defined(__CHERI__) \
+ || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ > 8))
+// for 128-bit pointers (cheri):
+#define MY_ALIGN_PTR_DOWN(p, align) \
+ ((void *)((char *)(p) - ((size_t)(MY_uintptr_t)(p) & ((align) - 1))))
+#else
+#define MY_ALIGN_PTR_DOWN(p, align) \
+ ((void *)((((MY_uintptr_t)(p)) & ~((MY_uintptr_t)(align) - 1))))
+#endif
+#endif
-#if !defined(_WIN32) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)
+#if !defined(_WIN32) \
+ && (defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) \
+ || defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L))
#define USE_posix_memalign
#endif
@@ -399,14 +413,13 @@ static int posix_memalign(void **ptr, size_t align, size_t size)
#define ALLOC_ALIGN_SIZE ((size_t)1 << 7)
-static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
+void *z7_AlignedAlloc(size_t size)
{
- #ifndef USE_posix_memalign
+#ifndef USE_posix_memalign
void *p;
void *pAligned;
size_t newSize;
- UNUSED_VAR(pp)
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */
@@ -431,10 +444,9 @@ static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
return pAligned;
- #else
+#else
void *p;
- UNUSED_VAR(pp)
if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size))
return NULL;
@@ -443,19 +455,37 @@ static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
return p;
- #endif
+#endif
+}
+
+
+void z7_AlignedFree(void *address)
+{
+#ifndef USE_posix_memalign
+ if (address)
+ MyFree(((void **)address)[-1]);
+#else
+ free(address);
+#endif
+}
+
+
+static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
+{
+ UNUSED_VAR(pp)
+ return z7_AlignedAlloc(size);
}
static void SzAlignedFree(ISzAllocPtr pp, void *address)
{
UNUSED_VAR(pp)
- #ifndef USE_posix_memalign
+#ifndef USE_posix_memalign
if (address)
MyFree(((void **)address)[-1]);
- #else
+#else
free(address);
- #endif
+#endif
}
@@ -463,16 +493,44 @@ const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
-#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
-
/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */
-#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
-/*
-#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1]
-*/
+#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR
+#if 1
+ #define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
+ #define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
+#else
+ // we can use this simplified code,
+ // if (CAlignOffsetAlloc::offset == (k * sizeof(void *))
+ #define REAL_BLOCK_PTR_VAR(p) (((void **)(p))[-1])
+#endif
+#endif
+
+
+#if 0
+#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR
+#include <stdio.h>
+static void PrintPtr(const char *s, const void *p)
+{
+ const Byte *p2 = (const Byte *)&p;
+ unsigned i;
+ printf("%s %p ", s, p);
+ for (i = sizeof(p); i != 0;)
+ {
+ i--;
+ printf("%02x", p2[i]);
+ }
+ printf("\n");
+}
+#endif
+#endif
+
static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
{
+#if defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR)
+ UNUSED_VAR(pp)
+ return z7_AlignedAlloc(size);
+#else
const CAlignOffsetAlloc *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CAlignOffsetAlloc, vt);
void *adr;
void *pAligned;
@@ -501,6 +559,12 @@ static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr +
alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset;
+#if 0
+ printf("\nalignSize = %6x, offset=%6x, size=%8x \n", (unsigned)alignSize, (unsigned)p->offset, (unsigned)size);
+ PrintPtr("base", adr);
+ PrintPtr("alig", pAligned);
+#endif
+
PrintLn();
Print("- Aligned: ");
Print(" size="); PrintHex(size, 8);
@@ -512,11 +576,16 @@ static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
REAL_BLOCK_PTR_VAR(pAligned) = adr;
return pAligned;
+#endif
}
static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
{
+#if defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR)
+ UNUSED_VAR(pp)
+ z7_AlignedFree(address);
+#else
if (address)
{
const CAlignOffsetAlloc *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CAlignOffsetAlloc, vt);
@@ -525,6 +594,7 @@ static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
PrintLn();
ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address));
}
+#endif
}
diff --git a/src/Common/lzma/Alloc.h b/src/Common/lzma/Alloc.h
index fac5b62f..01bf6b7d 100644
--- a/src/Common/lzma/Alloc.h
+++ b/src/Common/lzma/Alloc.h
@@ -1,5 +1,5 @@
/* Alloc.h -- Memory allocation functions
-2023-03-04 : Igor Pavlov : Public domain */
+2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_ALLOC_H
#define ZIP7_INC_ALLOC_H
@@ -22,6 +22,9 @@ void *MyAlloc(size_t size);
void MyFree(void *address);
void *MyRealloc(void *address, size_t size);
+void *z7_AlignedAlloc(size_t size);
+void z7_AlignedFree(void *p);
+
#ifdef _WIN32
#ifdef Z7_LARGE_PAGES
@@ -33,12 +36,14 @@ void MidFree(void *address);
void *BigAlloc(size_t size);
void BigFree(void *address);
+/* #define Z7_BIG_ALLOC_IS_ZERO_FILLED */
+
#else
-#define MidAlloc(size) MyAlloc(size)
-#define MidFree(address) MyFree(address)
-#define BigAlloc(size) MyAlloc(size)
-#define BigFree(address) MyFree(address)
+#define MidAlloc(size) z7_AlignedAlloc(size)
+#define MidFree(address) z7_AlignedFree(address)
+#define BigAlloc(size) z7_AlignedAlloc(size)
+#define BigFree(address) z7_AlignedFree(address)
#endif
diff --git a/src/Common/lzma/Compiler.h b/src/Common/lzma/Compiler.h
index 185a52de..2a9c2b7a 100644
--- a/src/Common/lzma/Compiler.h
+++ b/src/Common/lzma/Compiler.h
@@ -1,5 +1,5 @@
/* Compiler.h : Compiler specific defines and pragmas
-2023-04-02 : Igor Pavlov : Public domain */
+2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_COMPILER_H
#define ZIP7_INC_COMPILER_H
@@ -25,11 +25,79 @@
#define Z7_MINGW
#endif
+#if defined(__LCC__) && (defined(__MCST__) || defined(__e2k__))
+#define Z7_MCST_LCC
+#define Z7_MCST_LCC_VERSION (__LCC__ * 100 + __LCC_MINOR__)
+#endif
+
+/*
+#if defined(__AVX2__) \
+ || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \
+ || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \
+ || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \
+ || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \
+ || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400)
+ #define Z7_COMPILER_AVX2_SUPPORTED
+ #endif
+#endif
+*/
+
// #pragma GCC diagnostic ignored "-Wunknown-pragmas"
#ifdef __clang__
// padding size of '' with 4 bytes to alignment boundary
#pragma GCC diagnostic ignored "-Wpadded"
+
+#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) \
+ && defined(__FreeBSD__)
+// freebsd:
+#pragma GCC diagnostic ignored "-Wexcess-padding"
+#endif
+
+#if __clang_major__ >= 16
+#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
+#endif
+
+#if __clang_major__ == 13
+#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16)
+// cheri
+#pragma GCC diagnostic ignored "-Wcapability-to-integer-cast"
+#endif
+#endif
+
+#if __clang_major__ == 13
+ // for <arm_neon.h>
+ #pragma GCC diagnostic ignored "-Wreserved-identifier"
+#endif
+
+#endif // __clang__
+
+#if defined(_WIN32) && defined(__clang__) && __clang_major__ >= 16
+// #pragma GCC diagnostic ignored "-Wcast-function-type-strict"
+#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION \
+ _Pragma("GCC diagnostic ignored \"-Wcast-function-type-strict\"")
+#else
+#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
+#endif
+
+typedef void (*Z7_void_Function)(void);
+#if defined(__clang__) || defined(__GNUC__)
+#define Z7_CAST_FUNC_C (Z7_void_Function)
+#elif defined(_MSC_VER) && _MSC_VER > 1920
+#define Z7_CAST_FUNC_C (void *)
+// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()'
+#else
+#define Z7_CAST_FUNC_C
+#endif
+/*
+#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__)
+ // #pragma GCC diagnostic ignored "-Wcast-function-type"
+#endif
+*/
+#ifdef __GNUC__
+#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40000) && (Z7_GCC_VERSION < 70000)
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
#endif
@@ -101,7 +169,8 @@
_Pragma("clang loop unroll(disable)") \
_Pragma("clang loop vectorize(disable)")
#define Z7_ATTRIB_NO_VECTORIZE
-#elif defined(__GNUC__) && (__GNUC__ >= 5)
+#elif defined(__GNUC__) && (__GNUC__ >= 5) \
+ && (!defined(Z7_MCST_LCC_VERSION) || (Z7_MCST_LCC_VERSION >= 12610))
#define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
// __attribute__((optimize("no-unroll-loops")));
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE
@@ -142,15 +211,23 @@
#endif
-#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 36000))
-#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \
+#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30600))
+
+#if (Z7_CLANG_VERSION < 130000)
+#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreserved-id-macro\"")
+#else
+#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"")
-#define Z7_DIAGNOSCTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \
+#endif
+
+#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \
_Pragma("GCC diagnostic pop")
#else
-#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
-#define Z7_DIAGNOSCTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
+#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
+#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
#endif
#define UNUSED_VAR(x) (void)x;
diff --git a/src/Common/lzma/CpuArch.c b/src/Common/lzma/CpuArch.c
index 33f8a3ab..6e02551e 100644
--- a/src/Common/lzma/CpuArch.c
+++ b/src/Common/lzma/CpuArch.c
@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code
-2023-05-18 : Igor Pavlov : Public domain */
+Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -17,7 +17,7 @@
/*
cpuid instruction supports (subFunction) parameter in ECX,
that is used only with some specific (function) parameter values.
- But we always use only (subFunction==0).
+ most functions use only (subFunction==0).
*/
/*
__cpuid(): MSVC and GCC/CLANG use same function/macro name
@@ -49,43 +49,49 @@
#if defined(MY_CPU_AMD64) && defined(__PIC__) \
&& ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__))
-#define x86_cpuid_MACRO(p, func) { \
+ /* "=&r" selects free register. It can select even rbx, if that register is free.
+ "=&D" for (RDI) also works, but the code can be larger with "=&D"
+ "2"(subFun) : 2 is (zero-based) index in the output constraint list "=c" (ECX). */
+
+#define x86_cpuid_MACRO_2(p, func, subFunc) { \
__asm__ __volatile__ ( \
ASM_LN "mov %%rbx, %q1" \
ASM_LN "cpuid" \
ASM_LN "xchg %%rbx, %q1" \
- : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); }
-
- /* "=&r" selects free register. It can select even rbx, if that register is free.
- "=&D" for (RDI) also works, but the code can be larger with "=&D"
- "2"(0) means (subFunction = 0),
- 2 is (zero-based) index in the output constraint list "=c" (ECX). */
+ : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); }
#elif defined(MY_CPU_X86) && defined(__PIC__) \
&& ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__))
-#define x86_cpuid_MACRO(p, func) { \
+#define x86_cpuid_MACRO_2(p, func, subFunc) { \
__asm__ __volatile__ ( \
ASM_LN "mov %%ebx, %k1" \
ASM_LN "cpuid" \
ASM_LN "xchg %%ebx, %k1" \
- : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); }
+ : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); }
#else
-#define x86_cpuid_MACRO(p, func) { \
+#define x86_cpuid_MACRO_2(p, func, subFunc) { \
__asm__ __volatile__ ( \
ASM_LN "cpuid" \
- : "=a" ((p)[0]), "=b" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); }
+ : "=a" ((p)[0]), "=b" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); }
#endif
+#define x86_cpuid_MACRO(p, func) x86_cpuid_MACRO_2(p, func, 0)
void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
{
x86_cpuid_MACRO(p, func)
}
+static
+void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc)
+{
+ x86_cpuid_MACRO_2(p, func, subFunc)
+}
+
Z7_NO_INLINE
UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void)
@@ -205,11 +211,39 @@ void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
__asm ret 0
}
+static
+void __declspec(naked) Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc)
+{
+ UNUSED_VAR(p)
+ UNUSED_VAR(func)
+ UNUSED_VAR(subFunc)
+ __asm push ebx
+ __asm push edi
+ __asm mov edi, ecx // p
+ __asm mov eax, edx // func
+ __asm mov ecx, [esp + 12] // subFunc
+ __asm cpuid
+ __asm mov [edi ], eax
+ __asm mov [edi + 4], ebx
+ __asm mov [edi + 8], ecx
+ __asm mov [edi + 12], edx
+ __asm pop edi
+ __asm pop ebx
+ __asm ret 4
+}
+
#else // MY_CPU_AMD64
#if _MSC_VER >= 1600
#include <intrin.h>
#define MY_cpuidex __cpuidex
+
+static
+void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc)
+{
+ __cpuidex((int *)p, func, subFunc);
+}
+
#else
/*
__cpuid (func == (0 or 7)) requires subfunction number in ECX.
@@ -219,20 +253,25 @@ void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
We still can use __cpuid for low (func) values that don't require ECX,
but __cpuid() in old MSVC will be incorrect for some func values: (func == 7).
So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction,
- where ECX value is first parameter for FASTCALL / NO_INLINE func,
+ where ECX value is first parameter for FASTCALL / NO_INLINE func.
So the caller of MY_cpuidex_HACK() sets ECX as subFunction, and
old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value.
DON'T remove Z7_NO_INLINE and Z7_FASTCALL for MY_cpuidex_HACK(): !!!
*/
static
-Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(UInt32 subFunction, UInt32 func, int *CPUInfo)
+Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(Int32 subFunction, Int32 func, Int32 *CPUInfo)
{
UNUSED_VAR(subFunction)
__cpuid(CPUInfo, func);
}
#define MY_cpuidex(info, func, func2) MY_cpuidex_HACK(func2, func, info)
#pragma message("======== MY_cpuidex_HACK WAS USED ========")
+static
+void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc)
+{
+ MY_cpuidex_HACK(subFunc, func, (Int32 *)p);
+}
#endif // _MSC_VER >= 1600
#if !defined(MY_CPU_AMD64)
@@ -242,13 +281,13 @@ Z7_NO_INLINE
#endif
void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func)
{
- MY_cpuidex((int *)p, (int)func, 0);
+ MY_cpuidex((Int32 *)p, (Int32)func, 0);
}
Z7_NO_INLINE
UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void)
{
- int a[4];
+ Int32 a[4];
MY_cpuidex(a, 0, 0);
return a[0];
}
@@ -384,7 +423,7 @@ BoolInt CPU_IsSupported_CMOV(void)
UInt32 a[4];
if (!x86cpuid_Func_1(&a[0]))
return 0;
- return (a[3] >> 15) & 1;
+ return (BoolInt)(a[3] >> 15) & 1;
}
BoolInt CPU_IsSupported_SSE(void)
@@ -393,7 +432,7 @@ BoolInt CPU_IsSupported_SSE(void)
CHECK_SYS_SSE_SUPPORT
if (!x86cpuid_Func_1(&a[0]))
return 0;
- return (a[3] >> 25) & 1;
+ return (BoolInt)(a[3] >> 25) & 1;
}
BoolInt CPU_IsSupported_SSE2(void)
@@ -402,7 +441,7 @@ BoolInt CPU_IsSupported_SSE2(void)
CHECK_SYS_SSE_SUPPORT
if (!x86cpuid_Func_1(&a[0]))
return 0;
- return (a[3] >> 26) & 1;
+ return (BoolInt)(a[3] >> 26) & 1;
}
#endif
@@ -419,17 +458,17 @@ static UInt32 x86cpuid_Func_1_ECX(void)
BoolInt CPU_IsSupported_AES(void)
{
- return (x86cpuid_Func_1_ECX() >> 25) & 1;
+ return (BoolInt)(x86cpuid_Func_1_ECX() >> 25) & 1;
}
BoolInt CPU_IsSupported_SSSE3(void)
{
- return (x86cpuid_Func_1_ECX() >> 9) & 1;
+ return (BoolInt)(x86cpuid_Func_1_ECX() >> 9) & 1;
}
BoolInt CPU_IsSupported_SSE41(void)
{
- return (x86cpuid_Func_1_ECX() >> 19) & 1;
+ return (BoolInt)(x86cpuid_Func_1_ECX() >> 19) & 1;
}
BoolInt CPU_IsSupported_SHA(void)
@@ -441,7 +480,24 @@ BoolInt CPU_IsSupported_SHA(void)
{
UInt32 d[4];
z7_x86_cpuid(d, 7);
- return (d[1] >> 29) & 1;
+ return (BoolInt)(d[1] >> 29) & 1;
+ }
+}
+
+
+BoolInt CPU_IsSupported_SHA512(void)
+{
+ if (!CPU_IsSupported_AVX2()) return False; // maybe CPU_IsSupported_AVX() is enough here
+
+ if (z7_x86_cpuid_GetMaxFunc() < 7)
+ return False;
+ {
+ UInt32 d[4];
+ z7_x86_cpuid_subFunc(d, 7, 0);
+ if (d[0] < 1) // d[0] - is max supported subleaf value
+ return False;
+ z7_x86_cpuid_subFunc(d, 7, 1);
+ return (BoolInt)(d[0]) & 1;
}
}
@@ -638,10 +694,10 @@ BoolInt CPU_IsSupported_AVX(void)
{
const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK);
- // printf("\n=== XGetBV=%d\n", bm);
+ // printf("\n=== XGetBV=0x%x\n", bm);
return 1
- & (bm >> 1) // SSE state is supported (set by OS) for storing/restoring
- & (bm >> 2); // AVX state is supported (set by OS) for storing/restoring
+ & (BoolInt)(bm >> 1) // SSE state is supported (set by OS) for storing/restoring
+ & (BoolInt)(bm >> 2); // AVX state is supported (set by OS) for storing/restoring
}
// since Win7SP1: we can use GetEnabledXStateFeatures();
}
@@ -658,9 +714,38 @@ BoolInt CPU_IsSupported_AVX2(void)
z7_x86_cpuid(d, 7);
// printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
return 1
- & (d[1] >> 5); // avx2
+ & (BoolInt)(d[1] >> 5); // avx2
+ }
+}
+
+#if 0
+BoolInt CPU_IsSupported_AVX512F_AVX512VL(void)
+{
+ if (!CPU_IsSupported_AVX())
+ return False;
+ if (z7_x86_cpuid_GetMaxFunc() < 7)
+ return False;
+ {
+ UInt32 d[4];
+ BoolInt v;
+ z7_x86_cpuid(d, 7);
+ // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
+ v = 1
+ & (BoolInt)(d[1] >> 16) // avx512f
+ & (BoolInt)(d[1] >> 31); // avx512vl
+ if (!v)
+ return False;
+ }
+ {
+ const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK);
+ // printf("\n=== XGetBV=0x%x\n", bm);
+ return 1
+ & (BoolInt)(bm >> 5) // OPMASK
+ & (BoolInt)(bm >> 6) // ZMM upper 256-bit
+ & (BoolInt)(bm >> 7); // ZMM16 ... ZMM31
}
}
+#endif
BoolInt CPU_IsSupported_VAES_AVX2(void)
{
@@ -673,9 +758,9 @@ BoolInt CPU_IsSupported_VAES_AVX2(void)
z7_x86_cpuid(d, 7);
// printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
return 1
- & (d[1] >> 5) // avx2
+ & (BoolInt)(d[1] >> 5) // avx2
// & (d[1] >> 31) // avx512vl
- & (d[2] >> 9); // vaes // VEX-256/EVEX
+ & (BoolInt)(d[2] >> 9); // vaes // VEX-256/EVEX
}
}
@@ -688,7 +773,7 @@ BoolInt CPU_IsSupported_PageGB(void)
if (d[0] < 0x80000001)
return False;
z7_x86_cpuid(d, 0x80000001);
- return (d[3] >> 26) & 1;
+ return (BoolInt)(d[3] >> 26) & 1;
}
}
@@ -747,6 +832,18 @@ BoolInt CPU_IsSupported_NEON(void)
return z7_sysctlbyname_Get_BoolInt("hw.optional.neon");
}
+BoolInt CPU_IsSupported_SHA512(void)
+{
+ return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha512");
+}
+
+/*
+BoolInt CPU_IsSupported_SHA3(void)
+{
+ return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha3");
+}
+*/
+
#ifdef MY_CPU_ARM64
#define APPLE_CRYPTO_SUPPORT_VAL 1
#else
@@ -760,33 +857,70 @@ BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; }
#else // __APPLE__
-#include <sys/auxv.h>
+#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216)
+ #define Z7_GETAUXV_AVAILABLE
+#else
+// #pragma message("=== is not NEW GLIBC === ")
+ #if defined __has_include
+ #if __has_include (<sys/auxv.h>)
+// #pragma message("=== sys/auxv.h is avail=== ")
+ #define Z7_GETAUXV_AVAILABLE
+ #endif
+ #endif
+#endif
+#ifdef Z7_GETAUXV_AVAILABLE
+// #pragma message("=== Z7_GETAUXV_AVAILABLE === ")
+#include <sys/auxv.h>
#define USE_HWCAP
+#endif
#ifdef USE_HWCAP
+#if defined(__FreeBSD__)
+static unsigned long MY_getauxval(int aux)
+{
+ unsigned long val;
+ if (elf_aux_info(aux, &val, sizeof(val)))
+ return 0;
+ return val;
+}
+#else
+#define MY_getauxval getauxval
+ #if defined __has_include
+ #if __has_include (<asm/hwcap.h>)
#include <asm/hwcap.h>
+ #endif
+ #endif
+#endif
#define MY_HWCAP_CHECK_FUNC_2(name1, name2) \
- BoolInt CPU_IsSupported_ ## name1() { return (getauxval(AT_HWCAP) & (HWCAP_ ## name2)) ? 1 : 0; }
+ BoolInt CPU_IsSupported_ ## name1(void) { return (MY_getauxval(AT_HWCAP) & (HWCAP_ ## name2)); }
#ifdef MY_CPU_ARM64
#define MY_HWCAP_CHECK_FUNC(name) \
MY_HWCAP_CHECK_FUNC_2(name, name)
+#if 1 || defined(__ARM_NEON)
+ BoolInt CPU_IsSupported_NEON(void) { return True; }
+#else
MY_HWCAP_CHECK_FUNC_2(NEON, ASIMD)
+#endif
// MY_HWCAP_CHECK_FUNC (ASIMD)
#elif defined(MY_CPU_ARM)
#define MY_HWCAP_CHECK_FUNC(name) \
- BoolInt CPU_IsSupported_ ## name() { return (getauxval(AT_HWCAP2) & (HWCAP2_ ## name)) ? 1 : 0; }
+ BoolInt CPU_IsSupported_ ## name(void) { return (MY_getauxval(AT_HWCAP2) & (HWCAP2_ ## name)); }
MY_HWCAP_CHECK_FUNC_2(NEON, NEON)
#endif
#else // USE_HWCAP
#define MY_HWCAP_CHECK_FUNC(name) \
- BoolInt CPU_IsSupported_ ## name() { return 0; }
+ BoolInt CPU_IsSupported_ ## name(void) { return 0; }
+#if defined(__ARM_NEON)
+ BoolInt CPU_IsSupported_NEON(void) { return True; }
+#else
MY_HWCAP_CHECK_FUNC(NEON)
+#endif
#endif // USE_HWCAP
@@ -794,6 +928,19 @@ MY_HWCAP_CHECK_FUNC (CRC32)
MY_HWCAP_CHECK_FUNC (SHA1)
MY_HWCAP_CHECK_FUNC (SHA2)
MY_HWCAP_CHECK_FUNC (AES)
+#ifdef MY_CPU_ARM64
+// <hwcap.h> supports HWCAP_SHA512 and HWCAP_SHA3 since 2017.
+// we define them here, if they are not defined
+#ifndef HWCAP_SHA3
+// #define HWCAP_SHA3 (1 << 17)
+#endif
+#ifndef HWCAP_SHA512
+// #pragma message("=== HWCAP_SHA512 define === ")
+#define HWCAP_SHA512 (1 << 21)
+#endif
+MY_HWCAP_CHECK_FUNC (SHA512)
+// MY_HWCAP_CHECK_FUNC (SHA3)
+#endif
#endif // __APPLE__
#endif // _WIN32
diff --git a/src/Common/lzma/CpuArch.h b/src/Common/lzma/CpuArch.h
index 8e5d8a54..a6297ea4 100644
--- a/src/Common/lzma/CpuArch.h
+++ b/src/Common/lzma/CpuArch.h
@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
-2023-04-02 : Igor Pavlov : Public domain */
+Igor Pavlov : Public domain */
#ifndef ZIP7_INC_CPU_ARCH_H
#define ZIP7_INC_CPU_ARCH_H
@@ -20,6 +20,7 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8)
*/
+#if !defined(_M_ARM64EC)
#if defined(_M_X64) \
|| defined(_M_AMD64) \
|| defined(__x86_64__) \
@@ -35,6 +36,7 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#endif
#define MY_CPU_64BIT
#endif
+#endif
#if defined(_M_IX86) \
@@ -47,17 +49,26 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#if defined(_M_ARM64) \
+ || defined(_M_ARM64EC) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__) \
|| defined(__aarch64__)
#define MY_CPU_ARM64
- #ifdef __ILP32__
+#if defined(__ILP32__) \
+ || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
#define MY_CPU_NAME "arm64-32"
#define MY_CPU_SIZEOF_POINTER 4
- #else
+#elif defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16)
+ #define MY_CPU_NAME "arm64-128"
+ #define MY_CPU_SIZEOF_POINTER 16
+#else
+#if defined(_M_ARM64EC)
+ #define MY_CPU_NAME "arm64ec"
+#else
#define MY_CPU_NAME "arm64"
+#endif
#define MY_CPU_SIZEOF_POINTER 8
- #endif
+#endif
#define MY_CPU_64BIT
#endif
@@ -133,8 +144,36 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#endif
+#if defined(__sparc__) \
+ || defined(__sparc)
+ #define MY_CPU_SPARC
+ #if defined(__LP64__) \
+ || defined(_LP64) \
+ || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)
+ #define MY_CPU_NAME "sparcv9"
+ #define MY_CPU_SIZEOF_POINTER 8
+ #define MY_CPU_64BIT
+ #elif defined(__sparc_v9__) \
+ || defined(__sparcv9)
+ #define MY_CPU_64BIT
+ #if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
+ #define MY_CPU_NAME "sparcv9-32"
+ #else
+ #define MY_CPU_NAME "sparcv9m"
+ #endif
+ #elif defined(__sparc_v8__) \
+ || defined(__sparcv8)
+ #define MY_CPU_NAME "sparcv8"
+ #define MY_CPU_SIZEOF_POINTER 4
+ #else
+ #define MY_CPU_NAME "sparc"
+ #endif
+#endif
+
+
#if defined(__riscv) \
|| defined(__riscv__)
+ #define MY_CPU_RISCV
#if __riscv_xlen == 32
#define MY_CPU_NAME "riscv32"
#elif __riscv_xlen == 64
@@ -145,6 +184,39 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#endif
+#if defined(__loongarch__)
+ #define MY_CPU_LOONGARCH
+ #if defined(__loongarch64) || defined(__loongarch_grlen) && (__loongarch_grlen == 64)
+ #define MY_CPU_64BIT
+ #endif
+ #if defined(__loongarch64)
+ #define MY_CPU_NAME "loongarch64"
+ #define MY_CPU_LOONGARCH64
+ #else
+ #define MY_CPU_NAME "loongarch"
+ #endif
+#endif
+
+
+// #undef MY_CPU_NAME
+// #undef MY_CPU_SIZEOF_POINTER
+// #define __e2k__
+// #define __SIZEOF_POINTER__ 4
+#if defined(__e2k__)
+ #define MY_CPU_E2K
+ #if defined(__ILP32__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
+ #define MY_CPU_NAME "e2k-32"
+ #define MY_CPU_SIZEOF_POINTER 4
+ #else
+ #define MY_CPU_NAME "e2k"
+ #if defined(__LP64__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)
+ #define MY_CPU_SIZEOF_POINTER 8
+ #endif
+ #endif
+ #define MY_CPU_64BIT
+#endif
+
+
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64
#endif
@@ -175,6 +247,7 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|| defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \
+ || defined(_LITTLE_ENDIAN) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
@@ -251,6 +324,7 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#ifndef MY_CPU_NAME
+ // #define MY_CPU_IS_UNKNOWN
#ifdef MY_CPU_LE
#define MY_CPU_NAME "LE"
#elif defined(MY_CPU_BE)
@@ -295,9 +369,19 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#define Z7_BSWAP64(v) _byteswap_uint64(v)
#define Z7_CPU_FAST_BSWAP_SUPPORTED
-#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
- || (defined(__clang__) && Z7_has_builtin(__builtin_bswap16))
-
+/* GCC can generate slow code that calls function for __builtin_bswap32() for:
+ - GCC for RISCV, if Zbb/XTHeadBb extension is not used.
+ - GCC for SPARC.
+ The code from CLANG for SPARC also is not fastest.
+ So we don't define Z7_CPU_FAST_BSWAP_SUPPORTED in some cases.
+*/
+#elif (!defined(MY_CPU_RISCV) || defined (__riscv_zbb) || defined(__riscv_xtheadbb)) \
+ && !defined(MY_CPU_SPARC) \
+ && ( \
+ (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
+ || (defined(__clang__) && Z7_has_builtin(__builtin_bswap16)) \
+ )
+
#define Z7_BSWAP16(v) __builtin_bswap16(v)
#define Z7_BSWAP32(v) __builtin_bswap32(v)
#define Z7_BSWAP64(v) __builtin_bswap64(v)
@@ -329,13 +413,48 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
- || defined(MY_CPU_ARM64)
+ || defined(MY_CPU_ARM64) \
+ || defined(MY_CPU_RISCV) && defined(__riscv_misaligned_fast) \
+ || defined(MY_CPU_E2K) && defined(__iset__) && (__iset__ >= 6)
#define MY_CPU_LE_UNALIGN
#define MY_CPU_LE_UNALIGN_64
#elif defined(__ARM_FEATURE_UNALIGNED)
- /* gcc9 for 32-bit arm can use LDRD instruction that requires 32-bit alignment.
- So we can't use unaligned 64-bit operations. */
- #define MY_CPU_LE_UNALIGN
+/* === ALIGNMENT on 32-bit arm and LDRD/STRD/LDM/STM instructions.
+ Description of problems:
+problem-1 : 32-bit ARM architecture:
+ multi-access (pair of 32-bit accesses) instructions (LDRD/STRD/LDM/STM)
+ require 32-bit (WORD) alignment (by 32-bit ARM architecture).
+ So there is "Alignment fault exception", if data is not aligned for 32-bit.
+
+problem-2 : 32-bit kernels and arm64 kernels:
+ 32-bit linux kernels provide fixup for these "paired" instruction "Alignment fault exception".
+ So unaligned paired-access instructions work via exception handler in kernel in 32-bit linux.
+
+ But some arm64 kernels do not handle these faults in 32-bit programs.
+ So we have unhandled exception for such instructions.
+ Probably some new arm64 kernels have fixed it, and unaligned
+ paired-access instructions work in new kernels?
+
+problem-3 : compiler for 32-bit arm:
+ Compilers use LDRD/STRD/LDM/STM for UInt64 accesses
+ and for another cases where two 32-bit accesses are fused
+ to one multi-access instruction.
+ So UInt64 variables must be aligned for 32-bit, and each
+ 32-bit access must be aligned for 32-bit, if we want to
+ avoid "Alignment fault" exception (handled or unhandled).
+
+problem-4 : performace:
+ Even if unaligned access is handled by kernel, it will be slow.
+ So if we allow unaligned access, we can get fast unaligned
+ single-access, and slow unaligned paired-access.
+
+ We don't allow unaligned access on 32-bit arm, because compiler
+ genarates paired-access instructions that require 32-bit alignment,
+ and some arm64 kernels have no handler for these instructions.
+ Also unaligned paired-access instructions will be slow, if kernel handles them.
+*/
+ // it must be disabled:
+ // #define MY_CPU_LE_UNALIGN
#endif
#endif
@@ -390,11 +509,19 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED)
+#if 0
+// Z7_BSWAP16 can be slow for x86-msvc
+#define GetBe16_to32(p) (Z7_BSWAP16 (*(const UInt16 *)(const void *)(p)))
+#else
+#define GetBe16_to32(p) (Z7_BSWAP32 (*(const UInt16 *)(const void *)(p)) >> 16)
+#endif
+
#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p))
#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); }
#if defined(MY_CPU_LE_UNALIGN_64)
#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p))
+#define SetBe64(p, v) { (*(UInt64 *)(void *)(p)) = Z7_BSWAP64(v); }
#endif
#else
@@ -417,11 +544,27 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#endif
+#ifndef SetBe64
+#define SetBe64(p, v) { Byte *_ppp_ = (Byte *)(p); UInt64 _vvv_ = (v); \
+ _ppp_[0] = (Byte)(_vvv_ >> 56); \
+ _ppp_[1] = (Byte)(_vvv_ >> 48); \
+ _ppp_[2] = (Byte)(_vvv_ >> 40); \
+ _ppp_[3] = (Byte)(_vvv_ >> 32); \
+ _ppp_[4] = (Byte)(_vvv_ >> 24); \
+ _ppp_[5] = (Byte)(_vvv_ >> 16); \
+ _ppp_[6] = (Byte)(_vvv_ >> 8); \
+ _ppp_[7] = (Byte)_vvv_; }
+#endif
+
#ifndef GetBe16
+#ifdef GetBe16_to32
+#define GetBe16(p) ( (UInt16) GetBe16_to32(p))
+#else
#define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] ))
#endif
+#endif
#if defined(MY_CPU_BE)
@@ -439,11 +582,13 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#if defined(MY_CPU_BE)
+#define GetBe64a(p) (*(const UInt64 *)(const void *)(p))
#define GetBe32a(p) (*(const UInt32 *)(const void *)(p))
#define GetBe16a(p) (*(const UInt16 *)(const void *)(p))
#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
+#define GetUi64a(p) GetUi64(p)
#define GetUi32a(p) GetUi32(p)
#define GetUi16a(p) GetUi16(p)
#define SetUi32a(p, v) SetUi32(p, v)
@@ -451,11 +596,13 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#elif defined(MY_CPU_LE)
+#define GetUi64a(p) (*(const UInt64 *)(const void *)(p))
#define GetUi32a(p) (*(const UInt32 *)(const void *)(p))
#define GetUi16a(p) (*(const UInt16 *)(const void *)(p))
#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
#define SetUi16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
+#define GetBe64a(p) GetBe64(p)
#define GetBe32a(p) GetBe32(p)
#define GetBe16a(p) GetBe16(p)
#define SetBe32a(p, v) SetBe32(p, v)
@@ -466,6 +613,11 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#endif
+#ifndef GetBe16_to32
+#define GetBe16_to32(p) GetBe16(p)
+#endif
+
+
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_OR_ARM64) \
|| defined(MY_CPU_PPC_OR_PPC64)
@@ -486,6 +638,7 @@ UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void);
BoolInt CPU_IsSupported_AES(void);
BoolInt CPU_IsSupported_AVX(void);
BoolInt CPU_IsSupported_AVX2(void);
+BoolInt CPU_IsSupported_AVX512F_AVX512VL(void);
BoolInt CPU_IsSupported_VAES_AVX2(void);
BoolInt CPU_IsSupported_CMOV(void);
BoolInt CPU_IsSupported_SSE(void);
@@ -493,6 +646,7 @@ BoolInt CPU_IsSupported_SSE2(void);
BoolInt CPU_IsSupported_SSSE3(void);
BoolInt CPU_IsSupported_SSE41(void);
BoolInt CPU_IsSupported_SHA(void);
+BoolInt CPU_IsSupported_SHA512(void);
BoolInt CPU_IsSupported_PageGB(void);
#elif defined(MY_CPU_ARM_OR_ARM64)
@@ -510,6 +664,7 @@ BoolInt CPU_IsSupported_SHA1(void);
BoolInt CPU_IsSupported_SHA2(void);
BoolInt CPU_IsSupported_AES(void);
#endif
+BoolInt CPU_IsSupported_SHA512(void);
#endif
diff --git a/src/Common/lzma/LzFind.c b/src/Common/lzma/LzFind.c
index 0fbd5aae..1ce40464 100644
--- a/src/Common/lzma/LzFind.c
+++ b/src/Common/lzma/LzFind.c
@@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms
-2023-03-14 : Igor Pavlov : Public domain */
+2024-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -108,9 +108,15 @@ static int LzInWindow_Create2(CMatchFinder *p, UInt32 blockSize, ISzAllocPtr all
return (p->bufBase != NULL);
}
-static const Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+static const Byte *MatchFinder_GetPointerToCurrentPos(void *p)
+{
+ return ((CMatchFinder *)p)->buffer;
+}
-static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return GET_AVAIL_BYTES(p); }
+static UInt32 MatchFinder_GetNumAvailableBytes(void *p)
+{
+ return GET_AVAIL_BYTES((CMatchFinder *)p);
+}
Z7_NO_INLINE
@@ -571,8 +577,9 @@ void MatchFinder_Init_4(CMatchFinder *p)
#define CYC_TO_POS_OFFSET 0
// #define CYC_TO_POS_OFFSET 1 // for debug
-void MatchFinder_Init(CMatchFinder *p)
+void MatchFinder_Init(void *_p)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
MatchFinder_Init_HighHash(p);
MatchFinder_Init_LowHash(p);
MatchFinder_Init_4(p);
@@ -607,16 +614,16 @@ void MatchFinder_Init(CMatchFinder *p)
#endif
#endif
-// #elif defined(MY_CPU_ARM_OR_ARM64)
-#elif defined(MY_CPU_ARM64)
+#elif defined(MY_CPU_ARM64) \
+ /* || (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) */
- #if defined(__clang__) && (__clang_major__ >= 8) \
- || defined(__GNUC__) && (__GNUC__ >= 8)
+ #if defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \
+ || defined(__GNUC__) && (__GNUC__ >= 6)
#define USE_LZFIND_SATUR_SUB_128
#ifdef MY_CPU_ARM64
// #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("")))
#else
- // #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("fpu=crypto-neon-fp-armv8")))
+ #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("fpu=neon")))
#endif
#elif defined(_MSC_VER)
@@ -625,7 +632,7 @@ void MatchFinder_Init(CMatchFinder *p)
#endif
#endif
- #if defined(_MSC_VER) && defined(MY_CPU_ARM64)
+ #if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64)
#include <arm64_neon.h>
#else
#include <arm_neon.h>
@@ -1082,9 +1089,11 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
#define MOVE_POS \
- ++p->cyclicBufferPos; \
+ p->cyclicBufferPos++; \
p->buffer++; \
- { const UInt32 pos1 = p->pos + 1; p->pos = pos1; if (pos1 == p->posLimit) MatchFinder_CheckLimits(p); }
+ { const UInt32 pos1 = p->pos + 1; \
+ p->pos = pos1; \
+ if (pos1 == p->posLimit) MatchFinder_CheckLimits(p); }
#define MOVE_POS_RET MOVE_POS return distances;
@@ -1103,20 +1112,26 @@ static void MatchFinder_MovePos(CMatchFinder *p)
}
#define GET_MATCHES_HEADER2(minLen, ret_op) \
- unsigned lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
- lenLimit = (unsigned)p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
+ UInt32 hv; const Byte *cur; UInt32 curMatch; \
+ UInt32 lenLimit = p->lenLimit; \
+ if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; } \
cur = p->buffer;
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return distances)
-#define SKIP_HEADER(minLen) do { GET_MATCHES_HEADER2(minLen, continue)
+#define SKIP_HEADER(minLen) \
+ do { GET_MATCHES_HEADER2(minLen, continue)
-#define MF_PARAMS(p) lenLimit, curMatch, p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
+#define MF_PARAMS(p) lenLimit, curMatch, p->pos, p->buffer, p->son, \
+ p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
-#define SKIP_FOOTER SkipMatchesSpec(MF_PARAMS(p)); MOVE_POS } while (--num);
+#define SKIP_FOOTER \
+ SkipMatchesSpec(MF_PARAMS(p)); \
+ MOVE_POS \
+ } while (--num);
#define GET_MATCHES_FOOTER_BASE(_maxLen_, func) \
- distances = func(MF_PARAMS(p), \
- distances, (UInt32)_maxLen_); MOVE_POS_RET
+ distances = func(MF_PARAMS(p), distances, (UInt32)_maxLen_); \
+ MOVE_POS_RET
#define GET_MATCHES_FOOTER_BT(_maxLen_) \
GET_MATCHES_FOOTER_BASE(_maxLen_, GetMatchesSpec1)
@@ -1133,8 +1148,9 @@ static void MatchFinder_MovePos(CMatchFinder *p)
for (; c != lim; c++) if (*(c + diff) != *c) break; \
maxLen = (unsigned)(c - cur); }
-static UInt32* Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+static UInt32* Bt2_MatchFinder_GetMatches(void *_p, UInt32 *distances)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
GET_MATCHES_HEADER(2)
HASH2_CALC
curMatch = p->hash[hv];
@@ -1158,8 +1174,9 @@ UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
mmm = pos;
-static UInt32* Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+static UInt32* Bt3_MatchFinder_GetMatches(void *_p, UInt32 *distances)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
UInt32 mmm;
UInt32 h2, d2, pos;
unsigned maxLen;
@@ -1199,8 +1216,9 @@ static UInt32* Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
}
-static UInt32* Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+static UInt32* Bt4_MatchFinder_GetMatches(void *_p, UInt32 *distances)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
UInt32 mmm;
UInt32 h2, h3, d2, d3, pos;
unsigned maxLen;
@@ -1267,10 +1285,12 @@ static UInt32* Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
}
-static UInt32* Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+static UInt32* Bt5_MatchFinder_GetMatches(void *_p, UInt32 *distances)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
UInt32 mmm;
- UInt32 h2, h3, d2, d3, maxLen, pos;
+ UInt32 h2, h3, d2, d3, pos;
+ unsigned maxLen;
UInt32 *hash;
GET_MATCHES_HEADER(5)
@@ -1339,8 +1359,9 @@ static UInt32* Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
}
-static UInt32* Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+static UInt32* Hc4_MatchFinder_GetMatches(void *_p, UInt32 *distances)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
UInt32 mmm;
UInt32 h2, h3, d2, d3, pos;
unsigned maxLen;
@@ -1407,10 +1428,12 @@ static UInt32* Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
}
-static UInt32 * Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+static UInt32 * Hc5_MatchFinder_GetMatches(void *_p, UInt32 *distances)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
UInt32 mmm;
- UInt32 h2, h3, d2, d3, maxLen, pos;
+ UInt32 h2, h3, d2, d3, pos;
+ unsigned maxLen;
UInt32 *hash;
GET_MATCHES_HEADER(5)
@@ -1466,7 +1489,7 @@ static UInt32 * Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (*(cur - d2 + 3) != cur[3])
break;
UPDATE_maxLen
- distances[-2] = maxLen;
+ distances[-2] = (UInt32)maxLen;
if (maxLen == lenLimit)
{
p->son[p->cyclicBufferPos] = curMatch;
@@ -1489,8 +1512,9 @@ UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
}
-static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+static void Bt2_MatchFinder_Skip(void *_p, UInt32 num)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
SKIP_HEADER(2)
{
HASH2_CALC
@@ -1511,8 +1535,9 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_FOOTER
}
-static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+static void Bt3_MatchFinder_Skip(void *_p, UInt32 num)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
SKIP_HEADER(3)
{
UInt32 h2;
@@ -1526,8 +1551,9 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_FOOTER
}
-static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+static void Bt4_MatchFinder_Skip(void *_p, UInt32 num)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
SKIP_HEADER(4)
{
UInt32 h2, h3;
@@ -1542,8 +1568,9 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_FOOTER
}
-static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+static void Bt5_MatchFinder_Skip(void *_p, UInt32 num)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
SKIP_HEADER(5)
{
UInt32 h2, h3;
@@ -1589,8 +1616,9 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
}} while(num); \
-static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+static void Hc4_MatchFinder_Skip(void *_p, UInt32 num)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
HC_SKIP_HEADER(4)
UInt32 h2, h3;
@@ -1604,8 +1632,9 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
}
-static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+static void Hc5_MatchFinder_Skip(void *_p, UInt32 num)
{
+ CMatchFinder *p = (CMatchFinder *)_p;
HC_SKIP_HEADER(5)
UInt32 h2, h3;
@@ -1634,41 +1663,41 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable)
{
- vTable->Init = (Mf_Init_Func)MatchFinder_Init;
- vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
- vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
+ vTable->Init = MatchFinder_Init;
+ vTable->GetNumAvailableBytes = MatchFinder_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = MatchFinder_GetPointerToCurrentPos;
if (!p->btMode)
{
if (p->numHashBytes <= 4)
{
- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ vTable->GetMatches = Hc4_MatchFinder_GetMatches;
+ vTable->Skip = Hc4_MatchFinder_Skip;
}
else
{
- vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip;
+ vTable->GetMatches = Hc5_MatchFinder_GetMatches;
+ vTable->Skip = Hc5_MatchFinder_Skip;
}
}
else if (p->numHashBytes == 2)
{
- vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
+ vTable->GetMatches = Bt2_MatchFinder_GetMatches;
+ vTable->Skip = Bt2_MatchFinder_Skip;
}
else if (p->numHashBytes == 3)
{
- vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
+ vTable->GetMatches = Bt3_MatchFinder_GetMatches;
+ vTable->Skip = Bt3_MatchFinder_Skip;
}
else if (p->numHashBytes == 4)
{
- vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
+ vTable->GetMatches = Bt4_MatchFinder_GetMatches;
+ vTable->Skip = Bt4_MatchFinder_Skip;
}
else
{
- vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip;
+ vTable->GetMatches = Bt5_MatchFinder_GetMatches;
+ vTable->Skip = Bt5_MatchFinder_Skip;
}
}
diff --git a/src/Common/lzma/LzFind.h b/src/Common/lzma/LzFind.h
index a3f72c98..67e8a6e0 100644
--- a/src/Common/lzma/LzFind.h
+++ b/src/Common/lzma/LzFind.h
@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms
-2023-03-04 : Igor Pavlov : Public domain */
+2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZ_FIND_H
#define ZIP7_INC_LZ_FIND_H
@@ -144,7 +144,8 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable);
void MatchFinder_Init_LowHash(CMatchFinder *p);
void MatchFinder_Init_HighHash(CMatchFinder *p);
void MatchFinder_Init_4(CMatchFinder *p);
-void MatchFinder_Init(CMatchFinder *p);
+// void MatchFinder_Init(CMatchFinder *p);
+void MatchFinder_Init(void *p);
UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
diff --git a/src/Common/lzma/LzFindMt.c b/src/Common/lzma/LzFindMt.c
index 5253e6eb..ac9d59d0 100644
--- a/src/Common/lzma/LzFindMt.c
+++ b/src/Common/lzma/LzFindMt.c
@@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
-2023-04-02 : Igor Pavlov : Public domain */
+2024-01-22 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -94,7 +94,7 @@ static void MtSync_Construct(CMtSync *p)
}
-#define DEBUG_BUFFER_LOCK // define it to debug lock state
+// #define DEBUG_BUFFER_LOCK // define it to debug lock state
#ifdef DEBUG_BUFFER_LOCK
#include <stdlib.h>
@@ -877,8 +877,9 @@ SRes MatchFinderMt_InitMt(CMatchFinderMt *p)
}
-static void MatchFinderMt_Init(CMatchFinderMt *p)
+static void MatchFinderMt_Init(void *_p)
{
+ CMatchFinderMt *p = (CMatchFinderMt *)_p;
CMatchFinder *mf = MF(p);
p->btBufPos =
@@ -981,8 +982,9 @@ static UInt32 MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
-static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
+static const Byte * MatchFinderMt_GetPointerToCurrentPos(void *_p)
{
+ CMatchFinderMt *p = (CMatchFinderMt *)_p;
return p->pointerToCurPos;
}
@@ -990,8 +992,9 @@ static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
-static UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
+static UInt32 MatchFinderMt_GetNumAvailableBytes(void *_p)
{
+ CMatchFinderMt *p = (CMatchFinderMt *)_p;
if (p->btBufPos != p->btBufPosLimit)
return p->btNumAvailBytes;
return MatchFinderMt_GetNextBlock_Bt(p);
@@ -1243,8 +1246,9 @@ static UInt32 * MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d)
}
-static UInt32 * MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *d)
+static UInt32 * MatchFinderMt2_GetMatches(void *_p, UInt32 *d)
{
+ CMatchFinderMt *p = (CMatchFinderMt *)_p;
const UInt32 *bt = p->btBufPos;
const UInt32 len = *bt++;
const UInt32 *btLim = bt + len;
@@ -1267,8 +1271,9 @@ static UInt32 * MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *d)
-static UInt32 * MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *d)
+static UInt32 * MatchFinderMt_GetMatches(void *_p, UInt32 *d)
{
+ CMatchFinderMt *p = (CMatchFinderMt *)_p;
const UInt32 *bt = p->btBufPos;
UInt32 len = *bt++;
const UInt32 avail = p->btNumAvailBytes - 1;
@@ -1315,14 +1320,16 @@ static UInt32 * MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *d)
#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += (size_t)*p->btBufPos + 1; } while (--num != 0);
-static void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt0_Skip(void *_p, UInt32 num)
{
+ CMatchFinderMt *p = (CMatchFinderMt *)_p;
SKIP_HEADER2_MT { p->btNumAvailBytes--;
SKIP_FOOTER_MT
}
-static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt2_Skip(void *_p, UInt32 num)
{
+ CMatchFinderMt *p = (CMatchFinderMt *)_p;
SKIP_HEADER_MT(2)
UInt32 h2;
MT_HASH2_CALC
@@ -1330,8 +1337,9 @@ static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
SKIP_FOOTER_MT
}
-static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt3_Skip(void *_p, UInt32 num)
{
+ CMatchFinderMt *p = (CMatchFinderMt *)_p;
SKIP_HEADER_MT(3)
UInt32 h2, h3;
MT_HASH3_CALC
@@ -1361,39 +1369,39 @@ static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder2 *vTable)
{
- vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
- vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
- vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
- vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
+ vTable->Init = MatchFinderMt_Init;
+ vTable->GetNumAvailableBytes = MatchFinderMt_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = MatchFinderMt_GetPointerToCurrentPos;
+ vTable->GetMatches = MatchFinderMt_GetMatches;
switch (MF(p)->numHashBytes)
{
case 2:
p->GetHeadsFunc = GetHeads2;
- p->MixMatchesFunc = (Mf_Mix_Matches)NULL;
- vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
- vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
+ p->MixMatchesFunc = NULL;
+ vTable->Skip = MatchFinderMt0_Skip;
+ vTable->GetMatches = MatchFinderMt2_GetMatches;
break;
case 3:
p->GetHeadsFunc = MF(p)->bigHash ? GetHeads3b : GetHeads3;
- p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
- vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
+ p->MixMatchesFunc = MixMatches2;
+ vTable->Skip = MatchFinderMt2_Skip;
break;
case 4:
p->GetHeadsFunc = MF(p)->bigHash ? GetHeads4b : GetHeads4;
// it's fast inline version of GetMatches()
- // vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches_Bt4;
+ // vTable->GetMatches = MatchFinderMt_GetMatches_Bt4;
- p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
- vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
+ p->MixMatchesFunc = MixMatches3;
+ vTable->Skip = MatchFinderMt3_Skip;
break;
default:
p->GetHeadsFunc = MF(p)->bigHash ? GetHeads5b : GetHeads5;
- p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
+ p->MixMatchesFunc = MixMatches4;
vTable->Skip =
- (Mf_Skip_Func)MatchFinderMt3_Skip;
- // (Mf_Skip_Func)MatchFinderMt4_Skip;
+ MatchFinderMt3_Skip;
+ // MatchFinderMt4_Skip;
break;
}
}
diff --git a/src/Common/lzma/LzFindMt.h b/src/Common/lzma/LzFindMt.h
index db5923ea..fcb479da 100644
--- a/src/Common/lzma/LzFindMt.h
+++ b/src/Common/lzma/LzFindMt.h
@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
-2023-03-05 : Igor Pavlov : Public domain */
+2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZ_FIND_MT_H
#define ZIP7_INC_LZ_FIND_MT_H
@@ -31,7 +31,10 @@ typedef struct
// UInt32 numBlocks_Sent;
} CMtSync;
-typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
+
+struct CMatchFinderMt_;
+
+typedef UInt32 * (*Mf_Mix_Matches)(struct CMatchFinderMt_ *p, UInt32 matchMinPos, UInt32 *distances);
/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
#define kMtCacheLineDummy 128
@@ -39,7 +42,7 @@ typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distance
typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
-typedef struct
+typedef struct CMatchFinderMt_
{
/* LZ */
const Byte *pointerToCurPos;
diff --git a/src/Common/lzma/LzmaEnc.c b/src/Common/lzma/LzmaEnc.c
index 6d13cac8..088b78f8 100644
--- a/src/Common/lzma/LzmaEnc.c
+++ b/src/Common/lzma/LzmaEnc.c
@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder
-2023-04-13: Igor Pavlov : Public domain */
+Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -72,11 +72,11 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
p->level = level;
if (p->dictSize == 0)
- p->dictSize =
- ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) :
- ( level <= 6 ? ((UInt32)1 << (level + 19)) :
- ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26)
- )));
+ p->dictSize = (unsigned)level <= 4 ?
+ (UInt32)1 << (level * 2 + 16) :
+ (unsigned)level <= sizeof(size_t) / 2 + 4 ?
+ (UInt32)1 << (level + 20) :
+ (UInt32)1 << (sizeof(size_t) / 2 + 24);
if (p->dictSize > p->reduceSize)
{
@@ -92,8 +92,8 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if (p->lp < 0) p->lp = 0;
if (p->pb < 0) p->pb = 2;
- if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
- if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
+ if (p->algo < 0) p->algo = (unsigned)level < 5 ? 0 : 1;
+ if (p->fb < 0) p->fb = (unsigned)level < 7 ? 32 : 64;
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
if (p->numHashBytes < 0) p->numHashBytes = (p->btMode ? 4 : 5);
if (p->mc == 0) p->mc = (16 + ((unsigned)p->fb >> 1)) >> (p->btMode ? 0 : 1);
@@ -195,11 +195,11 @@ unsigned GetPosSlot1(UInt32 pos);
unsigned GetPosSlot1(UInt32 pos)
{
unsigned res;
- BSR2_RET(pos, res);
+ BSR2_RET(pos, res)
return res;
}
-#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res) }
+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res) }
#else // ! LZMA_LOG_BSR
@@ -512,7 +512,7 @@ struct CLzmaEnc
COPY_ARR(d, s, posEncoders) \
(d)->lenProbs = (s)->lenProbs; \
(d)->repLenProbs = (s)->repLenProbs; \
- memcpy((d)->litProbs, (s)->litProbs, ((UInt32)0x300 << (p)->lclp) * sizeof(CLzmaProb));
+ memcpy((d)->litProbs, (s)->litProbs, ((size_t)0x300 * sizeof(CLzmaProb)) << (p)->lclp);
void LzmaEnc_SaveState(CLzmaEncHandle p)
{
@@ -1040,14 +1040,14 @@ Z7_NO_INLINE static void Z7_FASTCALL LenPriceEnc_UpdateTables(
UInt32 price = b;
do
{
- unsigned bit = sym & 1;
+ const unsigned bit = sym & 1;
sym >>= 1;
price += GET_PRICEa(probs[sym], bit);
}
while (sym >= 2);
{
- unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))];
+ const unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))];
prices[(size_t)i * 2 ] = price + GET_PRICEa_0(prob);
prices[(size_t)i * 2 + 1] = price + GET_PRICEa_1(prob);
}
@@ -1056,7 +1056,7 @@ Z7_NO_INLINE static void Z7_FASTCALL LenPriceEnc_UpdateTables(
{
unsigned posState;
- size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]);
+ const size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]);
for (posState = 1; posState < numPosStates; posState++)
memcpy(p->prices[posState] + kLenNumLowSymbols * 2, p->prices[0] + kLenNumLowSymbols * 2, num);
}
@@ -2696,12 +2696,12 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc,
#endif
{
- unsigned lclp = p->lc + p->lp;
+ const unsigned lclp = p->lc + p->lp;
if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
{
LzmaEnc_FreeLits(p, alloc);
- p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
- p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp);
+ p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp);
if (!p->litProbs || !p->saveState.litProbs)
{
LzmaEnc_FreeLits(p, alloc);
@@ -2802,8 +2802,8 @@ static void LzmaEnc_Init(CLzmaEnc *p)
}
{
- UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
- UInt32 k;
+ const size_t num = (size_t)0x300 << (p->lp + p->lc);
+ size_t k;
CLzmaProb *probs = p->litProbs;
for (k = 0; k < num; k++)
probs[k] = kProbInitValue;
diff --git a/src/Common/lzma/Precomp.h b/src/Common/lzma/Precomp.h
index 69afb2ff..7747fdd7 100644
--- a/src/Common/lzma/Precomp.h
+++ b/src/Common/lzma/Precomp.h
@@ -1,10 +1,127 @@
-/* Precomp.h -- StdAfx
-2023-04-02 : Igor Pavlov : Public domain */
+/* Precomp.h -- precompilation file
+2024-01-25 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_PRECOMP_H
#define ZIP7_INC_PRECOMP_H
+/*
+ this file must be included before another *.h files and before <windows.h>.
+ this file is included from the following files:
+ C\*.c
+ C\Util\*\Precomp.h <- C\Util\*\*.c
+ CPP\Common\Common.h <- *\StdAfx.h <- *\*.cpp
+
+ this file can set the following macros:
+ Z7_LARGE_PAGES 1
+ Z7_LONG_PATH 1
+ Z7_WIN32_WINNT_MIN 0x0500 (or higher) : we require at least win2000+ for 7-Zip
+ _WIN32_WINNT 0x0500 (or higher)
+ WINVER _WIN32_WINNT
+ UNICODE 1
+ _UNICODE 1
+*/
+
#include "Compiler.h"
-/* #include "7zTypes.h" */
+
+#ifdef _MSC_VER
+// #pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty
+#if _MSC_VER >= 1912
+// #pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception.
+#endif
+#endif
+
+/*
+// for debug:
+#define UNICODE 1
+#define _UNICODE 1
+#define _WIN32_WINNT 0x0500 // win2000
+#ifndef WINVER
+ #define WINVER _WIN32_WINNT
+#endif
+*/
+
+#ifdef _WIN32
+/*
+ this "Precomp.h" file must be included before <windows.h>,
+ if we want to define _WIN32_WINNT before <windows.h>.
+*/
+
+#ifndef Z7_LARGE_PAGES
+#ifndef Z7_NO_LARGE_PAGES
+#define Z7_LARGE_PAGES 1
+#endif
+#endif
+
+#ifndef Z7_LONG_PATH
+#ifndef Z7_NO_LONG_PATH
+#define Z7_LONG_PATH 1
+#endif
+#endif
+
+#ifndef Z7_DEVICE_FILE
+#ifndef Z7_NO_DEVICE_FILE
+// #define Z7_DEVICE_FILE 1
+#endif
+#endif
+
+// we don't change macros if included after <windows.h>
+#ifndef _WINDOWS_
+
+#ifndef Z7_WIN32_WINNT_MIN
+ #if defined(_M_ARM64) || defined(__aarch64__)
+ // #define Z7_WIN32_WINNT_MIN 0x0a00 // win10
+ #define Z7_WIN32_WINNT_MIN 0x0600 // vista
+ #elif defined(_M_ARM) && defined(_M_ARMT) && defined(_M_ARM_NT)
+ // #define Z7_WIN32_WINNT_MIN 0x0602 // win8
+ #define Z7_WIN32_WINNT_MIN 0x0600 // vista
+ #elif defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IA64)
+ #define Z7_WIN32_WINNT_MIN 0x0503 // win2003
+ // #elif defined(_M_IX86) || defined(__i386__)
+ // #define Z7_WIN32_WINNT_MIN 0x0500 // win2000
+ #else // x86 and another(old) systems
+ #define Z7_WIN32_WINNT_MIN 0x0500 // win2000
+ // #define Z7_WIN32_WINNT_MIN 0x0502 // win2003 // for debug
+ #endif
+#endif // Z7_WIN32_WINNT_MIN
+
+
+#ifndef Z7_DO_NOT_DEFINE_WIN32_WINNT
+#ifdef _WIN32_WINNT
+ // #error Stop_Compiling_Bad_WIN32_WINNT
+#else
+ #ifndef Z7_NO_DEFINE_WIN32_WINNT
+Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
+ #define _WIN32_WINNT Z7_WIN32_WINNT_MIN
+Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
+ #endif
+#endif // _WIN32_WINNT
+
+#ifndef WINVER
+ #define WINVER _WIN32_WINNT
+#endif
+#endif // Z7_DO_NOT_DEFINE_WIN32_WINNT
+
+
+#ifndef _MBCS
+#ifndef Z7_NO_UNICODE
+// UNICODE and _UNICODE are used by <windows.h> and by 7-zip code.
+
+#ifndef UNICODE
+#define UNICODE 1
+#endif
+
+#ifndef _UNICODE
+Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
+#define _UNICODE 1
+Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
+#endif
+
+#endif // Z7_NO_UNICODE
+#endif // _MBCS
+#endif // _WINDOWS_
+
+// #include "7zWindows.h"
+
+#endif // _WIN32
#endif
diff --git a/src/Common/lzma/Threads.c b/src/Common/lzma/Threads.c
index cf52bd30..464efeca 100644
--- a/src/Common/lzma/Threads.c
+++ b/src/Common/lzma/Threads.c
@@ -1,5 +1,5 @@
/* Threads.c -- multithreading library
-2023-03-04 : Igor Pavlov : Public domain */
+2024-03-28 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -195,20 +195,19 @@ WRes CriticalSection_Init(CCriticalSection *p)
// ---------- POSIX ----------
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__)
#ifndef Z7_AFFINITY_DISABLE
// _GNU_SOURCE can be required for pthread_setaffinity_np() / CPU_ZERO / CPU_SET
// clang < 3.6 : unknown warning group '-Wreserved-id-macro'
// clang 3.6 - 12.01 : gives warning "macro name is a reserved identifier"
// clang >= 13 : do not give warning
#if !defined(_GNU_SOURCE)
- #if defined(__clang__) && (__clang_major__ >= 4) && (__clang_major__ <= 12)
- #pragma GCC diagnostic ignored "-Wreserved-id-macro"
- #endif
-#define _GNU_SOURCE
+Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
+// #define _GNU_SOURCE
+Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
#endif // !defined(_GNU_SOURCE)
#endif // Z7_AFFINITY_DISABLE
-#endif // __APPLE__
+#endif // __linux__
#include "Threads.h"
@@ -244,8 +243,9 @@ WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param,
{
if (cpuSet)
{
- #ifdef Z7_AFFINITY_SUPPORTED
-
+ // pthread_attr_setaffinity_np() is not supported for MUSL compile.
+ // so we check for __GLIBC__ here
+#if defined(Z7_AFFINITY_SUPPORTED) && defined( __GLIBC__)
/*
printf("\n affinity :");
unsigned i;
@@ -267,7 +267,7 @@ WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param,
// ret2 =
pthread_attr_setaffinity_np(&attr, sizeof(*cpuSet), cpuSet);
// if (ret2) ret = ret2;
- #endif
+#endif
}
ret = pthread_create(&p->_tid, &attr, func, param);
@@ -369,13 +369,20 @@ WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
{ return AutoResetEvent_Create(p, 0); }
+#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13)
+// freebsd:
+#pragma GCC diagnostic ignored "-Wthread-safety-analysis"
+#endif
+
WRes Event_Set(CEvent *p)
{
RINOK(pthread_mutex_lock(&p->_mutex))
p->_state = True;
- int res1 = pthread_cond_broadcast(&p->_cond);
- int res2 = pthread_mutex_unlock(&p->_mutex);
- return (res2 ? res2 : res1);
+ {
+ const int res1 = pthread_cond_broadcast(&p->_cond);
+ const int res2 = pthread_mutex_unlock(&p->_mutex);
+ return (res2 ? res2 : res1);
+ }
}
WRes Event_Reset(CEvent *p)
@@ -408,8 +415,8 @@ WRes Event_Close(CEvent *p)
return 0;
p->_created = 0;
{
- int res1 = pthread_mutex_destroy(&p->_mutex);
- int res2 = pthread_cond_destroy(&p->_cond);
+ const int res1 = pthread_mutex_destroy(&p->_mutex);
+ const int res2 = pthread_cond_destroy(&p->_cond);
return (res1 ? res1 : res2);
}
}
@@ -487,8 +494,8 @@ WRes Semaphore_Close(CSemaphore *p)
return 0;
p->_created = 0;
{
- int res1 = pthread_mutex_destroy(&p->_mutex);
- int res2 = pthread_cond_destroy(&p->_cond);
+ const int res1 = pthread_mutex_destroy(&p->_mutex);
+ const int res2 = pthread_cond_destroy(&p->_cond);
return (res1 ? res1 : res2);
}
}
@@ -549,6 +556,18 @@ LONG InterlockedIncrement(LONG volatile *addend)
#endif
}
+LONG InterlockedDecrement(LONG volatile *addend)
+{
+ // Print("InterlockedDecrement")
+ #ifdef USE_HACK_UNSAFE_ATOMIC
+ LONG val = *addend - 1;
+ *addend = val;
+ return val;
+ #else
+ return __sync_sub_and_fetch(addend, 1);
+ #endif
+}
+
#endif // _WIN32
WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p)
diff --git a/src/Common/lzma/Threads.h b/src/Common/lzma/Threads.h
index 4028464a..c1484a27 100644
--- a/src/Common/lzma/Threads.h
+++ b/src/Common/lzma/Threads.h
@@ -1,5 +1,5 @@
/* Threads.h -- multithreading library
-2023-04-02 : Igor Pavlov : Public domain */
+2024-03-28 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_THREADS_H
#define ZIP7_INC_THREADS_H
@@ -9,12 +9,21 @@
#else
+#include "Compiler.h"
+
+// #define Z7_AFFINITY_DISABLE
#if defined(__linux__)
#if !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__)
#ifndef Z7_AFFINITY_DISABLE
#define Z7_AFFINITY_SUPPORTED
// #pragma message(" ==== Z7_AFFINITY_SUPPORTED")
-// #define _GNU_SOURCE
+#if !defined(_GNU_SOURCE)
+// #pragma message(" ==== _GNU_SOURCE set")
+// we need _GNU_SOURCE for cpu_set_t, if we compile for MUSL
+Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
+#define _GNU_SOURCE
+Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
+#endif
#endif
#endif
#endif
@@ -173,7 +182,7 @@ WRes CriticalSection_Init(CCriticalSection *p);
#else // _WIN32
-typedef struct _CEvent
+typedef struct
{
int _created;
int _manual_reset;
@@ -199,7 +208,7 @@ WRes Event_Wait(CEvent *p);
WRes Event_Close(CEvent *p);
-typedef struct _CSemaphore
+typedef struct
{
int _created;
UInt32 _count;
@@ -219,7 +228,7 @@ WRes Semaphore_Wait(CSemaphore *p);
WRes Semaphore_Close(CSemaphore *p);
-typedef struct _CCriticalSection
+typedef struct
{
pthread_mutex_t _mutex;
} CCriticalSection;
@@ -230,6 +239,7 @@ void CriticalSection_Enter(CCriticalSection *cs);
void CriticalSection_Leave(CCriticalSection *cs);
LONG InterlockedIncrement(LONG volatile *addend);
+LONG InterlockedDecrement(LONG volatile *addend);
#endif // _WIN32
diff --git a/src/Common/lzma/lzma-history.txt b/src/Common/lzma/lzma-history.txt
index a151c4b9..20e0a441 100644
--- a/src/Common/lzma/lzma-history.txt
+++ b/src/Common/lzma/lzma-history.txt
@@ -1,6 +1,80 @@
HISTORY of the LZMA SDK
-----------------------
+24.09 2024-11-29
+-------------------------
+- The default dictionary size values for LZMA/LZMA2 compression methods were increased:
+ dictionary size compression level
+ v24.08 v24.09 v24.09
+ 32-bit 64-bit
+ 8 MB 16 MB 16 MB -mx4
+ 16 MB 32 MB 32 MB -mx5 : Normal
+ 32 MB 64 MB 64 MB -mx6
+ 32 MB 64 MB 128 MB -mx7 : Maximum
+ 64 MB 64 MB 256 MB -mx8
+ 64 MB 64 MB 256 MB -mx9 : Ultra
+ The default dictionary size values for 32-bit versions of LZMA/LZMA2 don't exceed 64 MB.
+- If an archive update operation uses a temporary archive folder and
+ the archive is moved to the destination folder, 7-Zip shows the progress of moving
+ the archive file, as this operation can take a long time if the archive is large.
+- Some bugs were fixed.
+
+
+24.07 2024-06-19
+-------------------------
+- Changes in files:
+ Asm/x86/Sha256Opt.asm
+ Now it uses "READONLY" flag for constant array segment.
+ It fixes an issue where ".rodata" section in 7-Zip for x86/x64 Linux had a "WRITE" attribute.
+
+
+24.05 2024-05-14
+-------------------------
+- New switch -myv={MMNN} to set decoder compatibility version for 7z archive creating.
+ {MMNN} is 4-digit number that represents the version of 7-Zip without a dot.
+ If -myv={MMNN} switch is specified, 7-Zip will only use compression methods that can
+ be decoded by the specified version {MMNN} of 7-Zip and newer versions.
+ If -myv={MMNN} switch is not specified, -myv=2300 is used, and 7-Zip will only
+ use compression methods that can be decoded by 7-Zip 23.00 and newer versions.
+- New switch -myfa={FilterID} to allow 7-Zip to use the specified filter method for 7z archive creating.
+- New switch -myfd={FilterID} to disallow 7-Zip to use the specified filter method for 7z archive creating.
+
+
+24.03 2024-03-23
+-------------------------
+- 7-Zip now can use new RISCV filter for compression to 7z and xz archives.
+ RISCV filter can increase compression ratio for data containing executable
+ files compiled for RISC-V architecture.
+- The speed for LZMA and LZMA2 decompression in ARM64 version for Windows
+ was increased by 20%-60%.
+ It uses arm64 assembler code, and clang-cl is required for arm64 assembler code compiling.
+- -slmu switch : to show timestamps as UTC instead of LOCAL TIME.
+- -slsl switch : in console 7-Zip for Windows : to show file paths with
+ linux path separator slash '/' instead of backslash separator '\'.
+- 7-Zip supports .sha256 files that use backslash path separator '\'.
+- Some bugs were fixed.
+
+
+24.01 2024-01-31
+-------------------------
+- 7-Zip uses file C/Precomp.h that is included to all c and c++ files.
+ CPP/Common/Common.h also includes C/Precomp.h.
+ C/Precomp.h defines the following macros (if _WIN32 is defined):
+ Z7_LARGE_PAGES 1
+ Z7_LONG_PATH 1
+ Z7_WIN32_WINNT_MIN 0x0500 (or higher)
+ _WIN32_WINNT 0x0500 (or higher)
+ WINVER _WIN32_WINNT
+ UNICODE 1
+ _UNICODE 1
+ if _WIN32_WINNT is defined already, C/Precomp.h doesn't redefine it.
+
+- Speed optimizations for hash caclulation: CRC-32, CRC-64.
+- The bug was fixed: 7-Zip for Linux could fail for multivolume creation in some cases.
+- 7zr.exe for arm64 is included to LZMA SDK package.
+- Some bugs were fixed.
+
+
23.01 2023-06-20
-------------------------
- 7-Zip now can use new ARM64 filter for compression to 7z and xz archives.
diff --git a/src/Common/lzma/lzma-sdk.txt b/src/Common/lzma/lzma-sdk.txt
index 141b0fd4..f7016709 100644
--- a/src/Common/lzma/lzma-sdk.txt
+++ b/src/Common/lzma/lzma-sdk.txt
@@ -1,4 +1,4 @@
-LZMA SDK 23.01
+LZMA SDK 24.09
--------------
LZMA SDK provides the documentation, samples, header files,
@@ -137,9 +137,12 @@ DOC/Methods.txt - Compression method IDs for .7z
bin/installer/ - example script to create installer that uses SFX module,
-bin/7zdec.exe - simplified 7z archive decoder
-bin/7zr.exe - 7-Zip console program (reduced version)
+bin/7zdec.exe - simplified 7z archive decoder (x86 32-bit version)
+bin/7zr.exe - 7-Zip console program (reduced version) (x86 32-bit version)
bin/x64/7zr.exe - 7-Zip console program (reduced version) (x64 version)
+bin/x64/7zdec.exe - simplified 7z archive decoder (x64 version)
+bin/arm64/7zr.exe - 7-Zip console program (reduced version) (arm64 version)
+bin/arm64/7zdec.exe - simplified 7z archive decoder (arm64 version)
bin/lzma.exe - file->file LZMA encoder/decoder for Windows
bin/7zS2.sfx - small SFX module for installers (GUI version)
bin/7zS2con.sfx - small SFX module for installers (Console version)
@@ -235,7 +238,7 @@ Note:
LZMA features
-------------
- - Variable dictionary size (up to 1 GB)
+ - Variable dictionary size (up to 4 GB)
- Estimated compressing speed: about 2 MB/s on 2 GHz CPU
- Estimated decompressing speed:
- 20-30 MB/s on modern 2 GHz cpu
@@ -285,8 +288,8 @@ Usage: LZMA <e|d> inputFile outputFile [<switches>...]
-a{N}: set compression mode 0 = fast, 1 = normal
default: 1 (normal)
- d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
- The maximum value for dictionary size is 1 GB = 2^30 bytes.
+ d{N}: Sets Dictionary size - [0, 31], default: N=24 (32 MB)
+ The maximum value for dictionary size is N=31 (2 GB).
Dictionary size is calculated as DictionarySize = 2^N bytes.
For decompressing file compressed by LZMA method with dictionary
size D = 2^N you need about D bytes of memory (RAM).
@@ -321,7 +324,9 @@ Usage: LZMA <e|d> inputFile outputFile [<switches>...]
bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
+ bt5 d * 11.5 + 4MB Binary Tree with 5 bytes hashing.
hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
+ hc5 d * 7.5 + 4MB Hash Chain with 5 bytes hashing.
-eos: write End Of Stream marker. By default LZMA doesn't write
eos marker, since LZMA decoder knows uncompressed size