The branch stable/12 has been updated by mm: URL: https://cgit.FreeBSD.org/src/commit/?id=bbc312a1ec992ad32d02df7dfbea216b7cd095eb
commit bbc312a1ec992ad32d02df7dfbea216b7cd095eb Author: Martin Matuska <m...@freebsd.org> AuthorDate: 2022-02-09 23:35:42 +0000 Commit: Martin Matuska <m...@freebsd.org> CommitDate: 2022-02-23 10:01:09 +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 | 17 +- usr.bin/bsdcat/tests/Makefile | 2 + usr.bin/cpio/tests/Makefile | 2 + usr.bin/tar/tests/Makefile | 3 + 92 files changed, 36973 insertions(+), 828 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 <gh...@caip.rutgers.edu> +# Copyright (c) 2017 Reini Urban <rur...@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 *** 39561 LINES SKIPPED ***