git: bfa5e5858f63 - stable/13 - libarchive: import changes from upstream
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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 ***