git: 9597624d82c7 - stable/11 - libarchive: merge from vendor branch

From: Martin Matuska <mm_at_FreeBSD.org>
Date: Wed, 28 Dec 2022 22:45:16 UTC
The branch stable/11 has been updated by mm:

URL: https://cgit.FreeBSD.org/src/commit/?id=9597624d82c7ebd845c11bf4c7e27d6bbf42dd96

commit 9597624d82c7ebd845c11bf4c7e27d6bbf42dd96
Author:     Martin Matuska <mm@FreeBSD.org>
AuthorDate: 2022-12-13 19:21:13 +0000
Commit:     Martin Matuska <mm@FreeBSD.org>
CommitDate: 2022-12-28 22:16:47 +0000

    libarchive: merge from vendor branch
    
    Libarchive 3.6.2
    
    Important bug fixes:
      rar5 reader: fix possible garbled output with bsdtar -O (#1745)
      mtree reader: support reading mtree files with tabs (#1783)
      various small fixes for issues found by CodeQL
    
    (cherry picked from commit bd5e624a861433dee76fe00a8acedc9564425332)
---
 contrib/libarchive/NEWS                            |  2 +
 contrib/libarchive/README.md                       |  5 ++
 contrib/libarchive/cpio/test/test_option_t.c       | 24 +++++-
 contrib/libarchive/libarchive/archive.h            |  6 +-
 contrib/libarchive/libarchive/archive_digest.c     | 16 ++--
 contrib/libarchive/libarchive/archive_entry.c      | 14 ++++
 contrib/libarchive/libarchive/archive_entry.h      |  4 +-
 contrib/libarchive/libarchive/archive_hmac.c       | 29 ++++++++
 .../libarchive/libarchive/archive_hmac_private.h   |  7 ++
 contrib/libarchive/libarchive/archive_platform.h   |  3 +-
 .../libarchive/archive_read_disk_posix.c           |  7 +-
 .../libarchive/archive_read_support_filter_lz4.c   |  6 ++
 .../libarchive/archive_read_support_filter_lzop.c  |  2 +
 .../libarchive/archive_read_support_filter_xz.c    |  2 +
 .../libarchive/archive_read_support_format_7zip.c  |  8 +-
 .../libarchive/archive_read_support_format_cab.c   |  6 +-
 .../archive_read_support_format_iso9660.c          |  2 +-
 .../libarchive/archive_read_support_format_lha.c   |  6 +-
 .../libarchive/archive_read_support_format_mtree.c | 24 ++++--
 .../libarchive/archive_read_support_format_rar.c   | 10 +++
 .../libarchive/archive_read_support_format_rar5.c  |  9 +++
 .../libarchive/archive_read_support_format_tar.c   | 20 ++++-
 .../libarchive/archive_read_support_format_xar.c   |  4 +
 contrib/libarchive/libarchive/archive_string.c     |  6 +-
 contrib/libarchive/libarchive/archive_write.c      |  8 ++
 .../libarchive/archive_write_disk_posix.c          |  4 +-
 contrib/libarchive/libarchive/archive_write_open.3 |  1 +
 .../libarchive/archive_write_set_format_pax.c      |  2 +-
 contrib/libarchive/libarchive/filter_fork_posix.c  |  2 +-
 .../libarchive/test/test_acl_platform_nfs4.c       |  4 +-
 .../libarchive/test/test_archive_api_feature.c     |  2 +-
 .../libarchive/test/test_archive_match_time.c      | 30 ++++++++
 .../test/test_archive_string_conversion.c          |  1 +
 .../libarchive/test/test_read_format_mtree.c       | 30 ++++++++
 .../libarchive/test/test_read_format_rar5.c        | 43 ++++++++---
 .../test/test_read_format_tar_invalid_pax_size.c   | 53 +++++++++++++
 .../test_read_format_tar_invalid_pax_size.tar.uu   | 38 ++++++++++
 .../libarchive/test/test_read_truncated_filter.c   |  4 +-
 .../libarchive/libarchive/test/test_sparse_basic.c |  4 +-
 .../libarchive/libarchive/test/test_tar_large.c    |  4 +-
 .../libarchive/test/test_write_disk_secure744.c    |  2 +-
 .../libarchive/test/test_write_filter_b64encode.c  |  8 +-
 .../libarchive/test/test_write_filter_bzip2.c      | 12 +--
 .../libarchive/test/test_write_filter_compress.c   |  4 +-
 .../libarchive/test/test_write_filter_gzip.c       | 12 +--
 .../libarchive/test/test_write_filter_lrzip.c      |  4 +-
 .../libarchive/test/test_write_filter_lz4.c        | 16 ++--
 .../libarchive/test/test_write_filter_lzip.c       | 12 +--
 .../libarchive/test/test_write_filter_lzma.c       | 12 +--
 .../libarchive/test/test_write_filter_lzop.c       | 12 +--
 .../libarchive/test/test_write_filter_uuencode.c   |  8 +-
 .../libarchive/test/test_write_filter_xz.c         | 12 +--
 .../libarchive/test/test_write_filter_zstd.c       | 12 +--
 .../test/test_write_format_zip_compression_store.c | 23 +++++-
 .../libarchive/test/test_write_format_zip_file.c   | 21 +++++-
 .../test/test_write_format_zip_file_zip64.c        | 21 +++++-
 .../libarchive/test/test_write_format_zip_large.c  |  4 +-
 contrib/libarchive/tar/bsdtar.1                    |  2 +-
 contrib/libarchive/tar/subst.c                     |  1 +
 contrib/libarchive/tar/test/test_copy.c            | 20 ++---
 contrib/libarchive/tar/test/test_option_b.c        |  8 +-
 contrib/libarchive/tar/util.c                      | 21 +++---
 contrib/libarchive/test_utils/test_main.c          | 87 ++++++++++++++--------
 lib/libarchive/tests/Makefile                      |  2 +
 64 files changed, 610 insertions(+), 178 deletions(-)

diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS
index bf0515f34d8c..d6324487691b 100644
--- a/contrib/libarchive/NEWS
+++ b/contrib/libarchive/NEWS
@@ -1,3 +1,5 @@
+Wed 07, 2022: libarchive 3.6.2 released
+
 Apr 08, 2022: libarchive 3.6.1 released
 
 Feb 09, 2022: libarchive 3.6.0 released
diff --git a/contrib/libarchive/README.md b/contrib/libarchive/README.md
index d5ef70c2191d..404076237871 100644
--- a/contrib/libarchive/README.md
+++ b/contrib/libarchive/README.md
@@ -37,6 +37,7 @@ The top-level directory contains the following information files:
 * **configure** - configuration script, see INSTALL for details.  If your copy of the source lacks a `configure` script, you can try to construct it by running the script in `build/autogen.sh` (or use `cmake`).
 
 The following files in the top-level directory are used by the 'configure' script:
+
 * `Makefile.am`, `aclocal.m4`, `configure.ac` - used to build this distribution, only needed by maintainers
 * `Makefile.in`, `config.h.in` - templates used by configure script
 
@@ -71,6 +72,7 @@ know about any errors or omissions you find.
 ## Supported Formats
 
 Currently, the library automatically detects and reads the following formats:
+
   * Old V7 tar archives
   * POSIX ustar
   * GNU tar format (including GNU long filenames, long link names, and sparse files)
@@ -92,6 +94,7 @@ Currently, the library automatically detects and reads the following formats:
   * XAR archives
 
 The library also detects and handles any of the following before evaluating the archive:
+
   * uuencoded files
   * files with RPM wrapper
   * gzip compression
@@ -103,6 +106,7 @@ The library also detects and handles any of the following before evaluating the
   * zstandard compression
 
 The library can create archives in any of the following formats:
+
   * POSIX ustar
   * POSIX pax interchange format
   * "restricted" pax format, which will create ustar archives except for
@@ -122,6 +126,7 @@ The library can create archives in any of the following formats:
   * XAR archives
 
 When creating archives, the result can be filtered with any of the following:
+
   * uuencode
   * gzip compression
   * bzip2 compression
diff --git a/contrib/libarchive/cpio/test/test_option_t.c b/contrib/libarchive/cpio/test/test_option_t.c
index eaa73fa3a016..0f2dda27cc20 100644
--- a/contrib/libarchive/cpio/test/test_option_t.c
+++ b/contrib/libarchive/cpio/test/test_option_t.c
@@ -36,6 +36,14 @@ DEFINE_TEST(test_option_t)
 	time_t mtime;
 	char date[32];
 	char date2[32];
+	struct tm *tmptr;
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+	struct tm tmbuf;
+#endif
+#if defined(HAVE__LOCALTIME64_S)
+	errno_t terr;
+	__time64_t tmptime;
+#endif
 
 	/* List reference archive, make sure the TOC is correct. */
 	extract_reference_file("test_option_t.cpio");
@@ -87,11 +95,23 @@ DEFINE_TEST(test_option_t)
 #ifdef HAVE_LOCALE_H
 	setlocale(LC_ALL, "");
 #endif
+#if defined(HAVE_LOCALTIME_R)
+        tmptr = localtime_r(&mtime, &tmbuf);
+#elif defined(HAVE__LOCALTIME64_S)
+        tmptime = mtime;
+        terr = _localtime64_s(&tmbuf, &tmptime);
+        if (terr)
+                tmptr = NULL;
+        else
+                tmptr = &tmbuf;
+#else
+        tmptr = localtime(&mtime);
+#endif
 #if defined(_WIN32) && !defined(__CYGWIN__)
-	strftime(date2, sizeof(date2)-1, "%b %d  %Y", localtime(&mtime));
+	strftime(date2, sizeof(date2)-1, "%b %d  %Y", tmptr);
 	_snprintf(date, sizeof(date)-1, "%12.12s file", date2);
 #else
-	strftime(date2, sizeof(date2)-1, "%b %e  %Y", localtime(&mtime));
+	strftime(date2, sizeof(date2)-1, "%b %e  %Y", tmptr);
 	snprintf(date, sizeof(date)-1, "%12.12s file", date2);
 #endif
 	assertEqualMem(p + 42, date, strlen(date));
diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h
index ee1a02f4de01..5fa56de6c9fd 100644
--- a/contrib/libarchive/libarchive/archive.h
+++ b/contrib/libarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006001
+#define	ARCHIVE_VERSION_NUMBER 3006002
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -120,6 +120,8 @@ typedef ssize_t la_ssize_t;
 #   define __LA_DECL	__declspec(dllimport)
 #  endif
 # endif
+#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
+#  define __LA_DECL __attribute__((visibility("default")))
 #else
 /* Static libraries or non-Windows needs no special declaration. */
 # define __LA_DECL
@@ -155,7 +157,7 @@ __LA_DECL int		archive_version_number(void);
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.6.1"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.6.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_digest.c b/contrib/libarchive/libarchive/archive_digest.c
index a7bd5f0286a4..3361b19ada82 100644
--- a/contrib/libarchive/libarchive/archive_digest.c
+++ b/contrib/libarchive/libarchive/archive_digest.c
@@ -49,16 +49,16 @@
  * Initialize a Message digest.
  */
 static int
-win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
+win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
 {
 
 	ctx->valid = 0;
 	if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
-	    PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+	    prov, CRYPT_VERIFYCONTEXT)) {
 		if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
 			return (ARCHIVE_FAILED);
 		if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
-		    PROV_RSA_FULL, CRYPT_NEWKEYSET))
+		    prov, CRYPT_NEWKEYSET))
 			return (ARCHIVE_FAILED);
 	}
 
@@ -276,7 +276,7 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
 static int
 __archive_md5init(archive_md5_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_MD5));
+  return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
 }
 
 static int
@@ -659,7 +659,7 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
 static int
 __archive_sha1init(archive_sha1_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_SHA1));
+  return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
 }
 
 static int
@@ -919,7 +919,7 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
 static int
 __archive_sha256init(archive_sha256_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_SHA_256));
+  return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
 }
 
 static int
@@ -1155,7 +1155,7 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
 static int
 __archive_sha384init(archive_sha384_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_SHA_384));
+  return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
 }
 
 static int
@@ -1415,7 +1415,7 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
 static int
 __archive_sha512init(archive_sha512_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_SHA_512));
+  return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
 }
 
 static int
diff --git a/contrib/libarchive/libarchive/archive_entry.c b/contrib/libarchive/libarchive/archive_entry.c
index 6ad1802876b0..46940e0b4e64 100644
--- a/contrib/libarchive/libarchive/archive_entry.c
+++ b/contrib/libarchive/libarchive/archive_entry.c
@@ -568,6 +568,13 @@ archive_entry_nlink(struct archive_entry *entry)
 	return (entry->ae_stat.aest_nlink);
 }
 
+/* Instead, our caller could have chosen a specific encoding
+ * (archive_mstring_get_mbs, archive_mstring_get_utf8,
+ * archive_mstring_get_wcs).  So we should try multiple
+ * encodings.  Try mbs first because of history, even though
+ * utf8 might be better for pathname portability.
+ * Also omit wcs because of type mismatch (char * versus wchar *)
+ */
 const char *
 archive_entry_pathname(struct archive_entry *entry)
 {
@@ -575,6 +582,13 @@ archive_entry_pathname(struct archive_entry *entry)
 	if (archive_mstring_get_mbs(
 	    entry->archive, &entry->ae_pathname, &p) == 0)
 		return (p);
+#if HAVE_EILSEQ  /*{*/
+    if (errno == EILSEQ) {
+	    if (archive_mstring_get_utf8(
+	        entry->archive, &entry->ae_pathname, &p) == 0)
+		    return (p);
+    }
+#endif  /*}*/
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
 	return (NULL);
diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h
index 461866a5a6a2..ff64a4712a56 100644
--- a/contrib/libarchive/libarchive/archive_entry.h
+++ b/contrib/libarchive/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006001
+#define	ARCHIVE_VERSION_NUMBER 3006002
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
@@ -122,6 +122,8 @@ typedef ssize_t la_ssize_t;
 #   define __LA_DECL	__declspec(dllimport)
 #  endif
 # endif
+#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
+#  define __LA_DECL __attribute__((visibility("default")))
 #else
 /* Static libraries on all platforms and shared libraries on non-Windows. */
 # define __LA_DECL
diff --git a/contrib/libarchive/libarchive/archive_hmac.c b/contrib/libarchive/libarchive/archive_hmac.c
index 2a9d04c8d8f1..012fe1596211 100644
--- a/contrib/libarchive/libarchive/archive_hmac.c
+++ b/contrib/libarchive/libarchive/archive_hmac.c
@@ -230,10 +230,23 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
 static int
 __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	OSSL_PARAM params[2];
+
+	EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+	*ctx = EVP_MAC_CTX_new(mac);
+	if (*ctx == NULL)
+		return -1;
+	EVP_MAC_free(mac);
+	params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
+	params[1] = OSSL_PARAM_construct_end();
+	EVP_MAC_init(*ctx, key, key_len, params);
+#else
 	*ctx = HMAC_CTX_new();
 	if (*ctx == NULL)
 		return -1;
 	HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL);
+#endif
 	return 0;
 }
 
@@ -241,22 +254,38 @@ static void
 __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
     size_t data_len)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	EVP_MAC_update(*ctx, data, data_len);
+#else
 	HMAC_Update(*ctx, data, data_len);
+#endif
 }
 
 static void
 __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	size_t len = *out_len;
+#else
 	unsigned int len = (unsigned int)*out_len;
+#endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	EVP_MAC_final(*ctx, out, &len, *out_len);
+#else
 	HMAC_Final(*ctx, out, &len);
+#endif
 	*out_len = len;
 }
 
 static void
 __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	EVP_MAC_CTX_free(*ctx);
+#else
 	HMAC_CTX_free(*ctx);
+#endif
 	*ctx = NULL;
 }
 
diff --git a/contrib/libarchive/libarchive/archive_hmac_private.h b/contrib/libarchive/libarchive/archive_hmac_private.h
index 13a67d4955a5..50044a045e37 100644
--- a/contrib/libarchive/libarchive/archive_hmac_private.h
+++ b/contrib/libarchive/libarchive/archive_hmac_private.h
@@ -74,9 +74,16 @@ typedef mbedtls_md_context_t archive_hmac_sha1_ctx;
 typedef	struct hmac_sha1_ctx archive_hmac_sha1_ctx;
 
 #elif defined(HAVE_LIBCRYPTO)
+#include <openssl/opensslv.h>
+#include <openssl/hmac.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
+
+#else
 #include "archive_openssl_hmac_private.h"
 
 typedef	HMAC_CTX* archive_hmac_sha1_ctx;
+#endif
 
 #else
 
diff --git a/contrib/libarchive/libarchive/archive_platform.h b/contrib/libarchive/libarchive/archive_platform.h
index 668db4e81b02..bfd1c387eeba 100644
--- a/contrib/libarchive/libarchive/archive_platform.h
+++ b/contrib/libarchive/libarchive/archive_platform.h
@@ -195,8 +195,9 @@
 
 /*
  * 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))
+#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
diff --git a/contrib/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libarchive/libarchive/archive_read_disk_posix.c
index 2b39e672b49c..5a94ec5d4399 100644
--- a/contrib/libarchive/libarchive/archive_read_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_read_disk_posix.c
@@ -34,9 +34,6 @@ __FBSDID("$FreeBSD$");
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
-#ifdef HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
@@ -54,6 +51,8 @@ __FBSDID("$FreeBSD$");
 #endif
 #ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>
+#elif HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
 #endif
 /*
  * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
@@ -2103,6 +2102,8 @@ tree_push(struct tree *t, const char *path, int filesystem_id,
 	struct tree_entry *te;
 
 	te = calloc(1, sizeof(*te));
+	if (te == NULL)
+		__archive_errx(1, "Out of memory");
 	te->next = t->stack;
 	te->parent = t->current;
 	if (te->parent)
diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c b/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c
index ae0b08003f80..1e99542d7b7b 100644
--- a/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c
+++ b/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c
@@ -450,7 +450,9 @@ lz4_filter_read_descriptor(struct archive_read_filter *self)
 	chsum = (chsum >> 8) & 0xff;
 	chsum_verifier = read_buf[descriptor_bytes-1] & 0xff;
 	if (chsum != chsum_verifier)
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		goto malformed_error;
+#endif
 
 	__archive_read_filter_consume(self->upstream, descriptor_bytes);
 
@@ -521,7 +523,9 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
 		unsigned int chsum_block =
 		    archive_le32dec(read_buf + 4 + compressed_size);
 		if (chsum != chsum_block)
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			goto malformed_error;
+#endif
 	}
 
 
@@ -652,10 +656,12 @@ lz4_filter_read_default_stream(struct archive_read_filter *self, const void **p)
 			    state->xxh32_state);
 			state->xxh32_state = NULL;
 			if (checksum != checksum_stream) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 				archive_set_error(&self->archive->archive,
 				    ARCHIVE_ERRNO_MISC,
 				    "lz4 stream checksum error");
 				return (ARCHIVE_FATAL);
+#endif
 			}
 		} else if (ret > 0)
 			__archive_xxhash.XXH32_update(state->xxh32_state,
diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_lzop.c b/contrib/libarchive/libarchive/archive_read_support_filter_lzop.c
index afd2d4d0c49a..4ebdd3bf3eb1 100644
--- a/contrib/libarchive/libarchive/archive_read_support_filter_lzop.c
+++ b/contrib/libarchive/libarchive/archive_read_support_filter_lzop.c
@@ -283,7 +283,9 @@ consume_header(struct archive_read_filter *self)
 	else
 		checksum = adler32(adler32(0, NULL, 0), p, len);
 	if (archive_be32dec(p + len) != checksum)
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		goto corrupted;
+#endif
 	__archive_read_filter_consume(self->upstream, len + 4);
 	if (flags & EXTRA_FIELD) {
 		/* Skip extra field */
diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_xz.c b/contrib/libarchive/libarchive/archive_read_support_filter_xz.c
index 32ae0be92e0e..e313d39c0cf2 100644
--- a/contrib/libarchive/libarchive/archive_read_support_filter_xz.c
+++ b/contrib/libarchive/libarchive/archive_read_support_filter_xz.c
@@ -612,9 +612,11 @@ lzip_tail(struct archive_read_filter *self)
 	/* Check the crc32 value of the uncompressed data of the current
 	 * member */
 	if (state->crc32 != archive_le32dec(f)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
 		    "Lzip: CRC32 error");
 		return (ARCHIVE_FAILED);
+#endif
 	}
 
 	/* Check the uncompressed size of the current member */
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
index 564ba514a4b1..0ba4bee358b2 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
@@ -776,7 +776,7 @@ archive_read_format_7zip_read_header(struct archive_read *a,
 	}
 
 	/* Set up a more descriptive format name. */
-	sprintf(zip->format_name, "7-Zip");
+	snprintf(zip->format_name, sizeof(zip->format_name), "7-Zip");
 	a->archive.archive_format_name = zip->format_name;
 
 	return (ret);
@@ -2857,8 +2857,10 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
 	/* CRC check. */
 	if (crc32(0, (const unsigned char *)p + 12, 20)
 	    != archive_le32dec(p + 8)) {
+#ifdef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, -1, "Header CRC error");
 		return (ARCHIVE_FATAL);
+#endif
 	}
 
 	next_header_offset = archive_le64dec(p + 12);
@@ -2908,8 +2910,10 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
 		/* Check the EncodedHeader CRC.*/
 		if (r == 0 && zip->header_crc32 != next_header_crc) {
 			archive_set_error(&a->archive, -1,
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			    "Damaged 7-Zip archive");
 			r = -1;
+#endif
 		}
 		if (r == 0) {
 			if (zip->si.ci.folders[0].digest_defined)
@@ -2960,9 +2964,11 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
 
 		/* Check the Header CRC.*/
 		if (check_header_crc && zip->header_crc32 != next_header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			archive_set_error(&a->archive, -1,
 			    "Malformed 7-Zip archive");
 			return (ARCHIVE_FATAL);
+#endif
 		}
 		break;
 	default:
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_cab.c b/contrib/libarchive/libarchive/archive_read_support_format_cab.c
index 950f3d254de6..4d5029b1bd2e 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_cab.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_cab.c
@@ -996,7 +996,7 @@ archive_read_format_cab_read_header(struct archive_read *a,
 		cab->end_of_entry_cleanup = cab->end_of_entry = 1;
 
 	/* Set up a more descriptive format name. */
-	sprintf(cab->format_name, "CAB %d.%d (%s)",
+	snprintf(cab->format_name, sizeof(cab->format_name), "CAB %d.%d (%s)",
 	    hd->major, hd->minor, cab->entry_cffolder->compname);
 	a->archive.archive_format_name = cab->format_name;
 
@@ -1134,7 +1134,7 @@ cab_checksum_update(struct archive_read *a, size_t bytes)
 	}
 	if (sumbytes) {
 		int odd = sumbytes & 3;
-		if (sumbytes - odd > 0)
+		if ((int)(sumbytes - odd) > 0)
 			cfdata->sum_calculated = cab_checksum_cfdata_4(
 			    p, sumbytes - odd, cfdata->sum_calculated);
 		if (odd)
@@ -1171,12 +1171,14 @@ cab_checksum_finish(struct archive_read *a)
 	cfdata->sum_calculated = cab_checksum_cfdata(
 	    cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
 	if (cfdata->sum_calculated != cfdata->sum) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes",
 		    cab->entry_cffolder->cfdata_index -1,
 		    cfdata->sum, cfdata->sum_calculated,
 		    cfdata->compressed_size);
 		return (ARCHIVE_FAILED);
+#endif
 	}
 	return (ARCHIVE_OK);
 }
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c b/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c
index 15ded7c561e5..390ab84f43e3 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c
@@ -1757,7 +1757,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
 	size_t name_len;
 	const unsigned char *rr_start, *rr_end;
 	const unsigned char *p;
-	size_t dr_len;
+	size_t dr_len = 0;
 	uint64_t fsize, offset;
 	int32_t location;
 	int flags;
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_lha.c b/contrib/libarchive/libarchive/archive_read_support_format_lha.c
index bff0f01f41cf..bcfd42e1d920 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_lha.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_lha.c
@@ -739,7 +739,7 @@ archive_read_format_lha_read_header(struct archive_read *a,
 	if (lha->directory || lha->compsize == 0)
 		lha->end_of_entry = 1;
 
-	sprintf(lha->format_name, "lha -%c%c%c-",
+	snprintf(lha->format_name, sizeof(lha->format_name), "lha -%c%c%c-",
 	    lha->method[0], lha->method[1], lha->method[2]);
 	a->archive.archive_format_name = lha->format_name;
 
@@ -1039,9 +1039,11 @@ lha_read_file_header_2(struct archive_read *a, struct lha *lha)
 	}
 
 	if (header_crc != lha->header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "LHa header CRC error");
 		return (ARCHIVE_FATAL);
+#endif
 	}
 	return (err);
 }
@@ -1107,9 +1109,11 @@ lha_read_file_header_3(struct archive_read *a, struct lha *lha)
 		return (err);
 
 	if (header_crc != lha->header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "LHa header CRC error");
 		return (ARCHIVE_FATAL);
+#endif
 	}
 	return (err);
 invalid:
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
index 96eb133ed361..33a804501693 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
@@ -994,9 +994,11 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
 			struct mtree_entry *alt;
 			alt = (struct mtree_entry *)__archive_rb_tree_find_node(
 			    &mtree->rbtree, entry->name);
-			while (alt->next_dup)
-				alt = alt->next_dup;
-			alt->next_dup = entry;
+			if (alt != NULL) {
+				while (alt->next_dup)
+					alt = alt->next_dup;
+				alt->next_dup = entry;
+			}
 		}
 	}
 
@@ -1071,7 +1073,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
 			continue;
 		/* Non-printable characters are not allowed */
 		for (s = p;s < p + len - 1; s++) {
-			if (!isprint((unsigned char)*s)) {
+			if (!isprint((unsigned char)*s) && *s != '\t') {
 				r = ARCHIVE_FATAL;
 				break;
 			}
@@ -1250,9 +1252,17 @@ 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 &&
-				(errno != ENOENT ||
-				 archive_strlen(&mtree->contents_name) > 0)) {
+			if (mtree->fd == -1 && (
+#if defined(_WIN32) && !defined(__CYGWIN__)
+        /*
+         * On Windows, attempting to open a file with an
+         * invalid name result in EINVAL (Error 22)
+         */
+				(errno != ENOENT && errno != EINVAL)
+#else
+				errno != ENOENT
+#endif
+        || archive_strlen(&mtree->contents_name) > 0)) {
 				archive_set_error(&a->archive, errno,
 						"Can't open %s", path);
 				r = ARCHIVE_WARN;
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar.c b/contrib/libarchive/libarchive/archive_read_support_format_rar.c
index f9cbe2a8810d..793e8e985214 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_rar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_rar.c
@@ -1007,9 +1007,11 @@ archive_read_format_rar_read_header(struct archive_read *a,
 
       crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
       if ((crc32_val & 0xffff) != archive_le16dec(p)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
           "Header CRC error");
         return (ARCHIVE_FATAL);
+#endif
       }
       __archive_read_consume(a, skip);
       break;
@@ -1065,9 +1067,11 @@ archive_read_format_rar_read_header(struct archive_read *a,
 	      skip -= to_read;
       }
       if ((crc32_val & 0xffff) != crc32_expected) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 	      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		  "Header CRC error");
 	      return (ARCHIVE_FATAL);
+#endif
       }
       if (head_type == ENDARC_HEAD)
 	      return (ARCHIVE_EOF);
@@ -1432,9 +1436,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
   /* File Header CRC check. */
   crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7));
   if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
     archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
       "Header CRC error");
     return (ARCHIVE_FATAL);
+#endif
   }
   /* If no CRC error, Go on parsing File Header. */
   p = h;
@@ -1952,9 +1958,11 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
     *size = 0;
     *offset = rar->offset;
     if (rar->file_crc != rar->crc_calculated) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
       archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                         "File CRC error");
       return (ARCHIVE_FATAL);
+#endif
     }
     rar->entry_eof = 1;
     return (ARCHIVE_EOF);
@@ -2045,9 +2053,11 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
       *size = 0;
       *offset = rar->offset;
       if (rar->file_crc != rar->crc_calculated) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                           "File CRC error");
         return (ARCHIVE_FATAL);
+#endif
       }
       rar->entry_eof = 1;
       return (ARCHIVE_EOF);
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
index a3cfa72e77c8..38979cbe91a8 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
@@ -2821,11 +2821,13 @@ static int parse_block_header(struct archive_read* a, const uint8_t* p,
 	    ^ (uint8_t) (*block_size >> 16);
 
 	if(calculated_cksum != hdr->block_cksum) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Block checksum error: got 0x%x, expected 0x%x",
 		    hdr->block_cksum, calculated_cksum);
 
 		return ARCHIVE_FATAL;
+#endif
 	}
 
 	return ARCHIVE_OK;
@@ -3911,6 +3913,13 @@ static int do_unpack(struct archive_read* a, struct rar5* rar,
 			case GOOD:
 				/* fallthrough */
 			case BEST:
+				/* No data is returned here. But because a sparse-file aware
+				 * caller (like archive_read_data_into_fd) may treat zero-size
+				 * as a sparse file block, we need to update the offset
+				 * accordingly. At this point the decoder doesn't have any
+				 * pending uncompressed data blocks, so the current position in
+				 * the output file should be last_write_ptr. */
+				if (offset) *offset = rar->cstate.last_write_ptr;
 				return uncompress_file(a);
 			default:
 				archive_set_error(&a->archive,
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libarchive/libarchive/archive_read_support_format_tar.c
index 73bf323baf2f..892d9c7d26c9 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_tar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_tar.c
@@ -407,14 +407,13 @@ archive_read_format_tar_bid(struct archive_read *a, int best_bid)
 	/*
 	 * Check format of mode/uid/gid/mtime/size/rdevmajor/rdevminor fields.
 	 */
-	if (bid > 0 && (
-	    validate_number_field(header->mode, sizeof(header->mode)) == 0
+	if (validate_number_field(header->mode, sizeof(header->mode)) == 0
 	    || validate_number_field(header->uid, sizeof(header->uid)) == 0
 	    || validate_number_field(header->gid, sizeof(header->gid)) == 0
 	    || validate_number_field(header->mtime, sizeof(header->mtime)) == 0
 	    || validate_number_field(header->size, sizeof(header->size)) == 0
 	    || validate_number_field(header->rdevmajor, sizeof(header->rdevmajor)) == 0
-	    || validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0)) {
+	    || validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0) {
 		bid = 0;
 	}
 
@@ -2110,6 +2109,21 @@ pax_attribute(struct archive_read *a, struct tar *tar,
 			/* "size" is the size of the data in the entry. */
 			tar->entry_bytes_remaining
 			    = tar_atol10(value, strlen(value));
+			if (tar->entry_bytes_remaining < 0) {
+				tar->entry_bytes_remaining = 0;
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Tar size attribute is negative");
+				return (ARCHIVE_FATAL);
+			}
+			if (tar->entry_bytes_remaining == INT64_MAX) {
+				/* Note: tar_atol returns INT64_MAX on overflow */
+				tar->entry_bytes_remaining = 0;
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Tar size attribute overflow");
+				return (ARCHIVE_FATAL);
+			}
 			/*
 			 * The "size" pax header keyword always overrides the
 			 * "size" field in the tar header.
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_xar.c b/contrib/libarchive/libarchive/archive_read_support_format_xar.c
index 503ff58b91db..ec5b06edacd5 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_xar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_xar.c
@@ -624,7 +624,9 @@ read_toc(struct archive_read *a)
 		__archive_read_consume(a, xar->toc_chksum_size);
 		xar->offset += xar->toc_chksum_size;
 		if (r != ARCHIVE_OK)
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			return (ARCHIVE_FATAL);
+#endif
 	}
 
 	/*
@@ -827,10 +829,12 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
 		    xattr->a_sum.val, xattr->a_sum.len,
 		    xattr->e_sum.val, xattr->e_sum.len);
 		if (r != ARCHIVE_OK) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
 			    "Xattr checksum error");
 			r = ARCHIVE_WARN;
 			break;
+#endif
 		}
 		if (xattr->name.s == NULL) {
 			archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
diff --git a/contrib/libarchive/libarchive/archive_string.c b/contrib/libarchive/libarchive/archive_string.c
index ac66eee2c496..0fd918f47909 100644
--- a/contrib/libarchive/libarchive/archive_string.c
+++ b/contrib/libarchive/libarchive/archive_string.c
@@ -3988,10 +3988,10 @@ int
 archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes,
     const char **p, size_t *length, struct archive_string_conv *sc)
 {
-	int r, ret = 0;
-
-	(void)r; /* UNUSED */
+	int ret = 0;
 #if defined(_WIN32) && !defined(__CYGWIN__)
+	int r;
+
 	/*
 	 * Internationalization programming on Windows must use Wide
 	 * characters because Windows platform cannot make locale UTF-8.
diff --git a/contrib/libarchive/libarchive/archive_write.c b/contrib/libarchive/libarchive/archive_write.c
index 7d308a2ba8a5..3d3ba41f523e 100644
--- a/contrib/libarchive/libarchive/archive_write.c
+++ b/contrib/libarchive/libarchive/archive_write.c
@@ -201,6 +201,10 @@ __archive_write_allocate_filter(struct archive *_a)
 	struct archive_write_filter *f;
 
 	f = calloc(1, sizeof(*f));
+
+	if (f == NULL)
+		return (NULL);
+
 	f->archive = _a;
 	f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
 	if (a->filter_first == NULL)
@@ -548,6 +552,10 @@ archive_write_open2(struct archive *_a, void *client_data,
 	a->client_data = client_data;
 
 	client_filter = __archive_write_allocate_filter(_a);
+
+	if (client_filter == NULL)
+		return (ARCHIVE_FATAL);
+
 	client_filter->open = archive_write_client_open;
 	client_filter->write = archive_write_client_write;
 	client_filter->close = archive_write_client_close;
diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c
index a82dc83f4cda..1a36e6708c49 100644
--- a/contrib/libarchive/libarchive/archive_write_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c
@@ -1996,6 +1996,8 @@ archive_write_disk_new(void)
 		free(a);
 		return (NULL);
 	}
+	a->path_safe.s[0] = 0;
+
 #ifdef HAVE_ZLIB_H
 	a->decmpfs_compression_level = 5;
 #endif
@@ -2793,7 +2795,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
 	char *tail;
 	char *head;
 	int last;
-	char c;
+	char c = '\0';
 	int r;
 	struct stat st;
 	int chdir_fd;
diff --git a/contrib/libarchive/libarchive/archive_write_open.3 b/contrib/libarchive/libarchive/archive_write_open.3
index 29bffe49eb97..6bceb964f582 100644
--- a/contrib/libarchive/libarchive/archive_write_open.3
+++ b/contrib/libarchive/libarchive/archive_write_open.3
@@ -218,6 +218,7 @@ On failure, the callback should invoke
 .Fn archive_set_error
 to register an error code and message and
 return
+.Cm ARCHIVE_FATAL .
 .Bl -item -offset indent
 .It
 .Ft typedef int
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_pax.c b/contrib/libarchive/libarchive/archive_write_set_format_pax.c
index ec7d8eb6de88..a2e6d9ad1c53 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_pax.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_pax.c
@@ -1717,7 +1717,7 @@ build_pax_attribute_name(char *dest, const char *src)
 	 * to having clients override it.
 	 */
 #if HAVE_GETPID && 0  /* Disable this for now; see above comment. */
-	sprintf(buff, "PaxHeader.%d", getpid());
+	snprintf(buff, sizeof(buff), "PaxHeader.%d", getpid());
 #else
 	/* If the platform can't fetch the pid, don't include it. */
 	strcpy(buff, "PaxHeader");
diff --git a/contrib/libarchive/libarchive/filter_fork_posix.c b/contrib/libarchive/libarchive/filter_fork_posix.c
index ac255c4f8b20..62085a7099b7 100644
--- a/contrib/libarchive/libarchive/filter_fork_posix.c
+++ b/contrib/libarchive/libarchive/filter_fork_posix.c
@@ -76,7 +76,7 @@ int
*** 1626 LINES SKIPPED ***