1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 11:08:02 -06:00

Update Libzip to latest 1.9.2 (#1071)

* Libzip 1.9.2

Updated Libzip to latest version 1.9.2 and changed version number in the config.h from 1.7.3 to 1.9.2. Not sure if anything else needs to be tweaked :)

* Modified Libzip to work with Visual studio

* Update README.md

Update libzip copyright.

* Added the missing files.

I've added the missing files zipconf.h and config.h, I've missed those sorry for that!
This commit is contained in:
DLL125
2023-05-25 12:52:53 +02:00
committed by GitHub
parent b872702309
commit 1fc4168b81
145 changed files with 8187 additions and 3942 deletions

View File

@@ -219,7 +219,7 @@ Copyright (c) 1998-2000 Paul Le Roux. All rights reserved.
Copyright (c) 1998-2008 Brian Gladman, Worcester, UK. All rights reserved. Copyright (c) 1998-2008 Brian Gladman, Worcester, UK. All rights reserved.
Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler. Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler.
Copyright (c) 2016 Disk Cryptography Services for EFI (DCS), Alex Kolotnikov Copyright (c) 2016 Disk Cryptography Services for EFI (DCS), Alex Kolotnikov
Copyright (c) 1999-2017 Dieter Baron and Thomas Klausner. Copyright (c) 1999-2020 Dieter Baron and Thomas Klausner.
Copyright (c) 2013, Alexey Degtyarev. All rights reserved. Copyright (c) 2013, Alexey Degtyarev. All rights reserved.
Copyright (c) 1999-2016 Jack Lloyd. All rights reserved. Copyright (c) 1999-2016 Jack Lloyd. All rights reserved.
Copyright (c) 2013-2019 Stephan Mueller <smueller@chronox.de> Copyright (c) 2013-2019 Stephan Mueller <smueller@chronox.de>

View File

@@ -1,6 +1,6 @@
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,3 +1,35 @@
1.9.2 [2022-06-28]
* Fix version number in header file.
1.9.1 [2022-06-28]
===================
* Fix `zip_file_is_seekable()`.
1.9.0 [2022-06-13]
==================
* Add `zip_file_is_seekable()`.
* Improve compatibility with WinAES.
* Fix encoding handling in `zip_name_locate()`.
* Add option to `zipcmp` to output summary of changes.
* Various bug fixes and documentation improvements.
1.8.0 [2021-06-18]
==================
* Add support for zstd (Zstandard) compression.
* Add support for lzma (ID 14) compression.
* Add `zip_source_window_create()`.
* Add `zip_source_zip_create()` variant to `zip_source_zip()`.
* Allow method specific `comp_flags` in `zip_set_file_compression()`.
* Allow `zip_source_tell()` on sources that don't support seeking and `zip_ftell()` on compressed data.
* Provide more details for consistency check errors.
* Improve output of `zipcmp`.
* In `zipcmp`, dont ignore empty directories when comparing directory listing.
* Treat empty string as no password given in `zip_file_set_encryption()`, `zip_fopen_encrypted()`, and `zip_set_default_password()`.
1.7.3 [2020-07-15] 1.7.3 [2020-07-15]
================== ==================

View File

@@ -3,10 +3,10 @@
/* /*
compat.h -- compatibility defines. compat.h -- compatibility defines.
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -41,27 +41,26 @@
/* to have *_MAX definitions for all types when compiling with g++ */ /* to have *_MAX definitions for all types when compiling with g++ */
#define __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS
#ifdef _WIN32 #if defined(_WIN32) && defined(ZIP_DLL) && !defined(ZIP_STATIC)
#ifndef ZIP_EXTERN #ifdef BUILDING_LIBZIP
#ifndef ZIP_STATIC
#define ZIP_EXTERN __declspec(dllexport) #define ZIP_EXTERN __declspec(dllexport)
#else #else
#define ZIP_EXTERN #define ZIP_EXTERN __declspec(dllimport)
#endif #endif
#endif #endif
#ifdef _WIN32
/* for dup(), close(), etc. */ /* for dup(), close(), etc. */
#include <io.h> #include <io.h>
#endif #endif
#ifdef HAVE_STDBOOL_H #ifdef HAVE_STDBOOL_H
#include <stdbool.h> #include <stdbool.h>
#else #elif !defined(__BOOL_DEFINED)
#ifndef __cplusplus
typedef char bool; typedef char bool;
#define true 1 #define true 1
#define false 0 #define false 0
#endif #endif
#endif
#include <errno.h> #include <errno.h>
@@ -85,9 +84,6 @@ typedef char bool;
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#if defined(HAVE__CHMOD)
#define chmod _chmod
#endif
#if defined(HAVE__CLOSE) #if defined(HAVE__CLOSE)
#define close _close #define close _close
#endif #endif
@@ -101,7 +97,7 @@ typedef char bool;
#if !defined(HAVE_FILENO) && defined(HAVE__FILENO) #if !defined(HAVE_FILENO) && defined(HAVE__FILENO)
#define fileno _fileno #define fileno _fileno
#endif #endif
#if defined(HAVE__SNPRINTF) #if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
#define snprintf _snprintf #define snprintf _snprintf
#endif #endif
#if defined(HAVE__STRDUP) #if defined(HAVE__STRDUP)

View File

@@ -5,68 +5,72 @@
#endif #endif
/* BEGIN DEFINES */ /* BEGIN DEFINES */
/* #undef HAVE___PROGNAME */ /* #undef HAVE___PROGNAME */
#define HAVE__CHMOD
#define HAVE__CLOSE #define HAVE__CLOSE
#define HAVE__DUP #define HAVE__DUP
#define HAVE__FDOPEN #define HAVE__FDOPEN
#define HAVE__FILENO #define HAVE__FILENO
#define HAVE__OPEN
#define HAVE__SETMODE #define HAVE__SETMODE
#if defined(_MSC_VER) && _MSC_VER < 1900
#define HAVE__SNPRINTF
#else
/* #undef HAVE__SNPRINTF */ /* #undef HAVE__SNPRINTF */
#endif
#define HAVE__STRDUP #define HAVE__STRDUP
#define HAVE__STRICMP #define HAVE__STRICMP
#define HAVE__STRTOI64 #define HAVE__STRTOI64
#define HAVE__STRTOUI64 #define HAVE__STRTOUI64
#define HAVE__UMASK /* #undef HAVE__UMASK */
#define HAVE__UNLINK #define HAVE__UNLINK
/* #undef HAVE_ARC4RANDOM */
/* #undef HAVE_CLONEFILE */ /* #undef HAVE_CLONEFILE */
/* #undef HAVE_COMMONCRYPTO */ /* #undef HAVE_COMMONCRYPTO */
/* #undef HAVE_CRYPTO */ #define HAVE_CRYPTO
/* #undef HAVE_FICLONERANGE */ /* #undef HAVE_FICLONERANGE */
#define HAVE_FILENO #define HAVE_FILENO
/* #undef HAVE_FCHMOD */
/* #undef HAVE_FSEEKO */ /* #undef HAVE_FSEEKO */
/* #undef HAVE_FTELLO */ /* #undef HAVE_FTELLO */
/* #undef HAVE_GETPROGNAME */ /* #undef HAVE_GETPROGNAME */
/* #undef HAVE_GNUTLS */ /* #undef HAVE_GNUTLS */
/* #undef HAVE_LIBBZ2 */ /* #undef HAVE_LIBBZ2 */
#define HAVE_OPEN /* #undef HAVE_LIBLZMA */
/* #undef HAVE_OPENSSL */ /* #undef HAVE_LIBZSTD */
/* #undef HAVE_LOCALTIME_R */
/* #undef HAVE_MBEDTLS */
/* #undef HAVE_MKSTEMP */ /* #undef HAVE_MKSTEMP */
/* #undef HAVE_NULLABLE */
/* #undef HAVE_OPENSSL */
#define HAVE_SETMODE #define HAVE_SETMODE
#if defined(_MSC_VER) && _MSC_VER < 1900
/* #undef HAVE_SNPRINTF */ /* #undef HAVE_SNPRINTF */
/* #undef HAVE_SSIZE_T_LIBZIP */ #else
#define HAVE_SNPRINTF
#endif
/* #undef HAVE_STRCASECMP */ /* #undef HAVE_STRCASECMP */
#define HAVE_STRDUP #define HAVE_STRDUP
#define HAVE_STRICMP #define HAVE_STRICMP
#if defined(_MSC_VER) && _MSC_VER < 1800
/* #undef HAVE_STRTOLL */ /* #undef HAVE_STRTOLL */
/* #undef HAVE_STRTOULL */ /* #undef HAVE_STRTOULL */
#else
#define HAVE_STRTOLL
#define HAVE_STRTOULL
#endif
/* #undef HAVE_STRUCT_TM_TM_ZONE */ /* #undef HAVE_STRUCT_TM_TM_ZONE */
#if defined(_MSC_VER) && _MSC_VER < 1800
/* #undef HAVE_STDBOOL_H */ /* #undef HAVE_STDBOOL_H */
#else
#define HAVE_STDBOOL_H
#endif
/* #undef HAVE_STRINGS_H */ /* #undef HAVE_STRINGS_H */
/* #undef HAVE_UNISTD_H */ /* #undef HAVE_UNISTD_H */
#define __INT8_LIBZIP 1 #define HAVE_WINDOWS_CRYPTO
#define INT8_T_LIBZIP 1
#define UINT8_T_LIBZIP 1
#define __INT16_LIBZIP 2
#define INT16_T_LIBZIP 2
#define UINT16_T_LIBZIP 2
#define __INT32_LIBZIP 4
#define INT32_T_LIBZIP 4
#define UINT32_T_LIBZIP 4
#define __INT64_LIBZIP 8
#define INT64_T_LIBZIP 8
#define UINT64_T_LIBZIP 8
#define SHORT_LIBZIP 2
#define INT_LIBZIP 4
#define LONG_LIBZIP 4
#define LONG_LONG_LIBZIP 8
#define SIZEOF_OFF_T 4 #define SIZEOF_OFF_T 4
#ifdef _WIN64 #ifdef _WIN64
#define SIZE_T_LIBZIP 8 #define SIZEOF_SIZE_T 8
#else #else
#define SIZE_T_LIBZIP 4 #define SIZEOF_SIZE_T 4
#endif #endif
/* #undef SSIZE_T_LIBZIP */
/* #undef HAVE_DIRENT_H */ /* #undef HAVE_DIRENT_H */
/* #undef HAVE_FTS_H */ /* #undef HAVE_FTS_H */
/* #undef HAVE_NDIR_H */ /* #undef HAVE_NDIR_H */
@@ -76,18 +80,6 @@
#define HAVE_SHARED #define HAVE_SHARED
/* END DEFINES */ /* END DEFINES */
#define PACKAGE "libzip" #define PACKAGE "libzip"
#define VERSION "1.7.3" #define VERSION "1.9.2"
#ifndef HAVE_SSIZE_T_LIBZIP
# if SIZE_T_LIBZIP == INT_LIBZIP
typedef int ssize_t;
# elif SIZE_T_LIBZIP == LONG_LIBZIP
typedef long ssize_t;
# elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP
typedef long long ssize_t;
# else
#error no suitable type for ssize_t found
# endif
#endif
#endif /* HAD_CONFIG_H */ #endif /* HAD_CONFIG_H */

View File

@@ -3,10 +3,10 @@
/* /*
zip.h -- exported declarations. zip.h -- exported declarations.
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -45,9 +45,13 @@ extern "C" {
#include <zipconf.h> #include <zipconf.h>
#ifndef ZIP_EXTERN #ifndef ZIP_EXTERN
#ifndef ZIP_STATIC #if defined(ZIP_DLL) && !defined(ZIP_STATIC)
#ifdef _WIN32 #ifdef _WIN32
#ifdef BUILDING_LIBZIP
#define ZIP_EXTERN __declspec(dllexport)
#else
#define ZIP_EXTERN __declspec(dllimport) #define ZIP_EXTERN __declspec(dllimport)
#endif
#elif defined(__GNUC__) && __GNUC__ >= 4 #elif defined(__GNUC__) && __GNUC__ >= 4
#define ZIP_EXTERN __attribute__((visibility("default"))) #define ZIP_EXTERN __attribute__((visibility("default")))
#else #else
@@ -58,9 +62,6 @@ extern "C" {
#endif #endif
#endif #endif
#define _Nullable
#define _Nonnull
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <time.h> #include <time.h>
@@ -126,7 +127,7 @@ extern "C" {
#define ZIP_ER_INVAL 18 /* N Invalid argument */ #define ZIP_ER_INVAL 18 /* N Invalid argument */
#define ZIP_ER_NOZIP 19 /* N Not a zip archive */ #define ZIP_ER_NOZIP 19 /* N Not a zip archive */
#define ZIP_ER_INTERNAL 20 /* N Internal error */ #define ZIP_ER_INTERNAL 20 /* N Internal error */
#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ #define ZIP_ER_INCONS 21 /* L Zip archive inconsistent */
#define ZIP_ER_REMOVE 22 /* S Can't remove file */ #define ZIP_ER_REMOVE 22 /* S Can't remove file */
#define ZIP_ER_DELETED 23 /* N Entry has been deleted */ #define ZIP_ER_DELETED 23 /* N Entry has been deleted */
#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */ #define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */
@@ -144,6 +145,7 @@ extern "C" {
#define ZIP_ET_NONE 0 /* sys_err unused */ #define ZIP_ET_NONE 0 /* sys_err unused */
#define ZIP_ET_SYS 1 /* sys_err is errno */ #define ZIP_ET_SYS 1 /* sys_err is errno */
#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */ #define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */
#define ZIP_ET_LIBZIP 3 /* sys_err is libzip error code */
/* compression methods */ /* compression methods */
@@ -166,7 +168,9 @@ extern "C" {
/* 15-17 - Reserved by PKWARE */ /* 15-17 - Reserved by PKWARE */
#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ #define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */
#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ #define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
/* 20 - old value for Zstandard */
#define ZIP_CM_LZMA2 33 #define ZIP_CM_LZMA2 33
#define ZIP_CM_ZSTD 93 /* Zstandard compressed data */
#define ZIP_CM_XZ 95 /* XZ compressed data */ #define ZIP_CM_XZ 95 /* XZ compressed data */
#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */ #define ZIP_CM_JPEG 96 /* Compressed Jpeg data */
#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ #define ZIP_CM_WAVPACK 97 /* WavPack compressed data */
@@ -242,6 +246,8 @@ typedef enum zip_source_cmd zip_source_cmd_t;
#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd)) #define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd))
#define ZIP_SOURCE_CHECK_SUPPORTED(supported, cmd) (((supported) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd)) != 0)
/* clang-format off */ /* clang-format off */
#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \ #define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \
@@ -397,6 +403,7 @@ ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get_by_id(zip_t *_N
ZIP_EXTERN const char *_Nullable zip_file_get_comment(zip_t *_Nonnull, zip_uint64_t, zip_uint32_t *_Nullable, zip_flags_t); ZIP_EXTERN const char *_Nullable zip_file_get_comment(zip_t *_Nonnull, zip_uint64_t, zip_uint32_t *_Nullable, zip_flags_t);
ZIP_EXTERN zip_error_t *_Nonnull zip_file_get_error(zip_file_t *_Nonnull); ZIP_EXTERN zip_error_t *_Nonnull zip_file_get_error(zip_file_t *_Nonnull);
ZIP_EXTERN int zip_file_get_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t *_Nullable, zip_uint32_t *_Nullable); ZIP_EXTERN int zip_file_get_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t *_Nullable, zip_uint32_t *_Nullable);
ZIP_EXTERN int zip_file_is_seekable(zip_file_t *_Nonnull);
ZIP_EXTERN int zip_file_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull, zip_flags_t); ZIP_EXTERN int zip_file_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN int zip_file_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull, zip_flags_t); ZIP_EXTERN int zip_file_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull, zip_flags_t);
ZIP_EXTERN int zip_file_set_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, zip_uint16_t, zip_flags_t); ZIP_EXTERN int zip_file_set_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, zip_uint16_t, zip_flags_t);
@@ -463,8 +470,10 @@ ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip
ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t); ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *); ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *);
#endif #endif
ZIP_EXTERN zip_source_t *_Nullable zip_source_window_create(zip_source_t *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t); ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t); ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip_create(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
ZIP_EXTERN int zip_stat(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, zip_stat_t *_Nonnull); ZIP_EXTERN int zip_stat(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, zip_stat_t *_Nonnull);
ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull); ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull);
ZIP_EXTERN void zip_stat_init(zip_stat_t *_Nonnull); ZIP_EXTERN void zip_stat_init(zip_stat_t *_Nonnull);

View File

@@ -1,9 +1,9 @@
/* /*
zip_add.c -- add file via callback function zip_add.c -- add file via callback function
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_add_dir.c -- add directory zip_add_dir.c -- add directory
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_add_entry.c -- create and init struct zip_entry zip_add_entry.c -- create and init struct zip_entry
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -0,0 +1,285 @@
/*
zip_algorithm_bzip2.c -- bzip2 (de)compression routines
Copyright (C) 2017-2021 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"
#include <bzlib.h>
#include <limits.h>
#include <stdlib.h>
struct ctx {
zip_error_t *error;
bool compress;
int compression_flags;
bool end_of_input;
bz_stream zstr;
};
static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
zip_uint64_t compressed_size = (zip_uint64_t)((double)uncompressed_size * 1.006);
if (compressed_size < uncompressed_size) {
return ZIP_UINT64_MAX;
}
return compressed_size;
}
static void *
allocate(bool compress, int compression_flags, zip_error_t *error) {
struct ctx *ctx;
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
return NULL;
}
ctx->error = error;
ctx->compress = compress;
ctx->compression_flags = compression_flags;
if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
ctx->compression_flags = 9;
}
ctx->end_of_input = false;
ctx->zstr.bzalloc = NULL;
ctx->zstr.bzfree = NULL;
ctx->zstr.opaque = NULL;
return ctx;
}
static void *
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(true, compression_flags, error);
}
static void *
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(false, compression_flags, error);
}
static void
deallocate(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
free(ctx);
}
static zip_uint16_t
general_purpose_bit_flags(void *ud) {
return 0;
}
static int
map_error(int ret) {
switch (ret) {
case BZ_FINISH_OK:
case BZ_FLUSH_OK:
case BZ_OK:
case BZ_RUN_OK:
case BZ_STREAM_END:
return ZIP_ER_OK;
case BZ_DATA_ERROR:
case BZ_DATA_ERROR_MAGIC:
case BZ_UNEXPECTED_EOF:
return ZIP_ER_COMPRESSED_DATA;
case BZ_MEM_ERROR:
return ZIP_ER_MEMORY;
case BZ_PARAM_ERROR:
return ZIP_ER_INVAL;
case BZ_CONFIG_ERROR: /* actually, bzip2 miscompiled */
case BZ_IO_ERROR:
case BZ_OUTBUFF_FULL:
case BZ_SEQUENCE_ERROR:
return ZIP_ER_INTERNAL;
default:
return ZIP_ER_INTERNAL;
}
}
static bool
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
struct ctx *ctx = (struct ctx *)ud;
int ret;
ctx->zstr.avail_in = 0;
ctx->zstr.next_in = NULL;
ctx->zstr.avail_out = 0;
ctx->zstr.next_out = NULL;
if (ctx->compress) {
ret = BZ2_bzCompressInit(&ctx->zstr, ctx->compression_flags, 0, 30);
}
else {
ret = BZ2_bzDecompressInit(&ctx->zstr, 0, 0);
}
if (ret != BZ_OK) {
zip_error_set(ctx->error, map_error(ret), 0);
return false;
}
return true;
}
static bool
end(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
int err;
if (ctx->compress) {
err = BZ2_bzCompressEnd(&ctx->zstr);
}
else {
err = BZ2_bzDecompressEnd(&ctx->zstr);
}
if (err != BZ_OK) {
zip_error_set(ctx->error, map_error(err), 0);
return false;
}
return true;
}
static bool
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
struct ctx *ctx = (struct ctx *)ud;
if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
return false;
}
ctx->zstr.avail_in = (unsigned int)length;
ctx->zstr.next_in = (char *)data;
return true;
}
static void
end_of_input(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
ctx->end_of_input = true;
}
static zip_compression_status_t
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
struct ctx *ctx = (struct ctx *)ud;
int ret;
if (ctx->zstr.avail_in == 0 && !ctx->end_of_input) {
*length = 0;
return ZIP_COMPRESSION_NEED_DATA;
}
ctx->zstr.avail_out = (unsigned int)ZIP_MIN(UINT_MAX, *length);
ctx->zstr.next_out = (char *)data;
if (ctx->compress) {
ret = BZ2_bzCompress(&ctx->zstr, ctx->end_of_input ? BZ_FINISH : BZ_RUN);
}
else {
ret = BZ2_bzDecompress(&ctx->zstr);
}
*length = *length - ctx->zstr.avail_out;
switch (ret) {
case BZ_FINISH_OK: /* compression */
return ZIP_COMPRESSION_OK;
case BZ_OK: /* decompression */
case BZ_RUN_OK: /* compression */
if (ctx->zstr.avail_in == 0) {
return ZIP_COMPRESSION_NEED_DATA;
}
return ZIP_COMPRESSION_OK;
case BZ_STREAM_END:
return ZIP_COMPRESSION_END;
default:
zip_error_set(ctx->error, map_error(ret), 0);
return ZIP_COMPRESSION_ERROR;
}
}
/* clang-format off */
zip_compression_algorithm_t zip_algorithm_bzip2_compress = {
maximum_compressed_size,
compress_allocate,
deallocate,
general_purpose_bit_flags,
46,
start,
end,
input,
end_of_input,
process
};
zip_compression_algorithm_t zip_algorithm_bzip2_decompress = {
maximum_compressed_size,
decompress_allocate,
deallocate,
general_purpose_bit_flags,
46,
start,
end,
input,
end_of_input,
process
};
/* clang-format on */

View File

@@ -1,9 +1,9 @@
/* /*
zip_algorithm_deflate.c -- deflate (de)compression routines zip_algorithm_deflate.c -- deflate (de)compression routines
Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -46,6 +46,19 @@ struct ctx {
}; };
static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
/* max deflate size increase: size + ceil(size/16k)*5+6 */
zip_uint64_t compressed_size = uncompressed_size + (uncompressed_size + 16383) / 16384 * 5 + 6;
if (compressed_size < uncompressed_size) {
return ZIP_UINT64_MAX;
}
return compressed_size;
}
static void * static void *
allocate(bool compress, int compression_flags, zip_error_t *error) { allocate(bool compress, int compression_flags, zip_error_t *error) {
struct ctx *ctx; struct ctx *ctx;
@@ -110,7 +123,7 @@ general_purpose_bit_flags(void *ud) {
static bool static bool
start(void *ud) { start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
struct ctx *ctx = (struct ctx *)ud; struct ctx *ctx = (struct ctx *)ud;
int ret; int ret;
@@ -223,6 +236,7 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
/* clang-format off */ /* clang-format off */
zip_compression_algorithm_t zip_algorithm_deflate_compress = { zip_compression_algorithm_t zip_algorithm_deflate_compress = {
maximum_compressed_size,
compress_allocate, compress_allocate,
deallocate, deallocate,
general_purpose_bit_flags, general_purpose_bit_flags,
@@ -236,6 +250,7 @@ zip_compression_algorithm_t zip_algorithm_deflate_compress = {
zip_compression_algorithm_t zip_algorithm_deflate_decompress = { zip_compression_algorithm_t zip_algorithm_deflate_decompress = {
maximum_compressed_size,
decompress_allocate, decompress_allocate,
deallocate, deallocate,
general_purpose_bit_flags, general_purpose_bit_flags,

View File

@@ -0,0 +1,406 @@
/*
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
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"
#include <limits.h>
#include <lzma.h>
#include <stdlib.h>
#include <zlib.h>
enum header_state { INCOMPLETE, OUTPUT, DONE };
#define HEADER_BYTES_ZIP 9
#define HEADER_MAGIC_LENGTH 4
#define HEADER_MAGIC1_OFFSET 0
#define HEADER_MAGIC2_OFFSET 2
#define HEADER_SIZE_OFFSET 9
#define HEADER_SIZE_LENGTH 8
#define HEADER_PARAMETERS_LENGTH 5
#define HEADER_LZMA_ALONE_LENGTH (HEADER_PARAMETERS_LENGTH + HEADER_SIZE_LENGTH)
struct ctx {
zip_error_t *error;
bool compress;
zip_uint32_t compression_flags;
bool end_of_input;
lzma_stream zstr;
zip_uint16_t method;
/* header member is used for converting from zip to "lzma alone"
* format
*
* "lzma alone" file format starts with:
* 5 bytes lzma parameters
* 8 bytes uncompressed size
* compressed data
*
* zip archive on-disk format starts with
* 4 bytes magic (first two bytes vary, e.g. 0x0914 or 0x1002, next bytes are 0x0500)
* 5 bytes lzma parameters
* compressed data
*
* we read the data into a header of the form
* 4 bytes magic
* 5 bytes lzma parameters
* 8 bytes uncompressed size
*/
zip_uint8_t header[HEADER_MAGIC_LENGTH + HEADER_LZMA_ALONE_LENGTH];
zip_uint8_t header_bytes_offset;
enum header_state header_state;
zip_uint64_t uncompresssed_size;
};
static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
/*
According to https://sourceforge.net/p/sevenzip/discussion/45797/thread/b6bd62f8/
1) you can use
outSize = 1.10 * originalSize + 64 KB.
in most cases outSize is less then 1.02 from originalSize.
2) You can try LZMA2, where
outSize can be = 1.001 * originalSize + 1 KB.
*/
/* 13 bytes added for lzma alone header */
zip_uint64_t compressed_size = (zip_uint64_t)((double)uncompressed_size * 1.1) + 64 * 1024 + 13;
if (compressed_size < uncompressed_size) {
return ZIP_UINT64_MAX;
}
return compressed_size;
}
static void *
allocate(bool compress, int compression_flags, zip_error_t *error, zip_uint16_t method) {
struct ctx *ctx;
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
ctx->error = error;
ctx->compress = compress;
if (compression_flags < 0 || compression_flags > 9) {
ctx->compression_flags = 6; /* default value */
} else {
ctx->compression_flags = (zip_uint32_t)compression_flags;
}
ctx->compression_flags |= LZMA_PRESET_EXTREME;
ctx->end_of_input = false;
memset(ctx->header, 0, sizeof(ctx->header));
ctx->header_bytes_offset = 0;
if (ZIP_CM_LZMA) {
ctx->header_state = INCOMPLETE;
}
else {
ctx->header_state = DONE;
}
memset(&ctx->zstr, 0, sizeof(ctx->zstr));
ctx->method = method;
return ctx;
}
static void *
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(true, compression_flags, error, method);
}
static void *
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(false, compression_flags, error, method);
}
static void
deallocate(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
free(ctx);
}
static zip_uint16_t
general_purpose_bit_flags(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
if (!ctx->compress) {
return 0;
}
if (ctx->method == ZIP_CM_LZMA) {
/* liblzma always returns an EOS/EOPM marker, see
* https://sourceforge.net/p/lzmautils/discussion/708858/thread/84c5dbb9/#a5e4/3764 */
return 1 << 1;
}
return 0;
}
static int
map_error(lzma_ret ret) {
switch (ret) {
case LZMA_DATA_ERROR:
case LZMA_UNSUPPORTED_CHECK:
return ZIP_ER_COMPRESSED_DATA;
case LZMA_MEM_ERROR:
return ZIP_ER_MEMORY;
case LZMA_OPTIONS_ERROR:
return ZIP_ER_INVAL;
default:
return ZIP_ER_INTERNAL;
}
}
static bool
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
struct ctx *ctx = (struct ctx *)ud;
lzma_ret ret;
lzma_options_lzma opt_lzma;
lzma_lzma_preset(&opt_lzma, ctx->compression_flags);
lzma_filter filters[] = {
{.id = (ctx->method == ZIP_CM_LZMA ? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2), .options = &opt_lzma},
{.id = LZMA_VLI_UNKNOWN, .options = NULL},
};
ctx->zstr.avail_in = 0;
ctx->zstr.next_in = NULL;
ctx->zstr.avail_out = 0;
ctx->zstr.next_out = NULL;
if (ctx->compress) {
if (ctx->method == ZIP_CM_LZMA)
ret = lzma_alone_encoder(&ctx->zstr, filters[0].options);
else
ret = lzma_stream_encoder(&ctx->zstr, filters, LZMA_CHECK_CRC64);
}
else {
if (ctx->method == ZIP_CM_LZMA)
ret = lzma_alone_decoder(&ctx->zstr, UINT64_MAX);
else
ret = lzma_stream_decoder(&ctx->zstr, UINT64_MAX, LZMA_CONCATENATED);
}
if (ret != LZMA_OK) {
zip_error_set(ctx->error, map_error(ret), 0);
return false;
}
/* If general purpose bits 1 & 2 are both zero, write real uncompressed size in header. */
if ((attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) && (attributes->general_purpose_bit_mask & 0x6) == 0x6 && (attributes->general_purpose_bit_flags & 0x06) == 0 && (st->valid & ZIP_STAT_SIZE)) {
ctx->uncompresssed_size = st->size;
}
else {
ctx->uncompresssed_size = ZIP_UINT64_MAX;
}
return true;
}
static bool
end(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
lzma_end(&ctx->zstr);
return true;
}
static bool
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
struct ctx *ctx = (struct ctx *)ud;
if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
return false;
}
/* For decompression of LZMA1: Have we read the full "lzma alone" header yet? */
if (ctx->method == ZIP_CM_LZMA && !ctx->compress && ctx->header_state == INCOMPLETE) {
/* if not, get more of the data */
zip_uint8_t got = (zip_uint8_t)ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, length);
memcpy(ctx->header + ctx->header_bytes_offset, data, got);
ctx->header_bytes_offset += got;
length -= got;
data += got;
/* Do we have a complete header now? */
if (ctx->header_bytes_offset == HEADER_BYTES_ZIP) {
Bytef empty_buffer[1];
zip_buffer_t *buffer;
/* check magic */
if (ctx->header[HEADER_MAGIC2_OFFSET] != 0x05 || ctx->header[HEADER_MAGIC2_OFFSET + 1] != 0x00) {
/* magic does not match */
zip_error_set(ctx->error, ZIP_ER_COMPRESSED_DATA, 0);
return false;
}
/* set size of uncompressed data in "lzma alone" header to "unknown" */
if ((buffer = _zip_buffer_new(ctx->header + HEADER_SIZE_OFFSET, HEADER_SIZE_LENGTH)) == NULL) {
zip_error_set(ctx->error, ZIP_ER_MEMORY, 0);
return false;
}
_zip_buffer_put_64(buffer, ctx->uncompresssed_size);
_zip_buffer_free(buffer);
/* Feed header into "lzma alone" decoder, for
* initialization; this should not produce output. */
ctx->zstr.next_in = (void *)(ctx->header + HEADER_MAGIC_LENGTH);
ctx->zstr.avail_in = HEADER_LZMA_ALONE_LENGTH;
ctx->zstr.total_in = 0;
ctx->zstr.next_out = empty_buffer;
ctx->zstr.avail_out = sizeof(*empty_buffer);
ctx->zstr.total_out = 0;
/* this just initializes the decoder and does not produce output, so it consumes the complete header */
if (lzma_code(&ctx->zstr, LZMA_RUN) != LZMA_OK || ctx->zstr.total_out > 0) {
zip_error_set(ctx->error, ZIP_ER_COMPRESSED_DATA, 0);
return false;
}
ctx->header_state = DONE;
}
}
ctx->zstr.avail_in = (uInt)length;
ctx->zstr.next_in = (Bytef *)data;
return true;
}
static void
end_of_input(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
ctx->end_of_input = true;
}
static zip_compression_status_t
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
struct ctx *ctx = (struct ctx *)ud;
lzma_ret ret;
/* for compression of LZMA1 */
if (ctx->method == ZIP_CM_LZMA && ctx->compress) {
if (ctx->header_state == INCOMPLETE) {
/* write magic to output buffer */
ctx->header[0] = 0x09;
ctx->header[1] = 0x14;
ctx->header[2] = 0x05;
ctx->header[3] = 0x00;
/* generate lzma parameters into output buffer */
ctx->zstr.avail_out = HEADER_LZMA_ALONE_LENGTH;
ctx->zstr.next_out = ctx->header + HEADER_MAGIC_LENGTH;
ret = lzma_code(&ctx->zstr, LZMA_RUN);
if (ret != LZMA_OK || ctx->zstr.avail_out != 0) {
/* assume that the whole header will be provided with the first call to lzma_code */
return ZIP_COMPRESSION_ERROR;
}
ctx->header_state = OUTPUT;
}
if (ctx->header_state == OUTPUT) {
/* write header */
zip_uint8_t write_len = (zip_uint8_t)ZIP_MIN(HEADER_BYTES_ZIP - ctx->header_bytes_offset, *length);
memcpy(data, ctx->header + ctx->header_bytes_offset, write_len);
ctx->header_bytes_offset += write_len;
*length = write_len;
if (ctx->header_bytes_offset == HEADER_BYTES_ZIP) {
ctx->header_state = DONE;
}
return ZIP_COMPRESSION_OK;
}
}
ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
ctx->zstr.next_out = (Bytef *)data;
ret = lzma_code(&ctx->zstr, ctx->end_of_input ? LZMA_FINISH : LZMA_RUN);
*length = *length - ctx->zstr.avail_out;
switch (ret) {
case LZMA_OK:
return ZIP_COMPRESSION_OK;
case LZMA_STREAM_END:
return ZIP_COMPRESSION_END;
case LZMA_BUF_ERROR:
if (ctx->zstr.avail_in == 0) {
return ZIP_COMPRESSION_NEED_DATA;
}
/* fallthrough */
default:
zip_error_set(ctx->error, map_error(ret), 0);
return ZIP_COMPRESSION_ERROR;
}
}
/* Version Required should be set to 63 (6.3) because this compression
method was only defined in appnote.txt version 6.3.8, but Winzip
does not unpack it if the value is not 20. */
/* clang-format off */
zip_compression_algorithm_t zip_algorithm_xz_compress = {
maximum_compressed_size,
compress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
zip_compression_algorithm_t zip_algorithm_xz_decompress = {
maximum_compressed_size,
decompress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
/* clang-format on */

View File

@@ -0,0 +1,294 @@
/*
zip_algorithm_zstd.c -- zstd (de)compression routines
Copyright (C) 2020-2021 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"
#include <limits.h>
#include <stdlib.h>
#include <zstd.h>
#include <zstd_errors.h>
struct ctx {
zip_error_t *error;
bool compress;
int compression_flags;
bool end_of_input;
ZSTD_DStream *zdstream;
ZSTD_CStream *zcstream;
ZSTD_outBuffer out;
ZSTD_inBuffer in;
};
static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
return ZSTD_compressBound(uncompressed_size);
}
static void *
allocate(bool compress, int compression_flags, zip_error_t *error) {
struct ctx *ctx;
/* 0: let zstd choose */
if (compression_flags < ZSTD_minCLevel() || compression_flags > ZSTD_maxCLevel()) {
compression_flags = 0;
}
if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
return NULL;
}
ctx->error = error;
ctx->compress = compress;
ctx->compression_flags = compression_flags;
ctx->end_of_input = false;
ctx->zdstream = NULL;
ctx->zcstream = NULL;
ctx->in.src = NULL;
ctx->in.pos = 0;
ctx->in.size = 0;
ctx->out.dst = NULL;
ctx->out.pos = 0;
ctx->out.size = 0;
return ctx;
}
static void *
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(true, compression_flags, error);
}
static void *
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
return allocate(false, compression_flags, error);
}
static void
deallocate(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
free(ctx);
}
static zip_uint16_t
general_purpose_bit_flags(void *ud) {
/* struct ctx *ctx = (struct ctx *)ud; */
return 0;
}
static int
map_error(size_t ret) {
switch (ret) {
case ZSTD_error_no_error:
return ZIP_ER_OK;
case ZSTD_error_corruption_detected:
case ZSTD_error_checksum_wrong:
case ZSTD_error_dictionary_corrupted:
case ZSTD_error_dictionary_wrong:
return ZIP_ER_COMPRESSED_DATA;
case ZSTD_error_memory_allocation:
return ZIP_ER_MEMORY;
case ZSTD_error_parameter_unsupported:
case ZSTD_error_parameter_outOfBound:
return ZIP_ER_INVAL;
default:
return ZIP_ER_INTERNAL;
}
}
static bool
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
struct ctx *ctx = (struct ctx *)ud;
ctx->in.src = NULL;
ctx->in.pos = 0;
ctx->in.size = 0;
ctx->out.dst = NULL;
ctx->out.pos = 0;
ctx->out.size = 0;
if (ctx->compress) {
size_t ret;
ctx->zcstream = ZSTD_createCStream();
if (ctx->zcstream == NULL) {
zip_error_set(ctx->error, ZIP_ER_MEMORY, 0);
return false;
}
ret = ZSTD_initCStream(ctx->zcstream, ctx->compression_flags);
if (ZSTD_isError(ret)) {
zip_error_set(ctx->error, ZIP_ER_ZLIB, map_error(ret));
return false;
}
}
else {
ctx->zdstream = ZSTD_createDStream();
if (ctx->zdstream == NULL) {
zip_error_set(ctx->error, ZIP_ER_MEMORY, 0);
return false;
}
}
return true;
}
static bool
end(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
size_t ret;
if (ctx->compress) {
ret = ZSTD_freeCStream(ctx->zcstream);
ctx->zcstream = NULL;
}
else {
ret = ZSTD_freeDStream(ctx->zdstream);
ctx->zdstream = NULL;
}
if (ZSTD_isError(ret)) {
zip_error_set(ctx->error, map_error(ret), 0);
return false;
}
return true;
}
static bool
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
struct ctx *ctx = (struct ctx *)ud;
if (length > SIZE_MAX || ctx->in.pos != ctx->in.size) {
zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
return false;
}
ctx->in.src = (const void *)data;
ctx->in.size = (size_t)length;
ctx->in.pos = 0;
return true;
}
static void
end_of_input(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
ctx->end_of_input = true;
}
static zip_compression_status_t
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
struct ctx *ctx = (struct ctx *)ud;
size_t ret;
if (ctx->in.pos == ctx->in.size && !ctx->end_of_input) {
*length = 0;
return ZIP_COMPRESSION_NEED_DATA;
}
ctx->out.dst = data;
ctx->out.pos = 0;
ctx->out.size = ZIP_MIN(SIZE_MAX, *length);
if (ctx->compress) {
if (ctx->in.pos == ctx->in.size && ctx->end_of_input) {
ret = ZSTD_endStream(ctx->zcstream, &ctx->out);
if (ret == 0) {
*length = ctx->out.pos;
return ZIP_COMPRESSION_END;
}
}
else {
ret = ZSTD_compressStream(ctx->zcstream, &ctx->out, &ctx->in);
}
}
else {
ret = ZSTD_decompressStream(ctx->zdstream, &ctx->out, &ctx->in);
}
if (ZSTD_isError(ret)) {
zip_error_set(ctx->error, map_error(ret), 0);
return ZIP_COMPRESSION_ERROR;
}
*length = ctx->out.pos;
if (ctx->in.pos == ctx->in.size) {
return ZIP_COMPRESSION_NEED_DATA;
}
return ZIP_COMPRESSION_OK;
}
/* Version Required should be set to 63 (6.3) because this compression
method was only defined in appnote.txt version 6.3.7, but Winzip
does not unpack it if the value is not 20. */
/* clang-format off */
zip_compression_algorithm_t zip_algorithm_zstd_compress = {
maximum_compressed_size,
compress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
zip_compression_algorithm_t zip_algorithm_zstd_decompress = {
maximum_compressed_size,
decompress_allocate,
deallocate,
general_purpose_bit_flags,
20,
start,
end,
input,
end_of_input,
process
};
/* clang-format on */

View File

@@ -1,9 +1,9 @@
/* /*
zip_buffer.c -- bounds checked access to memory buffer zip_buffer.c -- bounds checked access to memory buffer
Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_close.c -- close zip archive and update changes zip_close.c -- close zip archive and update changes
Copyright (C) 1999-2020 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. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -207,7 +207,7 @@ zip_close(zip_t *za) {
zs = NULL; zs = NULL;
if (!ZIP_ENTRY_DATA_CHANGED(entry)) { if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
if ((zs = _zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { if ((zs = _zip_source_zip_new(za, i, ZIP_FL_UNCHANGED, 0, 0, NULL, &za->error)) == NULL) {
error = 1; error = 1;
break; break;
} }
@@ -333,34 +333,30 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
data_length = (zip_int64_t)st.size; data_length = (zip_int64_t)st.size;
if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) {
zip_uint64_t max_size; zip_uint64_t max_compressed_size;
zip_uint16_t compression_method = ZIP_CM_ACTUAL(de->comp_method);
switch (ZIP_CM_ACTUAL(de->comp_method)) { if (compression_method == ZIP_CM_STORE) {
case ZIP_CM_BZIP2: max_compressed_size = st.size;
/* computed by looking at increase of 10 random files of size 1MB when }
* compressed with bzip2, rounded up: 1.006 */ else {
max_size = 4269351188u; zip_compression_algorithm_t *algorithm = _zip_get_compression_algorithm(compression_method, true);
break; if (algorithm == NULL) {
max_compressed_size = ZIP_UINT64_MAX;
case ZIP_CM_DEFLATE: }
/* max deflate size increase: size + ceil(size/16k)*5+6 */ else {
max_size = 4293656963u; max_compressed_size = algorithm->maximum_compressed_size(st.size);
break; }
case ZIP_CM_STORE:
max_size = 0xffffffffu;
break;
default:
max_size = 0;
} }
if (st.size > max_size) { if (max_compressed_size > 0xffffffffu) {
flags |= ZIP_FL_FORCE_ZIP64; flags |= ZIP_FL_FORCE_ZIP64;
} }
} }
else else {
de->comp_size = st.comp_size; de->comp_size = st.comp_size;
data_length = (zip_int64_t)st.comp_size;
}
} }
if ((offstart = zip_source_tell_write(za->src)) < 0) { if ((offstart = zip_source_tell_write(za->src)) < 0) {
@@ -376,6 +372,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method); needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method);
needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE); needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE);
/* in these cases we can compute the CRC ourselves, so we do */
needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress; needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress;
needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE); needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE);
@@ -415,7 +412,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
} }
if (needs_crc) { if (needs_crc) {
if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) { if ((src_tmp = zip_source_crc_create(src_final, 0, &za->error)) == NULL) {
zip_source_free(src_final); zip_source_free(src_final);
return -1; return -1;
} }
@@ -451,14 +448,30 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
zip_source_free(src_final); zip_source_free(src_final);
return -1; return -1;
} }
if (de->encryption_method == ZIP_EM_TRAD_PKWARE) {
de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR;
/* 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, NULL, NULL, 0, &za->error)) == NULL) {
zip_source_free(src_final);
return -1;
}
zip_source_free(src_final);
src_final = src_tmp;
}
}
if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) { if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) {
/* error set by impl */ /* error set by impl */
zip_source_free(src_final); zip_source_free(src_final);
return -1; return -1;
} }
if (de->encryption_method == ZIP_EM_TRAD_PKWARE) {
de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR;
}
zip_source_free(src_final); zip_source_free(src_final);
src_final = src_tmp; src_final = src_tmp;
@@ -622,17 +635,15 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
static int static int
write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) { write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) {
zip_int64_t cd_start, end, size; if (zip_source_tell_write(za->src) < 0) {
if ((cd_start = zip_source_tell_write(za->src)) < 0) {
return -1; return -1;
} }
if ((size = _zip_cdir_write(za, filelist, survivors)) < 0) { if (_zip_cdir_write(za, filelist, survivors) < 0) {
return -1; return -1;
} }
if ((end = zip_source_tell_write(za->src)) < 0) { if (zip_source_tell_write(za->src) < 0) {
return -1; return -1;
} }

View File

@@ -0,0 +1,54 @@
/*
zip_crypto.h -- crypto definitions
Copyright (C) 2017-2021 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.
*/
#ifndef HAD_ZIP_CRYPTO_H
#define HAD_ZIP_CRYPTO_H
#define ZIP_CRYPTO_SHA1_LENGTH 20
#define ZIP_CRYPTO_AES_BLOCK_LENGTH 16
#if defined(HAVE_WINDOWS_CRYPTO)
#include "zip_crypto_win.h"
#elif defined(HAVE_COMMONCRYPTO)
#include "zip_crypto_commoncrypto.h"
#elif defined(HAVE_GNUTLS)
#include "zip_crypto_gnutls.h"
#elif defined(HAVE_OPENSSL)
#include "zip_crypto_openssl.h"
#elif defined(HAVE_MBEDTLS)
#include "zip_crypto_mbedtls.h"
#else
#error "no crypto backend found"
#endif
#endif /* HAD_ZIP_CRYPTO_H */

View File

@@ -0,0 +1,110 @@
/*
zip_crypto_commoncrypto.c -- CommonCrypto wrapper.
Copyright (C) 2018-2021 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 <stdlib.h>
#include "zipint.h"
#include "zip_crypto.h"
#include <fcntl.h>
#include <unistd.h>
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
CCCryptorRelease(aes);
}
bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
size_t len;
CCCryptorUpdate(aes, in, ZIP_CRYPTO_AES_BLOCK_LENGTH, out, ZIP_CRYPTO_AES_BLOCK_LENGTH, &len);
return true;
}
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
CCCryptorStatus ret;
ret = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES, kCCOptionECBMode, key, key_size / 8, NULL, &aes);
switch (ret) {
case kCCSuccess:
return aes;
case kCCMemoryFailure:
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
case kCCParamError:
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
default:
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return NULL;
}
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
return;
}
_zip_crypto_clear(hmac, sizeof(*hmac));
free(hmac);
}
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
_zip_crypto_hmac_t *hmac;
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
CCHmacInit(hmac, kCCHmacAlgSHA1, secret, secret_length);
return hmac;
}

View File

@@ -0,0 +1,53 @@
/*
zip_crypto_commoncrypto.h -- definitions for CommonCrypto wrapper.
Copyright (C) 2018 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <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.
*/
#ifndef HAD_ZIP_CRYPTO_COMMONCRYPTO_H
#define HAD_ZIP_CRYPTO_COMMONCRYPTO_H
#include <CommonCrypto/CommonCrypto.h>
#define _zip_crypto_aes_t struct _CCCryptor
#define _zip_crypto_hmac_t CCHmacContext
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
#define _zip_crypto_hmac(hmac, data, length) (CCHmacUpdate((hmac), (data), (length)), true)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
#define _zip_crypto_hmac_output(hmac, data) (CCHmacFinal((hmac), (data)), true)
#define _zip_crypto_pbkdf2(key, key_length, salt, salt_length, iterations, output, output_length) (CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)(key), (key_length), (salt), (salt_length), kCCPRFHmacAlgSHA1, (iterations), (output), (output_length)) == kCCSuccess)
#endif /* HAD_ZIP_CRYPTO_COMMONCRYPTO_H */

View File

@@ -0,0 +1,134 @@
/*
zip_crypto_gnutls.c -- GnuTLS wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <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 <stdlib.h>
#include "zipint.h"
#include "zip_crypto.h"
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
if ((aes = (_zip_crypto_aes_t *)malloc(sizeof(*aes))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
aes->key_size = key_size;
switch (aes->key_size) {
case 128:
nettle_aes128_set_encrypt_key(&aes->ctx.ctx_128, key);
break;
case 192:
nettle_aes192_set_encrypt_key(&aes->ctx.ctx_192, key);
break;
case 256:
nettle_aes256_set_encrypt_key(&aes->ctx.ctx_256, key);
break;
default:
zip_error_set(error, ZIP_ER_INVAL, 0);
free(aes);
return NULL;
}
return aes;
}
bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
switch (aes->key_size) {
case 128:
nettle_aes128_encrypt(&aes->ctx.ctx_128, ZIP_CRYPTO_AES_BLOCK_LENGTH, out, in);
break;
case 192:
nettle_aes192_encrypt(&aes->ctx.ctx_192, ZIP_CRYPTO_AES_BLOCK_LENGTH, out, in);
break;
case 256:
nettle_aes256_encrypt(&aes->ctx.ctx_256, ZIP_CRYPTO_AES_BLOCK_LENGTH, out, in);
break;
}
return true;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
_zip_crypto_clear(aes, sizeof(*aes));
free(aes);
}
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
_zip_crypto_hmac_t *hmac;
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (gnutls_hmac_init(hmac, GNUTLS_MAC_SHA1, secret, secret_length) < 0) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
free(hmac);
return NULL;
}
return hmac;
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
zip_uint8_t buf[ZIP_CRYPTO_SHA1_LENGTH];
if (hmac == NULL) {
return;
}
gnutls_hmac_deinit(*hmac, buf);
_zip_crypto_clear(hmac, sizeof(*hmac));
free(hmac);
}
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
return gnutls_rnd(GNUTLS_RND_KEY, buffer, length) == 0;
}

View File

@@ -0,0 +1,68 @@
/*
zip_crypto_gnutls.h -- definitions for GnuTLS wrapper.
Copyright (C) 2018-2021 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.
*/
#ifndef HAD_ZIP_CRYPTO_GNUTLS_H
#define HAD_ZIP_CRYPTO_GNUTLS_H
#define HAVE_SECURE_RANDOM
#include <nettle/aes.h>
#include <nettle/pbkdf2.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
typedef struct {
union {
struct aes128_ctx ctx_128;
struct aes192_ctx ctx_192;
struct aes256_ctx ctx_256;
} ctx;
zip_uint16_t key_size;
} _zip_crypto_aes_t;
#define _zip_crypto_hmac_t gnutls_hmac_hd_t
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
#define _zip_crypto_hmac(hmac, data, length) (gnutls_hmac(*(hmac), (data), (length)) == 0)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
#define _zip_crypto_hmac_output(hmac, data) (gnutls_hmac_output(*(hmac), (data)), true)
#define _zip_crypto_pbkdf2(key, key_length, salt, salt_length, iterations, output, output_length) (pbkdf2_hmac_sha1((key_length), (key), (iterations), (salt_length), (salt), (output_length), (output)), true)
#endif /* HAD_ZIP_CRYPTO_GNUTLS_H */

View File

@@ -0,0 +1,162 @@
/*
zip_crypto_mbedtls.c -- mbed TLS wrapper
Copyright (C) 2018-2021 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 <stdlib.h>
#include "zipint.h"
#include "zip_crypto.h"
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/pkcs5.h>
#include <limits.h>
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
if ((aes = (_zip_crypto_aes_t *)malloc(sizeof(*aes))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
mbedtls_aes_init(aes);
mbedtls_aes_setkey_enc(aes, (const unsigned char *)key, (unsigned int)key_size);
return aes;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
mbedtls_aes_free(aes);
free(aes);
}
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
_zip_crypto_hmac_t *hmac;
if (secret_length > INT_MAX) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
mbedtls_md_init(hmac);
if (mbedtls_md_setup(hmac, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1) != 0) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
free(hmac);
return NULL;
}
if (mbedtls_md_hmac_starts(hmac, (const unsigned char *)secret, (size_t)secret_length) != 0) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
free(hmac);
return NULL;
}
return hmac;
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
return;
}
mbedtls_md_free(hmac);
free(hmac);
}
bool
_zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, int iterations, zip_uint8_t *output, zip_uint64_t output_length) {
mbedtls_md_context_t sha1_ctx;
bool ok = true;
mbedtls_md_init(&sha1_ctx);
if (mbedtls_md_setup(&sha1_ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1) != 0) {
ok = false;
}
if (ok && mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, (const unsigned char *)key, (size_t)key_length, (const unsigned char *)salt, (size_t)salt_length, (unsigned int)iterations, (uint32_t)output_length, (unsigned char *)output) != 0) {
ok = false;
}
mbedtls_md_free(&sha1_ctx);
return ok;
}
typedef struct {
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
} zip_random_context_t;
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
static zip_random_context_t *ctx = NULL;
const unsigned char *pers = "zip_crypto_mbedtls";
if (!ctx) {
ctx = (zip_random_context_t *)malloc(sizeof(zip_random_context_t));
if (!ctx) {
return false;
}
mbedtls_entropy_init(&ctx->entropy);
mbedtls_ctr_drbg_init(&ctx->ctr_drbg);
if (mbedtls_ctr_drbg_seed(&ctx->ctr_drbg, mbedtls_entropy_func, &ctx->entropy, pers, strlen(pers)) != 0) {
mbedtls_ctr_drbg_free(&ctx->ctr_drbg);
mbedtls_entropy_free(&ctx->entropy);
free(ctx);
ctx = NULL;
return false;
}
}
return mbedtls_ctr_drbg_random(&ctx->ctr_drbg, (unsigned char *)buffer, (size_t)length) == 0;
}

View File

@@ -0,0 +1,56 @@
/*
zip_crypto_mbedtls.h -- definitions for mbedtls wrapper
Copyright (C) 2018-2021 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.
*/
#ifndef HAD_ZIP_CRYPTO_MBEDTLS_H
#define HAD_ZIP_CRYPTO_MBEDTLS_H
#define HAVE_SECURE_RANDOM
#include <mbedtls/aes.h>
#include <mbedtls/md.h>
#define _zip_crypto_aes_t mbedtls_aes_context
#define _zip_crypto_hmac_t mbedtls_md_context_t
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
#define _zip_crypto_aes_encrypt_block(aes, in, out) (mbedtls_aes_crypt_ecb((aes), MBEDTLS_AES_ENCRYPT, (in), (out)) == 0)
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
#define _zip_crypto_hmac(hmac, data, length) (mbedtls_md_hmac_update((hmac), (data), (length)) == 0)
#define _zip_crypto_hmac_output(hmac, data) (mbedtls_md_hmac_finish((hmac), (data)) == 0)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
bool _zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, int iterations, zip_uint8_t *output, zip_uint64_t output_length);
#endif /* HAD_ZIP_CRYPTO_MBEDTLS_H */

View File

@@ -0,0 +1,184 @@
/*
zip_crypto_openssl.c -- OpenSSL wrapper.
Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <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 <stdlib.h>
#include "zipint.h"
#include "zip_crypto.h"
#include <limits.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
#define USE_OPENSSL_1_0_API
#endif
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
const EVP_CIPHER* cipher_type;
switch (key_size) {
case 128:
cipher_type = EVP_aes_128_ecb();
break;
case 192:
cipher_type = EVP_aes_192_ecb();
break;
case 256:
cipher_type = EVP_aes_256_ecb();
break;
default:
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return NULL;
}
#ifdef USE_OPENSSL_1_0_API
if ((aes = (_zip_crypto_aes_t *)malloc(sizeof(*aes))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
memset(aes, 0, sizeof(*aes));
#else
if ((aes = EVP_CIPHER_CTX_new()) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
#endif
if (EVP_EncryptInit_ex(aes, cipher_type, NULL, key, NULL) != 1) {
#ifdef USE_OPENSSL_1_0_API
free(aes);
#else
EVP_CIPHER_CTX_free(aes);
#endif
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return NULL;
}
return aes;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
#ifdef USE_OPENSSL_1_0_API
EVP_CIPHER_CTX_cleanup(aes);
_zip_crypto_clear(aes, sizeof(*aes));
free(aes);
#else
EVP_CIPHER_CTX_free(aes);
#endif
}
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) {
return false;
}
return true;
}
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
_zip_crypto_hmac_t *hmac;
if (secret_length > INT_MAX) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
#ifdef USE_OPENSSL_1_0_API
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
HMAC_CTX_init(hmac);
#else
if ((hmac = HMAC_CTX_new()) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
#endif
if (HMAC_Init_ex(hmac, secret, (int)secret_length, EVP_sha1(), NULL) != 1) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
#ifdef USE_OPENSSL_1_0_API
free(hmac);
#else
HMAC_CTX_free(hmac);
#endif
return NULL;
}
return hmac;
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
return;
}
#ifdef USE_OPENSSL_1_0_API
HMAC_CTX_cleanup(hmac);
_zip_crypto_clear(hmac, sizeof(*hmac));
free(hmac);
#else
HMAC_CTX_free(hmac);
#endif
}
bool
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
unsigned int length;
return HMAC_Final(hmac, data, &length) == 1;
}
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
return RAND_bytes(buffer, length) == 1;
}

View File

@@ -0,0 +1,56 @@
/*
zip_crypto_openssl.h -- definitions for OpenSSL wrapper.
Copyright (C) 2018-2021 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.
*/
#ifndef HAD_ZIP_CRYPTO_OPENSSL_H
#define HAD_ZIP_CRYPTO_OPENSSL_H
#define HAVE_SECURE_RANDOM
#include <openssl/evp.h>
#include <openssl/hmac.h>
#define _zip_crypto_aes_t EVP_CIPHER_CTX
#define _zip_crypto_hmac_t HMAC_CTX
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
#define _zip_crypto_hmac(hmac, data, length) (HMAC_Update((hmac), (data), (length)) == 1)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
bool _zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data);
#define _zip_crypto_pbkdf2(key, key_length, salt, salt_length, iterations, output, output_length) (PKCS5_PBKDF2_HMAC_SHA1((const char *)(key), (key_length), (salt), (salt_length), (iterations), (output_length), (output)))
#endif /* HAD_ZIP_CRYPTO_OPENSSL_H */

View File

@@ -0,0 +1,495 @@
/*
zip_crypto_win.c -- Windows Crypto API wrapper.
Copyright (C) 2018-2021 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 <stdlib.h>
#include <limits.h>
#include "zipint.h"
#include "zip_crypto.h"
#define WIN32_LEAN_AND_MEAN
#define NOCRYPT
#include <windows.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
/*
This code is using the Cryptography API: Next Generation (CNG)
https://docs.microsoft.com/en-us/windows/desktop/seccng/cng-portal
This API is supported on
- Windows Vista or later (client OS)
- Windows Server 2008 (server OS)
- Windows Embedded Compact 2013 (don't know about Windows Embedded Compact 7)
The code was developed for Windows Embedded Compact 2013 (WEC2013),
but should be working for all of the above mentioned OSes.
There are 2 restrictions for WEC2013, Windows Vista and Windows Server 2008:
1.) The function "BCryptDeriveKeyPBKDF2" is not available
I found some code which is implementing this function using the deprecated Crypto API here:
https://www.idrix.fr/Root/content/view/37/54/
I took this code and converted it to the newer CNG API. The original code was more
flexible, but this is not needed here so i refactored it a bit and just kept what is needed.
The define "HAS_BCRYPTDERIVEKEYPBKDF2" controls whether "BCryptDeriveKeyPBKDF2"
of the CNG API is used or not. This define must not be set if you are compiling for WEC2013 or Windows Vista.
2.) "BCryptCreateHash" can't manage the memory needed for the hash object internally
On Windows 7 or later it is possible to pass NULL for the hash object buffer.
This is not supported on WEC2013, so we have to handle the memory allocation/deallocation ourselves.
There is no #ifdef to control that, because this is working for all supported OSes.
*/
#if !defined(WINCE) && !defined(__MINGW32__)
#define HAS_BCRYPTDERIVEKEYPBKDF2
#endif
#ifdef HAS_BCRYPTDERIVEKEYPBKDF2
bool
_zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length) {
BCRYPT_ALG_HANDLE hAlgorithm = NULL;
bool result;
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG))) {
return false;
}
result = BCRYPT_SUCCESS(BCryptDeriveKeyPBKDF2(hAlgorithm, (PUCHAR)key, (ULONG)key_length, (PUCHAR)salt, salt_length, iterations, output, output_length, 0));
BCryptCloseAlgorithmProvider(hAlgorithm, 0);
return result;
}
#else
#include <math.h>
#define DIGEST_SIZE 20
#define BLOCK_SIZE 64
typedef struct {
BCRYPT_ALG_HANDLE hAlgorithm;
BCRYPT_HASH_HANDLE hInnerHash;
BCRYPT_HASH_HANDLE hOuterHash;
ULONG cbHashObject;
PUCHAR pbInnerHash;
PUCHAR pbOuterHash;
} PRF_CTX;
static void
hmacFree(PRF_CTX *pContext) {
if (pContext->hOuterHash)
BCryptDestroyHash(pContext->hOuterHash);
if (pContext->hInnerHash)
BCryptDestroyHash(pContext->hInnerHash);
free(pContext->pbOuterHash);
free(pContext->pbInnerHash);
if (pContext->hAlgorithm)
BCryptCloseAlgorithmProvider(pContext->hAlgorithm, 0);
}
static BOOL
hmacPrecomputeDigest(BCRYPT_HASH_HANDLE hHash, PUCHAR pbPassword, DWORD cbPassword, BYTE mask) {
BYTE buffer[BLOCK_SIZE];
DWORD i;
if (cbPassword > BLOCK_SIZE) {
return FALSE;
}
memset(buffer, mask, sizeof(buffer));
for (i = 0; i < cbPassword; ++i) {
buffer[i] = (char)(pbPassword[i] ^ mask);
}
return BCRYPT_SUCCESS(BCryptHashData(hHash, buffer, sizeof(buffer), 0));
}
static BOOL
hmacInit(PRF_CTX *pContext, PUCHAR pbPassword, DWORD cbPassword) {
BOOL bStatus = FALSE;
ULONG cbResult;
BYTE key[DIGEST_SIZE];
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&pContext->hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, 0)) || !BCRYPT_SUCCESS(BCryptGetProperty(pContext->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&pContext->cbHashObject, sizeof(pContext->cbHashObject), &cbResult, 0)) || ((pContext->pbInnerHash = malloc(pContext->cbHashObject)) == NULL) || ((pContext->pbOuterHash = malloc(pContext->cbHashObject)) == NULL) || !BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &pContext->hInnerHash, pContext->pbInnerHash, pContext->cbHashObject, NULL, 0, 0)) || !BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &pContext->hOuterHash, pContext->pbOuterHash, pContext->cbHashObject, NULL, 0, 0))) {
goto hmacInit_end;
}
if (cbPassword > BLOCK_SIZE) {
BCRYPT_HASH_HANDLE hHash = NULL;
PUCHAR pbHashObject = malloc(pContext->cbHashObject);
if (pbHashObject == NULL) {
goto hmacInit_end;
}
bStatus = BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &hHash, pbHashObject, pContext->cbHashObject, NULL, 0, 0)) && BCRYPT_SUCCESS(BCryptHashData(hHash, pbPassword, cbPassword, 0)) && BCRYPT_SUCCESS(BCryptGetProperty(hHash, BCRYPT_HASH_LENGTH, (PUCHAR)&cbPassword, sizeof(cbPassword), &cbResult, 0)) && BCRYPT_SUCCESS(BCryptFinishHash(hHash, key, cbPassword, 0));
if (hHash)
BCryptDestroyHash(hHash);
free(pbHashObject);
if (!bStatus) {
goto hmacInit_end;
}
pbPassword = key;
}
bStatus = hmacPrecomputeDigest(pContext->hInnerHash, pbPassword, cbPassword, 0x36) && hmacPrecomputeDigest(pContext->hOuterHash, pbPassword, cbPassword, 0x5C);
hmacInit_end:
if (bStatus == FALSE)
hmacFree(pContext);
return bStatus;
}
static BOOL
hmacCalculateInternal(BCRYPT_HASH_HANDLE hHashTemplate, PUCHAR pbData, DWORD cbData, PUCHAR pbOutput, DWORD cbOutput, DWORD cbHashObject) {
BOOL success = FALSE;
BCRYPT_HASH_HANDLE hHash = NULL;
PUCHAR pbHashObject = malloc(cbHashObject);
if (pbHashObject == NULL) {
return FALSE;
}
if (BCRYPT_SUCCESS(BCryptDuplicateHash(hHashTemplate, &hHash, pbHashObject, cbHashObject, 0))) {
success = BCRYPT_SUCCESS(BCryptHashData(hHash, pbData, cbData, 0)) && BCRYPT_SUCCESS(BCryptFinishHash(hHash, pbOutput, cbOutput, 0));
BCryptDestroyHash(hHash);
}
free(pbHashObject);
return success;
}
static BOOL
hmacCalculate(PRF_CTX *pContext, PUCHAR pbData, DWORD cbData, PUCHAR pbDigest) {
DWORD cbResult;
DWORD cbHashObject;
return BCRYPT_SUCCESS(BCryptGetProperty(pContext->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&cbHashObject, sizeof(cbHashObject), &cbResult, 0)) && hmacCalculateInternal(pContext->hInnerHash, pbData, cbData, pbDigest, DIGEST_SIZE, cbHashObject) && hmacCalculateInternal(pContext->hOuterHash, pbDigest, DIGEST_SIZE, pbDigest, DIGEST_SIZE, cbHashObject);
}
static void
myxor(LPBYTE ptr1, LPBYTE ptr2, DWORD dwLen) {
while (dwLen--)
*ptr1++ ^= *ptr2++;
}
BOOL
pbkdf2(PUCHAR pbPassword, ULONG cbPassword, PUCHAR pbSalt, ULONG cbSalt, DWORD cIterations, PUCHAR pbDerivedKey, ULONG cbDerivedKey) {
BOOL bStatus = FALSE;
DWORD l, r, dwULen, i, j;
BYTE Ti[DIGEST_SIZE];
BYTE V[DIGEST_SIZE];
LPBYTE U = malloc(max((cbSalt + 4), DIGEST_SIZE));
PRF_CTX prfCtx = {0};
if (U == NULL) {
return FALSE;
}
if (pbPassword == NULL || cbPassword == 0 || pbSalt == NULL || cbSalt == 0 || cIterations == 0 || pbDerivedKey == NULL || cbDerivedKey == 0) {
free(U);
return FALSE;
}
if (!hmacInit(&prfCtx, pbPassword, cbPassword)) {
goto PBKDF2_end;
}
l = (DWORD)ceil((double)cbDerivedKey / (double)DIGEST_SIZE);
r = cbDerivedKey - (l - 1) * DIGEST_SIZE;
for (i = 1; i <= l; i++) {
ZeroMemory(Ti, DIGEST_SIZE);
for (j = 0; j < cIterations; j++) {
if (j == 0) {
/* construct first input for PRF */
memcpy(U, pbSalt, cbSalt);
U[cbSalt] = (BYTE)((i & 0xFF000000) >> 24);
U[cbSalt + 1] = (BYTE)((i & 0x00FF0000) >> 16);
U[cbSalt + 2] = (BYTE)((i & 0x0000FF00) >> 8);
U[cbSalt + 3] = (BYTE)((i & 0x000000FF));
dwULen = cbSalt + 4;
}
else {
memcpy(U, V, DIGEST_SIZE);
dwULen = DIGEST_SIZE;
}
if (!hmacCalculate(&prfCtx, U, dwULen, V)) {
goto PBKDF2_end;
}
myxor(Ti, V, DIGEST_SIZE);
}
if (i != l) {
memcpy(&pbDerivedKey[(i - 1) * DIGEST_SIZE], Ti, DIGEST_SIZE);
}
else {
/* Take only the first r bytes */
memcpy(&pbDerivedKey[(i - 1) * DIGEST_SIZE], Ti, r);
}
}
bStatus = TRUE;
PBKDF2_end:
hmacFree(&prfCtx);
free(U);
return bStatus;
}
bool
_zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length) {
return (key_length <= ZIP_UINT32_MAX) && pbkdf2((PUCHAR)key, (ULONG)key_length, (PUCHAR)salt, salt_length, iterations, output, output_length);
}
#endif
struct _zip_crypto_aes_s {
BCRYPT_ALG_HANDLE hAlgorithm;
BCRYPT_KEY_HANDLE hKey;
ULONG cbKeyObject;
PUCHAR pbKeyObject;
};
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes = (_zip_crypto_aes_t *)calloc(1, sizeof(*aes));
ULONG cbResult;
ULONG key_length = key_size / 8;
if (aes == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&aes->hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0))) {
_zip_crypto_aes_free(aes);
return NULL;
}
if (!BCRYPT_SUCCESS(BCryptSetProperty(aes->hAlgorithm, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0))) {
_zip_crypto_aes_free(aes);
return NULL;
}
if (!BCRYPT_SUCCESS(BCryptGetProperty(aes->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&aes->cbKeyObject, sizeof(aes->cbKeyObject), &cbResult, 0))) {
_zip_crypto_aes_free(aes);
return NULL;
}
aes->pbKeyObject = malloc(aes->cbKeyObject);
if (aes->pbKeyObject == NULL) {
_zip_crypto_aes_free(aes);
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if (!BCRYPT_SUCCESS(BCryptGenerateSymmetricKey(aes->hAlgorithm, &aes->hKey, aes->pbKeyObject, aes->cbKeyObject, (PUCHAR)key, key_length, 0))) {
_zip_crypto_aes_free(aes);
return NULL;
}
return aes;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
return;
}
if (aes->hKey != NULL) {
BCryptDestroyKey(aes->hKey);
}
if (aes->pbKeyObject != NULL) {
free(aes->pbKeyObject);
}
if (aes->hAlgorithm != NULL) {
BCryptCloseAlgorithmProvider(aes->hAlgorithm, 0);
}
free(aes);
}
bool
_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
ULONG cbResult;
NTSTATUS status = BCryptEncrypt(aes->hKey, (PUCHAR)in, ZIP_CRYPTO_AES_BLOCK_LENGTH, NULL, NULL, 0, (PUCHAR)out, ZIP_CRYPTO_AES_BLOCK_LENGTH, &cbResult, 0);
return BCRYPT_SUCCESS(status);
}
struct _zip_crypto_hmac_s {
BCRYPT_ALG_HANDLE hAlgorithm;
BCRYPT_HASH_HANDLE hHash;
DWORD cbHashObject;
PUCHAR pbHashObject;
DWORD cbHash;
PUCHAR pbHash;
};
/* https://code.msdn.microsoft.com/windowsdesktop/Hmac-Computation-Sample-11fe8ec1/sourcecode?fileId=42820&pathId=283874677 */
_zip_crypto_hmac_t *
_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error) {
NTSTATUS status;
ULONG cbResult;
_zip_crypto_hmac_t *hmac;
if (secret_length > INT_MAX) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
hmac = (_zip_crypto_hmac_t *)calloc(1, sizeof(*hmac));
if (hmac == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
status = BCryptOpenAlgorithmProvider(&hmac->hAlgorithm, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG);
if (!BCRYPT_SUCCESS(status)) {
_zip_crypto_hmac_free(hmac);
return NULL;
}
status = BCryptGetProperty(hmac->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hmac->cbHashObject, sizeof(hmac->cbHashObject), &cbResult, 0);
if (!BCRYPT_SUCCESS(status)) {
_zip_crypto_hmac_free(hmac);
return NULL;
}
hmac->pbHashObject = malloc(hmac->cbHashObject);
if (hmac->pbHashObject == NULL) {
_zip_crypto_hmac_free(hmac);
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
status = BCryptGetProperty(hmac->hAlgorithm, BCRYPT_HASH_LENGTH, (PUCHAR)&hmac->cbHash, sizeof(hmac->cbHash), &cbResult, 0);
if (!BCRYPT_SUCCESS(status)) {
_zip_crypto_hmac_free(hmac);
return NULL;
}
hmac->pbHash = malloc(hmac->cbHash);
if (hmac->pbHash == NULL) {
_zip_crypto_hmac_free(hmac);
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
status = BCryptCreateHash(hmac->hAlgorithm, &hmac->hHash, hmac->pbHashObject, hmac->cbHashObject, (PUCHAR)secret, (ULONG)secret_length, 0);
if (!BCRYPT_SUCCESS(status)) {
_zip_crypto_hmac_free(hmac);
return NULL;
}
return hmac;
}
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
return;
}
if (hmac->hHash != NULL) {
BCryptDestroyHash(hmac->hHash);
}
if (hmac->pbHash != NULL) {
free(hmac->pbHash);
}
if (hmac->pbHashObject != NULL) {
free(hmac->pbHashObject);
}
if (hmac->hAlgorithm) {
BCryptCloseAlgorithmProvider(hmac->hAlgorithm, 0);
}
free(hmac);
}
bool
_zip_crypto_hmac(_zip_crypto_hmac_t *hmac, zip_uint8_t *data, zip_uint64_t length) {
if (hmac == NULL || length > ULONG_MAX) {
return false;
}
return BCRYPT_SUCCESS(BCryptHashData(hmac->hHash, data, (ULONG)length, 0));
}
bool
_zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
if (hmac == NULL) {
return false;
}
return BCRYPT_SUCCESS(BCryptFinishHash(hmac->hHash, data, hmac->cbHash, 0));
}
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
return BCRYPT_SUCCESS(BCryptGenRandom(NULL, buffer, length, BCRYPT_USE_SYSTEM_PREFERRED_RNG));
}

View File

@@ -0,0 +1,53 @@
/*
zip_crypto_win.h -- Windows Crypto API wrapper.
Copyright (C) 2018-2021 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.
*/
#ifndef HAD_ZIP_CRYPTO_WIN_H
#define HAD_ZIP_CRYPTO_WIN_H
#define HAVE_SECURE_RANDOM
typedef struct _zip_crypto_aes_s _zip_crypto_aes_t;
typedef struct _zip_crypto_hmac_s _zip_crypto_hmac_t;
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes);
_zip_crypto_aes_t *_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error);
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out);
bool _zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length);
_zip_crypto_hmac_t *_zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error);
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac);
bool _zip_crypto_hmac(_zip_crypto_hmac_t *hmac, zip_uint8_t *data, zip_uint64_t length);
bool _zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data);
#endif /* HAD_ZIP_CRYPTO_WIN_H */

View File

@@ -1,9 +1,9 @@
/* /*
zip_delete.c -- delete file from zip archive zip_delete.c -- delete file from zip archive
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_dir_add.c -- add directory zip_dir_add.c -- add directory
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_dirent.c -- read directory entry (local or central), clean dirent zip_dirent.c -- read directory entry (local or central), clean dirent
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -421,7 +421,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
if (from_buffer) { if (from_buffer) {
if (_zip_buffer_left(buffer) < variable_size) { if (_zip_buffer_left(buffer) < variable_size) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW);
return -1; return -1;
} }
} }
@@ -437,7 +437,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
zde->filename = _zip_read_string(buffer, src, filename_len, 1, error); zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
if (!zde->filename) { if (!zde->filename) {
if (zip_error_code_zip(error) == ZIP_ER_EOF) { if (zip_error_code_zip(error) == ZIP_ER_EOF) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW);
} }
if (!from_buffer) { if (!from_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
@@ -447,7 +447,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_UTF8_IN_FILENAME);
if (!from_buffer) { if (!from_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
@@ -487,7 +487,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
} }
if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_UTF8_IN_COMMENT);
if (!from_buffer) { if (!from_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
@@ -562,7 +562,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
ok = false; ok = false;
} }
if (!ok) { if (!ok) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_ZIP64_EF);
_zip_buffer_free(ef_buffer); _zip_buffer_free(ef_buffer);
if (!from_buffer) { if (!from_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
@@ -651,7 +651,7 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL); ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL);
if (ef == NULL || ef_len < 7) { if (ef == NULL || ef_len < 7) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_WINZIPAES_EF);
return false; return false;
} }
@@ -668,9 +668,8 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
break; break;
case 2: case 2:
if (de->uncomp_size < 20 /* TODO: constant */) {
crc_valid = false; crc_valid = false;
} /* TODO: When checking consistency, check that crc is 0. */
break; break;
default: default:
@@ -704,7 +703,7 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
} }
if (ef_len != 7) { if (ef_len != 7) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_WINZIPAES_EF);
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
return false; return false;
} }

View File

@@ -1,9 +1,9 @@
/* /*
zip_discard.c -- discard and free struct zip zip_discard.c -- discard and free struct zip
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_entry.c -- struct zip_entry helper functions zip_entry.c -- struct zip_entry helper functions
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_error.c -- zip_error_t helper functions zip_error.c -- zip_error_t helper functions
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -68,6 +68,7 @@ zip_error_init_with_code(zip_error_t *error, int ze) {
error->zip_err = ze; error->zip_err = ze;
switch (zip_error_system_type(error)) { switch (zip_error_system_type(error)) {
case ZIP_ET_SYS: case ZIP_ET_SYS:
case ZIP_ET_LIBZIP:
error->sys_err = errno; error->sys_err = errno;
break; break;
@@ -80,10 +81,10 @@ zip_error_init_with_code(zip_error_t *error, int ze) {
ZIP_EXTERN int ZIP_EXTERN int
zip_error_system_type(const zip_error_t *error) { zip_error_system_type(const zip_error_t *error) {
if (error->zip_err < 0 || error->zip_err >= _zip_nerr_str) if (error->zip_err < 0 || error->zip_err >= _zip_err_str_count)
return ZIP_ET_NONE; return ZIP_ET_NONE;
return _zip_err_type[error->zip_err]; return _zip_err_str[error->zip_err].type;
} }

View File

@@ -1,9 +1,9 @@
/* /*
zip_error_clear.c -- clear zip error zip_error_clear.c -- clear zip error
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_error_get.c -- get zip error zip_error_get.c -- get zip error
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_error_get_sys_type.c -- return type of system error code zip_error_get_sys_type.c -- return type of system error code
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -37,8 +37,9 @@
ZIP_EXTERN int ZIP_EXTERN int
zip_error_get_sys_type(int ze) { zip_error_get_sys_type(int ze) {
if (ze < 0 || ze >= _zip_nerr_str) if (ze < 0 || ze >= _zip_err_str_count) {
return 0; return 0;
}
return _zip_err_type[ze];
return _zip_err_str[ze].type;
} }

View File

@@ -1,9 +1,9 @@
/* /*
zip_error_sterror.c -- get string representation of struct zip_error zip_error_sterror.c -- get string representation of struct zip_error
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -39,43 +39,68 @@
#include "zipint.h" #include "zipint.h"
ZIP_EXTERN const char * ZIP_EXTERN const char *
zip_error_strerror(zip_error_t *err) { zip_error_strerror(zip_error_t *err) {
const char *zs, *ss; const char *zip_error_string, *system_error_string;
char buf[128], *s; char buf[128], *s;
zip_error_fini(err); zip_error_fini(err);
if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) { if (err->zip_err < 0 || err->zip_err >= _zip_err_str_count) {
sprintf(buf, "Unknown error %d", err->zip_err); snprintf(buf, sizeof(buf), "Unknown error %d", err->zip_err);
zs = NULL; buf[sizeof(buf) - 1] = '\0'; /* make sure string is NUL-terminated */
ss = buf; zip_error_string = NULL;
system_error_string = buf;
} }
else { else {
zs = _zip_err_str[err->zip_err]; zip_error_string = _zip_err_str[err->zip_err].description;
switch (_zip_err_type[err->zip_err]) { switch (_zip_err_str[err->zip_err].type) {
case ZIP_ET_SYS: case ZIP_ET_SYS:
ss = strerror(err->sys_err); system_error_string = strerror(err->sys_err);
break; break;
case ZIP_ET_ZLIB: case ZIP_ET_ZLIB:
ss = zError(err->sys_err); system_error_string = zError(err->sys_err);
break; break;
default: case ZIP_ET_LIBZIP: {
ss = NULL; zip_uint8_t error = GET_ERROR_FROM_DETAIL(err->sys_err);
} int index = GET_INDEX_FROM_DETAIL(err->sys_err);
}
if (ss == NULL) if (error == 0) {
return zs; system_error_string = NULL;
}
else if (error >= _zip_err_details_count) {
snprintf(buf, sizeof(buf), "invalid detail error %u", error);
buf[sizeof(buf) - 1] = '\0'; /* make sure string is NUL-terminated */
system_error_string = buf;
}
else if (_zip_err_details[error].type == ZIP_DETAIL_ET_ENTRY && index < MAX_DETAIL_INDEX) {
snprintf(buf, sizeof(buf), "entry %d: %s", index, _zip_err_details[error].description);
buf[sizeof(buf) - 1] = '\0'; /* make sure string is NUL-terminated */
system_error_string = buf;
}
else { else {
if ((s = (char *)malloc(strlen(ss) + (zs ? strlen(zs) + 2 : 0) + 1)) == NULL) system_error_string = _zip_err_details[error].description;
return _zip_err_str[ZIP_ER_MEMORY]; }
break;
}
sprintf(s, "%s%s%s", (zs ? zs : ""), (zs ? ": " : ""), ss); default:
system_error_string = NULL;
}
}
if (system_error_string == NULL) {
return zip_error_string;
}
else {
if ((s = (char *)malloc(strlen(system_error_string) + (zip_error_string ? strlen(zip_error_string) + 2 : 0) + 1)) == NULL) {
return _zip_err_str[ZIP_ER_MEMORY].description;
}
sprintf(s, "%s%s%s", (zip_error_string ? zip_error_string : ""), (zip_error_string ? ": " : ""), system_error_string);
err->str = s; err->str = s;
return s; return s;

View File

@@ -1,9 +1,9 @@
/* /*
zip_error_to_str.c -- get string representation of zip error code zip_error_to_str.c -- get string representation of zip error code
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -44,12 +44,13 @@ ZIP_EXTERN int
zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) { zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) {
const char *zs, *ss; const char *zs, *ss;
if (ze < 0 || ze >= _zip_nerr_str) if (ze < 0 || ze >= _zip_err_str_count) {
return snprintf(buf, len, "Unknown error %d", ze); return snprintf(buf, len, "Unknown error %d", ze);
}
zs = _zip_err_str[ze]; zs = _zip_err_str[ze].description;
switch (_zip_err_type[ze]) { switch (_zip_err_str[ze].type) {
case ZIP_ET_SYS: case ZIP_ET_SYS:
ss = strerror(se); ss = strerror(se);
break; break;

View File

@@ -1,9 +1,9 @@
/* /*
zip_extra_field.c -- manipulate extra fields zip_extra_field.c -- manipulate extra fields
Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -219,7 +219,7 @@ _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_
ef_data = _zip_buffer_get(buffer, flen); ef_data = _zip_buffer_get(buffer, flen);
if (ef_data == NULL) { if (ef_data == NULL) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_EF_LENGTH);
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
_zip_ef_free(ef_head); _zip_ef_free(ef_head);
return false; return false;
@@ -247,7 +247,7 @@ _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_
zip_uint8_t *garbage; zip_uint8_t *garbage;
garbage = _zip_buffer_get(buffer, glen); garbage = _zip_buffer_get(buffer, glen);
if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) { if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EF_TRAILING_GARBAGE);
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
_zip_ef_free(ef_head); _zip_ef_free(ef_head);
return false; return false;

View File

@@ -1,9 +1,9 @@
/* /*
zip_extra_field_api.c -- public extra fields API functions zip_extra_field_api.c -- public extra fields API functions
Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_fclose.c -- close file in zip archive zip_fclose.c -- close file in zip archive
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_fdopen.c -- open read-only archive from file descriptor zip_fdopen.c -- open read-only archive from file descriptor
Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_add.c -- add file via callback function zip_file_add.c -- add file via callback function
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_error_clear.c -- clear zip file error zip_file_error_clear.c -- clear zip file error
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_error_get.c -- get zip file error zip_file_error_get.c -- get zip file error
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_get_comment.c -- get file comment zip_file_get_comment.c -- get file comment
Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_get_external_attributes.c -- get opsys/external attributes zip_file_get_external_attributes.c -- get opsys/external attributes
Copyright (C) 2013-2019 Dieter Baron and Thomas Klausner Copyright (C) 2013-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_get_offset.c -- get offset of file data in archive. zip_file_get_offset.c -- get offset of file data in archive.
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_rename.c -- rename file in zip archive zip_file_rename.c -- rename file in zip archive
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_replace.c -- replace file via callback function zip_file_replace.c -- replace file via callback function
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_set_comment.c -- set comment for file in archive zip_file_set_comment.c -- set comment for file in archive
Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -0,0 +1,116 @@
/*
zip_file_set_encryption.c -- set encryption for file in archive
Copyright (C) 2016-2021 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"
#include <stdlib.h>
#include <string.h>
ZIP_EXTERN int
zip_file_set_encryption(zip_t *za, zip_uint64_t idx, zip_uint16_t method, const char *password) {
zip_entry_t *e;
zip_uint16_t old_method;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if (ZIP_IS_RDONLY(za)) {
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
return -1;
}
if (method != ZIP_EM_NONE && _zip_get_encryption_implementation(method, ZIP_CODEC_ENCODE) == NULL) {
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
return -1;
}
e = za->entry + idx;
old_method = (e->orig == NULL ? ZIP_EM_NONE : e->orig->encryption_method);
if (method == old_method && password == NULL) {
if (e->changes) {
if (e->changes->changed & ZIP_DIRENT_PASSWORD) {
_zip_crypto_clear(e->changes->password, strlen(e->changes->password));
free(e->changes->password);
e->changes->password = (e->orig == NULL ? NULL : e->orig->password);
}
e->changes->changed &= ~(ZIP_DIRENT_ENCRYPTION_METHOD | ZIP_DIRENT_PASSWORD);
if (e->changes->changed == 0) {
_zip_dirent_free(e->changes);
e->changes = NULL;
}
}
}
else {
char *our_password = NULL;
if (password) {
if ((our_password = strdup(password)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
if (e->changes == NULL) {
if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) {
if (our_password) {
_zip_crypto_clear(our_password, strlen(our_password));
}
free(our_password);
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
}
e->changes->encryption_method = method;
e->changes->changed |= ZIP_DIRENT_ENCRYPTION_METHOD;
if (password) {
e->changes->password = our_password;
e->changes->changed |= ZIP_DIRENT_PASSWORD;
}
else {
if (e->changes->changed & ZIP_DIRENT_PASSWORD) {
_zip_crypto_clear(e->changes->password, strlen(e->changes->password));
free(e->changes->password);
e->changes->password = e->orig ? e->orig->password : NULL;
e->changes->changed &= ~ZIP_DIRENT_PASSWORD;
}
}
}
return 0;
}

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_set_external_attributes.c -- set external attributes for entry zip_file_set_external_attributes.c -- set external attributes for entry
Copyright (C) 2013-2019 Dieter Baron and Thomas Klausner Copyright (C) 2013-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_set_mtime.c -- set modification time of entry. zip_file_set_mtime.c -- set modification time of entry.
Copyright (C) 2014-2020 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. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -54,6 +54,11 @@ zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
e = za->entry + idx; e = za->entry + idx;
if (e->orig != NULL && e->orig->encryption_method == ZIP_EM_TRAD_PKWARE && !ZIP_ENTRY_CHANGED(e, ZIP_DIRENT_ENCRYPTION_METHOD) && !ZIP_ENTRY_DATA_CHANGED(e)) {
zip_error_set(&za->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
if (e->changes == NULL) { if (e->changes == NULL) {
if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0); zip_error_set(&za->error, ZIP_ER_MEMORY, 0);

View File

@@ -1,9 +1,9 @@
/* /*
zip_file_sterror.c -- get string representation of zip file error zip_file_sterror.c -- get string representation of zip file error
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_fopen.c -- open file in zip archive for reading zip_fopen.c -- open file in zip archive for reading
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_fopen_encrypted.c -- open file for reading with password zip_fopen_encrypted.c -- open file for reading with password
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_fopen_index.c -- open file in zip archive for reading by index zip_fopen_index.c -- open file in zip archive for reading by index
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_fopen_index_encrypted.c -- open file for reading by index w/ password zip_fopen_index_encrypted.c -- open file for reading by index w/ password
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -45,7 +45,11 @@ zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, cons
zip_file_t *zf; zip_file_t *zf;
zip_source_t *src; zip_source_t *src;
if ((src = _zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL) if (password != NULL && password[0] == '\0') {
password = NULL;
}
if ((src = _zip_source_zip_new(za, index, flags, 0, 0, password, &za->error)) == NULL)
return NULL; return NULL;
if (zip_source_open(src) < 0) { if (zip_source_open(src) < 0) {

View File

@@ -1,9 +1,9 @@
/* /*
zip_fread.c -- read from file zip_fread.c -- read from file
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -0,0 +1,61 @@
/*
zip_fseek.c -- seek in file
Copyright (C) 2016-2021 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"
ZIP_EXTERN zip_int8_t
zip_fseek(zip_file_t *zf, zip_int64_t offset, int whence) {
if (!zf)
return -1;
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);
return -1;
}
return 0;
}
ZIP_EXTERN int
zip_file_is_seekable(zip_file_t *zfile) {
if (!zfile) {
return -1;
}
return ZIP_SOURCE_CHECK_SUPPORTED(zip_source_supports(zfile->src), ZIP_SOURCE_SEEK);
}

View File

@@ -0,0 +1,54 @@
/*
zip_ftell.c -- tell position in file
Copyright (C) 2016-2021 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"
ZIP_EXTERN zip_int64_t
zip_ftell(zip_file_t *zf) {
zip_int64_t res;
if (!zf)
return -1;
if (zf->error.zip_err != 0)
return -1;
res = zip_source_tell(zf->src);
if (res < 0) {
_zip_error_set_from_source(&zf->error, zf->src);
return -1;
}
return res;
}

View File

@@ -1,9 +1,9 @@
/* /*
zip_get_archive_comment.c -- get archive comment zip_get_archive_comment.c -- get archive comment
Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_get_archive_flag.c -- get archive global flag zip_get_archive_flag.c -- get archive global flag
Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner Copyright (C) 2008-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_get_encryption_implementation.c -- get encryption implementation zip_get_encryption_implementation.c -- get encryption implementation
Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_get_file_comment.c -- get file comment zip_get_file_comment.c -- get file comment
Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_get_name.c -- get filename for a file in zip file zip_get_name.c -- get filename for a file in zip file
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_get_num_entries.c -- get number of entries in archive zip_get_num_entries.c -- get number of entries in archive
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_get_num_files.c -- get number of files in archive zip_get_num_files.c -- get number of files in archive
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_hash.c -- hash table string -> uint64 zip_hash.c -- hash table string -> uint64
Copyright (C) 2015-2019 Dieter Baron and Thomas Klausner Copyright (C) 2015-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_io_util.c -- I/O helper functions zip_io_util.c -- I/O helper functions
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -0,0 +1,41 @@
/*
zip_libzip_version.c -- return run-time version of library
Copyright (C) 2017-2021 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"
ZIP_EXTERN const char *
zip_libzip_version(void) {
return LIBZIP_VERSION;
}

View File

@@ -1,9 +1,9 @@
/* /*
zip_memdup.c -- internal zip function, "strdup" with len zip_memdup.c -- internal zip function, "strdup" with len
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_name_locate.c -- get index by name zip_name_locate.c -- get index by name
Copyright (C) 1999-2019 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. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -49,6 +49,7 @@ zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags) {
zip_int64_t zip_int64_t
_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error) { _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error) {
int (*cmp)(const char *, const char *); int (*cmp)(const char *, const char *);
zip_string_t *str = NULL;
const char *fn, *p; const char *fn, *p;
zip_uint64_t i; zip_uint64_t i;
@@ -60,7 +61,17 @@ _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *e
return -1; return -1;
} }
if (flags & (ZIP_FL_NOCASE | ZIP_FL_NODIR | ZIP_FL_ENC_CP437)) { if ((flags & (ZIP_FL_ENC_UTF_8 | ZIP_FL_ENC_RAW)) == 0 && fname[0] != '\0') {
if ((str = _zip_string_new((const zip_uint8_t *)fname, strlen(fname), flags, error)) == NULL) {
return -1;
}
if ((fname = (const char *)_zip_string_get(str, NULL, 0, error)) == NULL) {
_zip_string_free(str);
return -1;
}
}
if (flags & (ZIP_FL_NOCASE | ZIP_FL_NODIR | ZIP_FL_ENC_RAW | ZIP_FL_ENC_STRICT)) {
/* can't use hash table */ /* can't use hash table */
cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp; cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
@@ -79,14 +90,18 @@ _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *e
if (cmp(fname, fn) == 0) { if (cmp(fname, fn) == 0) {
_zip_error_clear(error); _zip_error_clear(error);
_zip_string_free(str);
return (zip_int64_t)i; return (zip_int64_t)i;
} }
} }
zip_error_set(error, ZIP_ER_NOENT, 0); zip_error_set(error, ZIP_ER_NOENT, 0);
_zip_string_free(str);
return -1; return -1;
} }
else { else {
return _zip_hash_lookup(za->names, (const zip_uint8_t *)fname, flags, error); zip_int64_t ret = _zip_hash_lookup(za->names, (const zip_uint8_t *)fname, flags, error);
_zip_string_free(str);
return ret;
} }
} }

View File

@@ -1,9 +1,9 @@
/* /*
zip_new.c -- create and init struct zip zip_new.c -- create and init struct zip
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_open.c -- open zip archive by name zip_open.c -- open zip archive by name
Copyright (C) 1999-2019 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. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -77,9 +77,6 @@ zip_open(const char *fn, int _flags, int *zep) {
ZIP_EXTERN zip_t * ZIP_EXTERN zip_t *
zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) { zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) {
static zip_int64_t needed_support_read = -1;
static zip_int64_t needed_support_write = -1;
unsigned int flags; unsigned int flags;
zip_int64_t supported; zip_int64_t supported;
exists_t exists; exists_t exists;
@@ -91,15 +88,11 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) {
flags = (unsigned int)_flags; flags = (unsigned int)_flags;
supported = zip_source_supports(src); supported = zip_source_supports(src);
if (needed_support_read == -1) { if ((supported & ZIP_SOURCE_SUPPORTS_SEEKABLE) != ZIP_SOURCE_SUPPORTS_SEEKABLE) {
needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1);
needed_support_write = zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1);
}
if ((supported & needed_support_read) != needed_support_read) {
zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); zip_error_set(error, ZIP_ER_OPNOTSUPP, 0);
return NULL; return NULL;
} }
if ((supported & needed_support_write) != needed_support_write) { if ((supported & ZIP_SOURCE_SUPPORTS_WRITABLE) != ZIP_SOURCE_SUPPORTS_WRITABLE) {
flags |= ZIP_RDONLY; flags |= ZIP_RDONLY;
} }
@@ -224,8 +217,14 @@ void
_zip_set_open_error(int *zep, const zip_error_t *err, int ze) { _zip_set_open_error(int *zep, const zip_error_t *err, int ze) {
if (err) { if (err) {
ze = zip_error_code_zip(err); ze = zip_error_code_zip(err);
if (zip_error_system_type(err) == ZIP_ET_SYS) { switch (zip_error_system_type(err)) {
case ZIP_ET_SYS:
case ZIP_ET_LIBZIP:
errno = zip_error_code_system(err); errno = zip_error_code_system(err);
break;
default:
break;
} }
} }
@@ -277,7 +276,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
if (cd->offset + cd->size > buf_offset + eocd_offset) { if (cd->offset + cd->size > buf_offset + eocd_offset) {
/* cdir spans past EOCD record */ /* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return NULL;
} }
@@ -289,7 +288,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
tail_len = _zip_buffer_left(buffer); tail_len = _zip_buffer_left(buffer);
if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) { if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_COMMENT_LENGTH_INVALID);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return NULL;
} }
@@ -308,7 +307,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
_zip_buffer_set_offset(buffer, cd->offset - buf_offset); _zip_buffer_set_offset(buffer, cd->offset - buf_offset);
if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) { if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return NULL;
} }
@@ -358,8 +357,11 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
} }
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 ((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 (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) { if (zip_error_code_zip(error) == ZIP_ER_INCONS) {
zip_error_set(error, ZIP_ER_INCONS, 0); 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_cdir_free(cd);
_zip_buffer_free(cd_buffer); _zip_buffer_free(cd_buffer);
@@ -370,7 +372,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
} }
if (i != cd->nentry || left > 0) { if (i != cd->nentry || left > 0) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_WRONG_ENTRIES_COUNT);
_zip_buffer_free(cd_buffer); _zip_buffer_free(cd_buffer);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return NULL;
@@ -394,7 +396,7 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err
} }
if (!ok) { if (!ok) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
_zip_buffer_free(cd_buffer); _zip_buffer_free(cd_buffer);
_zip_cdir_free(cd); _zip_cdir_free(cd);
return NULL; return NULL;
@@ -448,12 +450,15 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) {
} }
if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -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));
}
_zip_dirent_finalize(&temp); _zip_dirent_finalize(&temp);
return -1; return -1;
} }
if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) { if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_ENTRY_HEADER_MISMATCH, i));
_zip_dirent_finalize(&temp); _zip_dirent_finalize(&temp);
return -1; return -1;
} }
@@ -644,7 +649,7 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags
zip_uint64_t i, nentry, size, offset, eocd_offset; zip_uint64_t i, nentry, size, offset, eocd_offset;
if (_zip_buffer_left(buffer) < EOCDLEN) { if (_zip_buffer_left(buffer) < EOCDLEN) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD_LENGTH_INVALID);
return NULL; return NULL;
} }
@@ -677,12 +682,12 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags
if (offset + size > buf_offset + eocd_offset) { if (offset + size > buf_offset + eocd_offset) {
/* cdir spans past EOCD record */ /* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
return NULL; return NULL;
} }
if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) { if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_LENGTH_INVALID);
return NULL; return NULL;
} }
@@ -723,7 +728,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
/* does EOCD fit before EOCD locator? */ /* does EOCD fit before EOCD locator? */
if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) { if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_OVERLAPS_EOCD);
return NULL; return NULL;
} }
@@ -744,7 +749,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
} }
if (memcmp(_zip_buffer_get(buffer, 4), EOCD64_MAGIC, 4) != 0) { if (memcmp(_zip_buffer_get(buffer, 4), EOCD64_MAGIC, 4) != 0) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_WRONG_MAGIC);
if (free_buffer) { if (free_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
@@ -756,7 +761,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
/* is there a hole between EOCD and EOCD locator, or do they overlap? */ /* is there a hole between EOCD and EOCD locator, or do they overlap? */
if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) { if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_OVERLAPS_EOCD);
if (free_buffer) { if (free_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
@@ -778,7 +783,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
eocd_disk = eocd_disk64; eocd_disk = eocd_disk64;
} }
if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) { if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_EOCD64_MISMATCH);
if (free_buffer) { if (free_buffer) {
_zip_buffer_free(buffer); _zip_buffer_free(buffer);
} }
@@ -825,16 +830,16 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse
} }
if (offset + size > buf_offset + eocd_offset) { if (offset + size > buf_offset + eocd_offset) {
/* cdir spans past EOCD record */ /* cdir spans past EOCD record */
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
return NULL; return NULL;
} }
if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) { if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_OVERLAPS_EOCD);
return NULL; return NULL;
} }
if (nentry > size / CDENTRYSIZE) { if (nentry > size / CDENTRYSIZE) {
zip_error_set(error, ZIP_ER_INCONS, 0); zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_INVALID);
return NULL; return NULL;
} }

View File

@@ -3,7 +3,7 @@
Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -3,7 +3,7 @@
Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -0,0 +1,104 @@
/*
zip_random_unix.c -- fill the user's buffer with random stuff (Unix version)
Copyright (C) 2016-2021 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"
#ifdef HAVE_CRYPTO
#include "zip_crypto.h"
#endif
#ifdef HAVE_ARC4RANDOM
#include <stdlib.h>
#ifndef HAVE_SECURE_RANDOM
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
arc4random_buf(buffer, length);
return true;
}
#endif
#ifndef HAVE_RANDOM_UINT32
zip_uint32_t
zip_random_uint32(void) {
return arc4random();
}
#endif
#else /* HAVE_ARC4RANDOM */
#ifndef HAVE_SECURE_RANDOM
#include <fcntl.h>
#include <unistd.h>
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
int fd;
if ((fd = open("/dev/urandom", O_RDONLY)) < 0) {
return false;
}
if (read(fd, buffer, length) != length) {
close(fd);
return false;
}
close(fd);
return true;
}
#endif
#ifndef HAVE_RANDOM_UINT32
#include <stdlib.h>
zip_uint32_t
zip_random_uint32(void) {
static bool seeded = false;
zip_uint32_t value;
if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) {
return value;
}
if (!seeded) {
srandom((unsigned int)time(NULL));
}
return (zip_uint32_t)random();
}
#endif
#endif /* HAVE_ARC4RANDOM */

View File

@@ -1,9 +1,9 @@
/* /*
zip_filerange_crc.c -- compute CRC32 for a range of a file zip_random_uwp.c -- fill the user's buffer with random stuff (UWP version)
Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -31,54 +31,51 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <stdio.h>
#include "zipint.h" #include "zipint.h"
#ifdef HAVE_CRYPTO
#include "zip_crypto.h"
#endif
int #ifndef HAVE_SECURE_RANDOM
_zip_filerange_crc(zip_source_t *src, zip_uint64_t start, zip_uint64_t len, uLong *crcp, zip_error_t *error) {
DEFINE_BYTE_ARRAY(buf, BUFSIZE);
zip_int64_t n; #include <windows.h>
#include <bcrypt.h>
*crcp = crc32(0L, Z_NULL, 0); ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
if (start > ZIP_INT64_MAX) { BCRYPT_ALG_HANDLE hAlg = NULL;
zip_error_set(error, ZIP_ER_SEEK, EFBIG); NTSTATUS hr = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
return -1; if (!BCRYPT_SUCCESS(hr) || hAlg == NULL) {
return false;
}
hr = BCryptGenRandom(&hAlg, buffer, length, 0);
BCryptCloseAlgorithmProvider(&hAlg, 0);
if (!BCRYPT_SUCCESS(hr)) {
return false;
}
return true;
} }
if (zip_source_seek(src, (zip_int64_t)start, SEEK_SET) != 0) { #endif
_zip_error_set_from_source(error, src);
return -1; #ifndef HAVE_RANDOM_UINT32
#include <stdlib.h>
zip_uint32_t
zip_random_uint32(void) {
static bool seeded = false;
zip_uint32_t value;
if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) {
return value;
} }
if (!byte_array_init(buf, BUFSIZE)) { if (!seeded) {
zip_error_set(error, ZIP_ER_MEMORY, 0); srand((unsigned int)time(NULL));
return -1;
} }
while (len > 0) { return (zip_uint32_t)rand();
n = (zip_int64_t)(len > BUFSIZE ? BUFSIZE : len);
if ((n = zip_source_read(src, buf, (zip_uint64_t)n)) < 0) {
_zip_error_set_from_source(error, src);
byte_array_fini(buf);
return -1;
}
if (n == 0) {
zip_error_set(error, ZIP_ER_EOF, 0);
byte_array_fini(buf);
return -1;
}
*crcp = crc32(*crcp, buf, (uInt)n);
len -= (zip_uint64_t)n;
}
byte_array_fini(buf);
return 0;
} }
#endif

View File

@@ -0,0 +1,81 @@
/*
zip_random_win32.c -- fill the user's buffer with random stuff (Windows version)
Copyright (C) 2016-2021 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"
#ifdef HAVE_CRYPTO
#include "zip_crypto.h"
#endif
#include <windows.h>
#ifndef HAVE_SECURE_RANDOM
#include <wincrypt.h>
ZIP_EXTERN bool
zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
HCRYPTPROV hprov;
if (!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
return false;
}
if (!CryptGenRandom(hprov, length, buffer)) {
return false;
}
if (!CryptReleaseContext(hprov, 0)) {
return false;
}
return true;
}
#endif
#ifndef HAVE_RANDOM_UINT32
#include <stdlib.h>
zip_uint32_t
zip_random_uint32(void) {
static bool seeded = false;
zip_uint32_t value;
if (zip_secure_random((zip_uint8_t *)&value, sizeof(value))) {
return value;
}
if (!seeded) {
srand((unsigned int)time(NULL));
}
return (zip_uint32_t)rand();
}
#endif

View File

@@ -1,9 +1,9 @@
/* /*
zip_rename.c -- rename file in zip archive zip_rename.c -- rename file in zip archive
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_replace.c -- replace file via callback function zip_replace.c -- replace file via callback function
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_set_archive_comment.c -- set archive comment zip_set_archive_comment.c -- set archive comment
Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_get_archive_flag.c -- set archive global flag zip_get_archive_flag.c -- set archive global flag
Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner Copyright (C) 2008-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_set_default_password.c -- set default password for decryption zip_set_default_password.c -- set default password for decryption
Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -45,7 +45,7 @@ zip_set_default_password(zip_t *za, const char *passwd) {
free(za->default_password); free(za->default_password);
if (passwd) { if (passwd && passwd[0] != '\0') {
if ((za->default_password = strdup(passwd)) == NULL) { if ((za->default_password = strdup(passwd)) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0); zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1; return -1;

View File

@@ -1,9 +1,9 @@
/* /*
zip_set_file_comment.c -- set comment for file in archive zip_set_file_comment.c -- set comment for file in archive
Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner Copyright (C) 2006-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_set_file_compression.c -- set compression for file in archive zip_set_file_compression.c -- set compression for file in archive
Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner Copyright (C) 2012-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -40,7 +40,7 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui
zip_entry_t *e; zip_entry_t *e;
zip_int32_t old_method; zip_int32_t old_method;
if (idx >= za->nentry || flags > 9) { if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0); zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1; return -1;
} }

View File

@@ -1,9 +1,9 @@
/* /*
zip_set_name.c -- rename helper function zip_set_name.c -- rename helper function
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_accept_empty.c -- if empty source is a valid archive zip_source_accept_empty.c -- if empty source is a valid archive
Copyright (C) 2019 Dieter Baron and Thomas Klausner Copyright (C) 2019-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_begin_write.c -- start a new file for writing zip_source_begin_write.c -- start a new file for writing
Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_begin_write_cloning.c -- clone part of file for writing zip_source_begin_write_cloning.c -- clone part of file for writing
Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_buffer.c -- create zip data source from buffer zip_source_buffer.c -- create zip data source from buffer
Copyright (C) 1999-2019 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. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -361,7 +361,7 @@ buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) {
clone->fragment_offsets[clone->nfragments] = offset; clone->fragment_offsets[clone->nfragments] = offset;
clone->size = offset; clone->size = offset;
clone->first_owned_fragment = ZIP_MIN(buffer->first_owned_fragment, clone->nfragments - 1); clone->first_owned_fragment = ZIP_MIN(buffer->first_owned_fragment, clone->nfragments);
buffer->shared_buffer = clone; buffer->shared_buffer = clone;
clone->shared_buffer = buffer; clone->shared_buffer = buffer;
@@ -376,6 +376,10 @@ static zip_uint64_t
buffer_find_fragment(const buffer_t *buffer, zip_uint64_t offset) { buffer_find_fragment(const buffer_t *buffer, zip_uint64_t offset) {
zip_uint64_t low, high, mid; zip_uint64_t low, high, mid;
if (buffer->nfragments == 0) {
return 0;
}
low = 0; low = 0;
high = buffer->nfragments - 1; high = buffer->nfragments - 1;

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_call.c -- invoke callback command on zip_source zip_source_call.c -- invoke callback command on zip_source
Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_close.c -- close zip_source (stop reading) zip_source_close.c -- close zip_source (stop reading)
Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_commit_write.c -- commit changes to file zip_source_commit_write.c -- commit changes to file
Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_compress.c -- (de)compression routines zip_source_compress.c -- (de)compression routines
Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -67,14 +67,17 @@ static struct implementation implementations[] = {
{ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress}, {ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress},
#endif #endif
#if defined(HAVE_LIBLZMA) #if defined(HAVE_LIBLZMA)
/* Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2 {ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
/* Disabled - because 7z isn't able to unpack ZIP+LZMA2
archives made this way - and vice versa. archives made this way - and vice versa.
{ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
{ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, {ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
*/ */
{ZIP_CM_XZ, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, {ZIP_CM_XZ, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
#endif #endif
#if defined(HAVE_LIBZSTD)
{ZIP_CM_ZSTD, &zip_algorithm_zstd_compress, &zip_algorithm_zstd_decompress},
#endif
}; };
@@ -86,8 +89,8 @@ static void context_free(struct context *ctx);
static struct context *context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm); static struct context *context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm);
static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t); static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t);
static zip_compression_algorithm_t * zip_compression_algorithm_t *
get_algorithm(zip_int32_t method, bool compress) { _zip_get_compression_algorithm(zip_int32_t method, bool compress) {
size_t i; size_t i;
zip_uint16_t real_method = ZIP_CM_ACTUAL(method); zip_uint16_t real_method = ZIP_CM_ACTUAL(method);
@@ -110,7 +113,7 @@ zip_compression_method_supported(zip_int32_t method, int compress) {
if (method == ZIP_CM_STORE) { if (method == ZIP_CM_STORE) {
return 1; return 1;
} }
return get_algorithm(method, compress) != NULL; return _zip_get_compression_algorithm(method, compress) != NULL;
} }
zip_source_t * zip_source_t *
@@ -135,7 +138,7 @@ compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool co
return NULL; return NULL;
} }
if ((algorithm = get_algorithm(method, compress)) == NULL) { if ((algorithm = _zip_get_compression_algorithm(method, compress)) == NULL) {
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
return NULL; return NULL;
} }
@@ -305,18 +308,27 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
ctx = (struct context *)ud; ctx = (struct context *)ud;
switch (cmd) { switch (cmd) {
case ZIP_SOURCE_OPEN: case ZIP_SOURCE_OPEN: {
zip_stat_t st;
zip_file_attributes_t attributes;
ctx->size = 0; ctx->size = 0;
ctx->end_of_input = false; ctx->end_of_input = false;
ctx->end_of_stream = false; ctx->end_of_stream = false;
ctx->is_stored = false; ctx->is_stored = false;
ctx->first_read = -1; ctx->first_read = -1;
if (!ctx->algorithm->start(ctx->ud)) { if (zip_source_stat(src, &st) < 0 || zip_source_get_file_attributes(src, &attributes) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
if (!ctx->algorithm->start(ctx->ud, &st, &attributes)) {
return -1; return -1;
} }
return 0; return 0;
}
case ZIP_SOURCE_READ: case ZIP_SOURCE_READ:
return compress_read(src, ctx, data, len); return compress_read(src, ctx, data, len);
@@ -349,9 +361,6 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
st->size = ctx->size; st->size = ctx->size;
st->valid |= ZIP_STAT_SIZE; st->valid |= ZIP_STAT_SIZE;
} }
else {
st->valid &= ~ZIP_STAT_SIZE;
}
} }
} }
return 0; return 0;

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_crc.c -- pass-through source that calculates CRC32 and size zip_source_crc.c -- pass-through source that calculates CRC32 and size
Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -52,16 +52,16 @@ static zip_int64_t crc_read(zip_source_t *, void *, void *, zip_uint64_t, zip_so
zip_source_t * zip_source_t *
zip_source_crc(zip_t *za, zip_source_t *src, int validate) { zip_source_crc_create(zip_source_t *src, int validate, zip_error_t *error) {
struct crc_context *ctx; struct crc_context *ctx;
if (src == NULL) { if (src == NULL) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0); zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL; return NULL;
} }
if ((ctx = (struct crc_context *)malloc(sizeof(*ctx))) == NULL) { if ((ctx = (struct crc_context *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0); zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL; return NULL;
} }
@@ -72,7 +72,7 @@ zip_source_crc(zip_t *za, zip_source_t *src, int validate) {
ctx->crc = (zip_uint32_t)crc32(0, NULL, 0); ctx->crc = (zip_uint32_t)crc32(0, NULL, 0);
ctx->size = 0; ctx->size = 0;
return zip_source_layered(za, src, crc_read, ctx); return zip_source_layered_create(src, crc_read, ctx, error);
} }
@@ -112,7 +112,8 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
return -1; return -1;
} }
if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) { if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
zip_error_set(&ctx->error, ZIP_ER_INCONS, 0); /* We don't have the index here, but the caller should know which file they are reading from. */
zip_error_set(&ctx->error, ZIP_ER_INCONS, MAKE_DETAIL_WITH_INDEX(ZIP_ER_DETAIL_INVALID_FILE_LENGTH, MAX_DETAIL_INDEX));
return -1; return -1;
} }
} }

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_error.c -- get last error from zip_source zip_source_error.c -- get last error from zip_source
Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner Copyright (C) 2009-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_file.h -- header for common file operations zip_source_file.h -- header for common file operations
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. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@@ -34,7 +34,7 @@
struct zip_source_file_stat { struct zip_source_file_stat {
zip_uint64_t size; /* must be valid for regular files */ zip_uint64_t size; /* must be valid for regular files */
time_t mtime; /* must always be valid, is initialized to current time */ time_t mtime; /* must always be valid, is initialized to current time */
bool exists; /* must always be vaild */ bool exists; /* must always be valid */
bool regular_file; /* must always be valid */ bool regular_file; /* must always be valid */
}; };

View File

@@ -1,9 +1,9 @@
/* /*
zip_source_file_common.c -- create data source from file zip_source_file_common.c -- create data source from file
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner Copyright (C) 1999-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives. This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at> The authors can be contacted at <info@libzip.org>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

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