libarchive: merge from vendor branch

Libarchive 3.7.0

Important changes (relevant to FreeBSD):
  #1814 Do not account for NULL terminator when comparing with "TRAILER!!!"
  #1818 Add ability to produce multi-frame zstd archives
  #1840 year 2038 fix for pax archives on platforms with 64-bit time_t
  #1860 Make single bit bitfields unsigned to avoid clang 16 warning
  #1869 Fix FreeBSD builds with WARNS=6
  #1873 bsdunzip ported to libarchive from FreeBSD
  #1894 read support for zstd compression in 7zip archives
  #1918 ARM64 filter support in 7zip archives

MFC after:	2 weeks
PR:		272567 (exp-run)
This commit is contained in:
Martin Matuska 2023-07-24 07:42:43 +02:00
commit e64fe029e9
96 changed files with 4121 additions and 435 deletions

View File

@ -1,4 +1,8 @@
Wed 07, 2022: libarchive 3.6.2 released
Jul 18, 2023: libarchive 3.7.0 released
Jul 14, 2023: bsdunzip port from FreeBSD
Dec 07, 2022: libarchive 3.6.2 released
Apr 08, 2022: libarchive 3.6.1 released

View File

@ -7,7 +7,7 @@ command-line tools that use the libarchive library.
## Questions? Issues?
* http://www.libarchive.org is the home for ongoing
* https://www.libarchive.org is the home for ongoing
libarchive development, including documentation,
and links to the libarchive mailing lists.
* To report an issue, use the issue tracker at
@ -23,6 +23,7 @@ This distribution bundle includes the following major components:
* **tar**: the 'bsdtar' program is a full-featured 'tar' implementation built on libarchive
* **cpio**: the 'bsdcpio' program is a different interface to essentially the same functionality
* **cat**: the 'bsdcat' program is a simple replacement tool for zcat, bzcat, xzcat, and such
* **unzip**: the 'bsdunzip' program is a simple replacement tool for Info-ZIP's unzip
* **examples**: Some small example programs that you may find useful.
* **examples/minitar**: a compact sample demonstrating use of libarchive.
* **contrib**: Various items sent to me by third parties; please contact the authors with any questions.
@ -87,7 +88,7 @@ Currently, the library automatically detects and reads the following formats:
* ZIPX archives (with support for bzip2, ppmd8, lzma and xz compressed entries)
* GNU and BSD 'ar' archives
* 'mtree' format
* 7-Zip archives
* 7-Zip archives (including archives that use zstandard compression)
* Microsoft CAB format
* LHA and LZH archives
* RAR and RAR 5.0 archives (with some limitations due to RAR's proprietary status)
@ -192,6 +193,17 @@ questions we are asked about libarchive:
functions. On those platforms, libarchive will use the non-thread-safe
functions. Patches to improve this are of great interest to us.
* The function `archive_write_disk_header()` is _not_ thread safe on
POSIX machines and could lead to security issue resulting in world
writeable directories. Thus it must be mutexed by the calling code.
This is due to calling `umask(oldumask = umask(0))`, which sets the
umask for the whole process to 0 for a short time frame.
In case other thread calls the same function in parallel, it might
get interrupted by it and cause the executable to use umask=0 for the
remaining execution.
This will then lead to implicitely created directories to have 777
permissions without sticky bit.
* In particular, libarchive's modules to read or write a directory
tree do use `chdir()` to optimize the directory traversals. This
can cause problems for programs that expect to do disk access from

View File

@ -0,0 +1,19 @@
# Security Policy
If you have discovered a security vulnerability in this project, please report it
privately. **Do not disclose it as a public issue.** This gives us time to work with you
to fix the issue before public exposure, reducing the chance that the exploit will be
used before a patch is released.
You may submit the report in the following ways:
- send an email to security@libarchive.de; and/or
- send us a [private vulnerability report](https://github.com/libarchive/libarchive/security/advisories/new)
Please provide the following information in your report:
- A description of the vulnerability and its impact
- How to reproduce the issue
This project is maintained by volunteers on a reasonable-effort basis. As such, we ask
that you give me 90 days to work on a fix before public exposure.

View File

@ -442,6 +442,8 @@ main(int argc, char *argv[])
archive_match_free(cpio->matching);
free_cache(cpio->gname_cache);
free_cache(cpio->uname_cache);
archive_read_close(cpio->archive_read_disk);
archive_read_free(cpio->archive_read_disk);
free(cpio->destdir);
passphrase_free(cpio->ppbuff);
return (cpio->return_value);
@ -1151,13 +1153,9 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
time_t mtime;
static time_t now;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (!now)
time(&now);
@ -1205,15 +1203,10 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
else
fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M";
#endif
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
ltime = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&mtime, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = mtime;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&mtime);
#endif

View File

@ -43,6 +43,7 @@ DEFINE_TEST(test_option_J_upper)
if (strstr(p, "compression not available") != NULL) {
skipping("This version of bsdcpio was compiled "
"without xz support");
free(p);
return;
}
failure("-J option is broken");

View File

@ -37,10 +37,10 @@ is_octal(const char *p, size_t l)
return (1);
}
static int
static long long int
from_octal(const char *p, size_t l)
{
int r = 0;
long long int r = 0;
while (l > 0) {
r *= 8;
@ -161,7 +161,7 @@ DEFINE_TEST(test_option_c)
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
assertEqualMem(e + 36, "000001", 6); /* nlink */
failure("file entries should have rdev == 0 (dev was 0%o)",
failure("file entries should have rdev == 0 (dev was 0%llo)",
from_octal(e + 6, 6));
assertEqualMem(e + 42, "000000", 6); /* rdev */
t = from_octal(e + 48, 11); /* mtime */

View File

@ -37,13 +37,9 @@ DEFINE_TEST(test_option_t)
char date[32];
char date2[32];
struct tm *tmptr;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/* List reference archive, make sure the TOC is correct. */
extract_reference_file("test_option_t.cpio");
@ -95,15 +91,10 @@ DEFINE_TEST(test_option_t)
#ifdef HAVE_LOCALE_H
setlocale(LC_ALL, "");
#endif
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tmptr = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tmptr = localtime_r(&mtime, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = mtime;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tmptr = NULL;
else
tmptr = &tmbuf;
#else
tmptr = localtime(&mtime);
#endif

View File

@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3006002
#define ARCHIVE_VERSION_NUMBER 3007000
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@ -157,7 +157,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.6.2"
#define ARCHIVE_VERSION_ONLY_STRING "3.7.0"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);

View File

@ -36,6 +36,11 @@
#error Cannot use both OpenSSL and libmd.
#endif
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
/*
* Message digest functions for Windows platform.
*/
@ -48,6 +53,26 @@
/*
* Initialize a Message digest.
*/
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
static int
win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
{
NTSTATUS status;
ctx->valid = 0;
status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0);
if (!BCRYPT_SUCCESS(status))
return (ARCHIVE_FAILED);
status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0);
if (!BCRYPT_SUCCESS(status)) {
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
return (ARCHIVE_FAILED);
}
ctx->valid = 1;
return (ARCHIVE_OK);
}
#else
static int
win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
{
@ -70,6 +95,7 @@ win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
ctx->valid = 1;
return (ARCHIVE_OK);
}
#endif
/*
* Update a Message digest.
@ -81,23 +107,37 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
if (!ctx->valid)
return (ARCHIVE_FAILED);
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCryptHashData(ctx->hHash,
(PUCHAR)(uintptr_t)buf,
len, 0);
#else
CryptHashData(ctx->hash,
(unsigned char *)(uintptr_t)buf,
(DWORD)len, 0);
#endif
return (ARCHIVE_OK);
}
static int
win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
{
#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
DWORD siglen = (DWORD)bufsize;
#endif
if (!ctx->valid)
return (ARCHIVE_FAILED);
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
BCryptDestroyHash(ctx->hHash);
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
#else
CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
CryptDestroyHash(ctx->hash);
CryptReleaseContext(ctx->cryptProv, 0);
#endif
ctx->valid = 0;
return (ARCHIVE_OK);
}
@ -276,7 +316,11 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
static int
__archive_md5init(archive_md5_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
#endif
}
static int
@ -659,7 +703,11 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
static int
__archive_sha1init(archive_sha1_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
#endif
}
static int
@ -919,7 +967,11 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
static int
__archive_sha256init(archive_sha256_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
#endif
}
static int
@ -1155,7 +1207,11 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
static int
__archive_sha384init(archive_sha384_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
#endif
}
static int
@ -1415,7 +1471,11 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
static int
__archive_sha512init(archive_sha512_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
#endif
}
static int

View File

@ -164,6 +164,15 @@
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
/* don't use bcrypt when XP needs to be supported */
#include <bcrypt.h>
typedef struct {
int valid;
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
} Digest_CTX;
#else
#include <windows.h>
#include <wincrypt.h>
typedef struct {
@ -172,6 +181,7 @@ typedef struct {
HCRYPTHASH hash;
} Digest_CTX;
#endif
#endif
/* typedefs */
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)

View File

@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3006002
#define ARCHIVE_VERSION_NUMBER 3007000
/*
* Note: archive_entry.h is for use outside of libarchive; the

View File

@ -698,13 +698,9 @@ Convert(time_t Month, time_t Day, time_t Year,
time_t Julian;
int i;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (Year < 69)
Year += 2000;
@ -731,15 +727,10 @@ Convert(time_t Month, time_t Day, time_t Year,
Julian *= DAY;
Julian += Timezone;
Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Julian, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Julian;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Julian);
#endif
@ -755,36 +746,21 @@ DSTcorrect(time_t Start, time_t Future)
time_t StartDay;
time_t FutureDay;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Start, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Start;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Start);
#endif
StartDay = (ltime->tm_hour + 1) % 24;
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Future, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Future;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Future);
#endif
@ -799,24 +775,15 @@ RelativeDate(time_t Start, time_t zone, int dstmode,
{
struct tm *tm;
time_t t, now;
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
t = Start - zone;
#if defined(HAVE_GMTIME_R)
#if defined(HAVE_GMTIME_S)
tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf;
#elif defined(HAVE_GMTIME_R)
tm = gmtime_r(&t, &tmbuf);
#elif defined(HAVE__GMTIME64_S)
tmptime = t;
terr = _gmtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = gmtime(&t);
#endif
@ -835,25 +802,16 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
struct tm *tm;
time_t Month;
time_t Year;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (RelMonth == 0)
return 0;
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&Start, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Start;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&Start);
#endif
@ -993,10 +951,6 @@ __archive_get_date(time_t now, const char *p)
time_t Start;
time_t tod;
long tzone;
#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/* Clear out the parsed token array. */
memset(tokens, 0, sizeof(tokens));
@ -1005,36 +959,26 @@ __archive_get_date(time_t now, const char *p)
gds = &_gds;
/* Look up the current time. */
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&local, &now) ? NULL : &local;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&now, &local);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = now;
terr = _localtime64_s(&local, &tmptime);
if (terr)
tm = NULL;
else
tm = &local;
#else
memset(&local, 0, sizeof(local));
tm = localtime(&now);
#endif
if (tm == NULL)
return -1;
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S)
local = *tm;
#endif
/* Look up UTC if we can and use that to determine the current
* timezone offset. */
#if defined(HAVE_GMTIME_R)
#if defined(HAVE_GMTIME_S)
gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
#elif defined(HAVE_GMTIME_R)
gmt_ptr = gmtime_r(&now, &gmt);
#elif defined(HAVE__GMTIME64_S)
tmptime = now;
terr = _gmtime64_s(&gmt, &tmptime);
if (terr)
gmt_ptr = NULL;
else
gmt_ptr = &gmt;
#else
memset(&gmt, 0, sizeof(gmt));
gmt_ptr = gmtime(&now);
@ -1076,15 +1020,10 @@ __archive_get_date(time_t now, const char *p)
* time components instead of the local timezone. */
if (gds->HaveZone && gmt_ptr != NULL) {
now -= gds->Timezone;
#if defined(HAVE_GMTIME_R)
#if defined(HAVE_GMTIME_S)
gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
#elif defined(HAVE_GMTIME_R)
gmt_ptr = gmtime_r(&now, &gmt);
#elif defined(HAVE__GMTIME64_S)
tmptime = now;
terr = _gmtime64_s(&gmt, &tmptime);
if (terr)
gmt_ptr = NULL;
else
gmt_ptr = &gmt;
#else
gmt_ptr = gmtime(&now);
#endif

View File

@ -231,15 +231,20 @@ static int
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PARAM params[2];
EVP_MAC *mac;
EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
char sha1[] = "SHA1";
OSSL_PARAM params[] = {
OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
OSSL_PARAM_END
};
mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
*ctx = EVP_MAC_CTX_new(mac);
EVP_MAC_free(mac);
if (*ctx == NULL)
return -1;
EVP_MAC_free(mac);
params[0] = OSSL_PARAM_construct_utf8_string("digest", (char *)"SHA1", 0);
params[1] = OSSL_PARAM_construct_end();
EVP_MAC_init(*ctx, key, key_len, params);
#else
*ctx = HMAC_CTX_new();

View File

@ -77,6 +77,8 @@ typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
#include <openssl/opensslv.h>
#include <openssl/hmac.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/params.h>
typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
#else

View File

@ -33,7 +33,8 @@
#include <openssl/evp.h>
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
static inline EVP_MD_CTX *EVP_MD_CTX_new(void)

View File

@ -51,16 +51,27 @@ __FBSDID("$FreeBSD$");
#include <pthread.h>
#endif
static void arc4random_buf(void *, size_t);
static void la_arc4random_buf(void *, size_t);
#endif /* HAVE_ARC4RANDOM_BUF */
#include "archive.h"
#include "archive_random_private.h"
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
/* don't use bcrypt when XP needs to be supported */
#include <bcrypt.h>
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
#elif defined(HAVE_WINCRYPT_H)
#include <wincrypt.h>
#endif
#endif
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
@ -75,6 +86,20 @@ int
archive_random(void *buf, size_t nbytes)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
NTSTATUS status;
BCRYPT_ALG_HANDLE hAlg;
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0);
if (!BCRYPT_SUCCESS(status))
return ARCHIVE_FAILED;
status = BCryptGenRandom(hAlg, buf, nbytes, 0);
BCryptCloseAlgorithmProvider(hAlg, 0);
if (!BCRYPT_SUCCESS(status))
return ARCHIVE_FAILED;
return ARCHIVE_OK;
# else
HCRYPTPROV hProv;
BOOL success;
@ -92,6 +117,10 @@ archive_random(void *buf, size_t nbytes)
}
/* TODO: Does this case really happen? */
return ARCHIVE_FAILED;
# endif
#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
la_arc4random_buf(buf, nbytes);
return ARCHIVE_OK;
#else
arc4random_buf(buf, nbytes);
return ARCHIVE_OK;
@ -256,7 +285,7 @@ arc4_getbyte(void)
}
static void
arc4random_buf(void *_buf, size_t n)
la_arc4random_buf(void *_buf, size_t n)
{
uint8_t *buf = (uint8_t *)_buf;
_ARC4_LOCK();

View File

@ -95,8 +95,13 @@ archive_read_data_into_fd(struct archive *a, int fd)
"archive_read_data_into_fd");
can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
if (!can_lseek)
if (!can_lseek) {
nulls = calloc(1, nulls_size);
if (!nulls) {
r = ARCHIVE_FATAL;
goto cleanup;
}
}
while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
ARCHIVE_OK) {

View File

@ -1670,6 +1670,11 @@ setup_current_filesystem(struct archive_read_disk *a)
else
t->current_filesystem->name_max = nm;
#endif
if (t->current_filesystem->name_max == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot determine name_max");
return (ARCHIVE_FAILED);
}
#endif /* USE_READDIR_R */
return (ARCHIVE_OK);
}
@ -1860,7 +1865,16 @@ setup_current_filesystem(struct archive_read_disk *a)
#if defined(USE_READDIR_R)
/* Set maximum filename length. */
#if defined(HAVE_STATVFS)
t->current_filesystem->name_max = svfs.f_namelen;
#else
t->current_filesystem->name_max = sfs.f_namelen;
#endif
if (t->current_filesystem->name_max == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot determine name_max");
return (ARCHIVE_FAILED);
}
#endif
return (ARCHIVE_OK);
}
@ -1942,6 +1956,11 @@ setup_current_filesystem(struct archive_read_disk *a)
#if defined(USE_READDIR_R)
/* Set maximum filename length. */
t->current_filesystem->name_max = svfs.f_namemax;
if (t->current_filesystem->name_max == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot determine name_max");
return (ARCHIVE_FAILED);
}
#endif
return (ARCHIVE_OK);
}
@ -1996,6 +2015,11 @@ setup_current_filesystem(struct archive_read_disk *a)
else
t->current_filesystem->name_max = nm;
# endif /* _PC_NAME_MAX */
if (t->current_filesystem->name_max == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot determine name_max");
return (ARCHIVE_FAILED);
}
#endif /* USE_READDIR_R */
return (ARCHIVE_OK);
}
@ -2543,7 +2567,11 @@ tree_current_lstat(struct tree *t)
#else
if (tree_enter_working_dir(t) != 0)
return NULL;
#ifdef HAVE_LSTAT
if (lstat(tree_current_access_path(t), &t->lst) != 0)
#else
if (la_stat(tree_current_access_path(t), &t->lst) != 0)
#endif
#endif
return NULL;
t->flags |= hasLstat;

View File

@ -154,10 +154,10 @@ file_skip(struct archive *a, void *client_data, int64_t request)
#ifdef __ANDROID__
/* fileno() isn't safe on all platforms ... see above. */
if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
#elif HAVE_FSEEKO
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
#elif HAVE__FSEEKI64
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
#elif HAVE_FSEEKO
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
#else
if (fseek(mine->f, skip, SEEK_CUR) != 0)
#endif

View File

@ -255,6 +255,27 @@ have been concatenated together.
Without this option, only the contents of
the first concatenated archive would be read.
.El
.It Format zip
.Bl -tag -compact -width indent
.It Cm compat-2x
Libarchive 2.x incorrectly encoded Unicode filenames on
some platforms.
This option mimics the libarchive 2.x filename handling
so that such archives can be read correctly.
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file names.
.It Cm ignorecrc32
Skip the CRC32 check.
Mostly used for testing.
.It Cm mac-ext
Support Mac OS metadata extension that records data in special
files beginning with a period and underscore.
Defaults to enabled on Mac OS, disabled on other platforms.
Use
.Cm !mac-ext
to disable.
.El
.El
.\"
.Sh ERRORS

View File

@ -115,9 +115,9 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
unsigned prefix;
/* Zstd frame magic values */
const unsigned zstd_magic = 0xFD2FB528U;
const unsigned zstd_magic_skippable_start = 0x184D2A50U;
const unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
unsigned zstd_magic = 0xFD2FB528U;
unsigned zstd_magic_skippable_start = 0x184D2A50U;
unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
(void) self; /* UNUSED */
@ -170,7 +170,7 @@ static int
zstd_bidder_init(struct archive_read_filter *self)
{
struct private_data *state;
const size_t out_block_size = ZSTD_DStreamOutSize();
size_t out_block_size = ZSTD_DStreamOutSize();
void *out_block;
ZSTD_DStream *dstream;
@ -211,6 +211,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
ssize_t avail_in;
ZSTD_outBuffer out;
ZSTD_inBuffer in;
size_t ret;
state = (struct private_data *)self->data;
@ -219,7 +220,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
/* Try to fill the output buffer. */
while (out.pos < out.size && !state->eof) {
if (!state->in_frame) {
const size_t ret = ZSTD_initDStream(state->dstream);
ret = ZSTD_initDStream(state->dstream);
if (ZSTD_isError(ret)) {
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC,
@ -249,8 +250,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
in.pos = 0;
{
const size_t ret =
ZSTD_decompressStream(state->dstream, &out, &in);
ret = ZSTD_decompressStream(state->dstream, &out, &in);
if (ZSTD_isError(ret)) {
archive_set_error(&self->archive->archive,

View File

@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
#ifdef HAVE_ZSTD_H
#include <zstd.h>
#endif
#include "archive.h"
#include "archive_entry.h"
@ -80,8 +83,11 @@ __FBSDID("$FreeBSD$");
#define _7Z_IA64 0x03030401
#define _7Z_ARM 0x03030501
#define _7Z_ARMTHUMB 0x03030701
#define _7Z_ARM64 0xa
#define _7Z_SPARC 0x03030805
#define _7Z_ZSTD 0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */
/*
* 7-Zip header property IDs.
*/
@ -277,6 +283,11 @@ struct _7zip {
#ifdef HAVE_ZLIB_H
z_stream stream;
int stream_valid;
#endif
/* Decoding Zstandard data. */
#if HAVE_ZSTD_H
ZSTD_DStream *zstd_dstream;
int zstdstream_valid;
#endif
/* Decoding PPMd data. */
int ppmd7_stat;
@ -397,6 +408,9 @@ static int setup_decode_folder(struct archive_read *, struct _7z_folder *,
int);
static void x86_Init(struct _7zip *);
static size_t x86_Convert(struct _7zip *, uint8_t *, size_t);
static void arm_Init(struct _7zip *);
static size_t arm_Convert(struct _7zip *, uint8_t *, size_t);
static size_t arm64_Convert(struct _7zip *, uint8_t *, size_t);
static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
@ -1027,10 +1041,13 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
case _7Z_COPY:
case _7Z_BZ2:
case _7Z_DEFLATE:
case _7Z_ZSTD:
case _7Z_PPMD:
if (coder2 != NULL) {
if (coder2->codec != _7Z_X86 &&
coder2->codec != _7Z_X86_BCJ2) {
coder2->codec != _7Z_X86_BCJ2 &&
coder2->codec != _7Z_ARM &&
coder2->codec != _7Z_ARM64) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Unsupported filter %lx for %lx",
@ -1041,6 +1058,8 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
zip->bcj_state = 0;
if (coder2->codec == _7Z_X86)
x86_Init(zip);
else if (coder2->codec == _7Z_ARM)
arm_Init(zip);
}
break;
default:
@ -1137,6 +1156,12 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
filters[fi].id = LZMA_FILTER_ARMTHUMB;
fi++;
break;
#ifdef LZMA_FILTER_ARM64
case _7Z_ARM64:
filters[fi].id = LZMA_FILTER_ARM64;
fi++;
break;
#endif
case _7Z_SPARC:
filters[fi].id = LZMA_FILTER_SPARC;
fi++;
@ -1222,6 +1247,22 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
"BZ2 codec is unsupported");
return (ARCHIVE_FAILED);
#endif
case _7Z_ZSTD:
{
#if defined(HAVE_ZSTD_H)
if (zip->zstdstream_valid) {
ZSTD_freeDStream(zip->zstd_dstream);
zip->zstdstream_valid = 0;
}
zip->zstd_dstream = ZSTD_createDStream();
zip->zstdstream_valid = 1;
break;
#else
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"ZSTD codec is unsupported");
return (ARCHIVE_FAILED);
#endif
}
case _7Z_DEFLATE:
#ifdef HAVE_ZLIB_H
if (zip->stream_valid)
@ -1487,6 +1528,22 @@ decompress(struct archive_read *a, struct _7zip *zip,
t_avail_in = zip->stream.avail_in;
t_avail_out = zip->stream.avail_out;
break;
#endif
#ifdef HAVE_ZSTD_H
case _7Z_ZSTD:
{
ZSTD_inBuffer input = { t_next_in, t_avail_in, 0 }; // src, size, pos
ZSTD_outBuffer output = { t_next_out, t_avail_out, 0 }; // dst, size, pos
size_t const zret = ZSTD_decompressStream(zip->zstd_dstream, &output, &input);
if (ZSTD_isError(zret)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Zstd decompression failed: %s", ZSTD_getErrorName(zret));
return ARCHIVE_FAILED;
}
t_avail_in -= input.pos;
t_avail_out -= output.pos;
break;
}
#endif
case _7Z_PPMD:
{
@ -1572,16 +1629,23 @@ decompress(struct archive_read *a, struct _7zip *zip,
/*
* Decord BCJ.
*/
if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
size_t l = x86_Convert(zip, buff, *outbytes);
zip->odd_bcj_size = *outbytes - l;
if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
o_avail_in && ret != ARCHIVE_EOF) {
memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
zip->odd_bcj_size);
*outbytes = l;
} else
zip->odd_bcj_size = 0;
if (zip->codec != _7Z_LZMA2) {
if (zip->codec2 == _7Z_X86) {
size_t l = x86_Convert(zip, buff, *outbytes);
zip->odd_bcj_size = *outbytes - l;
if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
o_avail_in && ret != ARCHIVE_EOF) {
memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
zip->odd_bcj_size);
*outbytes = l;
} else
zip->odd_bcj_size = 0;
} else if (zip->codec2 == _7Z_ARM) {
*outbytes = arm_Convert(zip, buff, *outbytes);
} else if (zip->codec2 == _7Z_ARM64) {
*outbytes = arm64_Convert(zip, buff, *outbytes);
}
}
/*
@ -3727,6 +3791,116 @@ x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
return (bufferPos);
}
static void
arm_Init(struct _7zip *zip)
{
zip->bcj_ip = 8;
}
static size_t
arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
{
// This function was adapted from
// static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
// in https://git.tukaani.org/xz-embedded.git
/*
* Branch/Call/Jump (BCJ) filter decoders
*
* Authors: Lasse Collin <lasse.collin@tukaani.org>
* Igor Pavlov <https://7-zip.org/>
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*/
size_t i;
uint32_t addr;
for (i = 0; i + 4 <= size; i += 4) {
if (buf[i + 3] == 0xEB) {
// Calculate the transformed addr.
addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
| ((uint32_t)buf[i + 2] << 16);
addr <<= 2;
addr -= zip->bcj_ip + (uint32_t)i;
addr >>= 2;
// Store the transformed addr in buf.
buf[i] = (uint8_t)addr;
buf[i + 1] = (uint8_t)(addr >> 8);
buf[i + 2] = (uint8_t)(addr >> 16);
}
}
zip->bcj_ip += i;
return i;
}
static size_t
arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
{
// This function was adapted from
// static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
// in https://git.tukaani.org/xz-embedded.git
/*
* Branch/Call/Jump (BCJ) filter decoders
*
* Authors: Lasse Collin <lasse.collin@tukaani.org>
* Igor Pavlov <https://7-zip.org/>
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*/
size_t i;
uint32_t instr;
uint32_t addr;
for (i = 0; i + 4 <= size; i += 4) {
instr = (uint32_t)buf[i]
| ((uint32_t)buf[i+1] << 8)
| ((uint32_t)buf[i+2] << 16)
| ((uint32_t)buf[i+3] << 24);
if ((instr >> 26) == 0x25) {
/* BL instruction */
addr = instr - ((zip->bcj_ip + (uint32_t)i) >> 2);
instr = 0x94000000 | (addr & 0x03FFFFFF);
buf[i] = (uint8_t)instr;
buf[i+1] = (uint8_t)(instr >> 8);
buf[i+2] = (uint8_t)(instr >> 16);
buf[i+3] = (uint8_t)(instr >> 24);
} else if ((instr & 0x9F000000) == 0x90000000) {
/* ADRP instruction */
addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
/* Only convert values in the range +/-512 MiB. */
if ((addr + 0x020000) & 0x1C0000)
continue;
addr -= (zip->bcj_ip + (uint32_t)i) >> 12;
instr &= 0x9000001F;
instr |= (addr & 3) << 29;
instr |= (addr & 0x03FFFC) << 3;
instr |= (0U - (addr & 0x020000)) & 0xE00000;
buf[i] = (uint8_t)instr;
buf[i+1] = (uint8_t)(instr >> 8);
buf[i+2] = (uint8_t)(instr >> 16);
buf[i+3] = (uint8_t)(instr >> 24);
}
}
zip->bcj_ip += i;
return i;
}
/*
* Brought from LZMA SDK.
*

View File

@ -2294,10 +2294,10 @@ lzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br)
(br->cache_buffer << 48) |
((uint64_t)strm->next_in[1]) << 40 |
((uint64_t)strm->next_in[0]) << 32 |
((uint32_t)strm->next_in[3]) << 24 |
((uint32_t)strm->next_in[2]) << 16 |
((uint32_t)strm->next_in[5]) << 8 |
(uint32_t)strm->next_in[4];
((uint64_t)strm->next_in[3]) << 24 |
((uint64_t)strm->next_in[2]) << 16 |
((uint64_t)strm->next_in[5]) << 8 |
(uint64_t)strm->next_in[4];
strm->next_in += 6;
strm->avail_in -= 6;
br->cache_avail += 6 * 8;

View File

@ -441,7 +441,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
/* Compare name to "TRAILER!!!" to test for end-of-archive. */
if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!",
11) == 0) {
10) == 0) {
/* TODO: Store file location of start of block. */
archive_clear_error(&a->archive);
return (ARCHIVE_EOF);
@ -985,14 +985,14 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
static int64_t
le4(const unsigned char *p)
{
return ((p[0] << 16) + (((int64_t)p[1]) << 24) + (p[2] << 0) + (p[3] << 8));
return ((p[0] << 16) | (((int64_t)p[1]) << 24) | (p[2] << 0) | (p[3] << 8));
}
static int64_t
be4(const unsigned char *p)
{
return ((((int64_t)p[0]) << 24) + (p[1] << 16) + (p[2] << 8) + (p[3]));
return ((((int64_t)p[0]) << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
}
/*

View File

@ -1901,7 +1901,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* NUMBER of RRIP "PX" extension.
* Note: Old mkisofs did not record that FILE SERIAL NUMBER
* in ISO images.
* Note2: xorriso set 0 to the location of a symlink file.
* Note2: xorriso set 0 to the location of a symlink file.
*/
if (file->size == 0 && location >= 0) {
/* If file->size is zero, its location points wrong place,
@ -1955,7 +1955,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* made by makefs is not zero and its location is
* the same as those of next regular file. That is
* the same as hard like file and it causes unexpected
* error.
* error.
*/
if (file->size > 0 &&
(file->mode & AE_IFMT) == AE_IFLNK) {
@ -2747,7 +2747,7 @@ next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
* If directory entries all which are descendant of
* rr_moved are still remaining, expose their.
*/
if (iso9660->re_files.first != NULL &&
if (iso9660->re_files.first != NULL &&
iso9660->rr_moved != NULL &&
iso9660->rr_moved->rr_moved_has_re_only)
/* Expose "rr_moved" entry. */
@ -3180,11 +3180,11 @@ isodate17(const unsigned char *v)
static time_t
time_from_tm(struct tm *t)
{
#if HAVE_TIMEGM
#if HAVE__MKGMTIME
return _mkgmtime(t);
#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
#elif HAVE__MKGMTIME64
return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */

View File

@ -2009,10 +2009,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
((uint64_t)strm->next_in[0]) << 48 |
((uint64_t)strm->next_in[1]) << 40 |
((uint64_t)strm->next_in[2]) << 32 |
((uint32_t)strm->next_in[3]) << 24 |
((uint32_t)strm->next_in[4]) << 16 |
((uint32_t)strm->next_in[5]) << 8 |
(uint32_t)strm->next_in[6];
((uint64_t)strm->next_in[3]) << 24 |
((uint64_t)strm->next_in[4]) << 16 |
((uint64_t)strm->next_in[5]) << 8 |
(uint64_t)strm->next_in[6];
strm->next_in += 7;
strm->avail_in -= 7;
br->cache_avail += 7 * 8;
@ -2022,10 +2022,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
(br->cache_buffer << 48) |
((uint64_t)strm->next_in[0]) << 40 |
((uint64_t)strm->next_in[1]) << 32 |
((uint32_t)strm->next_in[2]) << 24 |
((uint32_t)strm->next_in[3]) << 16 |
((uint32_t)strm->next_in[4]) << 8 |
(uint32_t)strm->next_in[5];
((uint64_t)strm->next_in[2]) << 24 |
((uint64_t)strm->next_in[3]) << 16 |
((uint64_t)strm->next_in[4]) << 8 |
(uint64_t)strm->next_in[5];
strm->next_in += 6;
strm->avail_in -= 6;
br->cache_avail += 6 * 8;

View File

@ -1280,7 +1280,13 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
mtree->fd = -1;
st = NULL;
}
} else if (lstat(path, st) == -1) {
}
#ifdef HAVE_LSTAT
else if (lstat(path, st) == -1)
#else
else if (la_stat(path, st) == -1)
#endif
{
st = NULL;
}

View File

@ -1830,13 +1830,9 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
struct tm *tm;
time_t t;
long nsec;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (p + 2 > endp)
return (-1);
@ -1868,15 +1864,10 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
p++;
}
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&t, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = t;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&t);
#endif

View File

@ -530,11 +530,11 @@ strtoi_lim(const char *str, const char **ep, int llim, int ulim)
static time_t
time_from_tm(struct tm *t)
{
#if HAVE_TIMEGM
#if HAVE__MKGMTIME
return _mkgmtime(t);
#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
#elif HAVE__MKGMTIME64
return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */

View File

@ -1127,7 +1127,7 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
x |= p[1] - '0';
else
return (-1);
*b++ = x;
bsize--;
p += 2;
@ -1139,11 +1139,11 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
static time_t
time_from_tm(struct tm *t)
{
#if HAVE_TIMEGM
#if HAVE__MKGMTIME
return _mkgmtime(t);
#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
#elif HAVE__MKGMTIME64
return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */

View File

@ -2227,7 +2227,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
to_consume = zip->bzstream.total_in_lo32;
__archive_read_consume(a, to_consume);
total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) +
total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) |
zip->bzstream.total_out_lo32;
zip->entry_bytes_remaining -= to_consume;

View File

@ -1324,6 +1324,10 @@ free_sconv_object(struct archive_string_conv *sc)
}
#if defined(_WIN32) && !defined(__CYGWIN__)
# if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# define GetOEMCP() CP_OEMCP
# endif
static unsigned
my_atoi(const char *p)
{

View File

@ -42,9 +42,20 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
/* don't use bcrypt when XP needs to be supported */
#include <bcrypt.h>
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
#elif defined(HAVE_WINCRYPT_H)
#include <wincrypt.h>
#endif
#endif
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
@ -233,14 +244,16 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
L'u', L'v', L'w', L'x', L'y', L'z'
};
HCRYPTPROV hProv;
struct archive_wstring temp_name;
wchar_t *ws;
DWORD attr;
wchar_t *xp, *ep;
int fd;
hProv = (HCRYPTPROV)NULL;
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCRYPT_ALG_HANDLE hAlg = NULL;
#else
HCRYPTPROV hProv = (HCRYPTPROV)NULL;
#endif
fd = -1;
ws = NULL;
@ -314,23 +327,42 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
abort();
}
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
NULL, 0))) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
#else
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
#endif
for (;;) {
wchar_t *p;
HANDLE h;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
/* Generate a random file name through CryptGenRandom(). */
p = xp;
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
(DWORD)(ep - p)*sizeof(wchar_t), 0))) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
#else
if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
(BYTE*)p)) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
#endif
for (; p < ep; p++)
*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
@ -347,6 +379,17 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
/* mkstemp */
attr = FILE_ATTRIBUTE_NORMAL;
}
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileAttributes = attr & 0xFFFF;
createExParams.dwFileFlags = attr & 0xFFF00000;
h = CreateFile2(ws,
GENERIC_READ | GENERIC_WRITE | DELETE,
0,/* Not share */
CREATE_NEW,
&createExParams);
#else
h = CreateFileW(ws,
GENERIC_READ | GENERIC_WRITE | DELETE,
0,/* Not share */
@ -354,6 +397,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
CREATE_NEW,/* Create a new file only */
attr,
NULL);
#endif
if (h == INVALID_HANDLE_VALUE) {
/* The same file already exists. retry with
* a new filename. */
@ -372,8 +416,13 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
break;/* success! */
}
exit_tmpfile:
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (hAlg != NULL)
BCryptCloseAlgorithmProvider(hAlg, 0);
#else
if (hProv != (HCRYPTPROV)NULL)
CryptReleaseContext(hProv, 0);
#endif
free(ws);
if (template == temp_name.s)
archive_wstring_free(&temp_name);

View File

@ -310,6 +310,25 @@ __archive_write_output(struct archive_write *a, const void *buff, size_t length)
return (__archive_write_filter(a->filter_first, buff, length));
}
static int
__archive_write_filters_flush(struct archive_write *a)
{
struct archive_write_filter *f;
int ret, ret1;
ret = ARCHIVE_OK;
for (f = a->filter_first; f != NULL; f = f->next_filter) {
if (f->flush != NULL && f->bytes_written > 0) {
ret1 = (f->flush)(f);
if (ret1 < ret)
ret = ret1;
if (ret1 < ARCHIVE_WARN)
f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
}
}
return (ret);
}
int
__archive_write_nulls(struct archive_write *a, size_t length)
{
@ -740,6 +759,18 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
return (ARCHIVE_FAILED);
}
/* Flush filters at boundary. */
r2 = __archive_write_filters_flush(a);
if (r2 == ARCHIVE_FAILED) {
return (ARCHIVE_FAILED);
}
if (r2 == ARCHIVE_FATAL) {
a->archive.state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
if (r2 < ret)
ret = r2;
/* Format and write header. */
r2 = ((a->format_write_header)(a, entry));
if (r2 == ARCHIVE_FAILED) {

View File

@ -352,7 +352,7 @@ archive_compressor_compress_write(struct archive_write_filter *f,
while (length--) {
c = *bp++;
state->in_count++;
state->cur_fcode = (c << 16) + state->cur_code;
state->cur_fcode = (c << 16) | state->cur_code;
i = ((c << HSHIFT) ^ state->cur_code); /* Xor hashing. */
if (state->hashtab[i] == state->cur_fcode) {

View File

@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@ -50,10 +53,21 @@ __FBSDID("$FreeBSD$");
struct private_data {
int compression_level;
int threads;
int threads;
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
enum {
running,
finishing,
resetting,
} state;
int frame_per_file;
size_t min_frame_size;
size_t max_frame_size;
size_t cur_frame;
size_t cur_frame_in;
size_t cur_frame_out;
size_t total_in;
ZSTD_CStream *cstream;
int64_t total_in;
ZSTD_outBuffer out;
#else
struct archive_write_program_data *pdata;
@ -75,6 +89,7 @@ static int archive_compressor_zstd_options(struct archive_write_filter *,
static int archive_compressor_zstd_open(struct archive_write_filter *);
static int archive_compressor_zstd_write(struct archive_write_filter *,
const void *, size_t);
static int archive_compressor_zstd_flush(struct archive_write_filter *);
static int archive_compressor_zstd_close(struct archive_write_filter *);
static int archive_compressor_zstd_free(struct archive_write_filter *);
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
@ -103,6 +118,7 @@ archive_write_add_filter_zstd(struct archive *_a)
f->data = data;
f->open = &archive_compressor_zstd_open;
f->options = &archive_compressor_zstd_options;
f->flush = &archive_compressor_zstd_flush;
f->close = &archive_compressor_zstd_close;
f->free = &archive_compressor_zstd_free;
f->code = ARCHIVE_FILTER_ZSTD;
@ -110,6 +126,11 @@ archive_write_add_filter_zstd(struct archive *_a)
data->compression_level = CLEVEL_DEFAULT;
data->threads = 0;
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
data->frame_per_file = 0;
data->min_frame_size = 0;
data->max_frame_size = SIZE_MAX;
data->cur_frame_in = 0;
data->cur_frame_out = 0;
data->cstream = ZSTD_createCStream();
if (data->cstream == NULL) {
free(data);
@ -147,29 +168,18 @@ archive_compressor_zstd_free(struct archive_write_filter *f)
return (ARCHIVE_OK);
}
static int string_is_numeric (const char* value)
static int string_to_number(const char *string, intmax_t *numberp)
{
size_t len = strlen(value);
size_t i;
char *end;
if (len == 0) {
return (ARCHIVE_WARN);
}
else if (len == 1 && !(value[0] >= '0' && value[0] <= '9')) {
return (ARCHIVE_WARN);
}
else if (!(value[0] >= '0' && value[0] <= '9') &&
value[0] != '-' && value[0] != '+') {
return (ARCHIVE_WARN);
}
for (i = 1; i < len; i++) {
if (!(value[i] >= '0' && value[i] <= '9')) {
return (ARCHIVE_WARN);
}
}
return (ARCHIVE_OK);
if (string == NULL || *string == '\0')
return (ARCHIVE_WARN);
*numberp = strtoimax(string, &end, 10);
if (end == string || *end != '\0' || errno == EOVERFLOW) {
*numberp = 0;
return (ARCHIVE_WARN);
}
return (ARCHIVE_OK);
}
/*
@ -182,13 +192,13 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
struct private_data *data = (struct private_data *)f->data;
if (strcmp(key, "compression-level") == 0) {
int level = atoi(value);
intmax_t level;
if (string_to_number(value, &level) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
/* If we don't have the library, hard-code the max level */
int minimum = CLEVEL_MIN;
int maximum = CLEVEL_MAX;
if (string_is_numeric(value) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
maximum = ZSTD_maxCLevel();
#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
@ -207,19 +217,40 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
data->compression_level = level;
return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) {
int threads = atoi(value);
if (string_is_numeric(value) != ARCHIVE_OK) {
intmax_t threads;
if (string_to_number(value, &threads) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
int minimum = 0;
if (threads < minimum) {
if (threads < 0) {
return (ARCHIVE_WARN);
}
data->threads = threads;
return (ARCHIVE_OK);
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
} else if (strcmp(key, "frame-per-file") == 0) {
data->frame_per_file = 1;
return (ARCHIVE_OK);
} else if (strcmp(key, "min-frame-size") == 0) {
intmax_t min_frame_size;
if (string_to_number(value, &min_frame_size) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
if (min_frame_size < 0) {
return (ARCHIVE_WARN);
}
data->min_frame_size = min_frame_size;
return (ARCHIVE_OK);
} else if (strcmp(key, "max-frame-size") == 0) {
intmax_t max_frame_size;
if (string_to_number(value, &max_frame_size) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
if (max_frame_size < 1024) {
return (ARCHIVE_WARN);
}
data->max_frame_size = max_frame_size;
return (ARCHIVE_OK);
#endif
}
/* Note: The "warn" return is just to inform the options
@ -281,15 +312,22 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
size_t length)
{
struct private_data *data = (struct private_data *)f->data;
int ret;
/* Update statistics */
data->total_in += length;
return (drive_compressor(f, data, 0, buff, length));
}
if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK)
return (ret);
/*
* Flush the compressed stream.
*/
static int
archive_compressor_zstd_flush(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
return (ARCHIVE_OK);
if (data->frame_per_file && data->state == running &&
data->cur_frame_out > data->min_frame_size)
data->state = finishing;
return (drive_compressor(f, data, 1, NULL, 0));
}
/*
@ -300,57 +338,72 @@ archive_compressor_zstd_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
/* Finish zstd frame */
return drive_compressor(f, data, 1, NULL, 0);
if (data->state == running)
data->state = finishing;
return (drive_compressor(f, data, 1, NULL, 0));
}
/*
* Utility function to push input data through compressor,
* writing full output blocks as necessary.
*
* Note that this handles both the regular write case (finishing ==
* false) and the end-of-archive case (finishing == true).
*/
static int
drive_compressor(struct archive_write_filter *f,
struct private_data *data, int finishing, const void *src, size_t length)
struct private_data *data, int flush, const void *src, size_t length)
{
ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 };
ZSTD_inBuffer in = { .src = src, .size = length, .pos = 0 };
size_t ipos, opos, zstdret = 0;
int ret;
for (;;) {
if (data->out.pos == data->out.size) {
const int ret = __archive_write_filter(f->next_filter,
data->out.dst, data->out.size);
ipos = in.pos;
opos = data->out.pos;
switch (data->state) {
case running:
if (in.pos == in.size)
return (ARCHIVE_OK);
zstdret = ZSTD_compressStream(data->cstream,
&data->out, &in);
if (ZSTD_isError(zstdret))
goto zstd_fatal;
break;
case finishing:
zstdret = ZSTD_endStream(data->cstream, &data->out);
if (ZSTD_isError(zstdret))
goto zstd_fatal;
if (zstdret == 0)
data->state = resetting;
break;
case resetting:
ZSTD_CCtx_reset(data->cstream, ZSTD_reset_session_only);
data->cur_frame++;
data->cur_frame_in = 0;
data->cur_frame_out = 0;
data->state = running;
break;
}
data->total_in += in.pos - ipos;
data->cur_frame_in += in.pos - ipos;
data->cur_frame_out += data->out.pos - opos;
if (data->state == running &&
data->cur_frame_in >= data->max_frame_size) {
data->state = finishing;
}
if (data->out.pos == data->out.size ||
(flush && data->out.pos > 0)) {
ret = __archive_write_filter(f->next_filter,
data->out.dst, data->out.pos);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
goto fatal;
data->out.pos = 0;
}
/* If there's nothing to do, we're done. */
if (!finishing && in.pos == in.size)
return (ARCHIVE_OK);
{
const size_t zstdret = !finishing ?
ZSTD_compressStream(data->cstream, &data->out, &in)
: ZSTD_endStream(data->cstream, &data->out);
if (ZSTD_isError(zstdret)) {
archive_set_error(f->archive,
ARCHIVE_ERRNO_MISC,
"Zstd compression failed: %s",
ZSTD_getErrorName(zstdret));
return (ARCHIVE_FATAL);
}
/* If we're finishing, 0 means nothing left to flush */
if (finishing && zstdret == 0) {
const int ret = __archive_write_filter(f->next_filter,
data->out.dst, data->out.pos);
return (ret);
}
}
}
zstd_fatal:
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
"Zstd compression failed: %s",
ZSTD_getErrorName(zstdret));
fatal:
return (ARCHIVE_FATAL);
}
#else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
@ -367,17 +420,9 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
archive_strcpy(&as, "zstd --no-check");
if (data->compression_level < CLEVEL_STD_MIN) {
struct archive_string as2;
archive_string_init(&as2);
archive_string_sprintf(&as2, " --fast=%d", -data->compression_level);
archive_string_concat(&as, &as2);
archive_string_free(&as2);
archive_string_sprintf(&as, " --fast=%d", -data->compression_level);
} else {
struct archive_string as2;
archive_string_init(&as2);
archive_string_sprintf(&as2, " -%d", data->compression_level);
archive_string_concat(&as, &as2);
archive_string_free(&as2);
archive_string_sprintf(&as, " -%d", data->compression_level);
}
if (data->compression_level > CLEVEL_STD_MAX) {
@ -385,11 +430,7 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
}
if (data->threads != 0) {
struct archive_string as2;
archive_string_init(&as2);
archive_string_sprintf(&as2, " --threads=%d", data->threads);
archive_string_concat(&as, &as2);
archive_string_free(&as2);
archive_string_sprintf(&as, " --threads=%d", data->threads);
}
f->write = archive_compressor_zstd_write;
@ -407,6 +448,14 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
return __archive_write_program_write(f, data->pdata, buff, length);
}
static int
archive_compressor_zstd_flush(struct archive_write_filter *f)
{
(void)f; /* UNUSED */
return (ARCHIVE_OK);
}
static int
archive_compressor_zstd_close(struct archive_write_filter *f)
{

View File

@ -397,6 +397,7 @@ static int set_times_from_entry(struct archive_write_disk *);
static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
static ssize_t write_data_block(struct archive_write_disk *,
const char *, size_t);
static void close_file_descriptor(struct archive_write_disk *);
static int _archive_write_disk_close(struct archive *);
static int _archive_write_disk_free(struct archive *);
@ -514,7 +515,12 @@ lazy_stat(struct archive_write_disk *a)
* XXX At this point, symlinks should not be hit, otherwise
* XXX a race occurred. Do we want to check explicitly for that?
*/
if (lstat(a->name, &a->st) == 0) {
#ifdef HAVE_LSTAT
if (lstat(a->name, &a->st) == 0)
#else
if (la_stat(a->name, &a->st) == 0)
#endif
{
a->pst = &a->st;
return (ARCHIVE_OK);
}
@ -1726,6 +1732,7 @@ _archive_write_disk_finish_entry(struct archive *_a)
r = hfs_write_data_block(
a, null_d, a->file_remaining_bytes);
if (r < 0)
close_file_descriptor(a);
return ((int)r);
}
#endif
@ -1735,6 +1742,7 @@ _archive_write_disk_finish_entry(struct archive *_a)
a->filesize == 0) {
archive_set_error(&a->archive, errno,
"File size could not be restored");
close_file_descriptor(a);
return (ARCHIVE_FAILED);
}
#endif
@ -1744,8 +1752,10 @@ _archive_write_disk_finish_entry(struct archive *_a)
* to see what happened.
*/
a->pst = NULL;
if ((ret = lazy_stat(a)) != ARCHIVE_OK)
return (ret);
if ((ret = lazy_stat(a)) != ARCHIVE_OK) {
close_file_descriptor(a);
return (ret);
}
/* We can use lseek()/write() to extend the file if
* ftruncate didn't work or isn't available. */
if (a->st.st_size < a->filesize) {
@ -1753,11 +1763,13 @@ _archive_write_disk_finish_entry(struct archive *_a)
if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) {
archive_set_error(&a->archive, errno,
"Seek failed");
close_file_descriptor(a);
return (ARCHIVE_FATAL);
}
if (write(a->fd, &nul, 1) < 0) {
archive_set_error(&a->archive, errno,
"Write to restore size failed");
close_file_descriptor(a);
return (ARCHIVE_FATAL);
}
a->pst = NULL;
@ -2154,7 +2166,11 @@ restore_entry(struct archive_write_disk *a)
* then don't follow it.
*/
if (r != 0 || !S_ISDIR(a->mode))
#ifdef HAVE_LSTAT
r = lstat(a->name, &a->st);
#else
r = la_stat(a->name, &a->st);
#endif
if (r != 0) {
archive_set_error(&a->archive, errno,
"Can't stat existing object");
@ -2550,7 +2566,12 @@ _archive_write_disk_close(struct archive *_a)
goto skip_fixup_entry;
} else
#endif
if (lstat(p->name, &st) != 0 ||
if (
#ifdef HAVE_LSTAT
lstat(p->name, &st) != 0 ||
#else
la_stat(p->name, &st) != 0 ||
#endif
la_verify_filetype(st.st_mode,
p->filetype) == 0) {
goto skip_fixup_entry;
@ -2565,7 +2586,12 @@ _archive_write_disk_close(struct archive *_a)
goto skip_fixup_entry;
} else
#endif
if (lstat(p->name, &st) != 0 ||
if (
#ifdef HAVE_LSTAT
lstat(p->name, &st) != 0 ||
#else
la_stat(p->name, &st) != 0 ||
#endif
la_verify_filetype(st.st_mode,
p->filetype) == 0) {
goto skip_fixup_entry;
@ -2785,8 +2811,8 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
!(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT))
/* Platform doesn't have lstat, so we can't look for symlinks. */
(void)path; /* UNUSED */
(void)error_number; /* UNUSED */
(void)error_string; /* UNUSED */
(void)a_eno; /* UNUSED */
(void)a_estr; /* UNUSED */
(void)flags; /* UNUSED */
(void)checking_linkname; /* UNUSED */
return (ARCHIVE_OK);
@ -2859,8 +2885,10 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
/* Check that we haven't hit a symlink. */
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
r = fstatat(chdir_fd, head, &st, AT_SYMLINK_NOFOLLOW);
#else
#elif defined(HAVE_LSTAT)
r = lstat(head, &st);
#else
r = la_stat(head, &st);
#endif
if (r != 0) {
tail[0] = c;
@ -3558,7 +3586,9 @@ set_time(int fd, int mode, const char *name,
(void)fd; /* UNUSED */
(void)mode; /* UNUSED */
(void)name; /* UNUSED */
(void)atime; /* UNUSED */
(void)atime_nsec; /* UNUSED */
(void)mtime; /* UNUSED */
(void)mtime_nsec; /* UNUSED */
return (ARCHIVE_WARN);
#endif
@ -4391,7 +4421,12 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname)
*/
archive_strncpy(&datafork, pathname, p - pathname);
archive_strcat(&datafork, p + 2);
if (lstat(datafork.s, &st) == -1 ||
if (
#ifdef HAVE_LSTAT
lstat(datafork.s, &st) == -1 ||
#else
la_stat(datafork.s, &st) == -1 ||
#endif
(st.st_mode & AE_IFMT) != AE_IFREG)
goto skip_appledouble;
@ -4707,5 +4742,17 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
}
#endif
/*
* Close the file descriptor if one is open.
*/
static void close_file_descriptor(struct archive_write_disk* a)
{
if (a->fd >= 0) {
close(a->fd);
a->fd = -1;
}
}
#endif /* !_WIN32 || __CYGWIN__ */

View File

@ -53,6 +53,7 @@ struct archive_write_filter {
const char *key, const char *value);
int (*open)(struct archive_write_filter *);
int (*write)(struct archive_write_filter *, const void *, size_t);
int (*flush)(struct archive_write_filter *);
int (*close)(struct archive_write_filter *);
int (*free)(struct archive_write_filter *);
void *data;

View File

@ -652,7 +652,7 @@ struct iso_option {
#define VOLUME_IDENTIFIER_SIZE 32
/*
* Usage : !zisofs [DEFAULT]
* Usage : !zisofs [DEFAULT]
* : Disable to generate RRIP 'ZF' extension.
* : zisofs
* : Make files zisofs file and generate RRIP 'ZF'
@ -689,7 +689,7 @@ struct iso9660 {
uint64_t bytes_remaining;
int need_multi_extent;
/* Temporary string buffer for Joliet extension. */
/* Temporary string buffer for Joliet extension. */
struct archive_string utf16be;
struct archive_string mbs;
@ -2521,12 +2521,11 @@ get_gmoffset(struct tm *tm)
static void
get_tmfromtime(struct tm *tm, time_t *t)
{
#if HAVE_LOCALTIME_R
#if HAVE_LOCALTIME_S
localtime_s(tm, t);
#elif HAVE_LOCALTIME_R
tzset();
localtime_r(t, tm);
#elif HAVE__LOCALTIME64_S
__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
_localtime64_s(tm, &tmp_t);
#else
memcpy(tm, localtime(t), sizeof(*tm));
#endif
@ -4074,11 +4073,8 @@ write_information_block(struct archive_write *a)
}
memset(info.s, 0, info_size);
opt = 0;
#if defined(HAVE__CTIME64_S)
{
__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
}
#if defined(HAVE_CTIME_S)
ctime_s(buf, sizeof(buf), &(iso9660->birth_time));
#elif defined(HAVE_CTIME_R)
ctime_r(&(iso9660->birth_time), buf);
#else

View File

@ -100,6 +100,7 @@ static int has_non_ASCII(const char *);
static void sparse_list_clear(struct pax *);
static int sparse_list_add(struct pax *, int64_t, int64_t);
static char *url_encode(const char *in);
static time_t get_ustar_max_mtime(void);
/*
* Set output format to 'restricted pax' format.
@ -595,6 +596,8 @@ archive_write_pax_header(struct archive_write *a,
need_extension = 0;
pax = (struct pax *)a->format_data;
const time_t ustar_max_mtime = get_ustar_max_mtime();
/* Sanity check. */
if (archive_entry_pathname(entry_original) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@ -1116,16 +1119,13 @@ archive_write_pax_header(struct archive_write *a,
}
/*
* Technically, the mtime field in the ustar header can
* support 33 bits, but many platforms use signed 32-bit time
* values. The cutoff of 0x7fffffff here is a compromise.
* Yes, this check is duplicated just below; this helps to
* avoid writing an mtime attribute just to handle a
* high-resolution timestamp in "restricted pax" mode.
*/
if (!need_extension &&
((archive_entry_mtime(entry_main) < 0)
|| (archive_entry_mtime(entry_main) >= 0x7fffffff)))
|| (archive_entry_mtime(entry_main) >= ustar_max_mtime)))
need_extension = 1;
/* I use a star-compatible file flag attribute. */
@ -1190,7 +1190,7 @@ archive_write_pax_header(struct archive_write *a,
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
need_extension) {
if (archive_entry_mtime(entry_main) < 0 ||
archive_entry_mtime(entry_main) >= 0x7fffffff ||
archive_entry_mtime(entry_main) >= ustar_max_mtime ||
archive_entry_mtime_nsec(entry_main) != 0)
add_pax_attr_time(&(pax->pax_header), "mtime",
archive_entry_mtime(entry_main),
@ -1428,7 +1428,7 @@ archive_write_pax_header(struct archive_write *a,
/* Copy mtime, but clip to ustar limits. */
s = archive_entry_mtime(entry_main);
if (s < 0) { s = 0; }
if (s >= 0x7fffffff) { s = 0x7fffffff; }
if (s > ustar_max_mtime) { s = ustar_max_mtime; }
archive_entry_set_mtime(pax_attr_entry, s, 0);
/* Standard ustar doesn't support atime. */
@ -2046,3 +2046,18 @@ sparse_list_add(struct pax *pax, int64_t offset, int64_t length)
return (_sparse_list_add_block(pax, offset, length, 0));
}
static time_t
get_ustar_max_mtime(void)
{
/*
* Technically, the mtime field in the ustar header can
* support 33 bits. We are using all of them to keep
* tar/test/test_option_C_mtree.c simple and passing after 2038.
* For platforms that use signed 32-bit time values we
* use the 32-bit maximum.
*/
if (sizeof(time_t) > sizeof(int32_t))
return (time_t)0x1ffffffff;
else
return (time_t)0x7fffffff;
}

View File

@ -329,30 +329,21 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t)
{
/** like strftime(3) but for time_t objects */
struct tm *rt;
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
struct tm timeHere;
#endif
#if defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
char strtime[100];
size_t len;
#ifdef HAVE_GMTIME_R
if ((rt = gmtime_r(&t, &timeHere)) == NULL)
return;
#elif defined(HAVE__GMTIME64_S)
tmptime = t;
terr = _gmtime64_s(&timeHere, &tmptime);
if (terr)
rt = NULL;
else
rt = &timeHere;
#if defined(HAVE_GMTIME_S)
rt = gmtime_s(&timeHere, &t) ? NULL : &timeHere;
#elif defined(HAVE_GMTIME_R)
rt = gmtime_r(&t, &timeHere);
#else
if ((rt = gmtime(&t)) == NULL)
return;
rt = gmtime(&t);
#endif
if (!rt)
return;
/* leave the hard yacker to our role model strftime() */
len = strftime(strtime, sizeof(strtime)-1, fmt, rt);
archive_strncat(as, strtime, len);

View File

@ -906,15 +906,11 @@ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
{
char timestr[100];
struct tm tm;
#if defined(HAVE__GMTIME64_S)
__time64_t tmptime;
#endif
#if defined(HAVE_GMTIME_R)
#if defined(HAVE_GMTIME_S)
gmtime_s(&tm, &t);
#elif defined(HAVE_GMTIME_R)
gmtime_r(&t, &tm);
#elif defined(HAVE__GMTIME64_S)
tmptime = t;
_gmtime64_s(&tm, &tmptime);
#else
memcpy(&tm, gmtime(&t), sizeof(tm));
#endif

View File

@ -1382,25 +1382,14 @@ dos_time(const time_t unix_time)
{
struct tm *t;
unsigned int dt;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/* This will not preserve time when creating/extracting the archive
* on two systems with different time zones. */
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
t = localtime_s(&tmbuf, &unix_time) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
t = localtime_r(&unix_time, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = unix_time;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
t = NULL;
else
t = &tmbuf;
#else
t = localtime(&unix_time);
#endif

View File

@ -124,10 +124,9 @@ test_fuzz(const struct files *filesets)
newraw = realloc(rawimage, oldsize + size);
if (!assert(newraw != NULL))
{
free(rawimage);
rawimage = NULL;
free(tmp);
continue;
size = 0;
break;
}
rawimage = newraw;
memcpy(rawimage + oldsize, tmp, size);

View File

@ -1608,6 +1608,12 @@ test_parent(void)
int file_count;
int match_count;
int r;
#if defined(O_PATH) || defined(O_SEARCH) || \
(defined(__FreeBSD__) && defined(O_EXEC))
const char *ignore_traversals_test4;
ignore_traversals_test4 = getenv("IGNORE_TRAVERSALS_TEST4");
#endif
assertMakeDir("lock", 0311);
assertMakeDir("lock/dir1", 0755);
@ -1784,7 +1790,8 @@ test_parent(void)
if (r == ARCHIVE_FAILED) {
#if defined(O_PATH) || defined(O_SEARCH) || \
(defined(__FreeBSD__) && defined(O_EXEC))
assertEqualIntA(a, ARCHIVE_OK, r);
if (ignore_traversals_test4 == NULL)
assertEqualIntA(a, ARCHIVE_OK, r);
#endif
/* Close the disk object. */
archive_read_close(a);

View File

@ -30,6 +30,9 @@ __FBSDID("$FreeBSD");
#define open _open
#endif
#define __LIBARCHIVE_BUILD
#include <archive_crc32.h>
/*
* Extract a non-encoded file.
* The header of the 7z archive files is not encoded.
@ -283,6 +286,141 @@ test_extract_all_files(const char *refname)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/*
* Extract multi files.
* Like test_extract_all_files, but with zstandard compression.
*/
static void
test_extract_all_files_zstd(const char *refname)
{
struct archive_entry *ae;
struct archive *a;
char buff[128];
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
/* Verify directory dir1. Note that this comes before the dir1/file1 entry in recent versions of 7-Zip. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
assertEqualString("dir1/", archive_entry_pathname(ae));
assertEqualInt(2764801, archive_entry_mtime(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
/* Verify regular file1. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
assertEqualString("dir1/file1", archive_entry_pathname(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(13, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
assertEqualInt(13, archive_read_data(a, buff, sizeof(buff)));
assertEqualMem(buff, "aaaaaaaaaaaa\n", 13);
/* Verify regular file2. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
assertEqualString("file2", archive_entry_pathname(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(26, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
assertEqualInt(26, archive_read_data(a, buff, sizeof(buff)));
assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26);
/* Verify regular file3. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
assertEqualString("file3", archive_entry_pathname(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(39, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
assertEqualInt(39, archive_read_data(a, buff, sizeof(buff)));
assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39);
/* Verify regular file4. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
assertEqualString("file4", archive_entry_pathname(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(52, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
assertEqualInt(52, archive_read_data(a, buff, sizeof(buff)));
assertEqualMem(buff,
"aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52);
assertEqualInt(5, archive_file_count(a));
/* End of archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify archive format. */
assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
/* Close the archive. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/*
* Extract file from an archives using ZSTD compression with and without BCJ.
*/
static void
test_extract_file_zstd_bcj_nobjc(const char *refname)
{
struct archive_entry *ae;
struct archive *a;
char buff[4096];
uint32_t computed_crc = 0;
uint32_t expected_crc = 0xbd66eebc;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
/* Verify regular file: hw. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0775), archive_entry_mode(ae));
assertEqualString("hw", archive_entry_pathname(ae));
assertEqualInt(1685913368, archive_entry_mtime(ae));
assertEqualInt(15952, archive_entry_size(ae));
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
for (;;) {
la_ssize_t bytes_read = archive_read_data(a, buff, sizeof(buff));
assert(bytes_read >= 0);
if (bytes_read == 0) break;
computed_crc = crc32(computed_crc, buff, bytes_read);
}
assertEqualInt(computed_crc, expected_crc);
assertEqualInt(1, archive_file_count(a));
/* End of archive. */
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify archive format. */
assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
/* Close the archive. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/*
* Extract last file.
* The header of the 7z archive files is encoded with LZMA.
@ -782,6 +920,74 @@ DEFINE_TEST(test_read_format_7zip_deflate)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_zstd)
{
struct archive *a;
assert((a = archive_read_new()) != NULL);
/* Extracting with libzstd */
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping(
"7zip:zstd decoding is not supported on this platform");
} else {
test_extract_all_files_zstd("test_read_format_7zip_zstd.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_zstd_solid)
{
struct archive *a;
assert((a = archive_read_new()) != NULL);
/* Extracting with libzstd */
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping(
"7zip:zstd decoding is not supported on this platform");
} else {
test_extract_all_files_zstd("test_read_format_7zip_solid_zstd.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_zstd_bcj)
{
struct archive *a;
assert((a = archive_read_new()) != NULL);
/* Extracting with libzstd */
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping(
"7zip:zstd decoding is not supported on this platform");
} else {
test_extract_file_zstd_bcj_nobjc("test_read_format_7zip_zstd_bcj.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_zstd_nobcj)
{
struct archive *a;
assert((a = archive_read_new()) != NULL);
/* Extracting with libzstd */
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping(
"7zip:zstd decoding is not supported on this platform");
} else {
test_extract_file_zstd_bcj_nobjc("test_read_format_7zip_zstd_nobcj.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_empty)
{
test_empty_archive();
@ -832,7 +1038,147 @@ DEFINE_TEST(test_read_format_7zip_lzma2)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
static void
test_arm_filter(const char *refname)
{
struct archive *a;
struct archive_entry *ae;
char buff[7804];
uint32_t computed_crc = 0;
uint32_t expected_crc = 0x355ec4e1;
assert((a = archive_read_new()) != NULL);
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
assertEqualString("hw-gnueabihf", archive_entry_pathname(ae));
assertEqualInt(sizeof(buff), archive_entry_size(ae));
assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff)));
computed_crc = crc32(computed_crc, buff, sizeof(buff));
assertEqualInt(computed_crc, expected_crc);
assertEqualInt(1, archive_file_count(a));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_zstd_arm)
{
struct archive *a;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping(
"7zip:zstd decoding is not supported on this platform");
} else {
test_arm_filter("test_read_format_7zip_zstd_arm.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_lzma2_arm)
{
struct archive *a;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping(
"7zip:lzma decoding is not supported on this platform");
} else {
test_arm_filter("test_read_format_7zip_lzma2_arm.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_ppmd)
{
test_ppmd();
}
static void
test_arm64_filter(const char *refname)
{
struct archive *a;
struct archive_entry *ae;
char buff[70368];
uint32_t computed_crc = 0;
uint32_t expected_crc = 0xde97d594;
assert((a = archive_read_new()) != NULL);
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt((AE_IFREG | 0775), archive_entry_mode(ae));
assertEqualString("hw-arm64", archive_entry_pathname(ae));
assertEqualInt(sizeof(buff), archive_entry_size(ae));
assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff)));
computed_crc = crc32(computed_crc, buff, sizeof(buff));
assertEqualInt(computed_crc, expected_crc);
assertEqualInt(1, archive_file_count(a));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_lzma2_arm64)
{
#ifdef HAVE_LZMA_FILTER_ARM64
struct archive *a;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping(
"7zip:lzma decoding is not supported on this platform");
} else {
test_arm64_filter("test_read_format_7zip_lzma2_arm64.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
#else
skipping("This version of liblzma does not support LZMA_FILTER_ARM64");
#endif
}
DEFINE_TEST(test_read_format_7zip_deflate_arm64)
{
struct archive *a;
assert((a = archive_read_new()) != NULL);
if (ARCHIVE_OK != archive_read_support_filter_gzip(a)) {
skipping(
"7zip:deflate decoding is not supported on this platform");
} else {
test_arm64_filter("test_read_format_7zip_deflate_arm64.7z");
}
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}

View File

@ -0,0 +1,64 @@
begin 664 libarchive/test/test_read_format_7zip_deflate_arm64.7z
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
3`#)5M-E?M]D!%08!`""`_8$`````
`
end

View File

@ -0,0 +1,50 @@
begin 664 test_read_format_7zip_lzma2_arm.7z
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
D80!B`&D`:`!F````&0`4"@$```-.&5"<V0$5!@$`((#M@0``
`
end

View File

@ -0,0 +1,54 @@
begin 664 libarchive/test/test_read_format_7zip_lzma2_arm64.7z
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
C`'(`;0`V`#0````9`!0*`0`R5;397[?9`14&`0`@@/V!````
`
end

View File

@ -0,0 +1,9 @@
begin 664 test_read_format_7zip_solid_zstd.7z
M-WJ\KR<<``1&(FS)O@`````````B`````````$V+D*,HM2_]`$@!``!0*DT8
M!````"$````HM2_]((+%```P80IB8V0*!X"P/JZA4J4;TS.X,9C'`#4``($S
M!ZX/T5NC)*"0H'?;G=XO-Y<-`+"F*K87M`OOZ1+1#31#M/`2YN,FY:(1).I)
M(B(+;9$W4?0*8=3V5N;BSZ)(0UGD/'LOSN"0&#DNX!A2*5\#&8IP$1G=7-]@
MP\EE$]Z;/%6NU^\_,X:MD?57P#S>.+BINH?CHRX,::[Q5P*!X\DH````%P8V
?`0F`B``'"P$``2,#`0$%70`0```,@-H*`9/CZP``````
`
end

View File

@ -0,0 +1,12 @@
begin 664 test_read_format_7zip_zstd.7z
M-WJ\KR<<``2QPP_C,`$````````C``````````+H!E<HM2_]`$@!``!0*DT8
M!````!$````HM2_](`U%```080H!``80`BBU+_T`2`$``%`J31@$````%```
M`"BU+_T@&ET``"!A"F(*`@#`H`'8*+4O_0!(`0``4"I-&`0````6````*+4O
M_2`G;0``,&$*8@IC"@,4``@8V2BU+_T`2`$``%`J31@$````&0```"BU+_T@
M-(4``$!A"F(*8PID"@04``@8(QL``($S!ZYMP-,)%[KY0NUS!EQ9<T<AN:R"
M7Z^`KZ24FV4LJ?"A)\MX&!"$=31!F6U\W/D!@*G'-=Z@#"&#>8R#*L]U;J=*
M@K`Q6]^1F4MZF33TE2LJK8X@%5MY%P.#1*EM98=_,9"?K'$*_A0YVC)]1ML=
MK-5-,X82B;/_L`I&FQ!5HP#H````%P:`J`$)@(@`!PL!``$C`P$!!5T`$```
+#(#Z"@%\$`,4````
`
end

View File

@ -0,0 +1,61 @@
begin 644 test_read_format_7zip_zstd_arm.7z
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
166S@9)S9`14&`0`@@.V!````
`
end

View File

@ -0,0 +1,56 @@
begin 664 test_read_format_7zip_zstd_bcj.7z
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
@=P```!D$`````!0*`0``'';'*9?9`14&`0`@@/V!````
`
end

View File

@ -0,0 +1,56 @@
begin 664 test_read_format_7zip_zstd_nobcj.7z
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
3```<=L<IE]D!%08!`""`_8$`````
`
end

View File

@ -1310,6 +1310,8 @@ DEFINE_TEST(test_read_format_rar5_sfx)
assertA(size == archive_read_data(a, buff, size));
assertEqualMem(buff, test_txt, size);
EPILOGUE();
}
DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read)

View File

@ -746,6 +746,7 @@ DEFINE_TEST(test_read_format_zip_zstd_one_file)
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping("zstd is not fully supported on this platform");
archive_read_close(a);
archive_read_free(a);
return;
}
extract_reference_file(refname);
@ -771,6 +772,7 @@ DEFINE_TEST(test_read_format_zip_zstd_one_file_blockread)
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping("zstd is not fully supported on this platform");
archive_read_close(a);
archive_read_free(a);
return;
}
extract_reference_file(refname);
@ -796,6 +798,7 @@ DEFINE_TEST(test_read_format_zip_zstd_multi)
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping("zstd is not fully supported on this platform");
archive_read_close(a);
archive_read_free(a);
return;
}
extract_reference_file(refname);
@ -833,6 +836,7 @@ DEFINE_TEST(test_read_format_zip_zstd_multi_blockread)
if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
skipping("zstd is not fully supported on this platform");
archive_read_close(a);
archive_read_free(a);
return;
}
extract_reference_file(refname);
@ -1017,6 +1021,7 @@ DEFINE_TEST(test_read_format_zip_lzma_alone_leak)
if(ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
skipping("lzma reading is not fully supported on this platform");
archive_read_close(a);
archive_read_free(a);
return;
}

View File

@ -171,6 +171,8 @@ checker_free(struct checker *checker)
{
free(checker->shortbuf);
free(checker->fullbuf);
archive_read_free(checker->short_archive);
archive_read_free(checker->full_archive);
free(checker);
}

View File

@ -133,6 +133,33 @@ DEFINE_TEST(test_write_filter_zstd)
archive_write_set_filter_option(a, NULL, "threads", "-1")); /* negative */
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "threads", "4"));
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
/* frame-per-file: boolean */
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "frame-per-file", ""));
/* min-frame-size: >= 0 */
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_filter_option(a, NULL, "min-frame-size", ""));
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_filter_option(a, NULL, "min-frame-size", "-1"));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "min-frame-size", "0"));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "min-frame-size", "1048576"));
/* max-frame-size: >= 1024 */
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_filter_option(a, NULL, "max-frame-size", ""));
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_filter_option(a, NULL, "max-frame-size", "-1"));
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_filter_option(a, NULL, "max-frame-size", "0"));
assertEqualIntA(a, ARCHIVE_FAILED,
archive_write_set_filter_option(a, NULL, "max-frame-size", "1023"));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "max-frame-size", "1024"));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "max-frame-size", "1048576"));
#endif
assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {
snprintf(path, sizeof(path), "file%03d", i);

View File

@ -129,26 +129,17 @@ static void verify_uncompressed_contents(const char *buff, size_t used)
/* Misc variables */
unsigned long crc;
struct tm *tm;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/* p is the pointer to walk over the central directory,
* q walks over the local headers, the data and the data descriptors. */
const char *p, *q, *local_header, *extra_start;
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&tmbuf, &now) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&now, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = now;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&now);
#endif

View File

@ -74,12 +74,8 @@ DEFINE_TEST(test_write_format_zip_file)
struct archive_entry *ae;
time_t t = 1234567890;
struct tm *tm;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
size_t used, buffsize = 1000000;
unsigned long crc;
@ -98,15 +94,10 @@ DEFINE_TEST(test_write_format_zip_file)
zip_compression = 0;
#endif
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&t, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = t;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&t);
#endif

View File

@ -76,12 +76,8 @@ DEFINE_TEST(test_write_format_zip_file_zip64)
struct archive_entry *ae;
time_t t = 1234567890;
struct tm *tm;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
size_t used, buffsize = 1000000;
unsigned long crc;
@ -99,15 +95,10 @@ DEFINE_TEST(test_write_format_zip_file_zip64)
zip_compression = 0;
#endif
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&t, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = t;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&t);
#endif

View File

@ -149,6 +149,10 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
#if GCC_VERSION >= 409
__attribute__((__no_sanitize_undefined__))
#else
# if defined(__clang__)
__attribute__((no_sanitize("undefined")))
# endif
#endif
#if defined(_MSC_VER)
static __inline U32 A32(const void * x)

View File

@ -171,8 +171,10 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
int input, output, save_errno, i, need_restart;
char ch, *p, *end;
struct termios term, oterm;
#ifdef HAVE_SIGACTION
struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
struct sigaction savetstp, savettin, savettou, savepipe;
#endif
/* I suppose we could alloc on demand in this case (XXX). */
if (bufsiz == 0) {
@ -221,6 +223,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
oterm.c_lflag |= ECHO;
}
#ifdef HAVE_SIGACTION
/*
* Catch signals that would otherwise cause the user to end
* up with echo turned off in the shell. Don't worry about
@ -239,6 +242,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
(void)sigaction(SIGTSTP, &sa, &savetstp);
(void)sigaction(SIGTTIN, &sa, &savettin);
(void)sigaction(SIGTTOU, &sa, &savettou);
#endif
if (!(flags & RPP_STDIN)) {
int r = write(output, prompt, strlen(prompt));
@ -276,6 +280,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
continue;
signo[SIGTTOU] = sigttou;
}
#ifdef HAVE_SIGACTION
(void)sigaction(SIGALRM, &savealrm, NULL);
(void)sigaction(SIGHUP, &savehup, NULL);
(void)sigaction(SIGINT, &saveint, NULL);
@ -285,6 +290,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
(void)sigaction(SIGTSTP, &savetstp, NULL);
(void)sigaction(SIGTTIN, &savettin, NULL);
(void)sigaction(SIGTTOU, &savettou, NULL);
#endif
if (input != STDIN_FILENO)
(void)close(input);

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd January 31, 2020
.Dd December 1, 2022
.Dt TAR 1
.Os
.Sh NAME
@ -643,6 +643,19 @@ Specify the number of worker threads to use.
Setting threads to a special value 0 makes
.Xr zstd 1
use as many threads as there are CPU cores on the system.
.It Cm zstd:frame-per-file
Start a new compression frame at the beginning of each file in the
archive.
.It Cm zstd:min-frame-size Ns = Ns Ar N
In combination with
.Cm zstd:frame-per-file ,
do not start a new compression frame unless the current frame is at least
.Ar N
bytes.
.It Cm zstd:max-frame-size Ns = Ns Ar N
Start a new compression frame as soon as the current frame exceeds
.Ar N
bytes.
.It Cm lzop:compression-level
A decimal integer from 1 to 9 specifying the lzop compression level.
.It Cm xz:compression-level

View File

@ -44,6 +44,7 @@ DEFINE_TEST(test_option_lzma)
if (strstr(p, "Unsupported compression") != NULL) {
skipping("This version of bsdtar was compiled "
"without lzma support");
free(p);
return;
}
failure("--lzma option is broken");

View File

@ -668,13 +668,9 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
time_t tim;
static time_t now;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/*
* We avoid collecting the entire list in memory at once by
@ -746,15 +742,10 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y";
else
fmt = bsdtar->day_first ? DAY_FMT " %b %H:%M" : "%b " DAY_FMT " %H:%M";
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
ltime = localtime_s(&tmbuf, &tim) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&tim, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = tim;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&tim);
#endif

View File

@ -327,7 +327,7 @@ my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
int r;
memset(bhfi, 0, sizeof(*bhfi));
h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
h = CreateFileA(path, FILE_READ_ATTRIBUTES, 0, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
return (0);
@ -1432,7 +1432,7 @@ assertion_file_time(const char *file, int line,
/* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open
* a directory file. If not, CreateFile() will fail when
* the pathname is a directory. */
h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
h = CreateFileA(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE) {
failure_start(file, line, "Can't access %s\n", pathname);
@ -2345,7 +2345,7 @@ static void assert_version_id(char **qq, size_t *ss)
q += 3;
s -= 3;
}
/* Skip a single trailing a,b,c, or d. */
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
++q;
@ -2391,7 +2391,7 @@ void assertVersion(const char *prog, const char *base)
/* Version message should start with name of program, then space. */
assert(s > prog_len + 1);
failure("Version must start with '%s': ``%s''", base, p);
if (!assertEqualMem(q, base, prog_len)) {
free(p);
@ -2729,7 +2729,7 @@ canNodump(void)
/* Get extended attribute value from a path */
void *
getXattr(const char *path, const char *name, size_t *sizep)
{
{
void *value = NULL;
#if ARCHIVE_XATTR_SUPPORT
ssize_t size;
@ -3863,17 +3863,13 @@ main(int argc, char **argv)
int test_set[sizeof(tests) / sizeof(tests[0])];
int i = 0, j = 0, tests_run = 0, tests_failed = 0, option;
int testprogdir_len;
#ifdef PROGRAM
#ifdef PROGRAM
int tmp2_len;
#endif
time_t now;
struct tm *tmptr;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
char *refdir_alloc = NULL;
const char *progname;
@ -4109,15 +4105,10 @@ main(int argc, char **argv)
*/
now = time(NULL);
for (i = 0; ; i++) {
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tmptr = localtime_s(&tmbuf, &now) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tmptr = localtime_r(&now, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = now;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tmptr = NULL;
else
tmptr = &tmbuf;
#else
tmptr = localtime(&now);
#endif

View File

@ -0,0 +1,37 @@
############################################
#
# How to build bsdunzip
#
############################################
IF(ENABLE_UNZIP)
SET(bsdunzip_SOURCES
bsdunzip.c
bsdunzip_platform.h
../libarchive_fe/err.c
../libarchive_fe/err.h
../libarchive_fe/lafe_platform.h
../libarchive_fe/passphrase.c
../libarchive_fe/passphrase.h
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
# bsdunzip documentation
SET(bsdunzip_MANS bsdunzip.1)
# How to build bsdunzip
ADD_EXECUTABLE(bsdunzip ${bsdunzip_SOURCES})
IF(ENABLE_UNZIP_SHARED)
TARGET_LINK_LIBRARIES(bsdunzip archive ${ADDITIONAL_LIBS})
ELSE(ENABLE_UNZIP_SHARED)
TARGET_LINK_LIBRARIES(bsdunzip archive_static ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(bsdunzip PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
ENDIF(ENABLE_UNZIP_SHARED)
# Installation rules
INSTALL(TARGETS bsdunzip RUNTIME DESTINATION bin)
INSTALL_MAN(${bsdunzip_MANS})
ENDIF(ENABLE_UNZIP)
add_subdirectory(test)

View File

@ -0,0 +1,216 @@
.\"-
.\" Copyright (c) 2007-2008 Dag-Erling Smørgrav
.\" All rights reserved.
.\"
.\" 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.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
.\"
.\" $FreeBSD$
.\"
.Dd January 2, 2023
.Dt BSDUNZIP 1
.Os
.Sh NAME
.Nm bsdunzip
.Nd extract files from a ZIP archive
.Sh SYNOPSIS
.Nm
.Op Fl aCcfjLlnopqtuvy
.Op Fl d Ar dir
.Op Fl x Ar pattern
.Op Fl P Ar password
.Ar zipfile
.Op Ar member ...
.Sh DESCRIPTION
.\" ...
The following options are available:
.Bl -tag -width Fl
.It Fl a
When extracting a text file, convert DOS-style line endings to
Unix-style line endings.
.It Fl C
Match file names case-insensitively.
.It Fl c
Extract to stdout/screen.
When extracting files from the zipfile, they are written to stdout.
This is similar to
.Fl p ,
but does not suppress normal output.
.It Fl d Ar dir
Extract files into the specified directory rather than the current
directory.
.It Fl f
Update existing.
Extract only files from the zipfile if a file with the same name
already exists on disk and is older than the former.
Otherwise, the file is silently skipped.
.It Fl j
Ignore directories stored in the zipfile; instead, extract all files
directly into the extraction directory.
.It Fl L
Convert the names of the extracted files and directories to lowercase.
.It Fl l
List, rather than extract, the contents of the zipfile.
.It Fl n
No overwrite.
When extracting a file from the zipfile, if a file with the same name
already exists on disk, the file is silently skipped.
.It Fl o
Overwrite.
When extracting a file from the zipfile, if a file with the same name
already exists on disk, the existing file is replaced with the file
from the zipfile.
.It Fl p
Extract to stdout.
When extracting files from the zipfile, they are written to stdout.
The normal output is suppressed as if
.Fl q
was specified.
.It Fl P Ar password
Extract encrypted files using a password.
Putting a password on the command line using this option can be
insecure.
.It Fl q
Quiet: print less information while extracting.
.It Fl t
Test: do not extract anything, but verify the checksum of every file
in the archive.
.It Fl u
Update.
When extracting a file from the zipfile, if a file with the same name
already exists on disk, the existing file is replaced with the file
from the zipfile if and only if the latter is newer than the former.
Otherwise, the file is silently skipped.
.It Fl v
List verbosely, rather than extract, the contents of the zipfile.
This differs from
.Fl l
by using the long listing.
Note that most of the data is currently fake and does not reflect the
content of the archive.
.It Fl x Ar pattern
Exclude files matching the pattern
.Ar pattern .
.It Fl y
Print four digit years in listings instead of two.
.It Fl Z Ar mode
Emulate
.Xr zipinfo 1L
mode.
Enabling
.Xr zipinfo 1L
mode changes the way in which additional arguments are parsed.
Currently only
.Xr zipinfo 1L
mode 1 is supported, which lists the file names one per line.
.It Ar [member ...]
Optional list of members to extract from the zipfile.
Can include patterns, e.g.
.Ar 'memberdir/*'
will extract all files and dirs below memberdir.
.El
.Pp
Note that only one of
.Fl n ,
.Fl o ,
and
.Fl u
may be specified.
If specified filename is
.Qq - ,
then data is read from
.Va stdin .
.Sh ENVIRONMENT
If the
.Ev UNZIP_DEBUG
environment variable is defined, the
.Fl q
command-line option has no effect, and additional debugging
information will be printed to
.Va stderr .
.Sh COMPATIBILITY
The
.Nm
utility aims to be sufficiently compatible with other implementations
to serve as a drop-in replacement in the context of the
.Xr ports 7
system.
No attempt has been made to replicate functionality which is not
required for that purpose.
.Pp
For compatibility reasons, command-line options will be recognized if
they are listed not only before but also after the name of the
zipfile.
.Pp
Normally, the
.Fl a
option should only affect files which are marked as text files in the
zipfile's central directory.
Since the
.Xr archive 3
library does not provide access to that information, it is not available
to the
.Nm
utility.
Instead, the
.Nm
utility will assume that a file is a text file if no non-ASCII
characters are present within the first block of data decompressed for
that file.
If non-ASCII characters appear in subsequent blocks of data, a warning
will be issued.
.Pp
The
.Nm
utility is only able to process ZIP archives handled by
.Xr libarchive 3 .
Depending on the installed version of
.Xr libarchive 3 ,
this may or may not include self-extracting or ZIPX archives.
.Sh SEE ALSO
.Xr libarchive 3
.Sh HISTORY
The
.Nm
utility appeared in
.Fx 8.0 .
.Sh AUTHORS
The
.Nm
utility and this manual page were written by
.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org .
It uses the
.Xr archive 3
library developed by
.An Tim Kientzle Aq Mt kientzle@FreeBSD.org .
.Sh CAVEATS
The
.Nm
utility performs two scans of the command-line for arguments before
and after the archive name, so as to maintain compatibility with
Info-ZIP unzip.
As a result, the POSIX
.Ql --
double-dash string used to separate options from arguments will need to
be repeated.
For example, to extract a "-a.jpg" from "-b.zip" with overwrite, one
would need to invoke
.Dl bsdunzip -o -- -a.jpg -- -b.zip

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
*
* $FreeBSD: src/usr.bin/tar/bsdtar_platform.h,v 1.26 2008/12/06 07:37:14 kientzle Exp $
*/
/*
* This header is the first thing included in any of the bsdtar
* source files. As far as possible, platform-specific issues should
* be dealt with here and not within individual source files.
*/
#ifndef BSDUNZIP_PLATFORM_H_INCLUDED
#define BSDUNZIP_PLATFORM_H_INCLUDED
#if defined(PLATFORM_CONFIG_H)
/* Use hand-built config.h in environments that need it. */
#include PLATFORM_CONFIG_H
#else
/* Not having a config.h of some sort is a serious problem. */
#include "config.h"
#endif
/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
/* If not, define it so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
#ifdef HAVE_LIBARCHIVE
/* If we're using the platform libarchive, include system headers. */
#include <archive.h>
#include <archive_entry.h>
#else
/* Otherwise, include user headers. */
#include "archive.h"
#include "archive_entry.h"
#endif
#ifndef HAVE_GETOPT_OPTRESET
/*
* If platform doesn't use optreset for resetting getopt, declare it so
* C source doesn't have to know this platform-specific difference
*/
int optreset;
#endif
/* How to mark functions that don't return. */
/* This facilitates use of some newer static code analysis tools. */
#undef __LA_DEAD
#if defined(__GNUC__) && (__GNUC__ > 2 || \
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
#define __LA_DEAD __attribute__((__noreturn__))
#else
#define __LA_DEAD
#endif
#endif /* !BSDUNZIP_PLATFORM_H_INCLUDED */

View File

@ -0,0 +1,80 @@
############################################
#
# How to build bsdunzip_test
#
############################################
IF(ENABLE_UNZIP AND ENABLE_TEST)
SET(bsdunzip_test_SOURCES
../../libarchive_fe/err.c
../../test_utils/test_utils.c
../../test_utils/test_main.c
test.h
test_0.c
test_basic.c
test_glob.c
test_singlefile.c
test_C.c
test_p.c
test_d.c
test_j.c
test_L.c
test_n.c
test_o.c
test_q.c
test_t.c
test_t_bad.c
test_x.c
test_Z1.c
test_P_encryption.c
)
#
# Register target
#
ADD_EXECUTABLE(bsdunzip_test ${bsdunzip_test_SOURCES})
IF(ENABLE_ACL)
SET(TEST_ACL_LIBS "")
IF(HAVE_LIBACL)
LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY})
ENDIF(HAVE_LIBACL)
IF(HAVE_LIBRICHACL)
LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY})
ENDIF(HAVE_LIBRICHACL)
TARGET_LINK_LIBRARIES(bsdunzip_test ${TEST_ACL_LIBS})
ENDIF(ENABLE_ACL)
SET_PROPERTY(TARGET bsdunzip_test PROPERTY COMPILE_DEFINITIONS LIST_H)
#
# Generate list.h by grepping DEFINE_TEST() lines out of the C sources.
#
GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
${CMAKE_CURRENT_LIST_FILE} ${bsdunzip_test_SOURCES})
SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
${CMAKE_CURRENT_BINARY_DIR})
# list.h has a line DEFINE_TEST(testname) for every
# test. We can use that to define the tests for cmake by
# defining a DEFINE_TEST macro and reading list.h in.
MACRO (DEFINE_TEST _testname)
ADD_TEST(
NAME bsdunzip_${_testname}
COMMAND bsdunzip_test -vv
-p $<TARGET_FILE:bsdunzip>
-r ${CMAKE_CURRENT_SOURCE_DIR}
${_testname})
ENDMACRO (DEFINE_TEST _testname)
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/unzip/test)
# Experimental new test handling
ADD_CUSTOM_TARGET(run_bsdunzip_test
COMMAND bsdunzip_test -p $<TARGET_FILE:bsdunzip>
-r ${CMAKE_CURRENT_SOURCE_DIR}
-vv)
ADD_DEPENDENCIES(run_bsdunzip_test bsdunzip)
ADD_DEPENDENCIES(run_all_tests run_bsdunzip_test)
ENDIF(ENABLE_UNZIP AND ENABLE_TEST)

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2003-2017 Tim Kientzle
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
*
* $FreeBSD$
*/
/* Every test program should #include "test.h" as the first thing. */
#define KNOWNREF "test_basic.zip.uu"
#define ENVBASE "BSDUNZIP" /* Prefix for environment variables. */
#define PROGRAM "bsdunzip" /* Name of program being tested. */
#define PROGRAM_ALIAS "unzip" /* Generic alias for program */
#undef LIBRARY /* Not testing a library. */
#undef EXTRA_DUMP /* How to dump extra data */
#undef EXTRA_ERRNO /* How to dump errno */
/* How to generate extra version info. */
#define EXTRA_VERSION (systemf("%s -v", testprog) ? "" : "")
#include "test_common.h"

View File

@ -0,0 +1,58 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/*
* This first test does basic sanity checks on the environment. For
* most of these, we just exit on failure.
*/
#if !defined(_WIN32) || defined(__CYGWIN__)
#define DEV_NULL "/dev/null"
#else
#define DEV_NULL "NUL"
#endif
DEFINE_TEST(test_0)
{
struct stat st;
failure("File %s does not exist?!", testprog);
if (!assertEqualInt(0, stat(testprogfile, &st))) {
fprintf(stderr,
"\nFile %s does not exist; aborting test.\n\n",
testprog);
exit(1);
}
failure("%s is not executable?!", testprog);
if (!assert((st.st_mode & 0111) != 0)) {
fprintf(stderr,
"\nFile %s not executable; aborting test.\n\n",
testprog);
exit(1);
}
/* TODO: Ensure that our reference files are available. */
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test C arg - match case-insensitive */
DEFINE_TEST(test_C)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -C %s test_basic/caps >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test L arg - make names lowercase */
DEFINE_TEST(test_L)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -L %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("contents a\n", "test_basic/a");
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/caps");
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test P arg - password protected */
DEFINE_TEST(test_P)
{
const char *reffile = "test_encrypted.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -P password %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("plaintext\n", "encrypted/file.txt");
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test -Z1 arg - List filenames */
DEFINE_TEST(test_Z1)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -Z1 %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertTextFileContents("test_basic/\ntest_basic/a\ntest_basic/b\ntest_basic/c\ntest_basic/CAPS\n", "test.out");
assertEmptyFile("test.err");
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* This test just does a basic zip decompression */
DEFINE_TEST(test_basic)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("contents a\n", "test_basic/a");
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
}

View File

@ -0,0 +1,25 @@
begin 644 test_basic.zip
M4$L#!!0``````,J0MU8````````````````+`"``=&5S=%]B87-I8R]55`T`
M!]PX;63U.6UDW#AM9'5X"P`!!.@#```$Z`,``%!+`P04``@`"``)C;=6````
M```````+````#``@`'1E<W1?8F%S:6,O8554#0`'PS)M9/HY;603.&UD=7@+
M``$$Z`,```3H`P``2\[/*TG-*RE62.0"`%!+!PAY:C`$#0````L```!02P,$
M%``(``@`#HVW5@``````````"P````P`(`!T97-T7V)A<VEC+V)55`T`!\TR
M;63Z.6UD.SAM9'5X"P`!!.@#```$Z`,``$O.SRM)S2LI5DCB`@!02P<(NCD=
M+PT````+````4$L#!!0`"``(`%*-MU8```````````L````,`"``=&5S=%]B
M87-I8R]C550-``=,,VUDTSAM9,\X;61U>`L``03H`P``!.@#``!+SL\K2<TK
M*59(Y@(`4$L'"/L(!C8-````"P```%!+`P04``@`"`#*D+=6```````````.
M````#P`@`'1E<W1?8F%S:6,O0T%04U54#0`'W#AM9/HY;63<.&UD=7@+``$$
MZ`,```3H`P``2\[/*TG-*RE6<'8,".8"`%!+!P@I4T'W$`````X```!02P$"
M%`,4``````#*D+=6````````````````"P`@````````````[4$`````=&5S
M=%]B87-I8R]55`T`!]PX;63U.6UDW#AM9'5X"P`!!.@#```$Z`,``%!+`0(4
M`Q0`"``(``F-MU9Y:C`$#0````L````,`"````````````"D@4D```!T97-T
M7V)A<VEC+V%55`T`!\,R;63Z.6UD$SAM9'5X"P`!!.@#```$Z`,``%!+`0(4
M`Q0`"``(``Z-MU:Z.1TO#0````L````,`"````````````"D@;````!T97-T
M7V)A<VEC+V)55`T`!\TR;63Z.6UD.SAM9'5X"P`!!.@#```$Z`,``%!+`0(4
M`Q0`"``(`%*-MU;["`8V#0````L````,`"````````````"D@1<!``!T97-T
M7V)A<VEC+V-55`T`!TPS;633.&UDSSAM9'5X"P`!!.@#```$Z`,``%!+`0(4
M`Q0`"``(`,J0MU8I4T'W$`````X````/`"````````````"D@7X!``!T97-T
M7V)A<VEC+T-!4%-55`T`!]PX;63Z.6UDW#AM9'5X"P`!!.@#```$Z`,``%!+
4!08`````!0`%`,0!``#K`0``````
`
end

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test d arg - extract to target dir */
DEFINE_TEST(test_d)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -d foobar %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("contents a\n", "foobar/test_basic/a");
assertTextFileContents("contents b\n", "foobar/test_basic/b");
assertTextFileContents("contents c\n", "foobar/test_basic/c");
assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS");
}

View File

@ -0,0 +1,13 @@
begin 644 test_encrypted.zip
M4$L#!!0``````'*1MU8````````````````*`"``96YC<GEP=&5D+U54#0`'
M&#IM9!LZ;608.FUD=7@+``$$Z`,```3H`P``4$L#!!0`"0!C`'*1MU8`````
M``````H````2`"L`96YC<GEP=&5D+V9I;&4N='AT550-``<8.FUD&#IM9!@Z
M;61U>`L``03H`P``!.@#```!F0<``@!!10,(`*_-)-RYPDYFJ$Q9+L<I#-><
M'#C?XVBR9/=H?7U\LC!A^8<6[&CO#PM02P<(`````"@````*````4$L!`A0#
M%```````<I&W5@````````````````H`(````````````.U!`````&5N8W)Y
M<'1E9"]55`T`!Q@Z;60;.FUD&#IM9'5X"P`!!.@#```$Z`,``%!+`0(4`Q0`
M"0!C`'*1MU8`````*`````H````2`"L```````````"D@4@```!E;F-R>7!T
M960O9FEL92YT>'155`T`!Q@Z;608.FUD&#IM9'5X"P`!!.@#```$Z`,```&9
?!P`"`$%%`P@`4$L%!@`````"``(`PP```-L`````````
`
end

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test that the glob works */
DEFINE_TEST(test_glob)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s %s test_*/[ab] >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("contents a\n", "test_basic/a");
assertTextFileContents("contents b\n", "test_basic/b");
assertFileNotExists("test_basic/c");
assertFileNotExists("test_basic/CAPS");
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test j arg - don't make directories */
DEFINE_TEST(test_j)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -j %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("contents a\n", "a");
assertTextFileContents("contents b\n", "b");
assertTextFileContents("contents c\n", "c");
assertTextFileContents("contents CAPS\n", "CAPS");
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test n arg - don't overrite existing files */
DEFINE_TEST(test_n)
{
const char *reffile = "test_basic.zip";
int r;
assertMakeDir("test_basic", 0755);
assertMakeFile("test_basic/a", 0644, "orig a\n");
assertMakeFile("test_basic/b", 0644, "orig b\n");
extract_reference_file(reffile);
r = systemf("%s -n %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("orig a\n", "test_basic/a");
assertTextFileContents("orig b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test non existant file */
DEFINE_TEST(test_not_exist)
{
int r;
r = systemf("%s nonexist.zip >test.out 2>test.err", testprog);
assert(r != 0);
assertEmptyFile("test.out");
assertNonEmptyFile("test.err");
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test o arg - overrite existing files */
DEFINE_TEST(test_o)
{
const char *reffile = "test_basic.zip";
int r;
assertMakeDir("test_basic", 0755);
assertMakeFile("test_basic/a", 0644, "orig a\n");
assertMakeFile("test_basic/b", 0644, "orig b\n");
extract_reference_file(reffile);
r = systemf("%s -o %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertEmptyFile("test.err");
assertTextFileContents("contents a\n", "test_basic/a");
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test p arg - Print to stdout */
DEFINE_TEST(test_p)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -p %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertTextFileContents("contents a\ncontents b\ncontents c\ncontents CAPS\n", "test.out");
assertEmptyFile("test.err");
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test q arg - Quiet */
DEFINE_TEST(test_q)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -q %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("contents a\n", "test_basic/a");
assertTextFileContents("contents b\n", "test_basic/b");
assertTextFileContents("contents c\n", "test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Ensure single-file zips work */
DEFINE_TEST(test_singlefile)
{
const char *reffile = "test_singlefile.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("hello\n", "file.txt");
}

View File

@ -0,0 +1,8 @@
begin 644 test_singlefile.zip
M4$L#!!0`"``(`&"6MU8```````````8````(`"``9FEL92YT>'155`T`!U1#
M;6140VUD5$-M9'5X"P`!!.@#```$Z`,``,M(S<G)YP(`4$L'""`P.C8(````
M!@```%!+`0(4`Q0`"``(`&"6MU8@,#HV"`````8````(`"````````````"D
M@0````!F:6QE+G1X=%54#0`'5$-M9%1#;6140VUD=7@+``$$Z`,```3H`P``
64$L%!@`````!``$`5@```%X`````````
`
end

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test t arg - Test zip contents */
DEFINE_TEST(test_t)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -t %s >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test t arg - Test zip contents, but fail! */
DEFINE_TEST(test_t_bad)
{
const char *reffile = "test_t_bad.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s -t %s >test.out 2>test.err", testprog, reffile);
assert(r != 0);
assertNonEmptyFile("test.out");
assertNonEmptyFile("test.err");
}

View File

@ -0,0 +1,25 @@
begin 644 test_t_bad.zip
M4$L#!!0``````,J0MU8````````````````+`"``=&5S=%]B87-I8R]55`T`
M!]PX;63U.6UDW#AM9'5X"P`!!.@#```$Z`,``%!+`P04``@`"``)C;=6````
M```````+````#``@`'1E<W1?8F%S:6,O85546``'PS)M9/HY;603.&UD=7@+
M``$$Z`,```3H`P``2\[/*TG-*RE62.0"`%!+!PAY:C`$#0````L```!02P,$
M%&$(``@`#HVW5@``````````"P````P`(`!T97-T7V)A<VEC+V)55`T`!\TR
M;63Z.6UD.SAM9'5X"P`!!.@#```$Z`,``$O.SRM)S2LI5DCB`@!02P<(NCD=
M+PT````+````4$L#!!0`"``(`%*-MU8```````````L````,`"``=&5S=%]B
M87-I8R]C550-``=,,VUDTSAM9,\X;61U>`L``03H`P``!.@#``!+SL\K2<TK
M*59(Y@(`4$L'"/L(!C8-````"P```%!+`P04``@`"`#*D+=6```````````.
M````#P`@`'1E<W1?8F%S:6,O0T%04U54#0`'W#AM9/HY;63<.&UD=7@+``$$
MZ`,```3H`P``2\[/*TG-*RE6<'8,".8"`%!+!P@I4T'W$`````X```!02P$"
M%`,4``````#*D+=6````````````````"P`@````````````[4(`````=&5S
M=%]B87-I8R]55`T`!]PX;63U.6UDW#AM9'5X"P`!!.@#```$Z`,``%!+`0(4
M`Q0`"``(``F-MU9Y:C`$#0````L````,`"````````````"D@4D```!T97-T
M7V)A<VEC+V%55`T`!\,R;63Z.6UD$SAM9'5X"P`!!.@#```$Z`,``%!+`0(4
M`Q0`"``(``Z-MU:Z.1TO#0````L````,`"````````````"D@;````!T97-T
M7V)A<VEC+V)55`T`!\TR;63Z.6UD.SAM9'5X"P`!!.@#```$Z`,``%!+`0(4
M`Q0`"``(`%*-MU;["`8V#0````L````,`"````````````"D@1<!``!T97-T
M7V)A<VEC+V-55`T`!TPS;633.&UDSSAM9'5X"P`!!.@#```$Z`,``%!+`0(4
M`Q0`"``(`,J0MU8I4T'W$`````X````/`"````````````"D@7X!``!T97-T
M7V)A<VEC+T-!4%-55`T`!]PX;63Z.6UDW#AM9'5X"P`!!.@#```$Z`,``%!+
5!08`````!0`%`,0!``#K`0`````*
`
end

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 Adrian Vovk
* All rights reserved.
*
* 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
* in this position and unchanged.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h"
/* Test x arg - Exclude paths */
DEFINE_TEST(test_x)
{
const char *reffile = "test_basic.zip";
int r;
extract_reference_file(reffile);
r = systemf("%s %s -x test_basic/c >test.out 2>test.err", testprog, reffile);
assertEqualInt(0, r);
assertNonEmptyFile("test.out");
assertEmptyFile("test.err");
assertTextFileContents("contents a\n", "test_basic/a");
assertTextFileContents("contents b\n", "test_basic/b");
assertFileNotExists("test_basic/c");
assertTextFileContents("contents CAPS\n", "test_basic/CAPS");
}

View File

@ -432,6 +432,7 @@ ${PACKAGE}FILES+= test_read_format_7zip_bcj2_copy_1.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_bcj2_copy_2.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_bcj2_copy_lzma.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_bcj2_deflate.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_deflate_arm64.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_bcj2_lzma1_1.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_bcj2_lzma1_2.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_bcj2_lzma2_1.7z.uu
@ -458,11 +459,18 @@ ${PACKAGE}FILES+= test_read_format_7zip_lzma1.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_lzma1_2.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_lzma1_lzma2.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_lzma2.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_lzma2_arm.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_lzma2_arm64.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_malformed.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_malformed2.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_packinfo_digests.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_ppmd.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_solid_zstd.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_symbolic_name.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_zstd.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_zstd_arm.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_zstd_bcj.7z.uu
${PACKAGE}FILES+= test_read_format_7zip_zstd_nobcj.7z.uu
${PACKAGE}FILES+= test_read_format_ar.ar.uu
${PACKAGE}FILES+= test_read_format_cab_1.cab.uu
${PACKAGE}FILES+= test_read_format_cab_2.cab.uu