diff options
Diffstat (limited to 'contrib')
104 files changed, 1106 insertions, 540 deletions
diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS index caca7d5cbdb9..f2dd4102fa04 100644 --- a/contrib/libarchive/NEWS +++ b/contrib/libarchive/NEWS @@ -1,3 +1,5 @@ +Oct 15, 2026: libarchive 3.8.2 released + Jun 01, 2026: libarchive 3.8.1 released May 20, 2025: libarchive 3.8.0 released diff --git a/contrib/libarchive/SECURITY.md b/contrib/libarchive/SECURITY.md index 6ca188b603fe..f2f60e792a57 100644 --- a/contrib/libarchive/SECURITY.md +++ b/contrib/libarchive/SECURITY.md @@ -16,4 +16,4 @@ Please provide the following information in your report: - 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. +that you give us 90 days to work on a fix before public exposure. diff --git a/contrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh b/contrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh index 2aa4823fc3d0..b33aed5e5562 100755 --- a/contrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh +++ b/contrib/libarchive/build/ci/github_actions/install-macos-dependencies.sh @@ -5,6 +5,9 @@ set -eux #brew update > /dev/null #brew upgrade > /dev/null +# Workaround for cmake in local/pinned tap issue +brew uninstall cmake + # This does an upgrade if the package is already installed brew install \ autoconf \ diff --git a/contrib/libarchive/cat/bsdcat.c b/contrib/libarchive/cat/bsdcat.c index 731621fa9b75..2e78870ae50e 100644 --- a/contrib/libarchive/cat/bsdcat.c +++ b/contrib/libarchive/cat/bsdcat.c @@ -7,6 +7,9 @@ #include "bsdcat_platform.h" +#ifdef HAVE_SIGNAL_H +#include <signal.h> +#endif #include <stdio.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> @@ -22,7 +25,7 @@ #include <archive_entry.h> #include "bsdcat.h" -#include "err.h" +#include "lafe_err.h" #define BYTES_PER_BLOCK (20*512) @@ -105,6 +108,16 @@ main(int argc, char **argv) bsdcat = &bsdcat_storage; memset(bsdcat, 0, sizeof(*bsdcat)); +#if defined(HAVE_SIGACTION) && defined(SIGCHLD) + { /* Do not ignore SIGCHLD. */ + struct sigaction sa; + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGCHLD, &sa, NULL); + } +#endif + lafe_setprogname(*argv, "bsdcat"); bsdcat->argv = argv; diff --git a/contrib/libarchive/cat/cmdline.c b/contrib/libarchive/cat/cmdline.c index 8ecd74aa95e4..5a5fcaf0263f 100644 --- a/contrib/libarchive/cat/cmdline.c +++ b/contrib/libarchive/cat/cmdline.c @@ -22,7 +22,7 @@ #endif #include "bsdcat.h" -#include "err.h" +#include "lafe_err.h" /* * Short options for bsdcat. Please keep this sorted. diff --git a/contrib/libarchive/cpio/cmdline.c b/contrib/libarchive/cpio/cmdline.c index c67519947dbc..db06c03c011d 100644 --- a/contrib/libarchive/cpio/cmdline.c +++ b/contrib/libarchive/cpio/cmdline.c @@ -26,7 +26,7 @@ #endif #include "cpio.h" -#include "err.h" +#include "lafe_err.h" /* * Short options for cpio. Please keep this sorted. diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c index 2bf1bfa2985a..262db510568b 100644 --- a/contrib/libarchive/cpio/cpio.c +++ b/contrib/libarchive/cpio/cpio.c @@ -60,7 +60,7 @@ #endif #include "cpio.h" -#include "err.h" +#include "lafe_err.h" #include "line_reader.h" #include "passphrase.h" @@ -124,13 +124,21 @@ main(int argc, char *argv[]) cpio->buff_size = sizeof(buff); -#if defined(HAVE_SIGACTION) && defined(SIGPIPE) - { /* Ignore SIGPIPE signals. */ +#if defined(HAVE_SIGACTION) + { struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; +#ifdef SIGPIPE + /* Ignore SIGPIPE signals. */ sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, NULL); +#endif +#ifdef SIGCHLD + /* Do not ignore SIGCHLD. */ + sa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sa, NULL); +#endif } #endif diff --git a/contrib/libarchive/cpio/test/test_owner_parse.c b/contrib/libarchive/cpio/test/test_owner_parse.c index dfc78ca77aec..bd68f21cec9b 100644 --- a/contrib/libarchive/cpio/test/test_owner_parse.c +++ b/contrib/libarchive/cpio/test/test_owner_parse.c @@ -7,7 +7,7 @@ #include "test.h" #include "../cpio.h" -#include "err.h" +#include "lafe_err.h" #if !defined(_WIN32) #define ROOT "root" diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h index 002190a24663..98d7674e18f1 100644 --- a/contrib/libarchive/libarchive/archive.h +++ b/contrib/libarchive/libarchive/archive.h @@ -34,7 +34,7 @@ * assert that ARCHIVE_VERSION_NUMBER >= 2012108. */ /* Note: Compiler will complain if this does not match archive_entry.h! */ -#define ARCHIVE_VERSION_NUMBER 3008001 +#define ARCHIVE_VERSION_NUMBER 3008002 #include <sys/stat.h> #include <stddef.h> /* for wchar_t */ @@ -177,7 +177,7 @@ __LA_DECL int archive_version_number(void); /* * Textual name/version of the library, useful for version displays. */ -#define ARCHIVE_VERSION_ONLY_STRING "3.8.1" +#define ARCHIVE_VERSION_ONLY_STRING "3.8.2" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); diff --git a/contrib/libarchive/libarchive/archive_acl.c b/contrib/libarchive/libarchive/archive_acl.c index 9e71f5ee5610..362e3308f43f 100644 --- a/contrib/libarchive/libarchive/archive_acl.c +++ b/contrib/libarchive/libarchive/archive_acl.c @@ -270,6 +270,19 @@ acl_new_entry(struct archive_acl *acl, { struct archive_acl_entry *ap, *aq; + /* Reject an invalid type */ + switch (type) { + case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: + case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: + case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: + case ARCHIVE_ENTRY_ACL_TYPE_DENY: + case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: + case ARCHIVE_ENTRY_ACL_TYPE_ALARM: + break; + default: + return (NULL); + } + /* Type argument must be a valid NFS4 or POSIX.1e type. * The type must agree with anything already set and * the permset must be compatible. */ @@ -822,6 +835,9 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type, wname = NULL; id = -1; break; + default: + **wp = '\0'; + break; } *wp += wcslen(*wp); *(*wp)++ = L':'; @@ -878,6 +894,7 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type, wcscpy(*wp, L"alarm"); break; default: + *(*wp) = L'\0'; break; } *wp += wcslen(*wp); @@ -1057,6 +1074,9 @@ append_entry(char **p, const char *prefix, int type, name = NULL; id = -1; break; + default: + **p = '\0'; + break; } *p += strlen(*p); *(*p)++ = ':'; @@ -1112,6 +1132,9 @@ append_entry(char **p, const char *prefix, int type, case ARCHIVE_ENTRY_ACL_TYPE_ALARM: strcpy(*p, "alarm"); break; + default: + *(*p) = '\0'; + break; } *p += strlen(*p); } diff --git a/contrib/libarchive/libarchive/archive_check_magic.c b/contrib/libarchive/libarchive/archive_check_magic.c index d12f0c496e27..6b8e0c5595f4 100644 --- a/contrib/libarchive/libarchive/archive_check_magic.c +++ b/contrib/libarchive/libarchive/archive_check_magic.c @@ -30,6 +30,7 @@ #endif #include <stdio.h> +#include <errno.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif @@ -54,8 +55,14 @@ errmsg(const char *m) while (s > 0) { written = write(2, m, s); - if (written <= 0) + if (written == 0) return; + if (written < 0) + { + if (errno == EINTR) + continue; + return; + } m += written; s -= written; } diff --git a/contrib/libarchive/libarchive/archive_cryptor.c b/contrib/libarchive/libarchive/archive_cryptor.c index 1825af4dc510..9f03f9ca6dd0 100644 --- a/contrib/libarchive/libarchive/archive_cryptor.c +++ b/contrib/libarchive/libarchive/archive_cryptor.c @@ -151,7 +151,7 @@ pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, (void)rounds; /* UNUSED */ (void)derived_key; /* UNUSED */ (void)derived_key_len; /* UNUSED */ - return -1; /* UNSUPPORTED */ + return CRYPTOR_STUB_FUNCTION; /* UNSUPPORTED */ } #endif @@ -439,14 +439,14 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) (void)ctx; /* UNUSED */ (void)key; /* UNUSED */ (void)key_len; /* UNUSED */ - return -1; + return CRYPTOR_STUB_FUNCTION; } static int aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) { (void)ctx; /* UNUSED */ - return -1; + return CRYPTOR_STUB_FUNCTION; } static int @@ -469,7 +469,7 @@ aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in, (void)out; /* UNUSED */ (void)out_len; /* UNUSED */ aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */ - return -1; + return CRYPTOR_STUB_FUNCTION; } #else diff --git a/contrib/libarchive/libarchive/archive_cryptor_private.h b/contrib/libarchive/libarchive/archive_cryptor_private.h index 4b3c6c161433..1dbc5c17a01a 100644 --- a/contrib/libarchive/libarchive/archive_cryptor_private.h +++ b/contrib/libarchive/libarchive/archive_cryptor_private.h @@ -43,7 +43,7 @@ int __libarchive_cryptor_build_hack(void); #ifdef __APPLE__ # include <AvailabilityMacros.h> # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 -# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto +# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto 1 # endif #endif @@ -144,9 +144,15 @@ typedef struct { #else +#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\ + defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\ + defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\ + defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\ + defined(ARCHIVE_CRYPTO_SHA512_WIN) #if defined(_WIN32) && !defined(__CYGWIN__) && !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA) #define ARCHIVE_CRYPTOR_USE_WINCRYPT 1 #endif +#endif #define AES_BLOCK_SIZE 16 #define AES_MAX_KEY_SIZE 32 @@ -172,6 +178,9 @@ typedef int archive_crypto_ctx; #define archive_encrypto_aes_ctr_release(ctx) \ __archive_cryptor.encrypto_aes_ctr_release(ctx) +/* Stub return value if no encryption support exists. */ +#define CRYPTOR_STUB_FUNCTION -2 + /* Minimal interface to cryptographic functionality for internal use in * libarchive */ struct archive_cryptor diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h index 2b917b3fde8e..344f33bffac2 100644 --- a/contrib/libarchive/libarchive/archive_entry.h +++ b/contrib/libarchive/libarchive/archive_entry.h @@ -28,7 +28,7 @@ #define ARCHIVE_ENTRY_H_INCLUDED /* Note: Compiler will complain if this does not match archive.h! */ -#define ARCHIVE_VERSION_NUMBER 3008001 +#define ARCHIVE_VERSION_NUMBER 3008002 /* * Note: archive_entry.h is for use outside of libarchive; the diff --git a/contrib/libarchive/libarchive/archive_entry_paths.3 b/contrib/libarchive/libarchive/archive_entry_paths.3 index 0f849c9ebb35..f739b172308d 100644 --- a/contrib/libarchive/libarchive/archive_entry_paths.3 +++ b/contrib/libarchive/libarchive/archive_entry_paths.3 @@ -64,7 +64,7 @@ Streaming Archive Library (libarchive, -larchive) .Ft void .Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path" .Ft void -.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path" +.Fn archive_entry_copy_hardlink_w "struct archive_entry *a" "const wchar_t *path" .Ft int .Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path" .Ft void diff --git a/contrib/libarchive/libarchive/archive_entry_stat.c b/contrib/libarchive/libarchive/archive_entry_stat.c index c4906838ed0f..345d3d29b2f2 100644 --- a/contrib/libarchive/libarchive/archive_entry_stat.c +++ b/contrib/libarchive/libarchive/archive_entry_stat.c @@ -38,6 +38,7 @@ const struct stat * archive_entry_stat(struct archive_entry *entry) { + int64_t size; struct stat *st; if (entry->stat == NULL) { entry->stat = calloc(1, sizeof(*st)); @@ -74,7 +75,10 @@ archive_entry_stat(struct archive_entry *entry) st->st_ino = (ino_t)archive_entry_ino64(entry); st->st_nlink = archive_entry_nlink(entry); st->st_rdev = archive_entry_rdev(entry); - st->st_size = (off_t)archive_entry_size(entry); + size = archive_entry_size(entry); + st->st_size = (off_t)size; + if (st->st_size < 0 || (int64_t)st->st_size != size) + st->st_size = 0; st->st_mode = archive_entry_mode(entry); /* diff --git a/contrib/libarchive/libarchive/archive_parse_date.c b/contrib/libarchive/libarchive/archive_parse_date.c index cda0b11a555f..d9e968387d34 100644 --- a/contrib/libarchive/libarchive/archive_parse_date.c +++ b/contrib/libarchive/libarchive/archive_parse_date.c @@ -703,9 +703,7 @@ Convert(time_t Month, time_t Day, time_t Year, Year += 1900; DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 29 : 28; - /* Checking for 2038 bogusly assumes that time_t is 32 bits. But - I'm too lazy to try to check for time_t overflow in another way. */ - if (Year < EPOCH || Year >= 2038 + if (Year < EPOCH || (sizeof(time_t) <= 4 && Year >= 2038) || Month < 1 || Month > 12 /* Lint fluff: "conversion from long may lose accuracy" */ || Day < 1 || Day > DaysInMonth[(int)--Month] diff --git a/contrib/libarchive/libarchive/archive_platform.h b/contrib/libarchive/libarchive/archive_platform.h index f30df1104c83..33dc5582b7ed 100644 --- a/contrib/libarchive/libarchive/archive_platform.h +++ b/contrib/libarchive/libarchive/archive_platform.h @@ -183,16 +183,6 @@ #define CAN_RESTORE_METADATA_FD #endif -/* - * glibc 2.24 deprecates readdir_r - * bionic c deprecates readdir_r too - */ -#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__)) -#define USE_READDIR_R 1 -#else -#undef USE_READDIR_R -#endif - /* Set up defaults for internal error codes. */ #ifndef ARCHIVE_ERRNO_FILE_FORMAT #if HAVE_EFTYPE diff --git a/contrib/libarchive/libarchive/archive_platform_stat.h b/contrib/libarchive/libarchive/archive_platform_stat.h new file mode 100644 index 000000000000..5432b2f6433a --- /dev/null +++ b/contrib/libarchive/libarchive/archive_platform_stat.h @@ -0,0 +1,45 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 Tobias Stoeckmann + * All rights reserved. + */ + +/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */ + +#ifndef ARCHIVE_PLATFORM_STAT_H_INCLUDED +#define ARCHIVE_PLATFORM_STAT_H_INCLUDED + +#ifndef __LIBARCHIVE_BUILD +#error This header is only to be used internally to libarchive. +#endif + +#if defined(_WIN32) && !defined(__CYGWIN__) +/* We use _lseeki64() on Windows. */ +typedef int64_t la_seek_t; + +struct la_seek_stat { + int64_t st_mtime; + ino_t st_ino; + unsigned short st_mode; + uint32_t st_nlink; + gid_t st_gid; + la_seek_t st_size; + uid_t st_uid; + dev_t st_dev; + dev_t st_rdev; +}; +typedef struct la_seek_stat la_seek_stat_t; + +#define la_seek_fstat(fd, st) __la_seek_fstat((fd), (st)) +#define la_seek_stat(fd, st) __la_seek_stat((fd), (st)) + +#else +typedef off_t la_seek_t; +typedef struct stat la_seek_stat_t; + +#define la_seek_fstat(fd, st) fstat((fd), (st)) +#define la_seek_stat(fd, st) stat((fd), (st)) +#endif + +#endif /* !ARCHIVE_PLATFORM_STAT_H_INCLUDED */ diff --git a/contrib/libarchive/libarchive/archive_private.h b/contrib/libarchive/libarchive/archive_private.h index 050fc63c0b2e..3a926c6886ad 100644 --- a/contrib/libarchive/libarchive/archive_private.h +++ b/contrib/libarchive/libarchive/archive_private.h @@ -158,6 +158,7 @@ int __archive_check_magic(struct archive *, unsigned int magic, __LA_NORETURN void __archive_errx(int retvalue, const char *msg); void __archive_ensure_cloexec_flag(int fd); +int __archive_get_tempdir(struct archive_string *); int __archive_mktemp(const char *tmpdir); #if defined(_WIN32) && !defined(__CYGWIN__) int __archive_mkstemp(wchar_t *templates); diff --git a/contrib/libarchive/libarchive/archive_read.c b/contrib/libarchive/libarchive/archive_read.c index 50db87017706..c9b9d5981516 100644 --- a/contrib/libarchive/libarchive/archive_read.c +++ b/contrib/libarchive/libarchive/archive_read.c @@ -575,8 +575,7 @@ choose_filters(struct archive_read *a) return (ARCHIVE_OK); } - filter - = calloc(1, sizeof(*filter)); + filter = calloc(1, sizeof(*filter)); if (filter == NULL) return (ARCHIVE_FATAL); filter->bidder = best_bidder; @@ -834,7 +833,9 @@ archive_read_data(struct archive *_a, void *buff, size_t s) r = archive_read_data_block(a, &read_buf, &a->read_data_remaining, &a->read_data_offset); a->read_data_block = read_buf; - if (r == ARCHIVE_EOF) + if (r == ARCHIVE_EOF && + a->read_data_offset == a->read_data_output_offset && + a->read_data_remaining == 0) return (bytes_read); /* * Error codes are all negative, so the status diff --git a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c index 19d049770b78..42af4034b07e 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c @@ -338,7 +338,7 @@ setup_mac_metadata(struct archive_read_disk *a, int ret = ARCHIVE_OK; void *buff = NULL; int have_attrs; - const char *name, *tempdir; + const char *name; struct archive_string tempfile; (void)fd; /* UNUSED */ @@ -357,13 +357,11 @@ setup_mac_metadata(struct archive_read_disk *a, if (have_attrs == 0) return (ARCHIVE_OK); - tempdir = NULL; - if (issetugid() == 0) - tempdir = getenv("TMPDIR"); - if (tempdir == NULL) - tempdir = _PATH_TMP; archive_string_init(&tempfile); - archive_strcpy(&tempfile, tempdir); + if (__archive_get_tempdir(&tempfile) != ARCHIVE_OK) { + ret = ARCHIVE_WARN; + goto cleanup; + } archive_strcat(&tempfile, "tar.md.XXXXXX"); tempfd = mkstemp(tempfile.s); if (tempfd < 0) { diff --git a/contrib/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libarchive/libarchive/archive_read_disk_posix.c index a7a98e9cb1cd..54a8e66188f8 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_read_disk_posix.c @@ -168,9 +168,6 @@ struct filesystem { int synthetic; int remote; int noatime; -#if defined(USE_READDIR_R) - size_t name_max; -#endif long incr_xfer_size; long max_xfer_size; long min_xfer_size; @@ -203,10 +200,6 @@ struct tree { DIR *d; #define INVALID_DIR_HANDLE NULL struct dirent *de; -#if defined(USE_READDIR_R) - struct dirent *dirent; - size_t dirent_allocated; -#endif int flags; int visit_type; /* Error code from last failed operation. */ @@ -869,7 +862,7 @@ next_entry(struct archive_read_disk *a, struct tree *t, tree_enter_initial_dir(t); return (ARCHIVE_FATAL); case TREE_ERROR_DIR: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + archive_set_error(&a->archive, t->tree_errno, "%s: Couldn't visit directory", tree_current_path(t)); tree_enter_initial_dir(t); @@ -1578,9 +1571,6 @@ setup_current_filesystem(struct archive_read_disk *a) # endif #endif int r, xr = 0; -#if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX) - long nm; -#endif t->current_filesystem->synthetic = -1; t->current_filesystem->remote = -1; @@ -1647,35 +1637,6 @@ setup_current_filesystem(struct archive_read_disk *a) #endif t->current_filesystem->noatime = 0; -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX) - t->current_filesystem->name_max = sfs.f_namemax; -#else -# if defined(_PC_NAME_MAX) - /* Mac OS X does not have f_namemax in struct statfs. */ - if (tree_current_is_symblic_link_target(t)) { - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); - } else - nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); -# else - nm = -1; -# endif - if (nm == -1) - t->current_filesystem->name_max = NAME_MAX; - 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); } @@ -1863,19 +1824,6 @@ setup_current_filesystem(struct archive_read_disk *a) #endif t->current_filesystem->noatime = 0; -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -#if defined(HAVE_STATVFS) - t->current_filesystem->name_max = svfs.f_namemax; -#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); } @@ -1953,15 +1901,6 @@ setup_current_filesystem(struct archive_read_disk *a) #endif t->current_filesystem->noatime = 0; -#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); } @@ -1975,9 +1914,6 @@ static int setup_current_filesystem(struct archive_read_disk *a) { struct tree *t = a->tree; -#if defined(_PC_NAME_MAX) && defined(USE_READDIR_R) - long nm; -#endif t->current_filesystem->synthetic = -1;/* Not supported */ t->current_filesystem->remote = -1;/* Not supported */ t->current_filesystem->noatime = 0; @@ -1987,40 +1923,6 @@ setup_current_filesystem(struct archive_read_disk *a) t->current_filesystem->min_xfer_size = -1; t->current_filesystem->incr_xfer_size = -1; -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -# if defined(_PC_NAME_MAX) - if (tree_current_is_symblic_link_target(t)) { - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); - } else - nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); - if (nm == -1) -# endif /* _PC_NAME_MAX */ - /* - * Some systems (HP-UX or others?) incorrectly defined - * NAME_MAX macro to be a smaller value. - */ -# if defined(NAME_MAX) && NAME_MAX >= 255 - t->current_filesystem->name_max = NAME_MAX; -# else - /* No way to get a trusted value of maximum filename - * length. */ - t->current_filesystem->name_max = PATH_MAX; -# endif /* NAME_MAX */ -# if defined(_PC_NAME_MAX) - 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); } @@ -2112,8 +2014,11 @@ tree_dup(int fd) } #endif /* F_DUPFD_CLOEXEC */ new_fd = dup(fd); - __archive_ensure_cloexec_flag(new_fd); - return (new_fd); + if (new_fd != -1) { + __archive_ensure_cloexec_flag(new_fd); + return (new_fd); + } + return (-1); } /* @@ -2235,11 +2140,16 @@ tree_reopen(struct tree *t, const char *path, int restore_time) * so try again for execute. The consequences of not opening this are * unhelpful and unnecessary errors later. */ - if (t->initial_dir_fd < 0) + if (t->initial_dir_fd < 0) { t->initial_dir_fd = open(".", o_flag | O_CLOEXEC); + if (t->initial_dir_fd < 0) + return NULL; + } #endif __archive_ensure_cloexec_flag(t->initial_dir_fd); t->working_dir_fd = tree_dup(t->initial_dir_fd); + if (t->working_dir_fd < 0) + return NULL; return (t); } @@ -2449,12 +2359,11 @@ tree_dir_next_posix(struct tree *t) size_t namelen; if (t->d == NULL) { -#if defined(USE_READDIR_R) - size_t dirent_size; -#endif #if defined(HAVE_FDOPENDIR) - t->d = fdopendir(tree_dup(t->working_dir_fd)); + int fd = tree_dup(t->working_dir_fd); + if (fd != -1) + t->d = fdopendir(fd); #else /* HAVE_FDOPENDIR */ if (tree_enter_working_dir(t) == 0) { t->d = opendir("."); @@ -2470,45 +2379,12 @@ tree_dir_next_posix(struct tree *t) t->visit_type = r != 0 ? r : TREE_ERROR_DIR; return (t->visit_type); } -#if defined(USE_READDIR_R) - dirent_size = offsetof(struct dirent, d_name) + - t->filesystem_table[t->current->filesystem_id].name_max + 1; - if (t->dirent == NULL || t->dirent_allocated < dirent_size) { - free(t->dirent); - t->dirent = malloc(dirent_size); - if (t->dirent == NULL) { - closedir(t->d); - t->d = INVALID_DIR_HANDLE; - (void)tree_ascend(t); - tree_pop(t); - t->tree_errno = ENOMEM; - t->visit_type = TREE_ERROR_DIR; - return (t->visit_type); - } - t->dirent_allocated = dirent_size; - } -#endif /* USE_READDIR_R */ } for (;;) { errno = 0; -#if defined(USE_READDIR_R) - r = readdir_r(t->d, t->dirent, &t->de); -#ifdef _AIX - /* Note: According to the man page, return value 9 indicates - * that the readdir_r was not successful and the error code - * is set to the global errno variable. And then if the end - * of directory entries was reached, the return value is 9 - * and the third parameter is set to NULL and errno is - * unchanged. */ - if (r == 9) - r = errno; -#endif /* _AIX */ - if (r != 0 || t->de == NULL) { -#else t->de = readdir(t->d); if (t->de == NULL) { r = errno; -#endif closedir(t->d); t->d = INVALID_DIR_HANDLE; if (r != 0) { @@ -2747,9 +2623,6 @@ tree_free(struct tree *t) if (t == NULL) return; archive_string_free(&t->path); -#if defined(USE_READDIR_R) - free(t->dirent); -#endif free(t->sparse_list); for (i = 0; i < t->max_filesystem_id; i++) free(t->filesystem_table[i].allocation_ptr); diff --git a/contrib/libarchive/libarchive/archive_read_open_fd.c b/contrib/libarchive/libarchive/archive_read_open_fd.c index dc7c9e52c6f6..c85a62a3e2d7 100644 --- a/contrib/libarchive/libarchive/archive_read_open_fd.c +++ b/contrib/libarchive/libarchive/archive_read_open_fd.c @@ -48,6 +48,7 @@ #endif #include "archive.h" +#include "archive_platform_stat.h" struct read_fd_data { int fd; @@ -65,12 +66,12 @@ static int64_t file_skip(struct archive *, void *, int64_t request); int archive_read_open_fd(struct archive *a, int fd, size_t block_size) { - struct stat st; + la_seek_stat_t st; struct read_fd_data *mine; void *b; archive_clear_error(a); - if (fstat(fd, &st) != 0) { + if (la_seek_fstat(fd, &st) != 0) { archive_set_error(a, errno, "Can't stat fd %d", fd); return (ARCHIVE_FATAL); } @@ -133,7 +134,7 @@ static int64_t file_skip(struct archive *a, void *client_data, int64_t request) { struct read_fd_data *mine = (struct read_fd_data *)client_data; - off_t skip = (off_t)request; + la_seek_t skip = (la_seek_t)request; int64_t old_offset, new_offset; int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */ @@ -149,7 +150,8 @@ file_skip(struct archive *a, void *client_data, int64_t request) } /* Reduce 'skip' to the next smallest multiple of block_size */ - skip = (off_t)(((int64_t)skip / mine->block_size) * mine->block_size); + skip = (la_seek_t)(((int64_t)skip / mine->block_size) * mine->block_size); + if (skip == 0) return (0); @@ -185,27 +187,28 @@ static int64_t file_seek(struct archive *a, void *client_data, int64_t request, int whence) { struct read_fd_data *mine = (struct read_fd_data *)client_data; - off_t seek = (off_t)request; + la_seek_t seek = (la_seek_t)request; int64_t r; int seek_bits = sizeof(seek) * 8 - 1; /* off_t is a signed type. */ /* We use off_t here because lseek() is declared that way. */ - /* Reduce a request that would overflow the 'seek' variable. */ + /* Do not perform a seek which cannot be fulfilled. */ if (sizeof(request) > sizeof(seek)) { const int64_t max_seek = (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1; const int64_t min_seek = ~max_seek; - if (request > max_seek) - seek = (off_t)max_seek; - else if (request < min_seek) - seek = (off_t)min_seek; + if (request < min_seek || request > max_seek) { + errno = EOVERFLOW; + goto err; + } } r = lseek(mine->fd, seek, whence); if (r >= 0) return r; +err: if (errno == ESPIPE) { archive_set_error(a, errno, "A file descriptor(%d) is not seekable(PIPE)", mine->fd); diff --git a/contrib/libarchive/libarchive/archive_read_open_file.c b/contrib/libarchive/libarchive/archive_read_open_file.c index 742923abbee9..6ca2ff191aa8 100644 --- a/contrib/libarchive/libarchive/archive_read_open_file.c +++ b/contrib/libarchive/libarchive/archive_read_open_file.c @@ -48,6 +48,7 @@ #endif #include "archive.h" +#include "archive_platform_stat.h" struct read_FILE_data { FILE *f; @@ -65,7 +66,7 @@ static int64_t FILE_skip(struct archive *, void *, int64_t); int archive_read_open_FILE(struct archive *a, FILE *f) { - struct stat st; + la_seek_stat_t st; struct read_FILE_data *mine; size_t block_size = 128 * 1024; void *b; @@ -88,7 +89,7 @@ archive_read_open_FILE(struct archive *a, FILE *f) * streams that don't support fileno()). As a result, fileno() * should be used cautiously.) */ - if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) { + if (la_seek_fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) { archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); /* Enable the seek optimization only for regular files. */ mine->can_skip = 1; @@ -205,15 +206,15 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence) int seek_bits = sizeof(seek) * 8 - 1; (void)a; /* UNUSED */ - /* Reduce a request that would overflow the 'seek' variable. */ + /* Do not perform a seek which cannot be fulfilled. */ if (sizeof(request) > sizeof(seek)) { const int64_t max_seek = (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1; const int64_t min_seek = ~max_seek; - if (request > max_seek) - seek = max_seek; - else if (request < min_seek) - seek = min_seek; + if (request < min_seek || request > max_seek) { + errno = EOVERFLOW; + goto err; + } } #ifdef __ANDROID__ @@ -236,6 +237,7 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence) } #endif /* If we arrive here, the input is corrupted or truncated so fail. */ +err: archive_set_error(a, errno, "Error seeking in FILE* pointer"); return (ARCHIVE_FATAL); } diff --git a/contrib/libarchive/libarchive/archive_read_open_filename.c b/contrib/libarchive/libarchive/archive_read_open_filename.c index 5f5b3f1f7259..a910eefcbfd2 100644 --- a/contrib/libarchive/libarchive/archive_read_open_filename.c +++ b/contrib/libarchive/libarchive/archive_read_open_filename.c @@ -59,6 +59,7 @@ #endif #include "archive.h" +#include "archive_platform_stat.h" #include "archive_private.h" #include "archive_string.h" @@ -136,8 +137,10 @@ archive_read_open_filenames(struct archive *a, const char **filenames, mine->filename_type = FNT_STDIN; } else mine->filename_type = FNT_MBS; - if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) + if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) { + free(mine); return (ARCHIVE_FATAL); + } if (filenames == NULL) break; filename = *(filenames++); @@ -216,8 +219,10 @@ archive_read_open_filenames_w(struct archive *a, const wchar_t **wfilenames, archive_string_free(&fn); #endif } - if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) + if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) { + free(mine); return (ARCHIVE_FATAL); + } if (wfilenames == NULL) break; wfilename = *(wfilenames++); @@ -248,7 +253,7 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename, static int file_open(struct archive *a, void *client_data) { - struct stat st; + la_seek_stat_t st; struct read_file_data *mine = (struct read_file_data *)client_data; void *buffer; const char *filename = NULL; @@ -313,7 +318,7 @@ file_open(struct archive *a, void *client_data) goto fail; #endif } - if (fstat(fd, &st) != 0) { + if (la_seek_fstat(fd, &st) != 0) { #if defined(_WIN32) && !defined(__CYGWIN__) if (mine->filename_type == FNT_WCS) archive_set_error(a, errno, "Can't stat '%ls'", @@ -482,10 +487,11 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request) struct read_file_data *mine = (struct read_file_data *)client_data; #if defined(_WIN32) && !defined(__CYGWIN__) /* We use _lseeki64() on Windows. */ - int64_t old_offset, new_offset, skip = request; + int64_t old_offset, new_offset; #else - off_t old_offset, new_offset, skip = (off_t)request; + off_t old_offset, new_offset; #endif + la_seek_t skip = (la_seek_t)request; int skip_bits = sizeof(skip) * 8 - 1; /* We use off_t here because lseek() is declared that way. */ @@ -552,21 +558,21 @@ static int64_t file_seek(struct archive *a, void *client_data, int64_t request, int whence) { struct read_file_data *mine = (struct read_file_data *)client_data; - off_t seek = (off_t)request; + la_seek_t seek = (la_seek_t)request; int64_t r; int seek_bits = sizeof(seek) * 8 - 1; /* We use off_t here because lseek() is declared that way. */ - /* Reduce a request that would overflow the 'seek' variable. */ + /* Do not perform a seek which cannot be fulfilled. */ if (sizeof(request) > sizeof(seek)) { const int64_t max_seek = (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1; const int64_t min_seek = ~max_seek; - if (request > max_seek) - seek = (off_t)max_seek; - else if (request < min_seek) - seek = (off_t)min_seek; + if (request < min_seek || request > max_seek) { + errno = EOVERFLOW; + goto err; + } } r = lseek(mine->fd, seek, whence); @@ -574,6 +580,7 @@ file_seek(struct archive *a, void *client_data, int64_t request, int whence) return r; /* If the input is corrupted or truncated, fail. */ +err: if (mine->filename_type == FNT_STDIN) archive_set_error(a, errno, "Error seeking in stdin"); else if (mine->filename_type == FNT_MBS) diff --git a/contrib/libarchive/libarchive/archive_read_set_format.c b/contrib/libarchive/libarchive/archive_read_set_format.c index c74361b20c13..552ab12d2f92 100644 --- a/contrib/libarchive/libarchive/archive_read_set_format.c +++ b/contrib/libarchive/libarchive/archive_read_set_format.c @@ -37,7 +37,7 @@ int archive_read_set_format(struct archive *_a, int code) { int r1, r2, slots, i; - char str[10]; + const char *str; struct archive_read *a = (struct archive_read *)_a; if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK)) @@ -49,49 +49,49 @@ archive_read_set_format(struct archive *_a, int code) switch (code & ARCHIVE_FORMAT_BASE_MASK) { case ARCHIVE_FORMAT_7ZIP: - strcpy(str, "7zip"); + str = "7zip"; break; case ARCHIVE_FORMAT_AR: - strcpy(str, "ar"); + str = "ar"; break; case ARCHIVE_FORMAT_CAB: - strcpy(str, "cab"); + str = "cab"; break; case ARCHIVE_FORMAT_CPIO: - strcpy(str, "cpio"); + str = "cpio"; break; case ARCHIVE_FORMAT_EMPTY: - strcpy(str, "empty"); + str = "empty"; break; case ARCHIVE_FORMAT_ISO9660: - strcpy(str, "iso9660"); + str = "iso9660"; break; case ARCHIVE_FORMAT_LHA: - strcpy(str, "lha"); + str = "lha"; break; case ARCHIVE_FORMAT_MTREE: - strcpy(str, "mtree"); + str = "mtree"; break; case ARCHIVE_FORMAT_RAR: - strcpy(str, "rar"); + str = "rar"; break; case ARCHIVE_FORMAT_RAR_V5: - strcpy(str, "rar5"); + str = "rar5"; break; case ARCHIVE_FORMAT_RAW: - strcpy(str, "raw"); + str = "raw"; break; case ARCHIVE_FORMAT_TAR: - strcpy(str, "tar"); + str = "tar"; break; case ARCHIVE_FORMAT_WARC: - strcpy(str, "warc"); + str = "warc"; break; case ARCHIVE_FORMAT_XAR: - strcpy(str, "xar"); + str = "xar"; break; case ARCHIVE_FORMAT_ZIP: - strcpy(str, "zip"); + str = "zip"; break; default: archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_program.c b/contrib/libarchive/libarchive/archive_read_support_filter_program.c index 9e825223b26c..2c8e45302d8e 100644 --- a/contrib/libarchive/libarchive/archive_read_support_filter_program.c +++ b/contrib/libarchive/libarchive/archive_read_support_filter_program.c @@ -110,7 +110,7 @@ struct program_filter { pid_t child; #endif int exit_status; - int waitpid_return; + pid_t waitpid_return; int child_stdin, child_stdout; char *out_buf; @@ -242,16 +242,13 @@ child_stop(struct archive_read_filter *self, struct program_filter *state) state->waitpid_return = waitpid(state->child, &state->exit_status, 0); } while (state->waitpid_return == -1 && errno == EINTR); -#if defined(_WIN32) && !defined(__CYGWIN__) - CloseHandle(state->child); -#endif state->child = 0; } if (state->waitpid_return < 0) { /* waitpid() failed? This is ugly. */ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Child process exited badly"); + "Error closing child process"); return (ARCHIVE_WARN); } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c index f273f84be521..595462733104 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c @@ -80,7 +80,7 @@ /* * ELF format */ -#define ELF_HDR_MIN_LEN 0x34 +#define ELF_HDR_MIN_LEN 0x3f #define ELF_HDR_EI_CLASS_OFFSET 0x04 #define ELF_HDR_EI_DATA_OFFSET 0x05 @@ -811,6 +811,8 @@ find_elf_data_sec(struct archive_read *a) strtab_size = (*dec32)( h + e_shstrndx * e_shentsize + 0x14); } + if (strtab_size < 6 || strtab_size > SIZE_MAX) + break; /* * Read the STRTAB section to find the .data offset @@ -1391,7 +1393,8 @@ init_decompression(struct archive_read *a, struct _7zip *zip, * size to liblzma when using lzma_raw_decoder() liblzma * could correctly deal with BCJ+LZMA. But unfortunately * there is no way to do that. - * Discussion about this can be found at XZ Utils forum. + * + * Reference: https://web.archive.org/web/20240405171610/https://www.mail-archive.com/xz-devel@tukaani.org/msg00373.html */ if (coder2 != NULL) { zip->codec2 = coder2->codec; diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c index ba0e49de2408..ded13bee79a3 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c @@ -51,6 +51,7 @@ #include "archive.h" #include "archive_entry.h" #include "archive_entry_private.h" +#include "archive_platform_stat.h" #include "archive_private.h" #include "archive_rb.h" #include "archive_read_private.h" @@ -1073,6 +1074,8 @@ read_mtree(struct archive_read *a, struct mtree *mtree) /* Non-printable characters are not allowed */ for (s = p;s < p + len - 1; s++) { if (!isprint((unsigned char)*s) && *s != '\t') { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Non-printable character 0x%02X", (unsigned char)(*s)); r = ARCHIVE_FATAL; break; } @@ -1175,7 +1178,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, struct mtree *mtree, struct mtree_entry *mentry, int *use_next) { const char *path; - struct stat st_storage, *st; + la_seek_stat_t st_storage, *st; struct mtree_entry *mp; struct archive_entry *sparse_entry; int r = ARCHIVE_OK, r1, parsed_kws; @@ -1251,7 +1254,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, archive_entry_filetype(entry) == AE_IFDIR) { mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC); __archive_ensure_cloexec_flag(mtree->fd); - if (mtree->fd == -1 && ( + if (mtree->fd < 0 && ( #if defined(_WIN32) && !defined(__CYGWIN__) /* * On Windows, attempting to open a file with an @@ -1270,7 +1273,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, st = &st_storage; if (mtree->fd >= 0) { - if (fstat(mtree->fd, st) == -1) { + if (la_seek_fstat(mtree->fd, st) == -1) { archive_set_error(&a->archive, errno, "Could not fstat %s", path); r = ARCHIVE_WARN; @@ -1283,7 +1286,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, #ifdef HAVE_LSTAT else if (lstat(path, st) == -1) #else - else if (la_stat(path, st) == -1) + else if (la_seek_stat(path, st) == -1) #endif { st = NULL; @@ -2130,6 +2133,13 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, for (u = mtree->line.s + find_off; *u; ++u) { if (u[0] == '\n') { /* Ends with unescaped newline. */ + /* Check if preceded by '\r' for CRLF handling */ + if (u > mtree->line.s && u[-1] == '\r') { + /* CRLF ending - remove the '\r' */ + u[-1] = '\n'; + u[0] = '\0'; + total_size--; + } *start = mtree->line.s; return total_size; } else if (u[0] == '#') { @@ -2144,6 +2154,11 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, total_size -= 2; mtree->line.s[total_size] = '\0'; break; + } else if (u[1] == '\r' && u[2] == '\n') { + /* Trim escaped CRLF. */ + total_size -= 3; + mtree->line.s[total_size] = '\0'; + break; } else if (u[1] != '\0') { /* Skip the two-char escape sequence */ ++u; diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar.c b/contrib/libarchive/libarchive/archive_read_support_format_rar.c index 923ae5c65e17..9b401c00ba34 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_rar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_rar.c @@ -1117,8 +1117,6 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff, if (rar->entry_eof || rar->offset_seek >= rar->unp_size) { *size = 0; *offset = rar->offset; - if (*offset < rar->unp_size) - *offset = rar->unp_size; return (ARCHIVE_EOF); } @@ -1455,7 +1453,7 @@ read_header(struct archive_read *a, struct archive_entry *entry, return (ARCHIVE_FATAL); #endif } - /* If no CRC error, Go on parsing File Header. */ + /* If no CRC error, go on parsing File Header. */ p = h; endp = p + header_size - 7; memcpy(&file_header, p, sizeof(file_header)); @@ -2368,8 +2366,8 @@ parse_codes(struct archive_read *a) return (ARCHIVE_FATAL); } - /* Make sure ppmd7_contest is freed before Ppmd7_Construct - * because reading a broken file cause this abnormal sequence. */ + /* Make sure ppmd7_context is freed before Ppmd7_Construct + * because reading a broken file causes this abnormal sequence. */ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); rar->bytein.a = a; diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c index 48dde0c2e814..17e501e02e9f 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c @@ -1619,10 +1619,13 @@ static int process_head_file_extra(struct archive_read* a, { uint64_t extra_field_size; uint64_t extra_field_id = 0; - int ret = ARCHIVE_FATAL; uint64_t var_size; while(extra_data_size > 0) { + /* Make sure we won't fail if the file declares only unsupported + attributes. */ + int ret = ARCHIVE_OK; + if(!read_var(a, &extra_field_size, &var_size)) return ARCHIVE_EOF; @@ -1675,12 +1678,53 @@ static int process_head_file_extra(struct archive_read* a, if (ARCHIVE_OK != consume(a, extra_field_size)) { return ARCHIVE_EOF; } + + /* Don't fail on unsupported attribute -- we've handled it + by skipping over it. */ + ret = ARCHIVE_OK; + } + + if (ret != ARCHIVE_OK) { + /* Forward any errors signalled by the attribute parsing + functions. */ + return ret; } } - if(ret != ARCHIVE_OK) { - /* Attribute not implemented. */ - return ret; + if (extra_data_size != 0) { + /* We didn't skip everything, or we skipped too much; either way, + there's an error in this parsing function. */ + + archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, + "unsupported structure of file header extra data"); + return ARCHIVE_FATAL; + } + + return ARCHIVE_OK; +} + +static int file_entry_sanity_checks(struct archive_read* a, + size_t block_flags, uint8_t is_dir, uint64_t unpacked_size, + size_t packed_size) +{ + if (is_dir) { + const int declares_data_size = + (int) (unpacked_size != 0 || packed_size != 0); + + /* FILE entries for directories still declare HFL_DATA in block flags, + even though attaching data to such blocks doesn't make much sense. */ + if (declares_data_size) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "directory entries cannot have any data"); + return ARCHIVE_FATAL; + } + } else { + const int declares_hfl_data = (int) ((block_flags & HFL_DATA) != 0); + if (!declares_hfl_data) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "no data found in file/service block"); + return ARCHIVE_FATAL; + } } return ARCHIVE_OK; @@ -1701,6 +1745,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, int c_method = 0, c_version = 0; char name_utf8_buf[MAX_NAME_IN_BYTES]; const uint8_t* p; + int sanity_ret; enum FILE_FLAGS { DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004, @@ -1744,10 +1789,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, rar->file.bytes_remaining = data_size; } else { rar->file.bytes_remaining = 0; - - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "no data found in file/service block"); - return ARCHIVE_FATAL; } if(!read_var_sized(a, &file_flags, NULL)) @@ -1764,6 +1805,13 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, rar->file.dir = (uint8_t) ((file_flags & DIRECTORY) > 0); + sanity_ret = file_entry_sanity_checks(a, block_flags, rar->file.dir, + unpacked_size, data_size); + + if (sanity_ret != ARCHIVE_OK) { + return sanity_ret; + } + if(!read_var_sized(a, &file_attr, NULL)) return ARCHIVE_EOF; @@ -4163,7 +4211,7 @@ static int rar5_read_data(struct archive_read *a, const void **buff, * it's impossible to perform any decompression. */ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Can't decompress an entry marked as a directory"); - return ARCHIVE_FAILED; + return ARCHIVE_FATAL; } if(!rar->skip_mode && (rar->cstate.last_write_ptr > rar->file.unpacked_size)) { diff --git a/contrib/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libarchive/libarchive/archive_read_support_format_tar.c index 0c87bc6d732f..eeb2c725f6eb 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_tar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_tar.c @@ -233,7 +233,7 @@ static int tar_read_header(struct archive_read *, struct tar *, struct archive_entry *, int64_t *); static int tohex(int c); static char *url_decode(const char *, size_t); -static void tar_flush_unconsumed(struct archive_read *, int64_t *); +static int tar_flush_unconsumed(struct archive_read *, int64_t *); /* Sanity limits: These numbers should be low enough to * prevent a maliciously-crafted archive from forcing us to @@ -477,7 +477,7 @@ archive_read_format_tar_options(struct archive_read *a, * how much unconsumed data we have floating around, and to consume * anything outstanding since we're going to do read_aheads */ -static void +static int tar_flush_unconsumed(struct archive_read *a, int64_t *unconsumed) { if (*unconsumed) { @@ -490,9 +490,13 @@ tar_flush_unconsumed(struct archive_read *a, int64_t *unconsumed) memset(data, 0xff, *unconsumed); } */ - __archive_read_consume(a, *unconsumed); + int64_t consumed = __archive_read_consume(a, *unconsumed); + if (consumed != *unconsumed) { + return (ARCHIVE_FATAL); + } *unconsumed = 0; } + return (ARCHIVE_OK); } /* @@ -750,7 +754,9 @@ tar_read_header(struct archive_read *a, struct tar *tar, /* Find the next valid header record. */ while (1) { - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } /* Read 512-byte header record */ h = __archive_read_ahead(a, 512, &bytes); @@ -796,7 +802,9 @@ tar_read_header(struct archive_read *a, struct tar *tar, /* This is NOT a null block, so it must be a valid header. */ if (!checksum(a, h)) { - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } archive_set_error(&a->archive, EINVAL, "Damaged tar archive (bad header checksum)"); /* If we've read some critical information (pax headers, etc) @@ -1236,7 +1244,7 @@ header_volume(struct archive_read *a, struct tar *tar, header = (const struct archive_entry_header_ustar *)h; size = tar_atol(header->size, sizeof(header->size)); - if (size > (int64_t)pathname_limit) { + if (size < 0 || size > (int64_t)pathname_limit) { return (ARCHIVE_FATAL); } to_consume = ((size + 511) & ~511); @@ -1255,13 +1263,15 @@ read_bytes_to_string(struct archive_read *a, const void *src; /* Fail if we can't make our buffer big enough. */ - if (archive_string_ensure(as, (size_t)size+1) == NULL) { + if (archive_string_ensure(as, size + 1) == NULL) { archive_set_error(&a->archive, ENOMEM, "No memory"); return (ARCHIVE_FATAL); } - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } /* Read the body into the string. */ src = __archive_read_ahead(a, size, NULL); @@ -1272,9 +1282,9 @@ read_bytes_to_string(struct archive_read *a, *unconsumed = 0; return (ARCHIVE_FATAL); } - memcpy(as->s, src, (size_t)size); + memcpy(as->s, src, size); as->s[size] = '\0'; - as->length = (size_t)size; + as->length = size; *unconsumed += size; return (ARCHIVE_OK); } @@ -1715,7 +1725,9 @@ read_mac_metadata_blob(struct archive_read *a, * Q: Is the above idea really possible? Even * when there are GNU or pax extension entries? */ - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } data = __archive_read_ahead(a, msize, NULL); if (data == NULL) { archive_set_error(&a->archive, EINVAL, @@ -1900,7 +1912,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar, (long long)ext_size, (long long)ext_size_limit); return (ARCHIVE_WARN); } - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } /* Parse the size/name of each pax attribute in the body */ archive_string_init(&attr_name); @@ -1994,7 +2008,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar, /* Consume size, name, and `=` */ *unconsumed += p - attr_start; - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } if (value_length == 0) { archive_set_error(&a->archive, EINVAL, @@ -2017,7 +2033,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar, err = err_combine(err, r); /* Consume the `\n` that follows the pax attribute value. */ - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } p = __archive_read_ahead(a, 1, &did_read); if (p == NULL) { archive_set_error(&a->archive, EINVAL, @@ -2033,7 +2051,9 @@ header_pax_extension(struct archive_read *a, struct tar *tar, } ext_size -= 1; *unconsumed += 1; - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } } *unconsumed += ext_size + ext_padding; @@ -2290,7 +2310,9 @@ pax_attribute_read_number(struct archive_read *a, size_t value_length, int64_t * archive_string_init(&as); r = read_bytes_to_string(a, &as, value_length, &unconsumed); - tar_flush_unconsumed(a, &unconsumed); + if (tar_flush_unconsumed(a, &unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } if (r < ARCHIVE_OK) { archive_string_free(&as); *result = 0; @@ -2940,7 +2962,9 @@ header_gnutar(struct archive_read *a, struct tar *tar, /* Copy filename over (to ensure null termination). */ header = (const struct archive_entry_header_gnutar *)h; const char *existing_pathname = archive_entry_pathname(entry); - if (existing_pathname == NULL || existing_pathname[0] == '\0') { + const wchar_t *existing_wcs_pathname = archive_entry_pathname_w(entry); + if ((existing_pathname == NULL || existing_pathname[0] == '\0') + && (existing_wcs_pathname == NULL || existing_wcs_pathname[0] == L'\0')) { if (archive_entry_copy_pathname_l(entry, header->name, sizeof(header->name), tar->sconv) != 0) { err = set_conversion_failed_error(a, tar->sconv, "Pathname"); @@ -3093,7 +3117,9 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar, return (ARCHIVE_OK); do { - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } data = __archive_read_ahead(a, 512, &bytes_read); if (data == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, @@ -3283,7 +3309,9 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, int64_t *unconsumed) return (ARCHIVE_FATAL); } /* Skip rest of block... */ - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } bytes_read = tar->entry_bytes_remaining - remaining; to_skip = 0x1ff & -bytes_read; /* Fail if tar->entry_bytes_remaing would get negative */ @@ -3509,7 +3537,9 @@ readline(struct archive_read *a, struct tar *tar, const char **start, const char *s; void *p; - tar_flush_unconsumed(a, unconsumed); + if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) { + return (ARCHIVE_FATAL); + } t = __archive_read_ahead(a, 1, &bytes_read); if (bytes_read <= 0 || t == NULL) diff --git a/contrib/libarchive/libarchive/archive_read_support_format_warc.c b/contrib/libarchive/libarchive/archive_read_support_format_warc.c index 696f959c341d..d8f188cf0b44 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_warc.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_warc.c @@ -405,7 +405,7 @@ _warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off) /* it's our lucky day, no work, we can leave early */ *buf = NULL; *bsz = 0U; - *off = w->cntoff + 4U/*for \r\n\r\n separator*/; + *off = w->cntoff; w->unconsumed = 0U; return (ARCHIVE_EOF); } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_xar.c b/contrib/libarchive/libarchive/archive_read_support_format_xar.c index b4e1192ef771..36b5ab3ae04c 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_xar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_xar.c @@ -930,7 +930,7 @@ xar_read_data(struct archive_read *a, abort_read_data: *buff = NULL; *size = 0; - *offset = xar->total; + *offset = (int64_t)xar->entry_total; return (r); } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c index daf51933d687..9abd55709e3f 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c @@ -3015,8 +3015,8 @@ init_WinZip_AES_decryption(struct archive_read *a) p, salt_len, 1000, derived_key, key_len * 2 + 2); if (r != 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Decryption is unsupported due to lack of " - "crypto library"); + r == CRYPTOR_STUB_FUNCTION ? "Decryption is unsupported due " + "to lack of crypto library" : "Failed to process passphrase"); return (ARCHIVE_FAILED); } diff --git a/contrib/libarchive/libarchive/archive_string.c b/contrib/libarchive/libarchive/archive_string.c index 7437715f9122..3bb978335eb8 100644 --- a/contrib/libarchive/libarchive/archive_string.c +++ b/contrib/libarchive/libarchive/archive_string.c @@ -2015,7 +2015,7 @@ archive_strncat_l(struct archive_string *as, const void *_p, size_t n, /* We must allocate memory even if there is no data for conversion * or copy. This simulates archive_string_append behavior. */ if (length == 0) { - int tn = 1; + size_t tn = 1; if (sc != NULL && (sc->flag & SCONV_TO_UTF16)) tn = 2; if (archive_string_ensure(as, as->length + tn) == NULL) @@ -2752,7 +2752,8 @@ archive_string_append_unicode(struct archive_string *as, const void *_p, char *p, *endp; uint32_t uc; size_t w; - int n, ret = 0, ts, tm; + size_t ts, tm; + int n, ret = 0; int (*parse)(uint32_t *, const char *, size_t); size_t (*unparse)(char *, size_t, uint32_t); diff --git a/contrib/libarchive/libarchive/archive_string_sprintf.c b/contrib/libarchive/libarchive/archive_string_sprintf.c index 1c5910e0b2d3..69b0cdcd83d5 100644 --- a/contrib/libarchive/libarchive/archive_string_sprintf.c +++ b/contrib/libarchive/libarchive/archive_string_sprintf.c @@ -146,7 +146,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt, case 'z': s = va_arg(ap, ssize_t); break; default: s = va_arg(ap, int); break; } - append_int(as, s, 10); + append_int(as, s, 10); break; case 's': switch(long_flag) { diff --git a/contrib/libarchive/libarchive/archive_util.c b/contrib/libarchive/libarchive/archive_util.c index 900abd0c3c62..d048bbc94650 100644 --- a/contrib/libarchive/libarchive/archive_util.c +++ b/contrib/libarchive/libarchive/archive_util.c @@ -445,11 +445,39 @@ __archive_mkstemp(wchar_t *template) #else static int -get_tempdir(struct archive_string *temppath) +__archive_issetugid(void) { - const char *tmp; +#ifdef HAVE_ISSETUGID + return (issetugid()); +#elif HAVE_GETRESUID + uid_t ruid, euid, suid; + gid_t rgid, egid, sgid; + if (getresuid(&ruid, &euid, &suid) != 0) + return (-1); + if (ruid != euid || ruid != suid) + return (1); + if (getresgid(&ruid, &egid, &sgid) != 0) + return (-1); + if (rgid != egid || rgid != sgid) + return (1); +#elif HAVE_GETEUID + if (geteuid() != getuid()) + return (1); +#if HAVE_GETEGID + if (getegid() != getgid()) + return (1); +#endif +#endif + return (0); +} + +int +__archive_get_tempdir(struct archive_string *temppath) +{ + const char *tmp = NULL; - tmp = getenv("TMPDIR"); + if (__archive_issetugid() == 0) + tmp = getenv("TMPDIR"); if (tmp == NULL) #ifdef _PATH_TMP tmp = _PATH_TMP; @@ -476,7 +504,7 @@ __archive_mktemp(const char *tmpdir) archive_string_init(&temp_name); if (tmpdir == NULL) { - if (get_tempdir(&temp_name) != ARCHIVE_OK) + if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK) goto exit_tmpfile; } else { archive_strcpy(&temp_name, tmpdir); @@ -538,7 +566,7 @@ __archive_mktempx(const char *tmpdir, char *template) if (template == NULL) { archive_string_init(&temp_name); if (tmpdir == NULL) { - if (get_tempdir(&temp_name) != ARCHIVE_OK) + if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK) goto exit_tmpfile; } else archive_strcpy(&temp_name, tmpdir); diff --git a/contrib/libarchive/libarchive/archive_write.c b/contrib/libarchive/libarchive/archive_write.c index a8e7b63b5bfe..9b9cb196f0f9 100644 --- a/contrib/libarchive/libarchive/archive_write.c +++ b/contrib/libarchive/libarchive/archive_write.c @@ -360,7 +360,6 @@ archive_write_client_open(struct archive_write_filter *f) struct archive_none *state; void *buffer; size_t buffer_size; - int ret; f->bytes_per_block = archive_write_get_bytes_per_block(f->archive); f->bytes_in_last_block = @@ -385,13 +384,7 @@ archive_write_client_open(struct archive_write_filter *f) if (a->client_opener == NULL) return (ARCHIVE_OK); - ret = a->client_opener(f->archive, a->client_data); - if (ret != ARCHIVE_OK) { - free(state->buffer); - free(state); - f->data = NULL; - } - return (ret); + return (a->client_opener(f->archive, a->client_data)); } static int @@ -480,6 +473,7 @@ static int archive_write_client_free(struct archive_write_filter *f) { struct archive_write *a = (struct archive_write *)f->archive; + struct archive_none *state = (struct archive_none *)f->data; if (a->client_freer) (*a->client_freer)(&a->archive, a->client_data); @@ -492,6 +486,13 @@ archive_write_client_free(struct archive_write_filter *f) a->passphrase = NULL; } + /* Free state. */ + if (state != NULL) { + free(state->buffer); + free(state); + f->data = NULL; + } + return (ARCHIVE_OK); } @@ -548,8 +549,6 @@ archive_write_client_close(struct archive_write_filter *f) } if (a->client_closer) (*a->client_closer)(&a->archive, a->client_data); - free(state->buffer); - free(state); /* Clear the close handler myself not to be called again. */ f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; @@ -807,7 +806,10 @@ _archive_write_finish_entry(struct archive *_a) if (a->archive.state & ARCHIVE_STATE_DATA && a->format_finish_entry != NULL) ret = (a->format_finish_entry)(a); - a->archive.state = ARCHIVE_STATE_HEADER; + if (ret == ARCHIVE_FATAL) + a->archive.state = ARCHIVE_STATE_FATAL; + else + a->archive.state = ARCHIVE_STATE_HEADER; return (ret); } @@ -819,6 +821,7 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s) { struct archive_write *a = (struct archive_write *)_a; const size_t max_write = INT_MAX; + int ret; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_DATA, "archive_write_data"); @@ -826,7 +829,10 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s) if (s > max_write) s = max_write; archive_clear_error(&a->archive); - return ((a->format_write_data)(a, buff, s)); + ret = (a->format_write_data)(a, buff, s); + if (ret == ARCHIVE_FATAL) + a->archive.state = ARCHIVE_STATE_FATAL; + return (ret); } static struct archive_write_filter * diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c b/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c index 0726f08936ec..2434528d5133 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c @@ -281,6 +281,10 @@ static int archive_compressor_bzip2_free(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; + + /* May already have been called, but not necessarily. */ + (void)BZ2_bzCompressEnd(&(data->stream)); + free(data->compressed); free(data); f->data = NULL; diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c b/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c index 5ef43c1936ed..b09e669b753d 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c @@ -191,7 +191,8 @@ static int archive_compressor_gzip_open(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; - int ret; + int ret = ARCHIVE_OK; + int init_success; if (data->compressed == NULL) { size_t bs = 65536, bpb; @@ -221,44 +222,66 @@ archive_compressor_gzip_open(struct archive_write_filter *f) data->compressed[0] = 0x1f; /* GZip signature bytes */ data->compressed[1] = 0x8b; data->compressed[2] = 0x08; /* "Deflate" compression */ - data->compressed[3] = data->original_filename == NULL ? 0 : 0x8; + data->compressed[3] = 0x00; /* Flags */ if (data->timestamp >= 0) { time_t t = time(NULL); data->compressed[4] = (uint8_t)(t)&0xff; /* Timestamp */ data->compressed[5] = (uint8_t)(t>>8)&0xff; data->compressed[6] = (uint8_t)(t>>16)&0xff; data->compressed[7] = (uint8_t)(t>>24)&0xff; - } else + } else { memset(&data->compressed[4], 0, 4); - if (data->compression_level == 9) - data->compressed[8] = 2; - else if(data->compression_level == 1) - data->compressed[8] = 4; - else - data->compressed[8] = 0; + } + if (data->compression_level == 9) { + data->compressed[8] = 2; + } else if(data->compression_level == 1) { + data->compressed[8] = 4; + } else { + data->compressed[8] = 0; + } data->compressed[9] = 3; /* OS=Unix */ data->stream.next_out += 10; data->stream.avail_out -= 10; if (data->original_filename != NULL) { - strcpy((char*)data->compressed + 10, data->original_filename); - data->stream.next_out += strlen(data->original_filename) + 1; - data->stream.avail_out -= strlen(data->original_filename) + 1; + /* Limit "original filename" to 32k or the + * remaining space in the buffer, whichever is smaller. + */ + int ofn_length = strlen(data->original_filename); + int ofn_max_length = 32768; + int ofn_space_available = data->compressed + + data->compressed_buffer_size + - data->stream.next_out + - 1; + if (ofn_max_length > ofn_space_available) { + ofn_max_length = ofn_space_available; + } + if (ofn_length < ofn_max_length) { + data->compressed[3] |= 0x8; + strcpy((char*)data->compressed + 10, + data->original_filename); + data->stream.next_out += ofn_length + 1; + data->stream.avail_out -= ofn_length + 1; + } else { + archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, + "Gzip 'Original Filename' ignored because it is too long"); + ret = ARCHIVE_WARN; + } } f->write = archive_compressor_gzip_write; /* Initialize compression library. */ - ret = deflateInit2(&(data->stream), + init_success = deflateInit2(&(data->stream), data->compression_level, Z_DEFLATED, -15 /* < 0 to suppress zlib header */, 8, Z_DEFAULT_STRATEGY); - if (ret == Z_OK) { + if (init_success == Z_OK) { f->data = data; - return (ARCHIVE_OK); + return (ret); } /* Library setup failed: clean up. */ @@ -266,7 +289,7 @@ archive_compressor_gzip_open(struct archive_write_filter *f) "initializing compression library"); /* Override the error message if we know what really went wrong. */ - switch (ret) { + switch (init_success) { case Z_STREAM_ERROR: archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, "Internal error initializing " diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_program.c b/contrib/libarchive/libarchive/archive_write_add_filter_program.c index c661cc7f412f..f12db3373883 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_program.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_program.c @@ -330,6 +330,7 @@ __archive_write_program_close(struct archive_write_filter *f, struct archive_write_program_data *data) { int ret, status; + pid_t pid; ssize_t bytes_read; if (data->child == 0) @@ -373,14 +374,12 @@ cleanup: close(data->child_stdin); if (data->child_stdout != -1) close(data->child_stdout); - while (waitpid(data->child, &status, 0) == -1 && errno == EINTR) - continue; -#if defined(_WIN32) && !defined(__CYGWIN__) - CloseHandle(data->child); -#endif + do { + pid = waitpid(data->child, &status, 0); + } while (pid == -1 && errno == EINTR); data->child = 0; - if (status != 0) { + if (pid < 0 || status != 0) { archive_set_error(f->archive, EIO, "Error closing program: %s", data->program_name); ret = ARCHIVE_FATAL; diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c index c0a6e5a37a66..d4752c247157 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c @@ -391,6 +391,8 @@ archive_compressor_zstd_open(struct archive_write_filter *f) ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads); + ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_checksumFlag, 1); + #if ZSTD_VERSION_NUMBER >= MINVER_LONG ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance); #endif diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c index 1bbfd7a3d779..aeb27e1270ad 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c @@ -2204,7 +2204,7 @@ restore_entry(struct archive_write_disk *a) (void)clear_nochange_fflags(a); if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) && - S_ISREG(a->st.st_mode)) { + S_ISREG(a->mode)) { /* Use a temporary file to extract */ if ((a->fd = la_mktemp(a)) == -1) { archive_set_error(&a->archive, errno, @@ -2559,9 +2559,9 @@ _archive_write_disk_close(struct archive *_a) * for directories. For other file types * we need to verify via fstat() or lstat() */ - if (fd == -1 || p->filetype != AE_IFDIR) { + if (fd < 0 || p->filetype != AE_IFDIR) { #if HAVE_FSTAT - if (fd > 0 && ( + if (fd >= 0 && ( fstat(fd, &st) != 0 || la_verify_filetype(st.st_mode, p->filetype) == 0)) { @@ -3930,10 +3930,14 @@ clear_nochange_fflags(struct archive_write_disk *a) #ifdef UF_APPEND | UF_APPEND #endif -#ifdef EXT2_APPEND_FL +#if defined(FS_APPEND_FL) + | FS_APPEND_FL +#elif defined(EXT2_APPEND_FL) | EXT2_APPEND_FL #endif -#ifdef EXT2_IMMUTABLE_FL +#if defined(FS_IMMUTABLE_FL) + | FS_IMMUTABLE_FL +#elif defined(EXT2_IMMUTABLE_FL) | EXT2_IMMUTABLE_FL #endif ; @@ -4437,7 +4441,7 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname) */ fd = open(pathname, O_RDONLY | O_BINARY | O_CLOEXEC); __archive_ensure_cloexec_flag(fd); - if (fd == -1) { + if (fd < 0) { archive_set_error(&a->archive, errno, "Failed to open a restoring file"); ret = ARCHIVE_WARN; diff --git a/contrib/libarchive/libarchive/archive_write_open_fd.c b/contrib/libarchive/libarchive/archive_write_open_fd.c index 8a3f68d0699d..ba034ed92f8a 100644 --- a/contrib/libarchive/libarchive/archive_write_open_fd.c +++ b/contrib/libarchive/libarchive/archive_write_open_fd.c @@ -122,7 +122,7 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length mine = (struct write_fd_data *)client_data; for (;;) { bytesWritten = write(mine->fd, buff, length); - if (bytesWritten <= 0) { + if (bytesWritten < 0) { if (errno == EINTR) continue; archive_set_error(a, errno, "Write error"); diff --git a/contrib/libarchive/libarchive/archive_write_open_file.c b/contrib/libarchive/libarchive/archive_write_open_file.c index 4c6ebfb2269d..0b310f3da83b 100644 --- a/contrib/libarchive/libarchive/archive_write_open_file.c +++ b/contrib/libarchive/libarchive/archive_write_open_file.c @@ -85,16 +85,12 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length size_t bytesWritten; mine = client_data; - for (;;) { - bytesWritten = fwrite(buff, 1, length, mine->f); - if (bytesWritten <= 0) { - if (errno == EINTR) - continue; - archive_set_error(a, errno, "Write error"); - return (-1); - } - return (bytesWritten); + bytesWritten = fwrite(buff, 1, length, mine->f); + if (bytesWritten != length) { + archive_set_error(a, errno, "Write error"); + return (-1); } + return (bytesWritten); } static int diff --git a/contrib/libarchive/libarchive/archive_write_open_filename.c b/contrib/libarchive/libarchive/archive_write_open_filename.c index 34209426558c..7d0f9bde1dbb 100644 --- a/contrib/libarchive/libarchive/archive_write_open_filename.c +++ b/contrib/libarchive/libarchive/archive_write_open_filename.c @@ -108,6 +108,7 @@ open_filename(struct archive *a, int mbs_fn, const void *filename) else r = archive_mstring_copy_wcs(&mine->filename, filename); if (r < 0) { + free(mine); if (errno == ENOMEM) { archive_set_error(a, ENOMEM, "No memory"); return (ARCHIVE_FATAL); @@ -227,7 +228,7 @@ file_write(struct archive *a, void *client_data, const void *buff, mine = (struct write_file_data *)client_data; for (;;) { bytesWritten = write(mine->fd, buff, length); - if (bytesWritten <= 0) { + if (bytesWritten < 0) { if (errno == EINTR) continue; archive_set_error(a, errno, "Write error"); diff --git a/contrib/libarchive/libarchive/archive_write_set_format_7zip.c b/contrib/libarchive/libarchive/archive_write_set_format_7zip.c index c2bce5975a46..175285da13be 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_7zip.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_7zip.c @@ -686,7 +686,7 @@ write_to_temp(struct archive_write *a, const void *buff, size_t s) ws = write(zip->temp_fd, p, s); if (ws < 0) { archive_set_error(&(a->archive), errno, - "fwrite function failed"); + "write function failed"); return (ARCHIVE_FATAL); } s -= ws; diff --git a/contrib/libarchive/libarchive/archive_write_set_format_mtree.c b/contrib/libarchive/libarchive/archive_write_set_format_mtree.c index 02fbb2d2f555..8131574c8da2 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_mtree.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_mtree.c @@ -1927,7 +1927,7 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file, } /* - * Find out the position which points the last position of + * Find out the position which points to the last position of * path separator('/'). */ slash = NULL; @@ -2024,7 +2024,7 @@ mtree_entry_add_child_tail(struct mtree_entry *parent, } /* - * Find a entry from a parent entry with the name. + * Find an entry from a parent entry with given name. */ static struct mtree_entry * mtree_entry_find_child(struct mtree_entry *parent, const char *child_name) @@ -2148,10 +2148,10 @@ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep) /* Find next sub directory. */ if (!np->dir_info) { - /* NOT Directory! */ + /* NOT a directory! */ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "`%s' is not directory, we cannot insert `%s' ", + "`%s' is not a directory, we cannot insert `%s' ", np->pathname.s, file->pathname.s); return (ARCHIVE_FAILED); } @@ -2243,10 +2243,7 @@ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep) } same_entry: - /* - * We have already has the entry the filename of which is - * the same. - */ + /* We already have an entry with same filename. */ r = mtree_entry_exchange_same_entry(a, np, file); if (r < ARCHIVE_WARN) return (r); @@ -2264,13 +2261,13 @@ mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np, if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Found duplicate entries `%s' and its file type is " - "different", + "Found duplicate entries for `%s' with " + "differing file types.", np->pathname.s); return (ARCHIVE_FAILED); } - /* Update the existent mtree entry's attributes by the new one's. */ + /* Update the existing mtree entry's attributes by the new one's. */ archive_string_empty(&np->symlink); archive_string_concat(&np->symlink, &file->symlink); archive_string_empty(&np->uname); diff --git a/contrib/libarchive/libarchive/archive_write_set_format_xar.c b/contrib/libarchive/libarchive/archive_write_set_format_xar.c index 3775e9f5819a..9921f1032be5 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_xar.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_xar.c @@ -689,7 +689,7 @@ write_to_temp(struct archive_write *a, const void *buff, size_t s) ws = write(xar->temp_fd, p, s); if (ws < 0) { archive_set_error(&(a->archive), errno, - "fwrite function failed"); + "write function failed"); return (ARCHIVE_FATAL); } s -= ws; @@ -3418,8 +3418,8 @@ static int xml_writer_get_final_content_and_length(struct xml_writer *ctx, const char **out, size_t *size) { - *out = (const char*)ctx->bp->content; - *size = (size_t)ctx->bp->use; + *out = (const char*)xmlBufferContent(ctx->bp); + *size = (size_t)xmlBufferLength(ctx->bp); return (0); } diff --git a/contrib/libarchive/libarchive/archive_write_set_format_zip.c b/contrib/libarchive/libarchive/archive_write_set_format_zip.c index 3630b9f2b3a3..19121b519148 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_zip.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_zip.c @@ -1856,7 +1856,10 @@ archive_write_zip_finish_entry(struct archive_write *a) } ret = __archive_write_output(a, zip->buf, remainder); if (ret != ARCHIVE_OK) + { + deflateEnd(&zip->stream.deflate); return (ret); + } zip->entry_compressed_written += remainder; zip->written_bytes += remainder; zip->stream.deflate.next_out = zip->buf; @@ -1898,7 +1901,10 @@ archive_write_zip_finish_entry(struct archive_write *a) } ret = __archive_write_output(a, zip->buf, remainder); if (ret != ARCHIVE_OK) + { + BZ2_bzCompressEnd(&zip->stream.bzip2); return (ret); + } zip->entry_compressed_written += remainder; zip->written_bytes += remainder; zip->stream.bzip2.next_out = (char*)zip->buf; @@ -1940,13 +1946,17 @@ archive_write_zip_finish_entry(struct archive_write *a) } ret = __archive_write_output(a, zip->buf, remainder); if (ret != ARCHIVE_OK) + { + ZSTD_freeCStream(zip->stream.zstd.context); return (ret); + } zip->entry_compressed_written += remainder; zip->written_bytes += remainder; - zip->stream.zstd.out.dst = zip->buf; if (zip->stream.zstd.out.pos != zip->stream.zstd.out.size) finishing = 0; + zip->stream.zstd.out.dst = zip->buf; zip->stream.zstd.out.size = zip->len_buf; + zip->stream.zstd.out.pos = 0; } while (finishing); ZSTD_freeCStream(zip->stream.zstd.context); break; @@ -1984,7 +1994,10 @@ archive_write_zip_finish_entry(struct archive_write *a) } ret = __archive_write_output(a, zip->buf, remainder); if (ret != ARCHIVE_OK) + { + lzma_end(&zip->stream.lzma.context); return (ret); + } zip->entry_compressed_written += remainder; zip->written_bytes += remainder; zip->stream.lzma.context.next_out = zip->buf; @@ -2434,13 +2447,19 @@ init_winzip_aes_encryption(struct archive_write *a) "Can't generate random number for encryption"); return (ARCHIVE_FATAL); } - archive_pbkdf2_sha1(passphrase, strlen(passphrase), + ret = archive_pbkdf2_sha1(passphrase, strlen(passphrase), salt, salt_len, 1000, derived_key, key_len * 2 + 2); + if (ret != 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + ret == CRYPTOR_STUB_FUNCTION ? "Encryption is unsupported due to " + "lack of crypto library" : "Failed to process passphrase"); + return (ARCHIVE_FAILED); + } ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len); if (ret != 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Decryption is unsupported due to lack of crypto library"); + "Failed to initialize AES CTR mode"); return (ARCHIVE_FAILED); } ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len, diff --git a/contrib/libarchive/libarchive/filter_fork_posix.c b/contrib/libarchive/libarchive/filter_fork_posix.c index c895c08e59b3..7c48519336ff 100644 --- a/contrib/libarchive/libarchive/filter_fork_posix.c +++ b/contrib/libarchive/libarchive/filter_fork_posix.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 Joerg Sonnenberger - * Copyright (c) 2012 Michihiro NAKAJIMA + * Copyright (c) 2012 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -76,7 +76,15 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, { pid_t child = -1; int stdin_pipe[2], stdout_pipe[2], tmp; + +#if !defined(POSIX_SPAWN_CLOEXEC_DEFAULT) && \ + (HAVE_FORK || HAVE_VFORK) && \ + (HAVE_CLOSEFROM || HAVE_CLOSE_RANGE || defined(_SC_OPEN_MAX)) +#undef HAVE_POSIX_SPAWNP +#endif + #if HAVE_POSIX_SPAWNP + posix_spawnattr_t attr; posix_spawn_file_actions_t actions; int r; #endif @@ -107,11 +115,21 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, #if HAVE_POSIX_SPAWNP - r = posix_spawn_file_actions_init(&actions); + r = posix_spawnattr_init(&attr); if (r != 0) { errno = r; goto stdout_opened; } + r = posix_spawn_file_actions_init(&actions); + if (r != 0) { + errno = r; + goto attr_inited; + } +#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT + r = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT); + if (r != 0) + goto actions_inited; +#endif r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[1]); if (r != 0) goto actions_inited; @@ -136,11 +154,12 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, if (r != 0) goto actions_inited; } - r = posix_spawnp(&child, cmdline->path, &actions, NULL, + r = posix_spawnp(&child, cmdline->path, &actions, &attr, cmdline->argv, NULL); if (r != 0) goto actions_inited; posix_spawn_file_actions_destroy(&actions); + posix_spawnattr_destroy(&attr); #else /* HAVE_POSIX_SPAWNP */ @@ -162,6 +181,16 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, _exit(254); if (stdout_pipe[1] != 1 /* stdout */) close(stdout_pipe[1]); + +#if HAVE_CLOSEFROM + closefrom(3); +#elif HAVE_CLOSE_RANGE + close_range(3, ~0U, 0); +#elif defined(_SC_OPEN_MAX) + for (int i = sysconf(_SC_OPEN_MAX); i > 3;) + close(--i); +#endif + execvp(cmdline->path, cmdline->argv); _exit(254); } @@ -183,6 +212,8 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, actions_inited: errno = r; posix_spawn_file_actions_destroy(&actions); +attr_inited: + posix_spawnattr_destroy(&attr); #endif stdout_opened: close(stdout_pipe[0]); diff --git a/contrib/libarchive/libarchive/test/test_acl_nfs4.c b/contrib/libarchive/libarchive/test/test_acl_nfs4.c index 98d39689df69..050c0a063654 100644 --- a/contrib/libarchive/libarchive/test/test_acl_nfs4.c +++ b/contrib/libarchive/libarchive/test/test_acl_nfs4.c @@ -145,6 +145,13 @@ static struct archive_test_acl_t acls_bad[] = { ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE, ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, + + /* Multiple types */ + { ARCHIVE_ENTRY_ACL_TYPE_ALLOW | ARCHIVE_ENTRY_ACL_TYPE_AUDIT, + ARCHIVE_ENTRY_ACL_EXECUTE, + ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, + { ARCHIVE_ENTRY_ACL_TYPE_NFS4, ARCHIVE_ENTRY_ACL_EXECUTE, + ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, }; DEFINE_TEST(test_acl_nfs4) diff --git a/contrib/libarchive/libarchive/test/test_acl_posix1e.c b/contrib/libarchive/libarchive/test/test_acl_posix1e.c index 025ef6afd102..f9b6ffeb6ab7 100644 --- a/contrib/libarchive/libarchive/test/test_acl_posix1e.c +++ b/contrib/libarchive/libarchive/test/test_acl_posix1e.c @@ -94,6 +94,11 @@ static struct archive_test_acl_t acls_nfs4[] = { { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, + + /* Invalid type codes */ + { ARCHIVE_ENTRY_ACL_TYPE_ACCESS | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, + ARCHIVE_ENTRY_ACL_READ, + ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, }; DEFINE_TEST(test_acl_posix1e) diff --git a/contrib/libarchive/libarchive/test/test_archive_parse_date.c b/contrib/libarchive/libarchive/test/test_archive_parse_date.c index 0a70971b1da6..5251b3393999 100644 --- a/contrib/libarchive/libarchive/test/test_archive_parse_date.c +++ b/contrib/libarchive/libarchive/test/test_archive_parse_date.c @@ -39,6 +39,8 @@ DEFINE_TEST(test_archive_parse_date) assertEqualInt(get_date(now, "Jan 1, 1970 UTC"), 0); assertEqualInt(get_date(now, "7:12:18-0530 4 May 1983"), 420900138); assertEqualInt(get_date(now, "2004/01/29 513 mest"), 1075345980); + assertEqualInt(get_date(now, "2038-06-01 00:01:02 UTC"), + sizeof(time_t) <= 4 ? -1 : 2158963262); assertEqualInt(get_date(now, "99/02/17 7pm utc"), 919278000); assertEqualInt(get_date(now, "02/17/99 7:11am est"), 919253460); assertEqualInt(get_date(now, "now - 2 hours"), diff --git a/contrib/libarchive/libarchive/test/test_archive_string_conversion.c b/contrib/libarchive/libarchive/test/test_archive_string_conversion.c index 12976f3e70ec..055bddc75068 100644 --- a/contrib/libarchive/libarchive/test/test_archive_string_conversion.c +++ b/contrib/libarchive/libarchive/test/test_archive_string_conversion.c @@ -991,6 +991,7 @@ DEFINE_TEST(test_archive_string_update_utf8_koi8) static const char koi8_string[] = "\xD0\xD2\xC9"; static const wchar_t wcs_string[] = L"\U0000043f\U00000440\U00000438"; struct archive_mstring mstr; + struct archive *a; int r; memset(&mstr, 0, sizeof(mstr)); @@ -999,6 +1000,15 @@ DEFINE_TEST(test_archive_string_update_utf8_koi8) skipping("KOI8-R locale not available on this system."); return; } + a = archive_write_new(); + assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); + if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { + skipping("This system cannot convert character-set" + " from KOI8-R to UTF-8."); + archive_write_free(a); + return; + } + archive_write_free(a); r = archive_mstring_update_utf8(NULL, &mstr, utf8_string); diff --git a/contrib/libarchive/libarchive/test/test_entry.c b/contrib/libarchive/libarchive/test/test_entry.c index 9b21b83ecdfb..cff9c5c86efc 100644 --- a/contrib/libarchive/libarchive/test/test_entry.c +++ b/contrib/libarchive/libarchive/test/test_entry.c @@ -880,6 +880,17 @@ DEFINE_TEST(test_entry) if (pst == NULL) return; assertEqualInt(pst->st_uid, 22); + + /* Check behavior with large sizes. */ + archive_entry_set_size(e, INT64_MAX - 1); + assert((pst = archive_entry_stat(e)) != NULL); + if (pst == NULL) + return; + if (sizeof(pst->st_size) < sizeof(int64_t)) + assertEqualInt(pst->st_size, 0); + else + assertEqualInt(pst->st_size, INT64_MAX - 1); + /* We don't need to check high-res fields here. */ /* diff --git a/contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c b/contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c index 0042a0511d5a..51b614b6c023 100644 --- a/contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c +++ b/contrib/libarchive/libarchive/test/test_read_filter_gzip_recursive.c @@ -29,8 +29,8 @@ DEFINE_TEST(test_read_filter_gzip_recursive) const char *name = "test_read_filter_gzip_recursive.gz"; struct archive *a; - if (!canGzip()) { - skipping("gzip not available"); + if (archive_zlib_version() == NULL) { + skipping("zlib not available"); return; } diff --git a/contrib/libarchive/libarchive/test/test_read_format_7zip.c b/contrib/libarchive/libarchive/test/test_read_format_7zip.c index ad10ef06bbc5..3236fee2c9d3 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_7zip.c +++ b/contrib/libarchive/libarchive/test/test_read_format_7zip.c @@ -1285,19 +1285,26 @@ DEFINE_TEST(test_read_format_7zip_sfx_pe) const char test_txt[] = "123"; int size = sizeof(test_txt) - 1; - extract_reference_file(reffile); assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, bs)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt.txt", archive_entry_pathname(ae)); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping( + "7zip:lzma decoding is not supported on this platform"); + } else { + extract_reference_file(reffile); + assertA(0 == archive_read_support_filter_all(a)); + assertA(0 == archive_read_support_format_all(a)); + assertA(0 == archive_read_open_filename(a, reffile, bs)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); + assertA(0 == archive_read_next_header(a, &ae)); + assertEqualString("test.txt.txt", archive_entry_pathname(ae)); + + assertA(size == archive_read_data(a, buff, size)); + assertEqualMem(buff, test_txt, size); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } @@ -1316,19 +1323,26 @@ DEFINE_TEST(test_read_format_7zip_sfx_modified_pe) const char test_txt[] = "123"; int size = sizeof(test_txt) - 1; - extract_reference_file(reffile); assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, bs)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt.txt", archive_entry_pathname(ae)); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping( + "7zip:lzma decoding is not supported on this platform"); + } else { + extract_reference_file(reffile); + assertA(0 == archive_read_support_filter_all(a)); + assertA(0 == archive_read_support_format_all(a)); + assertA(0 == archive_read_open_filename(a, reffile, bs)); + + assertA(0 == archive_read_next_header(a, &ae)); + assertEqualString("test.txt.txt", archive_entry_pathname(ae)); + + assertA(size == archive_read_data(a, buff, size)); + assertEqualMem(buff, test_txt, size); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } @@ -1346,20 +1360,27 @@ DEFINE_TEST(test_read_format_7zip_sfx_elf) const char test_txt[] = "123"; int size = sizeof(test_txt) - 1; - extract_reference_file(reffile); assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, bs)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt.txt", archive_entry_pathname(ae)); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping( + "7zip:lzma decoding is not supported on this platform"); + } else { + extract_reference_file(reffile); + assertA(0 == archive_read_support_filter_all(a)); + assertA(0 == archive_read_support_format_all(a)); + assertA(0 == archive_read_open_filename(a, reffile, bs)); + + assertA(0 == archive_read_next_header(a, &ae)); + assertEqualString("test.txt.txt", archive_entry_pathname(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); + assertA(size == archive_read_data(a, buff, size)); + assertEqualMem(buff, test_txt, size); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + } + + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } DEFINE_TEST(test_read_format_7zip_extract_second) @@ -1597,9 +1618,9 @@ DEFINE_TEST(test_read_format_7zip_lzma2_powerpc) assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_gzip(a)) { + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { skipping( - "7zip:deflate decoding is not supported on this platform"); + "7zip:lzma decoding is not supported on this platform"); } else { test_powerpc_filter("test_read_format_7zip_lzma2_powerpc.7z"); } diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5.c b/contrib/libarchive/libarchive/test/test_read_format_rar5.c index fd233277bc1b..6ab0d236a1ed 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_rar5.c +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5.c @@ -1111,6 +1111,18 @@ DEFINE_TEST(test_read_format_rar5_nonempty_dir_stream) EPILOGUE(); } +DEFINE_TEST(test_read_format_rar5_nonempty_dir_data) +{ + PROLOGUE("test_read_format_rar5_dirdata.rar"); + + /* This archive is invalid. It declares a directory entry with nonzero + data size. */ + + assertA(archive_read_next_header(a, &ae) == ARCHIVE_FATAL); + + EPILOGUE(); +} + DEFINE_TEST(test_read_format_rar5_fileattr) { unsigned long set, clear, flag; @@ -1428,3 +1440,57 @@ DEFINE_TEST(test_read_format_rar5_data_ready_pointer_leak) EPILOGUE(); } + +DEFINE_TEST(test_read_format_rar5_only_crypt_exfld) +{ + /* GH #2711 */ + + char buf[4096]; + PROLOGUE("test_read_format_rar5_only_crypt_exfld.rar"); + + /* The reader should allow iteration through files, but should fail + during data extraction. */ + + assertA(archive_read_next_header(a, &ae) == ARCHIVE_OK); + assertA(archive_read_data(a, buf, sizeof(buf)) == ARCHIVE_FATAL); + + /* The reader should also provide a valid error message. */ + assertA(archive_error_string(a) != NULL); + + EPILOGUE(); +} + +DEFINE_TEST(test_read_format_rar5_only_unsupported_exfld) +{ + /* GH #2711 */ + + char buf[4096]; + PROLOGUE("test_read_format_rar5_unsupported_exfld.rar"); + + /* The reader should allow iteration through files, and it should + succeed with data extraction. */ + + assertA(archive_read_next_header(a, &ae) == ARCHIVE_OK); + + /* 48 is the expected number of bytes that should be extracted */ + assertA(archive_read_data(a, buf, sizeof(buf)) == 48); + + EPILOGUE(); +} + +DEFINE_TEST(test_read_format_rar5_invalidhash_and_validhtime_exfld) +{ + /* GH #2711 */ + + char buf[4096]; + PROLOGUE("test_read_format_rar5_invalid_hash_valid_htime_exfld.rar"); + + /* The reader should report an error when trying to process this data. + Returning EOF here means that the reader has failed to identify + malformed structure. */ + + assertA(archive_read_next_header(a, &ae) < 0); + assertA(archive_read_data(a, buf, sizeof(buf)) < 0); + + EPILOGUE(); +} diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_dirdata.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_dirdata.rar.uu new file mode 100644 index 000000000000..c7928f344a80 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_dirdata.rar.uu @@ -0,0 +1,6 @@ +begin 644 - +M4F%R(1H'`0`BD'[;,`$%,#8P`0&`@("``B?GD;$U`@(+@X``"_C5%:2#``(` +M`#"``S`P,#`P,#`P,#!);S#6KA',@]:N$?*IN;YV[8"1S>?4^`,#`R,#`P,# +-`P,#1)'C@XX*4`O.^P`` +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu new file mode 100644 index 000000000000..399acd814ae4 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu @@ -0,0 +1,6 @@ +begin 644 - +M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`#^T/5L)`(###$$,>V#`D840I@``0AF +M:6QE+G1X=`@"OX0]``$"`P(#`&EN=F%L:60@2$%32"!E>'1R82P@86YD(&QA +>=&5R(&$@=F%L:60@2%1)344@97AT<F$@/=^&`@4$ +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu new file mode 100644 index 000000000000..4f9faf350c11 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_only_crypt_exfld.rar.uu @@ -0,0 +1,7 @@ +begin 644 - +M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`"!0_"Y/0(#)2X$+NV#`IB>)!,``0AF +M:6QE+G1X="0!```&``````````````````````````````````````````!R +M87(U('-T;W)E9"!F:6QE('=I=&@@;VYL>2!A($-265!4(&5X=')A(&9I96QD +'(#W?A@(%!``` +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu new file mode 100644 index 000000000000..16b456bf4873 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_unsupported_exfld.rar.uu @@ -0,0 +1,6 @@ +begin 644 - +M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`#>[JDS)@(##C`$,.V#`BX6Z[0``0AF +M:6QE+G1X=`W_____#WA6-!(`````<F%R-2!S=&]R960@9FEL92!W:71H(&%N +?('5N<W5P<&]R=&5D(&5X=')A(&9I96QD(#W?A@(%!``` +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.c b/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.c new file mode 100644 index 000000000000..d110553acfaf --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2025 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" + +DEFINE_TEST(test_read_format_tar_V_negative_size) +{ + /* + * An archive that contains a `V` volume header with a negative body size + * + * This used to lead to an infinite loop: the tar reader would "advance" + * by the size of the body to skip it, which would in this case end up + * reversing back to the beginning of the same header. + */ + struct archive_entry *ae; + struct archive *a; + const char *refname = "test_read_format_tar_V_negative_size.tar"; + + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} diff --git a/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.tar.uu b/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.tar.uu new file mode 100644 index 000000000000..230d710c8f8f --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_tar_V_negative_size.tar.uu @@ -0,0 +1,20 @@ +Tar archive with a single `V` header that has a negative size. +This used to result in an infinite loop -- the tar reader would +"advance" by the size of the header, which in this case just backed +up to re-read the same header again. + +begin 644 test_read_format_tar_V_negative_size.tar +M`#(VXP```````````````````-Z;@"E&LOX^\@````````````!7````'``` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````#___\````````@```` +M````````````````````````````5H%ZL#X]SH\-``":SN#[C4;Z5OOW-&'] +M?HHQ%WRG?Z$Q>^E#_1.OY96VEI*Z<U[)$TR502_;F$;9FU"/F'!`V:0````` +M`````````````````````````````````````````````````````0`````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````0`````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +1```````````````````````` +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_set_format.c b/contrib/libarchive/libarchive/test/test_read_set_format.c index c760de0056d3..615dd8ae8022 100644 --- a/contrib/libarchive/libarchive/test/test_read_set_format.c +++ b/contrib/libarchive/libarchive/test/test_read_set_format.c @@ -138,7 +138,10 @@ DEFINE_TEST(test_read_append_filter) assertEqualInt(ARCHIVE_OK, archive_read_free(a)); return; } - assertEqualIntA(a, ARCHIVE_OK, r); + if (r == ARCHIVE_WARN && canGzip()) + assertEqualString(archive_error_string(a), "Using external gzip program"); + else + assertEqualIntA(a, ARCHIVE_OK, r); assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, archive, sizeof(archive))); assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae)); @@ -210,7 +213,7 @@ DEFINE_TEST(test_read_append_filter_wrong_program) /* * If we have "bunzip2 -q", try using that. */ - if (!canRunCommand("bunzip2 -h")) { + if (!canRunCommand("bunzip2 -h", NULL)) { skipping("Can't run bunzip2 program on this platform"); return; } diff --git a/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c b/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c index 20ca0d9a7b22..7b2e4f857a75 100644 --- a/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c +++ b/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c @@ -268,6 +268,35 @@ DEFINE_TEST(test_write_filter_bzip2) assertEqualInt(ARCHIVE_OK, archive_write_free(a)); /* + * Test behavior after a fatal error (triggered by giving + * archive_write_open_memory() a very small buffer). + */ + if (!use_prog) { + used1 = 0; + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_format_ustar(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_add_filter_bzip2(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_open_memory(a, buff, 100, &used1)); + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_filetype(ae, AE_IFREG); + archive_entry_set_size(ae, 4000000); + archive_entry_copy_pathname(ae, "file"); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_header(a, ae)); + for (i = 0; i < 1000000; i++) { + r = archive_write_data(a, &i, 4); + if (r == ARCHIVE_FATAL) + break; + } + assertEqualIntA(a, ARCHIVE_FATAL, r); + archive_entry_free(ae); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + } + + /* * Clean up. */ free(data); diff --git a/contrib/libarchive/libarchive/test/test_write_filter_gzip.c b/contrib/libarchive/libarchive/test/test_write_filter_gzip.c index 8fbdbed09744..a6681d7618b1 100644 --- a/contrib/libarchive/libarchive/test/test_write_filter_gzip.c +++ b/contrib/libarchive/libarchive/test/test_write_filter_gzip.c @@ -166,9 +166,15 @@ DEFINE_TEST(test_write_filter_gzip) assertEqualInt(rbuff[0], 0x1f); assertEqualInt(rbuff[1], 0x8b); assertEqualInt(rbuff[2], 0x08); - assertEqualInt(rbuff[3], 0x08); - assertEqualInt(rbuff[8], 2); /* RFC 1952 flag for compression level 9 */ - assertEqualString((const char*)rbuff+10, "testorgfilename"); + /* RFC 1952 flag for compression level 9 */ + assertEqualInt(rbuff[8], 2); + /* External gzip program might not save filename */ + if (!use_prog || rbuff[3] == 0x08) { + assertEqualInt(rbuff[3], 0x08); + assertEqualString((const char*)rbuff+10, "testorgfilename"); + } else { + assertEqualInt(rbuff[3], 0x00); + } /* Curiously, this test fails; the test data above compresses * better at default compression than at level 9. */ diff --git a/contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c b/contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c index a148f818dcec..d0496b025b64 100644 --- a/contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c +++ b/contrib/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c @@ -81,8 +81,11 @@ DEFINE_TEST(test_write_filter_gzip_timestamp) archive_entry_free(ae); assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - failure("Timestamp should be recorded"); - assert(memcmp(buff + 4, "\x00\x00\x00\x00", 4) != 0); + /* External gzip program might not save timestamp */ + if (!use_prog) { + failure("Timestamp should be recorded"); + assert(memcmp(buff + 4, "\x00\x00\x00\x00", 4) != 0); + } /* Test2: set "gzip:!timestamp" option. */ assert((a = archive_write_new()) != NULL); diff --git a/contrib/libarchive/libarchive_fe/err.c b/contrib/libarchive/libarchive_fe/lafe_err.c index f6dcf44af347..b108b9b1fea7 100644 --- a/contrib/libarchive/libarchive_fe/err.c +++ b/contrib/libarchive/libarchive_fe/lafe_err.c @@ -36,7 +36,7 @@ #include <string.h> #endif -#include "err.h" +#include "lafe_err.h" static void lafe_vwarnc(int, const char *, va_list) __LA_PRINTFLIKE(2, 0); diff --git a/contrib/libarchive/libarchive_fe/err.h b/contrib/libarchive/libarchive_fe/lafe_err.h index f4a66350a669..f4a66350a669 100644 --- a/contrib/libarchive/libarchive_fe/err.h +++ b/contrib/libarchive/libarchive_fe/lafe_err.h diff --git a/contrib/libarchive/libarchive_fe/line_reader.c b/contrib/libarchive/libarchive_fe/line_reader.c index 7f0429ece3cf..0af9db53c0a2 100644 --- a/contrib/libarchive/libarchive_fe/line_reader.c +++ b/contrib/libarchive/libarchive_fe/line_reader.c @@ -31,7 +31,7 @@ #include <stdlib.h> #include <string.h> -#include "err.h" +#include "lafe_err.h" #include "line_reader.h" #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) diff --git a/contrib/libarchive/libarchive_fe/passphrase.c b/contrib/libarchive/libarchive_fe/passphrase.c index 527ad2d63654..1b7a50453664 100644 --- a/contrib/libarchive/libarchive_fe/passphrase.c +++ b/contrib/libarchive/libarchive_fe/passphrase.c @@ -61,7 +61,7 @@ #include <readpassphrase.h> #endif -#include "err.h" +#include "lafe_err.h" #include "passphrase.h" #ifndef HAVE_READPASSPHRASE diff --git a/contrib/libarchive/tar/bsdtar.c b/contrib/libarchive/tar/bsdtar.c index 53ac135f0129..92e86fd6bd94 100644 --- a/contrib/libarchive/tar/bsdtar.c +++ b/contrib/libarchive/tar/bsdtar.c @@ -55,7 +55,7 @@ #endif #include "bsdtar.h" -#include "err.h" +#include "lafe_err.h" #if ARCHIVE_VERSION_NUMBER < 4000000 && !defined(_PATH_DEFTAPE) // Libarchive 4.0 and later will NOT define _PATH_DEFTAPE @@ -183,6 +183,11 @@ main(int argc, char **argv) sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, NULL); #endif +#ifdef SIGCHLD + /* Do not ignore SIGCHLD. */ + sa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sa, NULL); +#endif } #endif diff --git a/contrib/libarchive/tar/bsdtar.h b/contrib/libarchive/tar/bsdtar.h index 45dfeed7dce3..782d36d6f756 100644 --- a/contrib/libarchive/tar/bsdtar.h +++ b/contrib/libarchive/tar/bsdtar.h @@ -16,6 +16,12 @@ #define ENV_WRITER_OPTIONS "TAR_WRITER_OPTIONS" #define IGNORE_WRONG_MODULE_NAME "__ignore_wrong_module_name__," +#if defined(_MSC_VER ) && (_MSC_VER < 1927 ) /* Check if compiler pre-dated Visual Studio 2019 Release 16.8 */ +#define ARCHIVE_RESTRICT +#else +#define ARCHIVE_RESTRICT restrict +#endif + struct creation_set; /* * The internal state for the "bsdtar" program. @@ -188,7 +194,7 @@ int edit_pathname(struct bsdtar *, struct archive_entry *); void edit_mtime(struct bsdtar *, struct archive_entry *); int need_report(void); int pathcmp(const char *a, const char *b); -void safe_fprintf(FILE * restrict, const char * restrict fmt, ...) __LA_PRINTF(2, 3); +void safe_fprintf(FILE * ARCHIVE_RESTRICT, const char * ARCHIVE_RESTRICT fmt, ...) __LA_PRINTF(2, 3); void set_chdir(struct bsdtar *, const char *newdir); const char *tar_i64toa(int64_t); void tar_mode_c(struct bsdtar *bsdtar); diff --git a/contrib/libarchive/tar/cmdline.c b/contrib/libarchive/tar/cmdline.c index c766c1a52dbb..309be312c948 100644 --- a/contrib/libarchive/tar/cmdline.c +++ b/contrib/libarchive/tar/cmdline.c @@ -22,7 +22,7 @@ #endif #include "bsdtar.h" -#include "err.h" +#include "lafe_err.h" /* * Short options for tar. Please keep this sorted. diff --git a/contrib/libarchive/tar/creation_set.c b/contrib/libarchive/tar/creation_set.c index 6883090418b0..51f803354a5d 100644 --- a/contrib/libarchive/tar/creation_set.c +++ b/contrib/libarchive/tar/creation_set.c @@ -15,7 +15,7 @@ #endif #include "bsdtar.h" -#include "err.h" +#include "lafe_err.h" struct creation_set { char *create_format; diff --git a/contrib/libarchive/tar/read.c b/contrib/libarchive/tar/read.c index 8563fe714f9a..7cbcfb19ff0a 100644 --- a/contrib/libarchive/tar/read.c +++ b/contrib/libarchive/tar/read.c @@ -57,7 +57,7 @@ #endif #include "bsdtar.h" -#include "err.h" +#include "lafe_err.h" struct progress_data { struct bsdtar *bsdtar; diff --git a/contrib/libarchive/tar/subst.c b/contrib/libarchive/tar/subst.c index 5546b5f93b12..a5d644dc5a70 100644 --- a/contrib/libarchive/tar/subst.c +++ b/contrib/libarchive/tar/subst.c @@ -25,7 +25,7 @@ #define REG_BASIC 0 #endif -#include "err.h" +#include "lafe_err.h" struct subst_rule { struct subst_rule *next; diff --git a/contrib/libarchive/tar/test/test_crlf_mtree.c b/contrib/libarchive/tar/test/test_crlf_mtree.c new file mode 100644 index 000000000000..5ef8811369c1 --- /dev/null +++ b/contrib/libarchive/tar/test/test_crlf_mtree.c @@ -0,0 +1,74 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2018 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Arshan Khanifar <arshankhanifar@gmail.com> + * under sponsorship from the FreeBSD Foundation. + */ +#include "test.h" + +DEFINE_TEST(test_crlf_mtree) +{ + char *p0; + size_t s; + int r; + p0 = NULL; + char *content = "#mtree\r\n" + "f type=file uname=\\\r\n" + "root gname=root mode=0755 content=bar/foo\r\n" + "g type=file uname=root gname=root mode=0755 content=bar/goo\r\n"; + char *filename = "output.tar"; +#if defined(_WIN32) && !defined(__CYGWIN__) + char *p; +#endif + + /* an absolute path to mtree file */ + char *mtree_file = "/METALOG.mtree"; + char *absolute_path = malloc(strlen(testworkdir) + strlen(mtree_file) + 1); + strcpy(absolute_path, testworkdir); + strcat(absolute_path, mtree_file ); + + /* Create an archive using an mtree file. */ + assertMakeFile(absolute_path, 0777, content); + assertMakeDir("bar", 0775); + assertMakeFile("bar/foo", 0777, "abc"); + assertMakeFile("bar/goo", 0777, "abc"); + +#if defined(_WIN32) && !defined(__CYGWIN__) + p = absolute_path; + while(*p != '\0') { + if (*p == '/') + *p = '\\'; + p++; + } + + r = systemf("%s -cf %s @%s >step1.out 2>step1.err", testprog, filename, absolute_path); + failure("Error invoking %s -cf %s -C bar @%s", testprog, filename, absolute_path); +#else + r = systemf("%s -cf %s \"@%s\" >step1.out 2>step1.err", testprog, filename, absolute_path); + failure("Error invoking %s -cf %s -C bar \"@%s\"", testprog, filename, absolute_path); +#endif + + assertEqualInt(r, 0); + assertEmptyFile("step1.out"); + assertEmptyFile("step1.err"); + + /* Do validation of the constructed archive. */ + + p0 = slurpfile(&s, "output.tar"); + if (!assert(p0 != NULL)) + goto done; + if (!assert(s >= 2048)) + goto done; + assertEqualMem(p0 + 0, "f", 2); + assertEqualMem(p0 + 512, "abc", 4); + assertEqualMem(p0 + 1024, "g", 2); + assertEqualMem(p0 + 1536, "abc", 4); +done: + free(p0); + free(absolute_path); +} + + diff --git a/contrib/libarchive/tar/test/test_option_safe_writes.c b/contrib/libarchive/tar/test/test_option_safe_writes.c index b88479bc5f35..d30b9a745927 100644 --- a/contrib/libarchive/tar/test/test_option_safe_writes.c +++ b/contrib/libarchive/tar/test/test_option_safe_writes.c @@ -16,11 +16,12 @@ DEFINE_TEST(test_option_safe_writes) assertMakeFile("d", 0644, "c"); assertMakeFile("fs", 0644, "d"); assertMakeFile("ds", 0644, "e"); + assertMakeDir("fd", 0755); assertEqualInt(0, chdir("..")); /* Tar files up */ assertEqualInt(0, - systemf("%s -c -C in -f t.tar f fh d fs ds " + systemf("%s -c -C in -f t.tar f fh d fs ds fd " ">pack.out 2>pack.err", testprog)); /* Verify that nothing went to stdout or stderr. */ @@ -32,6 +33,7 @@ DEFINE_TEST(test_option_safe_writes) assertEqualInt(0, chdir("out")); assertMakeFile("f", 0644, "a"); assertMakeHardlink("fh", "f"); + assertMakeFile("fd", 0644, "b"); assertMakeDir("d", 0755); if (canSymlink()) { assertMakeSymlink("fs", "f", 0); @@ -55,4 +57,5 @@ DEFINE_TEST(test_option_safe_writes) assertTextFileContents("c","d"); assertTextFileContents("d","fs"); assertTextFileContents("e","ds"); + assertIsDir("fd", 0755); } diff --git a/contrib/libarchive/tar/util.c b/contrib/libarchive/tar/util.c index c99f67797562..fc5e15cb039f 100644 --- a/contrib/libarchive/tar/util.c +++ b/contrib/libarchive/tar/util.c @@ -41,7 +41,7 @@ #endif #include "bsdtar.h" -#include "err.h" +#include "lafe_err.h" #include "passphrase.h" static size_t bsdtar_expand_char(char *, size_t, size_t, char); @@ -682,6 +682,7 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry) { char tmp[100]; size_t w; + size_t sw; const char *p; const char *fmt; time_t tim; @@ -769,8 +770,8 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry) ltime = localtime(&tim); #endif if (ltime) - strftime(tmp, sizeof(tmp), fmt, ltime); - else + sw = strftime(tmp, sizeof(tmp), fmt, ltime); + if (!ltime || !sw) sprintf(tmp, "-- -- ----"); fprintf(out, " %s ", tmp); safe_fprintf(out, "%s", archive_entry_pathname(entry)); diff --git a/contrib/libarchive/tar/write.c b/contrib/libarchive/tar/write.c index 21984e980ebd..9e6c97b580b7 100644 --- a/contrib/libarchive/tar/write.c +++ b/contrib/libarchive/tar/write.c @@ -58,7 +58,7 @@ #endif #include "bsdtar.h" -#include "err.h" +#include "lafe_err.h" #include "line_reader.h" #ifndef O_BINARY @@ -111,7 +111,32 @@ seek_file(int fd, int64_t offset, int whence) return (SetFilePointerEx((HANDLE)_get_osfhandle(fd), distance, NULL, FILE_BEGIN) ? 1 : -1); } -#define open _open + +static int +_open_wrap_sopen(char const *const path, int const oflag, ...) +{ + va_list ap; + int r, pmode; + + pmode = 0; + if (oflag & _O_CREAT) + { + va_start(ap, oflag); + pmode = va_arg(ap, int); + va_end(ap); + } + + _sopen_s(&r, path, oflag, _SH_DENYNO, pmode & 0600); + if (r < 0) + { + /* _sopen_s populates errno */ + return -1; + } + + return r; +} + +#define open _open_wrap_sopen #define close _close #define read _read #ifdef lseek diff --git a/contrib/libarchive/test_utils/test_common.h b/contrib/libarchive/test_utils/test_common.h index 064f0a6ec241..a9df300e3be8 100644 --- a/contrib/libarchive/test_utils/test_common.h +++ b/contrib/libarchive/test_utils/test_common.h @@ -340,8 +340,14 @@ int canGrzip(void); /* Return true if this platform can run the "gzip" program. */ int canGzip(void); -/* Return true if this platform can run the specified command. */ -int canRunCommand(const char *); +/* Return true if this platform can run the specified command. + * + * Result can be optionally cached with `*tested`: + * - 0 if not tested yet + * - <0 if already tested negative + * - >0 if already tested positive + */ +int canRunCommand(const char *cmd, int *tested); /* Return true if this platform can run the "lrzip" program. */ int canLrzip(void); diff --git a/contrib/libarchive/test_utils/test_main.c b/contrib/libarchive/test_utils/test_main.c index fe330e5a052e..f4d443060d88 100644 --- a/contrib/libarchive/test_utils/test_main.c +++ b/contrib/libarchive/test_utils/test_main.c @@ -2523,167 +2523,77 @@ static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */ #else static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */ #endif + /* - * Can this platform run the bzip2 program? + * Can this platform run the specified command? */ int -canBzip2(void) +canRunCommand(const char *cmd, int *tested) { - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("bzip2 --help %s", redirectArgs) == 0) - value = 1; - } - return (value); + int value = tested ? *tested : 0; + if (!value) { + value = systemf("%s %s", cmd, redirectArgs) ? -1 : +1; + if (tested) + *tested = value; + } + return (value > 0); } +#define CAN_RUN_FUNC(Program, Command) \ + int can##Program(void) { \ + static int tested = 0; \ + return canRunCommand((Command), &tested); \ + } + +/* + * Can this platform run the bzip2 program? + */ +CAN_RUN_FUNC(Bzip2, "bzip2 --help") + /* * Can this platform run the grzip program? */ -int -canGrzip(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("grzip -V %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Grzip, "grzip -V") /* * Can this platform run the gzip program? */ -int -canGzip(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("gzip --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Gzip, "gzip --help") /* * Can this platform run the lrzip program? */ -int -canRunCommand(const char *cmd) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("%s %s", cmd, redirectArgs) == 0) - value = 1; - } - return (value); -} - -int -canLrzip(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lrzip -V %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Lrzip, "lrzip -V") /* * Can this platform run the lz4 program? */ -int -canLz4(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lz4 --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Lz4, "lz4 --help") /* * Can this platform run the zstd program? */ -int -canZstd(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("zstd --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Zstd, "zstd --help") /* * Can this platform run the lzip program? */ -int -canLzip(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lzip --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Lzip, "lzip --help") /* * Can this platform run the lzma program? */ -int -canLzma(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lzma --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Lzma, "lzma --help") /* * Can this platform run the lzop program? */ -int -canLzop(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lzop --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Lzop, "lzop --help") /* * Can this platform run the xz program? */ -int -canXz(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("xz --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} +CAN_RUN_FUNC(Xz, "xz --help") /* * Can this filesystem handle nodump flags. @@ -4184,6 +4094,9 @@ main(int argc, char **argv) if (testprogfile == NULL) { tmp2_len = strlen(testprogdir) + 1 + strlen(PROGRAM) + 1; +#if defined(_WIN32) && !defined(__CYGWIN__) + tmp2_len += 4; +#endif if ((tmp2 = malloc(tmp2_len)) == NULL) { fprintf(stderr, "ERROR: Out of memory."); @@ -4192,6 +4105,9 @@ main(int argc, char **argv) strncpy(tmp2, testprogdir, tmp2_len); strncat(tmp2, "/", tmp2_len); strncat(tmp2, PROGRAM, tmp2_len); +#if defined(_WIN32) && !defined(__CYGWIN__) + strncat(tmp2, ".exe", tmp2_len); +#endif testprogfile = tmp2; } diff --git a/contrib/libarchive/unzip/bsdunzip.c b/contrib/libarchive/unzip/bsdunzip.c index 621afbeb9d6a..1b520e841690 100644 --- a/contrib/libarchive/unzip/bsdunzip.c +++ b/contrib/libarchive/unzip/bsdunzip.c @@ -29,6 +29,9 @@ #ifdef HAVE_LOCALE_H #include <locale.h> #endif +#ifdef HAVE_SIGNAL_H +#include <signal.h> +#endif #ifdef HAVE_STDARG_H #include <stdarg.h> #endif @@ -54,7 +57,7 @@ #include "bsdunzip.h" #include "passphrase.h" -#include "err.h" +#include "lafe_err.h" /* command-line options */ static int a_opt; /* convert EOL */ @@ -1187,6 +1190,16 @@ main(int argc, char *argv[]) const char *zipfile; int nopts; +#if defined(HAVE_SIGACTION) && defined(SIGCHLD) + { /* Do not ignore SIGCHLD. */ + struct sigaction sa; + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGCHLD, &sa, NULL); + } +#endif + lafe_setprogname(*argv, "bsdunzip"); #if HAVE_SETLOCALE diff --git a/contrib/libarchive/unzip/cmdline.c b/contrib/libarchive/unzip/cmdline.c index 8afddedd5ead..8e6eedd2321c 100644 --- a/contrib/libarchive/unzip/cmdline.c +++ b/contrib/libarchive/unzip/cmdline.c @@ -21,7 +21,7 @@ #endif #include "bsdunzip.h" -#include "err.h" +#include "lafe_err.h" /* * Short options for bsdunzip. Please keep this sorted. diff --git a/contrib/libarchive/unzip/test/test_C.c b/contrib/libarchive/unzip/test/test_C.c index 66835c8406f3..d386bd61e85d 100644 --- a/contrib/libarchive/unzip/test/test_C.c +++ b/contrib/libarchive/unzip/test/test_C.c @@ -9,6 +9,7 @@ /* Test C arg - match case-insensitive */ DEFINE_TEST(test_C) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -19,4 +20,7 @@ DEFINE_TEST(test_C) assertEmptyFile("test.err"); assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_L.c b/contrib/libarchive/unzip/test/test_L.c index 5b004d5d5707..85b43f592542 100644 --- a/contrib/libarchive/unzip/test/test_L.c +++ b/contrib/libarchive/unzip/test/test_L.c @@ -9,6 +9,7 @@ /* Test L arg - make names lowercase */ DEFINE_TEST(test_L) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -22,4 +23,7 @@ DEFINE_TEST(test_L) assertTextFileContents("contents b\n", "test_basic/b"); assertTextFileContents("contents c\n", "test_basic/c"); assertTextFileContents("contents CAPS\n", "test_basic/caps"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_P_encryption.c b/contrib/libarchive/unzip/test/test_P_encryption.c index e2cf3cda0ebd..ed08a068811b 100644 --- a/contrib/libarchive/unzip/test/test_P_encryption.c +++ b/contrib/libarchive/unzip/test/test_P_encryption.c @@ -14,9 +14,13 @@ DEFINE_TEST(test_P_encryption) 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"); + if (r == 256) { + assertTextFileContents("unzip: Decryption is unsupported due to lack of crypto library\n", "test.err"); + } else { + assertEqualInt(0, r); + assertNonEmptyFile("test.out"); + assertEmptyFile("test.err"); - assertTextFileContents("plaintext\n", "encrypted/file.txt"); + assertTextFileContents("plaintext\n", "encrypted/file.txt"); + } } diff --git a/contrib/libarchive/unzip/test/test_basic.c b/contrib/libarchive/unzip/test/test_basic.c index 1f37dcd416a3..3a884aa30e5d 100644 --- a/contrib/libarchive/unzip/test/test_basic.c +++ b/contrib/libarchive/unzip/test/test_basic.c @@ -9,6 +9,7 @@ /* This test just does a basic zip decompression */ DEFINE_TEST(test_basic) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -22,4 +23,7 @@ DEFINE_TEST(test_basic) assertTextFileContents("contents b\n", "test_basic/b"); assertTextFileContents("contents c\n", "test_basic/c"); assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_d.c b/contrib/libarchive/unzip/test/test_d.c index ea67246207f2..cd7c3dfd97ad 100644 --- a/contrib/libarchive/unzip/test/test_d.c +++ b/contrib/libarchive/unzip/test/test_d.c @@ -9,6 +9,7 @@ /* Test d arg - extract to target dir - before zipfile argument */ DEFINE_TEST(test_d_before_zipfile) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -22,11 +23,15 @@ DEFINE_TEST(test_d_before_zipfile) assertTextFileContents("contents b\n", "foobar/test_basic/b"); assertTextFileContents("contents c\n", "foobar/test_basic/c"); assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } /* Test d arg - extract to target dir - after zipfile argument */ DEFINE_TEST(test_d_after_zipfile) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -40,4 +45,7 @@ DEFINE_TEST(test_d_after_zipfile) assertTextFileContents("contents b\n", "foobar/test_basic/b"); assertTextFileContents("contents c\n", "foobar/test_basic/c"); assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_doubledash.c b/contrib/libarchive/unzip/test/test_doubledash.c index 4467213dbb89..db0445ec3c24 100644 --- a/contrib/libarchive/unzip/test/test_doubledash.c +++ b/contrib/libarchive/unzip/test/test_doubledash.c @@ -9,6 +9,7 @@ /* Test double dash arg - swallow "--" and use next argument as file name */ DEFINE_TEST(test_doubledash) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -22,4 +23,7 @@ DEFINE_TEST(test_doubledash) assertTextFileContents("contents b\n", "test_basic/b"); assertTextFileContents("contents c\n", "test_basic/c"); assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_glob.c b/contrib/libarchive/unzip/test/test_glob.c index b53aa16fd85c..589ff1c55ef3 100644 --- a/contrib/libarchive/unzip/test/test_glob.c +++ b/contrib/libarchive/unzip/test/test_glob.c @@ -9,6 +9,7 @@ /* Test that the glob works */ DEFINE_TEST(test_glob) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -22,4 +23,7 @@ DEFINE_TEST(test_glob) assertTextFileContents("contents b\n", "test_basic/b"); assertFileNotExists("test_basic/c"); assertFileNotExists("test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_j.c b/contrib/libarchive/unzip/test/test_j.c index b87229f42e25..1fba8ca207ec 100644 --- a/contrib/libarchive/unzip/test/test_j.c +++ b/contrib/libarchive/unzip/test/test_j.c @@ -9,6 +9,7 @@ /* Test j arg - don't make directories */ DEFINE_TEST(test_j) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -22,4 +23,7 @@ DEFINE_TEST(test_j) assertTextFileContents("contents b\n", "b"); assertTextFileContents("contents c\n", "c"); assertTextFileContents("contents CAPS\n", "CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_n.c b/contrib/libarchive/unzip/test/test_n.c index bb75c5d7696d..a13623ce23df 100644 --- a/contrib/libarchive/unzip/test/test_n.c +++ b/contrib/libarchive/unzip/test/test_n.c @@ -9,6 +9,7 @@ /* Test n arg - don't overwrite existing files */ DEFINE_TEST(test_n) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -26,4 +27,7 @@ DEFINE_TEST(test_n) assertTextFileContents("orig b\n", "test_basic/b"); assertTextFileContents("contents c\n", "test_basic/c"); assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_o.c b/contrib/libarchive/unzip/test/test_o.c index 64f946774440..8c48348c41a4 100644 --- a/contrib/libarchive/unzip/test/test_o.c +++ b/contrib/libarchive/unzip/test/test_o.c @@ -9,6 +9,7 @@ /* Test o arg - overwrite existing files */ DEFINE_TEST(test_o) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -25,4 +26,7 @@ DEFINE_TEST(test_o) assertTextFileContents("contents b\n", "test_basic/b"); assertTextFileContents("contents c\n", "test_basic/c"); assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_p.c b/contrib/libarchive/unzip/test/test_p.c index 8bfffbe5dc39..13a7765463ec 100644 --- a/contrib/libarchive/unzip/test/test_p.c +++ b/contrib/libarchive/unzip/test/test_p.c @@ -9,6 +9,7 @@ /* Test p arg - Print to stdout */ DEFINE_TEST(test_p) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -17,4 +18,7 @@ DEFINE_TEST(test_p) assertEqualInt(0, r); assertTextFileContents("contents a\ncontents b\ncontents c\ncontents CAPS\n", "test.out"); assertEmptyFile("test.err"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_q.c b/contrib/libarchive/unzip/test/test_q.c index 13222a483992..0579e8028d76 100644 --- a/contrib/libarchive/unzip/test/test_q.c +++ b/contrib/libarchive/unzip/test/test_q.c @@ -9,6 +9,7 @@ /* Test q arg - Quiet */ DEFINE_TEST(test_q) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -22,4 +23,7 @@ DEFINE_TEST(test_q) assertTextFileContents("contents b\n", "test_basic/b"); assertTextFileContents("contents c\n", "test_basic/c"); assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_singlefile.c b/contrib/libarchive/unzip/test/test_singlefile.c index a72811f046d9..a5a35ecacc4d 100644 --- a/contrib/libarchive/unzip/test/test_singlefile.c +++ b/contrib/libarchive/unzip/test/test_singlefile.c @@ -9,6 +9,7 @@ /* Ensure single-file zips work */ DEFINE_TEST(test_singlefile) { +#ifdef HAVE_LIBZ const char *reffile = "test_singlefile.zip"; int r; @@ -19,4 +20,7 @@ DEFINE_TEST(test_singlefile) assertEmptyFile("test.err"); assertTextFileContents("hello\n", "file.txt"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_t.c b/contrib/libarchive/unzip/test/test_t.c index 55a516fc636f..7565830915c3 100644 --- a/contrib/libarchive/unzip/test/test_t.c +++ b/contrib/libarchive/unzip/test/test_t.c @@ -9,6 +9,7 @@ /* Test t arg - Test zip contents */ DEFINE_TEST(test_t) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -17,4 +18,7 @@ DEFINE_TEST(test_t) assertEqualInt(0, r); assertNonEmptyFile("test.out"); assertEmptyFile("test.err"); +#else + skipping("zlib not available"); +#endif } diff --git a/contrib/libarchive/unzip/test/test_x.c b/contrib/libarchive/unzip/test/test_x.c index 959beb1950df..43a2085dc5b2 100644 --- a/contrib/libarchive/unzip/test/test_x.c +++ b/contrib/libarchive/unzip/test/test_x.c @@ -9,6 +9,7 @@ /* Test x arg with single exclude path */ DEFINE_TEST(test_x_single) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -22,11 +23,15 @@ DEFINE_TEST(test_x_single) assertTextFileContents("contents b\n", "test_basic/b"); assertFileNotExists("test_basic/c"); assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } /* Test x arg with multiple exclude paths */ DEFINE_TEST(test_x_multiple) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -40,11 +45,15 @@ DEFINE_TEST(test_x_multiple) assertFileNotExists("test_basic/b"); assertFileNotExists("test_basic/c"); assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } /* Test x arg with multiple exclude paths and a d arg afterwards */ DEFINE_TEST(test_x_multiple_with_d) { +#ifdef HAVE_LIBZ const char *reffile = "test_basic.zip"; int r; @@ -58,4 +67,7 @@ DEFINE_TEST(test_x_multiple_with_d) assertFileNotExists("foobar/test_basic/b"); assertFileNotExists("foobar/test_basic/c"); assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS"); +#else + skipping("zlib not available"); +#endif } |