git: bfa5e5858f63 - stable/13 - libarchive: import changes from upstream

From: Martin Matuska <mm_at_FreeBSD.org>
Date: Wed, 23 Feb 2022 09:56:52 UTC
The branch stable/13 has been updated by mm:

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

commit bfa5e5858f63a2c36f698b3076e65103367b51a3
Author:     Martin Matuska <mm@FreeBSD.org>
AuthorDate: 2022-02-09 23:35:42 +0000
Commit:     Martin Matuska <mm@FreeBSD.org>
CommitDate: 2022-02-23 07:56:34 +0000

    libarchive: import changes from upstream
    
    Libarchive 3.6.0
    
    New features:
    PR #1614: tar: new option "--no-read-sparse"
    PR #1503: RAR reader: filter support
    PR #1585: RAR5 reader: self-extracting archive support
    
    New features (not used in FreeBSD base):
    PR #1567: tar: threads support for zstd (#1567)
    PR #1518: ZIP reader: zstd decompression support
    
    Security Fixes:
    PR #1491, #1492, #1493, CVE-2021-36976:
       fix invalid memory access and out of bounds read in RAR5 reader
    PR #1566, #1618, CVE-2021-31566:
       extended fix for following symlinks when processing the fixup list
    
    Other notable bugfixes and improvements:
    PR #1620: tar: respect "--ignore-zeros" in c, r and u modes
    PR #1625: reduced size of application binaries
    
    Relnotes:       yes
    
    (cherry picked from commit 833a452e9f082a7982a31c21f0da437dbbe0a39d)
---
 contrib/libarchive/.editorconfig                   |    18 +
 contrib/libarchive/.github/workflows/cifuzz.yml    |    24 +
 contrib/libarchive/NEWS                            |     4 +
 .../build/autoconf/m4_ax_compile_check_sizeof.m4   |   115 +
 contrib/libarchive/libarchive/archive.h            |     8 +-
 contrib/libarchive/libarchive/archive_blake2.h     |     4 +-
 .../libarchive/libarchive/archive_blake2_impl.h    |     2 +-
 .../libarchive/libarchive/archive_blake2s_ref.c    |     1 +
 .../libarchive/libarchive/archive_blake2sp_ref.c   |     1 +
 contrib/libarchive/libarchive/archive_cryptor.c    |     8 -
 contrib/libarchive/libarchive/archive_entry.h      |     4 +-
 contrib/libarchive/libarchive/archive_getdate.c    |     2 +-
 contrib/libarchive/libarchive/archive_pack_dev.c   |     3 +-
 contrib/libarchive/libarchive/archive_platform.h   |    30 +
 contrib/libarchive/libarchive/archive_private.h    |     5 +-
 contrib/libarchive/libarchive/archive_read.c       |   150 +-
 .../libarchive/archive_read_append_filter.c        |     4 +-
 contrib/libarchive/libarchive/archive_read_disk.3  |    80 +-
 .../libarchive/archive_read_disk_entry_from_file.c |     8 +-
 .../libarchive/archive_read_disk_posix.c           |    28 +-
 .../libarchive/libarchive/archive_read_private.h   |    53 +-
 .../libarchive/archive_read_set_options.c          |    32 +-
 .../libarchive/archive_read_support_filter_bzip2.c |    36 +-
 .../archive_read_support_filter_compress.c         |    43 +-
 .../libarchive/archive_read_support_filter_grzip.c |    23 +-
 .../libarchive/archive_read_support_filter_gzip.c  |    35 +-
 .../libarchive/archive_read_support_filter_lrzip.c |    24 +-
 .../libarchive/archive_read_support_filter_lz4.c   |    36 +-
 .../libarchive/archive_read_support_filter_lzop.c  |    29 +-
 .../archive_read_support_filter_program.c          |    63 +-
 .../libarchive/archive_read_support_filter_rpm.c   |    32 +-
 .../libarchive/archive_read_support_filter_uu.c    |    32 +-
 .../libarchive/archive_read_support_filter_xz.c    |    75 +-
 .../libarchive/archive_read_support_filter_zstd.c  |    29 +-
 .../libarchive/archive_read_support_format_mtree.c |   117 +-
 .../libarchive/archive_read_support_format_rar.c   |   806 +-
 .../libarchive/archive_read_support_format_rar5.c  |   247 +-
 .../libarchive/archive_read_support_format_tar.c   |    16 +-
 .../libarchive/archive_read_support_format_zip.c   |   159 +-
 contrib/libarchive/libarchive/archive_string.c     |     2 +-
 contrib/libarchive/libarchive/archive_write.c      |    36 +-
 .../libarchive/archive_write_add_filter_xz.c       |     4 +-
 .../libarchive/archive_write_add_filter_zstd.c     |    42 +-
 contrib/libarchive/libarchive/archive_write_disk.3 |     8 +-
 .../libarchive/archive_write_disk_posix.c          |    33 +-
 .../libarchive/archive_write_set_format_cpio.c     |     1 +
 .../archive_write_set_format_cpio_binary.c         |    32 +-
 .../libarchive/archive_write_set_format_iso9660.c  |     2 +
 .../libarchive/archive_write_set_format_pax.c      |    10 +-
 .../libarchive/archive_write_set_format_zip.c      |    14 +-
 contrib/libarchive/libarchive/libarchive.3         |    40 +-
 .../test/test_archive_write_add_filter_by_name.c   |    12 +-
 .../libarchive/test/test_compat_tar_directory.c    |    77 +
 .../test/test_compat_tar_directory_1.tar.uu        |    50 +
 contrib/libarchive/libarchive/test/test_fuzz.c     |     5 +
 .../libarchive/test/test_read_data_large.c         |     4 +-
 .../libarchive/libarchive/test/test_read_extract.c |     3 +-
 .../libarchive/test/test_read_format_rar5.c        |    76 +
 ...format_rar5_bad_window_sz_in_mltarc_file.rar.uu |     7 +
 ...at_rar5_decode_number_out_of_bounds_read.rar.uu |    10 +
 .../test/test_read_format_rar5_sfx.exe.uu          |  7048 +++++
 ...d_format_rar5_window_buf_and_size_desync.rar.uu |    11 +
 .../libarchive/test/test_read_format_rar_filter.c  |    57 +
 .../test/test_read_format_rar_filter.rar.uu        | 26650 +++++++++++++++++++
 .../libarchive/test/test_read_format_zip.c         |   124 +
 .../test/test_read_format_zip_zstd.zipx.uu         |    18 +
 .../test/test_read_format_zip_zstd_multi.zipx.uu   |    94 +
 .../libarchive/libarchive/test/test_read_large.c   |     4 +-
 .../libarchive/test/test_read_pax_truncated.c      |     4 +-
 .../libarchive/test/test_read_truncated.c          |     3 +-
 .../libarchive/test/test_read_truncated_filter.c   |    22 +-
 .../libarchive/libarchive/test/test_sparse_basic.c |    37 +-
 .../libarchive/test/test_write_disk_secure746.c    |     4 -
 .../libarchive/test/test_write_filter_zstd.c       |     4 +
 .../libarchive/test/test_write_format_7zip_large.c |     6 +-
 .../test/test_write_format_zip_entry_size_unset.c  |   321 +
 contrib/libarchive/tar/bsdtar.1                    |    21 +
 contrib/libarchive/tar/bsdtar.c                    |    61 +-
 contrib/libarchive/tar/bsdtar.h                    |     4 +
 contrib/libarchive/tar/cmdline.c                   |     2 +
 contrib/libarchive/tar/creation_set.c              |     2 +-
 contrib/libarchive/tar/read.c                      |     7 +-
 .../libarchive/tar/test/test_option_ignore_zeros.c |   147 +
 contrib/libarchive/tar/write.c                     |     4 +
 contrib/libarchive/test_utils/test_common.h        |     2 +
 contrib/libarchive/test_utils/test_main.c          |   104 +-
 contrib/libarchive/test_utils/test_utils.c         |   151 +-
 contrib/libarchive/test_utils/test_utils.h         |    11 +-
 lib/libarchive/tests/Makefile                      |    13 +
 usr.bin/bsdcat/tests/Makefile                      |     2 +
 usr.bin/cpio/tests/Makefile                        |     2 +
 usr.bin/tar/tests/Makefile                         |     3 +
 92 files changed, 36971 insertions(+), 826 deletions(-)

diff --git a/contrib/libarchive/.editorconfig b/contrib/libarchive/.editorconfig
new file mode 100644
index 000000000000..2b797a039e97
--- /dev/null
+++ b/contrib/libarchive/.editorconfig
@@ -0,0 +1,18 @@
+# To use this config on you editor, follow the instructions at:
+# http://editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+indent_style = tab
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.sh]
+indent_style = space
+indent_size = 4
+
+[CMakeLists.txt]
+indent_style = space
+indent_size = 2
diff --git a/contrib/libarchive/.github/workflows/cifuzz.yml b/contrib/libarchive/.github/workflows/cifuzz.yml
new file mode 100644
index 000000000000..e5c60e4b0de2
--- /dev/null
+++ b/contrib/libarchive/.github/workflows/cifuzz.yml
@@ -0,0 +1,24 @@
+name: CIFuzz
+on: [pull_request]
+jobs:
+  Fuzzing:
+    runs-on: ubuntu-latest
+    steps:
+    - name: Build Fuzzers
+      id: build
+      uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
+      with:
+        oss-fuzz-project-name: 'libarchive'
+        dry-run: false
+    - name: Run Fuzzers
+      uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
+      with:
+        oss-fuzz-project-name: 'libarchive'
+        fuzz-seconds: 600
+        dry-run: false
+    - name: Upload Crash
+      uses: actions/upload-artifact@v1
+      if: failure() && steps.build.outcome == 'success'
+      with:
+        name: artifacts
+        path: ./out/artifacts
diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS
index 096410620d6b..0ccdb5d61b04 100644
--- a/contrib/libarchive/NEWS
+++ b/contrib/libarchive/NEWS
@@ -1,3 +1,7 @@
+Feb 09, 2022: libarchive 3.6.0 released
+
+Feb 08, 2022: libarchive 3.5.3 released
+
 Aug 22, 2021: libarchive 3.5.2 released
 
 Dec 26, 2020: libarchive 3.5.1 released
diff --git a/contrib/libarchive/build/autoconf/m4_ax_compile_check_sizeof.m4 b/contrib/libarchive/build/autoconf/m4_ax_compile_check_sizeof.m4
new file mode 100644
index 000000000000..f834df6346c9
--- /dev/null
+++ b/contrib/libarchive/build/autoconf/m4_ax_compile_check_sizeof.m4
@@ -0,0 +1,115 @@
+# ============================================================================
+#  https://www.gnu.org/software/autoconf-archive/ax_compile_check_sizeof.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+#   AX_COMPILE_CHECK_SIZEOF(TYPE [, HEADERS [, EXTRA_SIZES...]])
+#
+# DESCRIPTION
+#
+#   This macro checks for the size of TYPE using compile checks, not run
+#   checks. You can supply extra HEADERS to look into. the check will cycle
+#   through 1 2 4 8 16 and any EXTRA_SIZES the user supplies. If a match is
+#   found, it will #define SIZEOF_`TYPE' to that value. Otherwise it will
+#   emit a configure time error indicating the size of the type could not be
+#   determined.
+#
+#   The trick is that C will not allow duplicate case labels. While this is
+#   valid C code:
+#
+#     switch (0) case 0: case 1:;
+#
+#   The following is not:
+#
+#     switch (0) case 0: case 0:;
+#
+#   Thus, the AC_COMPILE_IFELSE will fail if the currently tried size does
+#   not match.
+#
+#   Here is an example skeleton configure.in script, demonstrating the
+#   macro's usage:
+#
+#     AC_PROG_CC
+#     AC_CHECK_HEADERS(stddef.h unistd.h)
+#     AC_TYPE_SIZE_T
+#     AC_CHECK_TYPE(ssize_t, int)
+#
+#     headers='#ifdef HAVE_STDDEF_H
+#     #include <stddef.h>
+#     #endif
+#     #ifdef HAVE_UNISTD_H
+#     #include <unistd.h>
+#     #endif
+#     '
+#
+#     AX_COMPILE_CHECK_SIZEOF(char)
+#     AX_COMPILE_CHECK_SIZEOF(short)
+#     AX_COMPILE_CHECK_SIZEOF(int)
+#     AX_COMPILE_CHECK_SIZEOF(long)
+#     AX_COMPILE_CHECK_SIZEOF(unsigned char *)
+#     AX_COMPILE_CHECK_SIZEOF(void *)
+#     AX_COMPILE_CHECK_SIZEOF(size_t, $headers)
+#     AX_COMPILE_CHECK_SIZEOF(ssize_t, $headers)
+#     AX_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers)
+#     AX_COMPILE_CHECK_SIZEOF(off_t, $headers)
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Kaveh Ghazi <ghazi@caip.rutgers.edu>
+#   Copyright (c) 2017 Reini Urban <rurban@cpan.org>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 8
+
+AU_ALIAS([AC_COMPILE_CHECK_SIZEOF], [AX_COMPILE_CHECK_SIZEOF])
+AC_DEFUN([AX_COMPILE_CHECK_SIZEOF],
+[changequote(<<, >>)dnl
+dnl The name to #define.
+define(<<AC_TYPE_NAME>>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl
+dnl The cache variable name.
+define(<<AC_CV_NAME>>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl
+changequote([, ])dnl
+AC_MSG_CHECKING(size of $1)
+AC_CACHE_VAL(AC_CV_NAME,
+[for ac_size in 4 8 1 2 16 $3 ; do # List sizes in rough order of prevalence.
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+$2
+]], [[switch (0) case 0: case (sizeof ($1) == $ac_size):;]])], [AC_CV_NAME=$ac_size])
+  if test x$AC_CV_NAME != x ; then break; fi
+done
+])
+if test x$AC_CV_NAME = x ; then
+  AC_MSG_ERROR([cannot determine a size for $1])
+fi
+AC_MSG_RESULT($AC_CV_NAME)
+AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1])
+undefine([AC_TYPE_NAME])dnl
+undefine([AC_CV_NAME])dnl
+])
diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h
index a44da908ad90..67381bf24be0 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 3005002
+#define	ARCHIVE_VERSION_NUMBER 3006000
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -97,7 +97,7 @@ typedef ssize_t la_ssize_t;
 #endif
 
 /* Large file support for Android */
-#ifdef __ANDROID__
+#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__)
 #include "android_lf.h"
 #endif
 
@@ -155,7 +155,7 @@ __LA_DECL int		archive_version_number(void);
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.5.2"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.6.0"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
@@ -1024,6 +1024,8 @@ __LA_DECL int  archive_read_disk_set_atime_restored(struct archive *);
 #define	ARCHIVE_READDISK_NO_ACL			(0x0020)
 /* Default: File flags are read from disk. */
 #define	ARCHIVE_READDISK_NO_FFLAGS		(0x0040)
+/* Default: Sparse file information is read from disk. */
+#define	ARCHIVE_READDISK_NO_SPARSE		(0x0080)
 
 __LA_DECL int  archive_read_disk_set_behavior(struct archive *,
 		    int flags);
diff --git a/contrib/libarchive/libarchive/archive_blake2.h b/contrib/libarchive/libarchive/archive_blake2.h
index dd6fe6fe5a98..8f6b5e9221f4 100644
--- a/contrib/libarchive/libarchive/archive_blake2.h
+++ b/contrib/libarchive/libarchive/archive_blake2.h
@@ -21,8 +21,10 @@
 
 #if defined(_MSC_VER)
 #define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
-#else
+#elif defined(__GNUC__)
 #define BLAKE2_PACKED(x) x __attribute__((packed))
+#else
+#define BLAKE2_PACKED(x) _Pragma("pack 1") x _Pragma("pack 0")
 #endif
 
 #if defined(__cplusplus)
diff --git a/contrib/libarchive/libarchive/archive_blake2_impl.h b/contrib/libarchive/libarchive/archive_blake2_impl.h
index 0f05defea36f..eb8619ca7c98 100644
--- a/contrib/libarchive/libarchive/archive_blake2_impl.h
+++ b/contrib/libarchive/libarchive/archive_blake2_impl.h
@@ -154,7 +154,7 @@ static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
 /* prevents compiler optimizing out memset() */
 static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
 {
-  static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
+  static void *(__LA_LIBC_CC *const volatile memset_v)(void *, int, size_t) = &memset;
   memset_v(v, 0, n);
 }
 
diff --git a/contrib/libarchive/libarchive/archive_blake2s_ref.c b/contrib/libarchive/libarchive/archive_blake2s_ref.c
index d92ffd0fc56a..b21a02ba6811 100644
--- a/contrib/libarchive/libarchive/archive_blake2s_ref.c
+++ b/contrib/libarchive/libarchive/archive_blake2s_ref.c
@@ -17,6 +17,7 @@
 #include <string.h>
 #include <stdio.h>
 
+#include "archive_platform.h"
 #include "archive_blake2.h"
 #include "archive_blake2_impl.h"
 
diff --git a/contrib/libarchive/libarchive/archive_blake2sp_ref.c b/contrib/libarchive/libarchive/archive_blake2sp_ref.c
index aef101084a8b..f412c8e2a657 100644
--- a/contrib/libarchive/libarchive/archive_blake2sp_ref.c
+++ b/contrib/libarchive/libarchive/archive_blake2sp_ref.c
@@ -21,6 +21,7 @@
 #include <omp.h>
 #endif
 
+#include "archive_platform.h"
 #include "archive_blake2.h"
 #include "archive_blake2_impl.h"
 
diff --git a/contrib/libarchive/libarchive/archive_cryptor.c b/contrib/libarchive/libarchive/archive_cryptor.c
index d4bca906b6ee..112baf161348 100644
--- a/contrib/libarchive/libarchive/archive_cryptor.c
+++ b/contrib/libarchive/libarchive/archive_cryptor.c
@@ -401,14 +401,6 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
 	memcpy(ctx->key, key, key_len);
 	memset(ctx->nonce, 0, sizeof(ctx->nonce));
 	ctx->encr_pos = AES_BLOCK_SIZE;
-#if OPENSSL_VERSION_NUMBER  >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
-	if (!EVP_CIPHER_CTX_reset(ctx->ctx)) {
-		EVP_CIPHER_CTX_free(ctx->ctx);
-		ctx->ctx = NULL;
-	}
-#else
-	EVP_CIPHER_CTX_init(ctx->ctx);
-#endif
 	return 0;
 }
 
diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h
index 90372b4d8f90..8b76360a777f 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 3005002
+#define	ARCHIVE_VERSION_NUMBER 3006000
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
@@ -99,7 +99,7 @@ typedef ssize_t la_ssize_t;
 #endif
 
 /* Large file support for Android */
-#ifdef __ANDROID__
+#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__)
 #include "android_lf.h"
 #endif
 
diff --git a/contrib/libarchive/libarchive/archive_getdate.c b/contrib/libarchive/libarchive/archive_getdate.c
index 3ec5bba88896..39e224cb9010 100644
--- a/contrib/libarchive/libarchive/archive_getdate.c
+++ b/contrib/libarchive/libarchive/archive_getdate.c
@@ -714,7 +714,7 @@ Convert(time_t Month, time_t Day, time_t Year,
 	    ? 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 || 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_pack_dev.c b/contrib/libarchive/libarchive/archive_pack_dev.c
index f8286d82183f..d95444d979f2 100644
--- a/contrib/libarchive/libarchive/archive_pack_dev.c
+++ b/contrib/libarchive/libarchive/archive_pack_dev.c
@@ -77,7 +77,7 @@ static	pack_t	pack_12_20;
 static	pack_t	pack_14_18;
 static	pack_t	pack_8_24;
 static	pack_t	pack_bsdos;
-static	int	compare_format(const void *, const void *);
+static	int	__LA_LIBC_CC compare_format(const void *, const void *);
 
 static const char iMajorError[] = "invalid major number";
 static const char iMinorError[] = "invalid minor number";
@@ -310,6 +310,7 @@ static const struct format {
 };
 
 static int
+__LA_LIBC_CC
 compare_format(const void *key, const void *element)
 {
 	const char		*name;
diff --git a/contrib/libarchive/libarchive/archive_platform.h b/contrib/libarchive/libarchive/archive_platform.h
index e7e6466b2e4e..668db4e81b02 100644
--- a/contrib/libarchive/libarchive/archive_platform.h
+++ b/contrib/libarchive/libarchive/archive_platform.h
@@ -69,8 +69,16 @@
  * either Windows or Posix APIs. */
 #if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
 #include "archive_windows.h"
+/* The C library on Windows specifies a calling convention for callback
+ * functions and exports; when we interact with them (capture pointers,
+ * call and pass function pointers) we need to match their calling
+ * convention.
+ * This only matters when libarchive is built with /Gr, /Gz or /Gv
+ * (which change the default calling convention.) */
+#define __LA_LIBC_CC __cdecl
 #else
 #define la_stat(path,stref)		stat(path,stref)
+#define __LA_LIBC_CC
 #endif
 
 /*
@@ -155,6 +163,28 @@
 #define	INTMAX_MIN ((intmax_t)(~INTMAX_MAX))
 #endif
 
+/* Some platforms lack the standard PRIxN/PRIdN definitions. */
+#if !HAVE_INTTYPES_H || !defined(PRIx32) || !defined(PRId32)
+#ifndef PRIx32
+#if SIZEOF_INT == 4
+#define PRIx32 "x"
+#elif SIZEOF_LONG == 4
+#define PRIx32 "lx"
+#else
+#error No suitable 32-bit unsigned integer type found for this platform
+#endif
+#endif // PRIx32
+#ifndef PRId32
+#if SIZEOF_INT == 4
+#define PRId32 "d"
+#elif SIZEOF_LONG == 4
+#define PRId32 "ld"
+#else
+#error No suitable 32-bit signed integer type found for this platform
+#endif
+#endif // PRId32
+#endif // !HAVE_INTTYPES_H || !defined(PRIx32) || !defined(PRId32)
+
 /*
  * If we can't restore metadata using a file descriptor, then
  * for compatibility's sake, close files before trying to restore metadata.
diff --git a/contrib/libarchive/libarchive/archive_private.h b/contrib/libarchive/libarchive/archive_private.h
index 1b769e8452dc..4eaf9ddbe680 100644
--- a/contrib/libarchive/libarchive/archive_private.h
+++ b/contrib/libarchive/libarchive/archive_private.h
@@ -107,14 +107,11 @@ struct archive {
 	 * Some public API functions depend on the "real" type of the
 	 * archive object.
 	 */
-	struct archive_vtable *vtable;
+	const struct archive_vtable *vtable;
 
 	int		  archive_format;
 	const char	 *archive_format_name;
 
-	int	  compression_code;	/* Currently active compression. */
-	const char *compression_name;
-
 	/* Number of file entries processed. */
 	int		  file_count;
 
diff --git a/contrib/libarchive/libarchive/archive_read.c b/contrib/libarchive/libarchive/archive_read.c
index c32526762708..ee514d78a618 100644
--- a/contrib/libarchive/libarchive/archive_read.c
+++ b/contrib/libarchive/libarchive/archive_read.c
@@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
 static int	choose_filters(struct archive_read *);
 static int	choose_format(struct archive_read *);
 static int	close_filters(struct archive_read *);
-static struct archive_vtable *archive_read_vtable(void);
 static int64_t	_archive_filter_bytes(struct archive *, int);
 static int	_archive_filter_code(struct archive *, int);
 static const char *_archive_filter_name(struct archive *, int);
@@ -73,26 +72,18 @@ static int	_archive_read_next_header2(struct archive *,
 		    struct archive_entry *);
 static int64_t  advance_file_pointer(struct archive_read_filter *, int64_t);
 
-static struct archive_vtable *
-archive_read_vtable(void)
-{
-	static struct archive_vtable av;
-	static int inited = 0;
-
-	if (!inited) {
-		av.archive_filter_bytes = _archive_filter_bytes;
-		av.archive_filter_code = _archive_filter_code;
-		av.archive_filter_name = _archive_filter_name;
-		av.archive_filter_count = _archive_filter_count;
-		av.archive_read_data_block = _archive_read_data_block;
-		av.archive_read_next_header = _archive_read_next_header;
-		av.archive_read_next_header2 = _archive_read_next_header2;
-		av.archive_free = _archive_read_free;
-		av.archive_close = _archive_read_close;
-		inited = 1;
-	}
-	return (&av);
-}
+static const struct archive_vtable
+archive_read_vtable = {
+	.archive_filter_bytes = _archive_filter_bytes,
+	.archive_filter_code = _archive_filter_code,
+	.archive_filter_name = _archive_filter_name,
+	.archive_filter_count = _archive_filter_count,
+	.archive_read_data_block = _archive_read_data_block,
+	.archive_read_next_header = _archive_read_next_header,
+	.archive_read_next_header2 = _archive_read_next_header2,
+	.archive_free = _archive_read_free,
+	.archive_close = _archive_read_close,
+};
 
 /*
  * Allocate, initialize and return a struct archive object.
@@ -109,7 +100,7 @@ archive_read_new(void)
 
 	a->archive.state = ARCHIVE_STATE_NEW;
 	a->entry = archive_entry_new2(&a->archive);
-	a->archive.vtable = archive_read_vtable();
+	a->archive.vtable = &archive_read_vtable;
 
 	a->passphrases.last = &a->passphrases.first;
 
@@ -245,24 +236,29 @@ client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence)
 }
 
 static int
-client_close_proxy(struct archive_read_filter *self)
+read_client_close_proxy(struct archive_read *a)
 {
 	int r = ARCHIVE_OK, r2;
 	unsigned int i;
 
-	if (self->archive->client.closer == NULL)
+	if (a->client.closer == NULL)
 		return (r);
-	for (i = 0; i < self->archive->client.nodes; i++)
+	for (i = 0; i < a->client.nodes; i++)
 	{
-		r2 = (self->archive->client.closer)
-			((struct archive *)self->archive,
-				self->archive->client.dataset[i].data);
+		r2 = (a->client.closer)
+			((struct archive *)a, a->client.dataset[i].data);
 		if (r > r2)
 			r = r2;
 	}
 	return (r);
 }
 
+static int
+client_close_proxy(struct archive_read_filter *self)
+{
+	return read_client_close_proxy(self->archive);
+}
+
 static int
 client_open_proxy(struct archive_read_filter *self)
 {
@@ -298,9 +294,7 @@ client_switch_proxy(struct archive_read_filter *self, unsigned int iindex)
 			r1 = (self->archive->client.closer)
 				((struct archive *)self->archive, self->data);
 		self->data = data2;
-		if (self->archive->client.opener != NULL)
-			r2 = (self->archive->client.opener)
-				((struct archive *)self->archive, self->data);
+		r2 = client_open_proxy(self);
 	}
 	return (r1 < r2) ? r1 : r2;
 }
@@ -457,13 +451,18 @@ archive_read_prepend_callback_data(struct archive *_a, void *client_data)
 	return archive_read_add_callback_data(_a, client_data, 0);
 }
 
+static const struct archive_read_filter_vtable
+none_reader_vtable = {
+	.read = client_read_proxy,
+	.close = client_close_proxy,
+};
+
 int
 archive_read_open1(struct archive *_a)
 {
 	struct archive_read *a = (struct archive_read *)_a;
 	struct archive_read_filter *filter, *tmp;
 	int slot, e = ARCHIVE_OK;
-	unsigned int i;
 
 	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
 	    "archive_read_open");
@@ -481,11 +480,7 @@ archive_read_open1(struct archive *_a)
 		e = (a->client.opener)(&a->archive, a->client.dataset[0].data);
 		if (e != 0) {
 			/* If the open failed, call the closer to clean up. */
-			if (a->client.closer) {
-				for (i = 0; i < a->client.nodes; i++)
-					(a->client.closer)(&a->archive,
-					    a->client.dataset[i].data);
-			}
+			read_client_close_proxy(a);
 			return (e);
 		}
 	}
@@ -497,14 +492,11 @@ archive_read_open1(struct archive *_a)
 	filter->upstream = NULL;
 	filter->archive = a;
 	filter->data = a->client.dataset[0].data;
-	filter->open = client_open_proxy;
-	filter->read = client_read_proxy;
-	filter->skip = client_skip_proxy;
-	filter->seek = client_seek_proxy;
-	filter->close = client_close_proxy;
-	filter->sswitch = client_switch_proxy;
+	filter->vtable = &none_reader_vtable;
 	filter->name = "none";
 	filter->code = ARCHIVE_FILTER_NONE;
+	filter->can_skip = 1;
+	filter->can_seek = 1;
 
 	a->client.dataset[0].begin_position = 0;
 	if (!a->filter || !a->bypass_filter_bidding)
@@ -570,12 +562,12 @@ choose_filters(struct archive_read *a)
 
 		bidder = a->bidders;
 		for (i = 0; i < number_bidders; i++, bidder++) {
-			if (bidder->bid != NULL) {
-				bid = (bidder->bid)(bidder, a->filter);
-				if (bid > best_bid) {
-					best_bid = bid;
-					best_bidder = bidder;
-				}
+			if (bidder->vtable == NULL)
+				continue;
+			bid = (bidder->vtable->bid)(bidder, a->filter);
+			if (bid > best_bid) {
+				best_bid = bid;
+				best_bidder = bidder;
 			}
 		}
 
@@ -587,8 +579,6 @@ choose_filters(struct archive_read *a)
 				__archive_read_free_filters(a);
 				return (ARCHIVE_FATAL);
 			}
-			a->archive.compression_name = a->filter->name;
-			a->archive.compression_code = a->filter->code;
 			return (ARCHIVE_OK);
 		}
 
@@ -600,7 +590,7 @@ choose_filters(struct archive_read *a)
 		filter->archive = a;
 		filter->upstream = a->filter;
 		a->filter = filter;
-		r = (best_bidder->init)(a->filter);
+		r = (best_bidder->vtable->init)(a->filter);
 		if (r != ARCHIVE_OK) {
 			__archive_read_free_filters(a);
 			return (ARCHIVE_FATAL);
@@ -614,10 +604,9 @@ choose_filters(struct archive_read *a)
 int
 __archive_read_header(struct archive_read *a, struct archive_entry *entry)
 {
-	if (a->filter->read_header)
-		return a->filter->read_header(a->filter, entry);
-	else
+	if (!a->filter->vtable->read_header)
 		return (ARCHIVE_OK);
+	return a->filter->vtable->read_header(a->filter, entry);
 }
 
 /*
@@ -1006,8 +995,8 @@ close_filters(struct archive_read *a)
 	/* Close each filter in the pipeline. */
 	while (f != NULL) {
 		struct archive_read_filter *t = f->upstream;
-		if (!f->closed && f->close != NULL) {
-			int r1 = (f->close)(f);
+		if (!f->closed && f->vtable != NULL) {
+			int r1 = (f->vtable->close)(f);
 			f->closed = 1;
 			if (r1 < r)
 				r = r1;
@@ -1112,11 +1101,10 @@ _archive_read_free(struct archive *_a)
 	/* Release the bidder objects. */
 	n = sizeof(a->bidders)/sizeof(a->bidders[0]);
 	for (i = 0; i < n; i++) {
-		if (a->bidders[i].free != NULL) {
-			int r1 = (a->bidders[i].free)(&a->bidders[i]);
-			if (r1 < r)
-				r = r1;
-		}
+		if (a->bidders[i].vtable == NULL ||
+		    a->bidders[i].vtable->free == NULL)
+			continue;
+		(a->bidders[i].vtable->free)(&a->bidders[i]);
 	}
 
 	/* Release passphrase list. */
@@ -1241,19 +1229,35 @@ __archive_read_register_format(struct archive_read *a,
  * initialization functions.
  */
 int
-__archive_read_get_bidder(struct archive_read *a,
-    struct archive_read_filter_bidder **bidder)
+__archive_read_register_bidder(struct archive_read *a,
+	void *bidder_data,
+	const char *name,
+	const struct archive_read_filter_bidder_vtable *vtable)
 {
+	struct archive_read_filter_bidder *bidder;
 	int i, number_slots;
 
+	archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
+	    ARCHIVE_STATE_NEW, "__archive_read_register_bidder");
+
 	number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
 
 	for (i = 0; i < number_slots; i++) {
-		if (a->bidders[i].bid == NULL) {
-			memset(a->bidders + i, 0, sizeof(a->bidders[0]));
-			*bidder = (a->bidders + i);
-			return (ARCHIVE_OK);
+		if (a->bidders[i].vtable != NULL)
+			continue;
+		memset(a->bidders + i, 0, sizeof(a->bidders[0]));
+		bidder = (a->bidders + i);
+		bidder->data = bidder_data;
+		bidder->name = name;
+		bidder->vtable = vtable;
+		if (bidder->vtable->bid == NULL || bidder->vtable->init == NULL) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+					"Internal error: "
+					"no bid/init for filter bidder");
+			return (ARCHIVE_FATAL);
 		}
+
+		return (ARCHIVE_OK);
 	}
 
 	archive_set_error(&a->archive, ENOMEM,
@@ -1382,7 +1386,7 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
 					*avail = 0;
 				return (NULL);
 			}
-			bytes_read = (filter->read)(filter,
+			bytes_read = (filter->vtable->read)(filter,
 			    &filter->client_buff);
 			if (bytes_read < 0) {		/* Read error. */
 				filter->client_total = filter->client_avail = 0;
@@ -1561,8 +1565,8 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request)
 		return (total_bytes_skipped);
 
 	/* If there's an optimized skip function, use it. */
-	if (filter->skip != NULL) {
-		bytes_skipped = (filter->skip)(filter, request);
+	if (filter->can_skip != 0) {
+		bytes_skipped = client_skip_proxy(filter, request);
 		if (bytes_skipped < 0) {	/* error */
 			filter->fatal = 1;
 			return (bytes_skipped);
@@ -1576,7 +1580,7 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request)
 
 	/* Use ordinary reads as necessary to complete the request. */
 	for (;;) {
-		bytes_read = (filter->read)(filter, &filter->client_buff);
+		bytes_read = (filter->vtable->read)(filter, &filter->client_buff);
 		if (bytes_read < 0) {
 			filter->client_buff = NULL;
 			filter->fatal = 1;
@@ -1631,7 +1635,7 @@ __archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
 
 	if (filter->closed || filter->fatal)
 		return (ARCHIVE_FATAL);
-	if (filter->seek == NULL)
+	if (filter->can_seek == 0)
 		return (ARCHIVE_FAILED);
 
 	client = &(filter->archive->client);
diff --git a/contrib/libarchive/libarchive/archive_read_append_filter.c b/contrib/libarchive/libarchive/archive_read_append_filter.c
index da7c55b9b088..25dc4b2a2b7f 100644
--- a/contrib/libarchive/libarchive/archive_read_append_filter.c
+++ b/contrib/libarchive/libarchive/archive_read_append_filter.c
@@ -135,7 +135,7 @@ archive_read_append_filter(struct archive *_a, int code)
     filter->archive = a;
     filter->upstream = a->filter;
     a->filter = filter;
-    r2 = (bidder->init)(a->filter);
+    r2 = (bidder->vtable->init)(a->filter);
     if (r2 != ARCHIVE_OK) {
       __archive_read_free_filters(a);
       return (ARCHIVE_FATAL);
@@ -192,7 +192,7 @@ archive_read_append_filter_program_signature(struct archive *_a,
   filter->archive = a;
   filter->upstream = a->filter;
   a->filter = filter;
-  r = (bidder->init)(a->filter);
+  r = (bidder->vtable->init)(a->filter);
   if (r != ARCHIVE_OK) {
     __archive_read_free_filters(a);
     return (ARCHIVE_FATAL);
diff --git a/contrib/libarchive/libarchive/archive_read_disk.3 b/contrib/libarchive/libarchive/archive_read_disk.3
index 82d6a5c8562c..8b568d7b0568 100644
--- a/contrib/libarchive/libarchive/archive_read_disk.3
+++ b/contrib/libarchive/libarchive/archive_read_disk.3
@@ -29,6 +29,8 @@
 .Os
 .Sh NAME
 .Nm archive_read_disk_new ,
+.Nm archive_read_disk_open ,
+.Nm archive_read_disk_open_w ,
 .Nm archive_read_disk_set_behavior ,
 .Nm archive_read_disk_set_symlink_logical ,
 .Nm archive_read_disk_set_symlink_physical ,
@@ -38,7 +40,14 @@
 .Nm archive_read_disk_uname ,
 .Nm archive_read_disk_set_uname_lookup ,
 .Nm archive_read_disk_set_gname_lookup ,
-.Nm archive_read_disk_set_standard_lookup
+.Nm archive_read_disk_set_standard_lookup ,
+.Nm archive_read_disk_descend ,
+.Nm archive_read_disk_can_descend ,
+.Nm archive_read_disk_current_filesystem ,
+.Nm archive_read_disk_current_filesystem_is_synthetic ,
+.Nm archive_read_disk_current_filesystem_is_remote ,
+.Nm archive_read_disk_set_matching ,
+.Nm archive_read_disk_set_metadata_filter_callback ,
 .Nd functions for reading objects from disk
 .Sh LIBRARY
 Streaming Archive Library (libarchive, -larchive)
@@ -47,6 +56,10 @@ Streaming Archive Library (libarchive, -larchive)
 .Ft struct archive *
 .Fn archive_read_disk_new "void"
 .Ft int
+.Fn archive_read_disk_open "struct archive *" "const char *"
+.Ft int
+.Fn archive_read_disk_open_w "struct archive *" "const wchar_t *" 
+.Ft int
 .Fn archive_read_disk_set_behavior "struct archive *" "int"
 .Ft int
 .Fn archive_read_disk_set_symlink_logical "struct archive *"
@@ -81,6 +94,29 @@ Streaming Archive Library (libarchive, -larchive)
 .Fa "int fd"
 .Fa "const struct stat *"
 .Fc
+.Ft int
+.Fn archive_read_disk_descend "struct archive *"
+.Ft int
+.Fn archive_read_disk_can_descend "struct archive *"
+.Ft int
+.Fn archive_read_disk_current_filesystem "struct archive *"
+.Ft int
+.Fn archive_read_disk_current_filesystem_is_synthetic "struct archive *"
+.Ft int
+.Fn archive_read_disk_current_filesystem_is_remote "struct archive *"
+.Ft int
+.Fo archive_read_disk_set_matching
+.Fa "struct archive *"
+.Fa "struct archive *"
+.Fa "void (*excluded_func)(struct archive *, void *, struct archive entry *)"
+.Fa "void *"
+.Fc
+.Ft int 
+.Fo archive_read_disk_set_metadata_filter_callback
+.Fa "struct archive *"
+.Fa "int (*metadata_filter_func)(struct archive *, void*, struct archive_entry *)"
+.Fa "void *"
+.Fc
 .Sh DESCRIPTION
 These functions provide an API for reading information about
 objects on disk.
@@ -92,6 +128,14 @@ objects.
 Allocates and initializes a
 .Tn struct archive
 object suitable for reading object information from disk.
+.It Fn archive_read_disk_open
+Opens the file or directory from the given path and prepares the
+.Tn struct archive
+to read it from disk.
+.It Fn archive_read_disk_open_w
+Opens the file or directory from the given path as a wide character string and prepares the
+.Tn struct archive
+to read it from disk.
 .It Fn archive_read_disk_set_behavior
 Configures various behavior options when reading entries from disk.
 The flags field consists of a bitwise OR of one or more of the
@@ -137,6 +181,9 @@ for more information on extended file attributes.
 .It Cm ARCHIVE_READDISK_RESTORE_ATIME
 Restore access time of traversed files.
 By default, access time of traversed files is not restored.
+.It Cm ARCHIVE_READDISK_NO_SPARSE
+Do not read sparse file information.
+By default, sparse file information is read from disk.
 .El
 .It Xo
*** 39557 LINES SKIPPED ***