From a3375e947c028b7edf29f76389dfefff1fae3f34 Mon Sep 17 00:00:00 2001 From: mm Date: Wed, 19 Feb 2020 01:51:44 +0000 Subject: [PATCH] MFC r356212,r356366,r356416,r357785 Update libarchive to version 3.4.2 Relevant vendor changes (r356212): Issue #351: Refactor and implement private state logic for write filters PR #1252: RAR5 reader - verify window size for solid files (OSS-Fuzz 15482) PR #1255: zip writer - don't append unused NUL for directories PR #1260: Fix sparse file offset overflow on 32-bit systems PR #1263: UNICODE filename support for reading lha/lzh format Issue #1276: Bugfix and optimize archive_wstring_append_from_mbs() PR #1288: Add the "xattrhdr" option to pax write options PR #1295: 7z reader - fix reading archives with digests in PackInfo PR #1296: RAR5 reader - verify window size for multivolume archives PR #1297: ZIP reader - support LZMA_STREAM_END marker in 'lzma alone' files Issue #1298: Fix a heap-buffer-overflow in archive_string_append_from_wcs() OSS-Fuzz 19360, 19362: LHA reader - plug two memory leaks on error Fix possible off-by-one when dealing with readlink(2) Relevant vendor changes (r356366): Issue #1302: Plug memory leak on failure of archive_write_client_open() Relevant vendor changes (r356416): Issue #1302: Re-do fix for archive_write_client_open() Relevant vendor changes (r357785): PR #1289: atomic extraction support (bsdtar -x --safe-writes) PR #1308: big endian fix for UTF16 support in LHA reader PR #1326: reject RAR5 files that declare invalid header flags Issue #987: fix support 7z archive entries with Delta filter Issue #1317: fix compression output buffer handling in XAR writer Issue #1319: fix uname or gname longer than 32 characters in pax writer Issue #1325: fix use after free when archiving hardlinks in ISO9660 or XAR Use localtime_r() and gmtime_r() instead of localtime() and gmtime() git-svn-id: svn://svn.freebsd.org/base/stable/10@358090 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- contrib/libarchive/NEWS | 14 + contrib/libarchive/cat/bsdcat.h | 5 + contrib/libarchive/cat/test/test_0.c | 2 +- contrib/libarchive/cpio/cpio.c | 22 +- contrib/libarchive/cpio/test/test_basic.c | 14 +- .../libarchive/cpio/test/test_format_newc.c | 15 +- contrib/libarchive/libarchive/archive.h | 6 +- .../libarchive/archive_acl_private.h | 6 +- .../libarchive/libarchive/archive_blake2.h | 5 +- .../libarchive/archive_blake2_impl.h | 5 +- .../libarchive/archive_cmdline_private.h | 6 +- contrib/libarchive/libarchive/archive_crc32.h | 5 + .../libarchive/libarchive/archive_cryptor.c | 62 +++ .../libarchive/archive_cryptor_private.h | 24 +- .../libarchive/libarchive/archive_digest.c | 228 ++++++++++ .../libarchive/archive_digest_private.h | 43 +- .../libarchive/libarchive/archive_endian.h | 11 +- contrib/libarchive/libarchive/archive_entry.c | 10 +- contrib/libarchive/libarchive/archive_entry.h | 5 +- .../libarchive/libarchive/archive_entry_acl.3 | 21 +- .../libarchive/archive_entry_locale.h | 6 +- .../libarchive/archive_entry_private.h | 6 +- .../libarchive/libarchive/archive_getdate.c | 149 ++++++- .../libarchive/libarchive/archive_getdate.h | 6 +- contrib/libarchive/libarchive/archive_hmac.c | 50 +++ .../libarchive/archive_hmac_private.h | 12 +- .../libarchive/archive_openssl_evp_private.h | 5 + .../libarchive/archive_openssl_hmac_private.h | 5 + .../libarchive/archive_options_private.h | 4 + .../libarchive/libarchive/archive_pack_dev.c | 9 +- .../libarchive/libarchive/archive_pack_dev.h | 6 +- .../libarchive/libarchive/archive_pathmatch.h | 6 +- .../libarchive/archive_platform_acl.h | 6 + .../libarchive/archive_platform_xattr.h | 6 + contrib/libarchive/libarchive/archive_ppmd7.c | 2 +- .../libarchive/archive_ppmd7_private.h | 6 +- .../libarchive/archive_ppmd8_private.h | 4 +- .../libarchive/archive_ppmd_private.h | 6 +- .../libarchive/libarchive/archive_private.h | 11 +- .../libarchive/archive_random_private.h | 6 +- contrib/libarchive/libarchive/archive_rb.h | 21 +- contrib/libarchive/libarchive/archive_read.c | 2 +- .../archive_read_disk_entry_from_file.c | 6 +- .../libarchive/archive_read_disk_posix.c | 49 +-- .../libarchive/archive_read_disk_private.h | 6 +- .../libarchive/archive_read_private.h | 6 +- .../libarchive/archive_read_set_options.3 | 34 +- .../archive_read_support_filter_uu.c | 30 +- .../archive_read_support_format_7zip.c | 11 +- .../archive_read_support_format_lha.c | 206 ++++++--- .../archive_read_support_format_mtree.c | 1 + .../archive_read_support_format_rar.c | 69 ++- .../archive_read_support_format_rar5.c | 288 ++++++++----- .../archive_read_support_format_warc.c | 3 +- .../archive_read_support_format_xar.c | 17 +- .../archive_read_support_format_zip.c | 17 + .../libarchive/libarchive/archive_string.c | 40 +- .../libarchive/libarchive/archive_string.h | 6 +- .../libarchive/archive_string_composition.h | 6 +- contrib/libarchive/libarchive/archive_util.c | 230 ++++++---- contrib/libarchive/libarchive/archive_write.c | 91 +++- .../archive_write_add_filter_b64encode.c | 12 +- .../archive_write_add_filter_bzip2.c | 10 +- .../archive_write_add_filter_compress.c | 22 +- .../archive_write_add_filter_gzip.c | 9 +- .../libarchive/archive_write_add_filter_lz4.c | 11 +- .../archive_write_add_filter_lzop.c | 10 +- .../archive_write_add_filter_program.c | 12 +- .../archive_write_add_filter_uuencode.c | 12 +- .../libarchive/archive_write_add_filter_xz.c | 9 +- .../archive_write_add_filter_zstd.c | 12 +- .../libarchive/archive_write_disk.3 | 7 +- .../libarchive/archive_write_disk_posix.c | 80 +++- .../libarchive/archive_write_disk_private.h | 6 +- .../libarchive/archive_write_private.h | 14 +- .../libarchive/archive_write_set_format.c | 45 ++ .../archive_write_set_format_7zip.c | 3 +- .../libarchive/archive_write_set_format_ar.c | 1 + .../archive_write_set_format_cpio.c | 1 + .../archive_write_set_format_cpio_newc.c | 1 + .../archive_write_set_format_gnutar.c | 15 +- .../archive_write_set_format_iso9660.c | 22 +- .../libarchive/archive_write_set_format_pax.c | 122 ++++-- .../archive_write_set_format_private.h | 42 ++ .../archive_write_set_format_shar.c | 5 +- .../archive_write_set_format_ustar.c | 30 +- .../archive_write_set_format_v7tar.c | 29 +- .../archive_write_set_format_warc.c | 18 +- .../libarchive/archive_write_set_format_xar.c | 65 ++- .../libarchive/archive_write_set_format_zip.c | 38 +- .../libarchive/archive_write_set_options.3 | 259 +++++++++-- .../libarchive/libarchive/archive_xxhash.h | 5 +- contrib/libarchive/libarchive/filter_fork.h | 6 +- ...t_archive_write_set_format_filter_by_ext.c | 2 +- .../libarchive/test/test_compat_zip.c | 10 +- .../libarchive/libarchive/test/test_fuzz.c | 3 +- .../libarchive/test/test_open_failure.c | 16 +- .../libarchive/libarchive/test/test_open_fd.c | 27 +- .../libarchive/test/test_pax_xattr_header.c | 130 ++++++ .../test/test_pax_xattr_header_all.tar.uu | 72 ++++ .../test_pax_xattr_header_libarchive.tar.uu | 72 ++++ .../test/test_pax_xattr_header_schily.tar.uu | 72 ++++ .../test_read_disk_directory_traversals.c | 3 +- .../libarchive/test/test_read_extract.c | 2 +- .../libarchive/test/test_read_format_7zip.c | 19 +- .../test_read_format_7zip_delta4_lzma1.7z.uu | 407 ++++++++++++++++++ .../test_read_format_7zip_delta4_lzma2.7z.uu | 407 ++++++++++++++++++ ...st_read_format_7zip_packinfo_digests.7z.uu | 7 + .../test_read_format_7zip_packinfo_digests.c | 89 ++++ .../test/test_read_format_gtar_sparse.c | 5 +- .../test_read_format_lha_filename_utf16.c | 143 ++++++ ...test_read_format_lha_filename_utf16.lzh.uu | 19 + .../libarchive/test/test_read_format_rar5.c | 105 +++-- ...format_rar5_block_size_is_too_small.rar.uu | 8 + ...at_rar5_different_solid_window_size.rar.uu | 73 ++++ ...mat_rar5_different_winsize_on_merge.rar.uu | 16 + .../libarchive/test/test_read_format_zip.c | 8 +- .../test_read_format_zip_7075_utf8_paths.c | 2 +- .../test_read_format_zip_comment_stored.c | 2 +- .../test/test_read_format_zip_extra_padding.c | 2 +- .../test_read_format_zip_high_compression.c | 2 +- .../test/test_read_format_zip_jar.c | 2 +- .../test/test_read_format_zip_mac_metadata.c | 2 +- .../test/test_read_format_zip_malformed.c | 2 +- .../test/test_read_format_zip_msdos.c | 2 +- .../test/test_read_format_zip_nested.c | 2 +- .../test/test_read_format_zip_nofiletype.c | 2 +- .../test/test_read_format_zip_padded.c | 2 +- .../test/test_read_format_zip_sfx.c | 2 +- ...format_zip_with_invalid_traditional_eocd.c | 2 +- .../test/test_read_format_zip_zip64.c | 4 +- .../libarchive/test/test_read_pax_truncated.c | 6 +- .../test/test_read_truncated_filter.c | 4 +- .../libarchive/test/test_sparse_basic.c | 17 +- .../libarchive/test/test_write_disk.c | 2 +- .../test/test_write_format_cpio_empty.c | 2 +- .../libarchive/test/test_write_format_pax.c | 46 ++ .../test/test_write_format_shar_empty.c | 2 +- .../libarchive/test/test_write_format_tar.c | 2 +- .../test/test_write_format_tar_sparse.c | 4 +- .../libarchive/test/test_write_format_xar.c | 3 + .../test/test_write_format_zip_file.c | 2 +- .../test/test_write_format_zip_file_zip64.c | 2 +- contrib/libarchive/libarchive_fe/err.h | 9 +- contrib/libarchive/tar/bsdtar.1 | 49 ++- contrib/libarchive/tar/bsdtar.c | 6 + contrib/libarchive/tar/bsdtar.h | 7 + contrib/libarchive/tar/cmdline.c | 2 + contrib/libarchive/tar/test/test_basic.c | 2 +- contrib/libarchive/tar/test/test_copy.c | 4 +- .../libarchive/tar/test/test_option_C_upper.c | 2 +- contrib/libarchive/tar/test/test_option_s.c | 6 +- .../tar/test/test_option_safe_writes.c | 77 ++++ contrib/libarchive/tar/util.c | 22 +- contrib/libarchive/test_utils/test_common.h | 28 +- contrib/libarchive/test_utils/test_main.c | 44 +- lib/libarchive/tests/Makefile | 13 + usr.bin/bsdcat/Makefile | 2 +- usr.bin/cpio/Makefile | 2 +- usr.bin/tar/Makefile | 2 +- usr.bin/tar/tests/Makefile | 1 + 161 files changed, 4077 insertions(+), 930 deletions(-) create mode 100644 contrib/libarchive/libarchive/archive_write_set_format_private.h create mode 100644 contrib/libarchive/libarchive/test/test_pax_xattr_header.c create mode 100644 contrib/libarchive/libarchive/test/test_pax_xattr_header_all.tar.uu create mode 100644 contrib/libarchive/libarchive/test/test_pax_xattr_header_libarchive.tar.uu create mode 100644 contrib/libarchive/libarchive/test/test_pax_xattr_header_schily.tar.uu create mode 100644 contrib/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma1.7z.uu create mode 100644 contrib/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu create mode 100644 contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu create mode 100644 contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.c create mode 100644 contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.c create mode 100644 contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu create mode 100644 contrib/libarchive/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu create mode 100644 contrib/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu create mode 100644 contrib/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu create mode 100644 contrib/libarchive/tar/test/test_option_safe_writes.c diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS index 222532d1e..15360f5d9 100644 --- a/contrib/libarchive/NEWS +++ b/contrib/libarchive/NEWS @@ -1,3 +1,17 @@ +Feb 11, 2020: libarchive 3.4.2 released + +Jan 23, 2020: Important fixes for writing XAR archives + +Jan 20, 2020: New tar option: --safe-writes (atomical file extraction) + +Jan 03, 2020: Support mbed TLS (PolarSSL) as optional crypto provider + +Dec 30, 2019: libarchive 3.4.1 released + +Dec 11, 2019: New pax write option "xattrhdr" + +Nov 17, 2019: Unicode filename support for reading lha/lzh archives + Jun 11, 2019: libarchive 3.4.0 released May 18, 2019: Fixes for reading Android APK and JAR archives diff --git a/contrib/libarchive/cat/bsdcat.h b/contrib/libarchive/cat/bsdcat.h index 2e055e7c1..6467d6e3d 100644 --- a/contrib/libarchive/cat/bsdcat.h +++ b/contrib/libarchive/cat/bsdcat.h @@ -23,6 +23,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef BSDCAT_H_INCLUDED +#define BSDCAT_H_INCLUDED + #if defined(PLATFORM_CONFIG_H) /* Use hand-built config.h in environments that need it. */ #include PLATFORM_CONFIG_H @@ -54,3 +57,5 @@ void usage(FILE *stream, int eval); void bsdcat_next(void); void bsdcat_print_error(void); void bsdcat_read_to_stdout(const char* filename); + +#endif diff --git a/contrib/libarchive/cat/test/test_0.c b/contrib/libarchive/cat/test/test_0.c index f9fe5d847..c806c2435 100644 --- a/contrib/libarchive/cat/test/test_0.c +++ b/contrib/libarchive/cat/test/test_0.c @@ -59,7 +59,7 @@ DEFINE_TEST(test_0) * we know some option that will succeed. */ if (0 != systemf("%s --version >" DEV_NULL, testprog)) { - failure("Unable to successfully run: %s --version\n", testprog, testprog); + failure("Unable to successfully run: %s --version\n", testprog); assert(0); } diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c index c4735b035..719943a7d 100644 --- a/contrib/libarchive/cpio/cpio.c +++ b/contrib/libarchive/cpio/cpio.c @@ -1137,6 +1137,14 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry) const char *fmt; time_t mtime; static time_t now; + struct tm *ltime; +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif if (!now) time(&now); @@ -1184,7 +1192,19 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry) else fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M"; #endif - strftime(date, sizeof(date), fmt, localtime(&mtime)); +#if defined(HAVE_LOCALTIME_R) + ltime = localtime_r(&mtime, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = mtime; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; +#else + ltime = localtime(&mtime); +#endif + strftime(date, sizeof(date), fmt, ltime); fprintf(out, "%s%3d %-8s %-8s %8s %12s %s", archive_entry_strmode(entry), diff --git a/contrib/libarchive/cpio/test/test_basic.c b/contrib/libarchive/cpio/test/test_basic.c index 1c2447856..9a23399aa 100644 --- a/contrib/libarchive/cpio/test/test_basic.c +++ b/contrib/libarchive/cpio/test/test_basic.c @@ -33,15 +33,15 @@ verify_files(const char *msg) */ /* Regular file with 2 links. */ - failure(msg); + failure("%s", msg); assertIsReg("file", 0644); - failure(msg); + failure("%s", msg); assertFileSize("file", 10); - failure(msg); + failure("%s", msg); assertFileNLinks("file", 2); /* Another name for the same file. */ - failure(msg); + failure("%s", msg); assertIsHardlink("linkfile", "file"); /* Symlink */ @@ -49,11 +49,11 @@ verify_files(const char *msg) assertIsSymlink("symlink", "file", 0); /* Another file with 1 link and different permissions. */ - failure(msg); + failure("%s", msg); assertIsReg("file2", 0777); - failure(msg); + failure("%s", msg); assertFileSize("file2", 10); - failure(msg); + failure("%s", msg); assertFileNLinks("file2", 1); /* dir */ diff --git a/contrib/libarchive/cpio/test/test_format_newc.c b/contrib/libarchive/cpio/test/test_format_newc.c index c9d6f1d21..aa1a9bbb8 100644 --- a/contrib/libarchive/cpio/test/test_format_newc.c +++ b/contrib/libarchive/cpio/test/test_format_newc.c @@ -205,9 +205,11 @@ DEFINE_TEST(test_format_newc) gid = from_hex(e + 30, 8); /* gid */ assertEqualMem(e + 38, "00000003", 8); /* nlink */ t = from_hex(e + 46, 8); /* mtime */ - failure("t=0x%08x now=0x%08x=%d", t, now, now); + failure("t=%#08jx now=%#08jx=%jd", (intmax_t)t, (intmax_t)now, + (intmax_t)now); assert(t <= now); /* File wasn't created in future. */ - failure("t=0x%08x now - 2=0x%08x = %d", t, now - 2, now - 2); + failure("t=%#08jx now - 2=%#08jx=%jd", (intmax_t)t, (intmax_t)now - 2, + (intmax_t)now - 2); assert(t >= now - 2); /* File was created w/in last 2 secs. */ failure("newc format stores body only with last appearance of a link\n" " first appearance should be empty, so this file size\n" @@ -243,7 +245,8 @@ DEFINE_TEST(test_format_newc) assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */ assertEqualMem(e + 38, "00000001", 8); /* nlink */ t2 = from_hex(e + 46, 8); /* mtime */ - failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2); + failure("First entry created at t=%#08jx this entry created" + " at t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualMem(e + 54, "00000005", 8); /* File size */ fs = from_hex(e + 54, 8); @@ -278,7 +281,8 @@ DEFINE_TEST(test_format_newc) assertEqualInt(nlinks("dir"), from_hex(e + 38, 8)); /* nlinks */ #endif t2 = from_hex(e + 46, 8); /* mtime */ - failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2); + failure("First entry created at t=%#08jx this entry created at" + "t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualMem(e + 54, "00000000", 8); /* File size */ fs = from_hex(e + 54, 8); @@ -311,7 +315,8 @@ DEFINE_TEST(test_format_newc) assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */ assertEqualMem(e + 38, "00000003", 8); /* nlink */ t2 = from_hex(e + 46, 8); /* mtime */ - failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2); + failure("First entry created at t=%#08jx this entry created at" + "t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualInt(10, from_hex(e + 54, 8)); /* File size */ fs = from_hex(e + 54, 8); diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h index c0035eb2d..560f320cf 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 3004000 +#define ARCHIVE_VERSION_NUMBER 3004002 #include #include /* for wchar_t */ @@ -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.4.0" +#define ARCHIVE_VERSION_ONLY_STRING "3.4.2" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); @@ -693,6 +693,8 @@ __LA_DECL int archive_read_set_passphrase_callback(struct archive *, #define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000) /* Default: Do not clear no-change flags when unlinking object */ #define ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS (0x20000) +/* Default: Do not extract atomically (using rename) */ +#define ARCHIVE_EXTRACT_SAFE_WRITES (0x40000) __LA_DECL int archive_read_extract(struct archive *, struct archive_entry *, int flags); diff --git a/contrib/libarchive/libarchive/archive_acl_private.h b/contrib/libarchive/libarchive/archive_acl_private.h index ef0b0234c..af108162c 100644 --- a/contrib/libarchive/libarchive/archive_acl_private.h +++ b/contrib/libarchive/libarchive/archive_acl_private.h @@ -25,13 +25,13 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED +#define ARCHIVE_ACL_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED -#define ARCHIVE_ACL_PRIVATE_H_INCLUDED - #include "archive_string.h" struct archive_acl_entry { diff --git a/contrib/libarchive/libarchive/archive_blake2.h b/contrib/libarchive/libarchive/archive_blake2.h index 337be1946..dd6fe6fe5 100644 --- a/contrib/libarchive/libarchive/archive_blake2.h +++ b/contrib/libarchive/libarchive/archive_blake2.h @@ -12,8 +12,9 @@ More information about the BLAKE2 hash function can be found at https://blake2.net. */ -#ifndef BLAKE2_H -#define BLAKE2_H + +#ifndef ARCHIVE_BLAKE2_H +#define ARCHIVE_BLAKE2_H #include #include diff --git a/contrib/libarchive/libarchive/archive_blake2_impl.h b/contrib/libarchive/libarchive/archive_blake2_impl.h index c1df82e0c..0f05defea 100644 --- a/contrib/libarchive/libarchive/archive_blake2_impl.h +++ b/contrib/libarchive/libarchive/archive_blake2_impl.h @@ -12,8 +12,9 @@ More information about the BLAKE2 hash function can be found at https://blake2.net. */ -#ifndef BLAKE2_IMPL_H -#define BLAKE2_IMPL_H + +#ifndef ARCHIVE_BLAKE2_IMPL_H +#define ARCHIVE_BLAKE2_IMPL_H #include #include diff --git a/contrib/libarchive/libarchive/archive_cmdline_private.h b/contrib/libarchive/libarchive/archive_cmdline_private.h index 4e409e814..57a19494f 100644 --- a/contrib/libarchive/libarchive/archive_cmdline_private.h +++ b/contrib/libarchive/libarchive/archive_cmdline_private.h @@ -25,15 +25,15 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_CMDLINE_PRIVATE_H +#define ARCHIVE_CMDLINE_PRIVATE_H + #ifndef __LIBARCHIVE_BUILD #ifndef __LIBARCHIVE_TEST #error This header is only to be used internally to libarchive. #endif #endif -#ifndef ARCHIVE_CMDLINE_PRIVATE_H -#define ARCHIVE_CMDLINE_PRIVATE_H - struct archive_cmdline { char *path; char **argv; diff --git a/contrib/libarchive/libarchive/archive_crc32.h b/contrib/libarchive/libarchive/archive_crc32.h index 0a9470770..c0456acc7 100644 --- a/contrib/libarchive/libarchive/archive_crc32.h +++ b/contrib/libarchive/libarchive/archive_crc32.h @@ -25,6 +25,9 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_CRC32_H +#define ARCHIVE_CRC32_H + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif @@ -76,3 +79,5 @@ crc32(unsigned long crc, const void *_p, size_t len) crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); return (crc ^ 0xffffffffUL); } + +#endif diff --git a/contrib/libarchive/libarchive/archive_cryptor.c b/contrib/libarchive/libarchive/archive_cryptor.c index 74df5c405..8ab2b0979 100644 --- a/contrib/libarchive/libarchive/archive_cryptor.c +++ b/contrib/libarchive/libarchive/archive_cryptor.c @@ -85,6 +85,35 @@ pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, return (BCRYPT_SUCCESS(status)) ? 0: -1; } +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H) + +static int +pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, + size_t salt_len, unsigned rounds, uint8_t *derived_key, + size_t derived_key_len) +{ + mbedtls_md_context_t ctx; + const mbedtls_md_info_t *info; + int ret; + + mbedtls_md_init(&ctx); + info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + if (info == NULL) { + mbedtls_md_free(&ctx); + return (-1); + } + ret = mbedtls_md_setup(&ctx, info, 1); + if (ret != 0) { + mbedtls_md_free(&ctx); + return (-1); + } + ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw, + pw_len, salt, salt_len, rounds, derived_key_len, derived_key); + + mbedtls_md_free(&ctx); + return (ret); +} + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H) static int @@ -269,6 +298,39 @@ aes_ctr_release(archive_crypto_ctx *ctx) return 0; } +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H) + +static int +aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) +{ + mbedtls_aes_init(&ctx->ctx); + ctx->key_len = key_len; + memcpy(ctx->key, key, key_len); + memset(ctx->nonce, 0, sizeof(ctx->nonce)); + ctx->encr_pos = AES_BLOCK_SIZE; + return 0; +} + +static int +aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) +{ + if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key, + ctx->key_len * 8) != 0) + return (-1); + if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce, + ctx->encr_buf) != 0) + return (-1); + return 0; +} + +static int +aes_ctr_release(archive_crypto_ctx *ctx) +{ + mbedtls_aes_free(&ctx->ctx); + memset(ctx, 0, sizeof(*ctx)); + return 0; +} + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H) static int diff --git a/contrib/libarchive/libarchive/archive_cryptor_private.h b/contrib/libarchive/libarchive/archive_cryptor_private.h index b9759220d..64a20556a 100644 --- a/contrib/libarchive/libarchive/archive_cryptor_private.h +++ b/contrib/libarchive/libarchive/archive_cryptor_private.h @@ -23,13 +23,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - #ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED #define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED +#ifndef __LIBARCHIVE_BUILD +#error This header is only to be used internally to libarchive. +#endif /* * On systems that do not support any recognized crypto libraries, * the archive_cryptor.c file will normally define no usable symbols. @@ -83,6 +82,23 @@ typedef struct { unsigned encr_pos; } archive_crypto_ctx; +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H) +#include +#include +#include + +#define AES_MAX_KEY_SIZE 32 +#define AES_BLOCK_SIZE 16 + +typedef struct { + mbedtls_aes_context ctx; + uint8_t key[AES_MAX_KEY_SIZE]; + unsigned key_len; + uint8_t nonce[AES_BLOCK_SIZE]; + uint8_t encr_buf[AES_BLOCK_SIZE]; + unsigned encr_pos; +} archive_crypto_ctx; + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H) #if defined(HAVE_NETTLE_PBKDF2_H) #include diff --git a/contrib/libarchive/libarchive/archive_digest.c b/contrib/libarchive/libarchive/archive_digest.c index 415392303..34c58ac94 100644 --- a/contrib/libarchive/libarchive/archive_digest.c +++ b/contrib/libarchive/libarchive/archive_digest.c @@ -178,6 +178,40 @@ __archive_libsystem_md5final(archive_md5_ctx *ctx, void *md) return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) + +static int +__archive_mbedtls_md5init(archive_md5_ctx *ctx) +{ + mbedtls_md5_init(ctx); + if (mbedtls_md5_starts_ret(ctx) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_md5update(archive_md5_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_md5_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_md5final(archive_md5_ctx *ctx, void *md) +{ + if (mbedtls_md5_finish_ret(ctx, md) == 0) { + mbedtls_md5_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_md5_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE) static int @@ -335,6 +369,40 @@ __archive_libmd_ripemd160final(archive_rmd160_ctx *ctx, void *md) return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) + +static int +__archive_mbedtls_ripemd160init(archive_rmd160_ctx *ctx) +{ + mbedtls_ripemd160_init(ctx); + if (mbedtls_ripemd160_starts_ret(ctx) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_ripemd160_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_ripemd160final(archive_rmd160_ctx *ctx, void *md) +{ + if (mbedtls_ripemd160_finish_ret(ctx, md) == 0) { + mbedtls_ripemd160_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_ripemd160_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE) static int @@ -491,6 +559,40 @@ __archive_libsystem_sha1final(archive_sha1_ctx *ctx, void *md) return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) + +static int +__archive_mbedtls_sha1init(archive_sha1_ctx *ctx) +{ + mbedtls_sha1_init(ctx); + if (mbedtls_sha1_starts_ret(ctx) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha1update(archive_sha1_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_sha1_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha1final(archive_sha1_ctx *ctx, void *md) +{ + if (mbedtls_sha1_finish_ret(ctx, md) == 0) { + mbedtls_sha1_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_sha1_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE) static int @@ -720,6 +822,40 @@ __archive_libsystem_sha256final(archive_sha256_ctx *ctx, void *md) return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) + +static int +__archive_mbedtls_sha256init(archive_sha256_ctx *ctx) +{ + mbedtls_sha256_init(ctx); + if (mbedtls_sha256_starts_ret(ctx, 0) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha256update(archive_sha256_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_sha256_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha256final(archive_sha256_ctx *ctx, void *md) +{ + if (mbedtls_sha256_finish_ret(ctx, md) == 0) { + mbedtls_sha256_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_sha256_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE) static int @@ -921,6 +1057,40 @@ __archive_libsystem_sha384final(archive_sha384_ctx *ctx, void *md) return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) + +static int +__archive_mbedtls_sha384init(archive_sha384_ctx *ctx) +{ + mbedtls_sha512_init(ctx); + if (mbedtls_sha512_starts_ret(ctx, 1) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha384update(archive_sha384_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha384final(archive_sha384_ctx *ctx, void *md) +{ + if (mbedtls_sha512_finish_ret(ctx, md) == 0) { + mbedtls_sha512_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_sha512_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE) static int @@ -1146,6 +1316,40 @@ __archive_libsystem_sha512final(archive_sha512_ctx *ctx, void *md) return (ARCHIVE_OK); } +#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) + +static int +__archive_mbedtls_sha512init(archive_sha512_ctx *ctx) +{ + mbedtls_sha512_init(ctx); + if (mbedtls_sha512_starts_ret(ctx, 0) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha512update(archive_sha512_ctx *ctx, const void *indata, + size_t insize) +{ + if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0) + return (ARCHIVE_OK); + else + return (ARCHIVE_FATAL); +} + +static int +__archive_mbedtls_sha512final(archive_sha512_ctx *ctx, void *md) +{ + if (mbedtls_sha512_finish_ret(ctx, md) == 0) { + mbedtls_sha512_free(ctx); + return (ARCHIVE_OK); + } else { + mbedtls_sha512_free(ctx); + return (ARCHIVE_FATAL); + } +} + #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE) static int @@ -1276,6 +1480,10 @@ const struct archive_digest __archive_digest = &__archive_libsystem_md5init, &__archive_libsystem_md5update, &__archive_libsystem_md5final, +#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) + &__archive_mbedtls_md5init, + &__archive_mbedtls_md5update, + &__archive_mbedtls_md5final, #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE) &__archive_nettle_md5init, &__archive_nettle_md5update, @@ -1303,6 +1511,10 @@ const struct archive_digest __archive_digest = &__archive_libmd_ripemd160init, &__archive_libmd_ripemd160update, &__archive_libmd_ripemd160final, +#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) + &__archive_mbedtls_ripemd160init, + &__archive_mbedtls_ripemd160update, + &__archive_mbedtls_ripemd160final, #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE) &__archive_nettle_ripemd160init, &__archive_nettle_ripemd160update, @@ -1330,6 +1542,10 @@ const struct archive_digest __archive_digest = &__archive_libsystem_sha1init, &__archive_libsystem_sha1update, &__archive_libsystem_sha1final, +#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) + &__archive_mbedtls_sha1init, + &__archive_mbedtls_sha1update, + &__archive_mbedtls_sha1final, #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE) &__archive_nettle_sha1init, &__archive_nettle_sha1update, @@ -1369,6 +1585,10 @@ const struct archive_digest __archive_digest = &__archive_libsystem_sha256init, &__archive_libsystem_sha256update, &__archive_libsystem_sha256final, +#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) + &__archive_mbedtls_sha256init, + &__archive_mbedtls_sha256update, + &__archive_mbedtls_sha256final, #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE) &__archive_nettle_sha256init, &__archive_nettle_sha256update, @@ -1404,6 +1624,10 @@ const struct archive_digest __archive_digest = &__archive_libsystem_sha384init, &__archive_libsystem_sha384update, &__archive_libsystem_sha384final, +#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) + &__archive_mbedtls_sha384init, + &__archive_mbedtls_sha384update, + &__archive_mbedtls_sha384final, #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE) &__archive_nettle_sha384init, &__archive_nettle_sha384update, @@ -1443,6 +1667,10 @@ const struct archive_digest __archive_digest = &__archive_libsystem_sha512init, &__archive_libsystem_sha512update, &__archive_libsystem_sha512final +#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) + &__archive_mbedtls_sha512init, + &__archive_mbedtls_sha512update, + &__archive_mbedtls_sha512final #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE) &__archive_nettle_sha512init, &__archive_nettle_sha512update, diff --git a/contrib/libarchive/libarchive/archive_digest_private.h b/contrib/libarchive/libarchive/archive_digest_private.h index b4fd6ca22..15312ee9a 100644 --- a/contrib/libarchive/libarchive/archive_digest_private.h +++ b/contrib/libarchive/libarchive/archive_digest_private.h @@ -24,13 +24,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef ARCHIVE_DIGEST_PRIVATE_H_INCLUDED +#define ARCHIVE_DIGEST_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif - -#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED -#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED - /* * Crypto support in various Operating Systems: * @@ -112,6 +111,24 @@ #include #endif +/* mbed TLS crypto headers */ +#if defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) +#include +#endif +#if defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) +#include +#endif +#if defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) +#include +#endif +#if defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) +#include +#endif +#if defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\ + defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) +#include +#endif + /* Nettle crypto headers */ #if defined(ARCHIVE_CRYPTO_MD5_NETTLE) #include @@ -159,6 +176,8 @@ typedef MD5_CTX archive_md5_ctx; typedef MD5_CTX archive_md5_ctx; #elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) typedef CC_MD5_CTX archive_md5_ctx; +#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) +typedef mbedtls_md5_context archive_md5_ctx; #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE) typedef struct md5_ctx archive_md5_ctx; #elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL) @@ -173,6 +192,8 @@ typedef unsigned char archive_md5_ctx; typedef RMD160_CTX archive_rmd160_ctx; #elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD) typedef RIPEMD160_CTX archive_rmd160_ctx; +#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) +typedef mbedtls_ripemd160_context archive_rmd160_ctx; #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE) typedef struct ripemd160_ctx archive_rmd160_ctx; #elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) @@ -187,6 +208,8 @@ typedef SHA1_CTX archive_sha1_ctx; typedef SHA1_CTX archive_sha1_ctx; #elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) typedef CC_SHA1_CTX archive_sha1_ctx; +#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) +typedef mbedtls_sha1_context archive_sha1_ctx; #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE) typedef struct sha1_ctx archive_sha1_ctx; #elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) @@ -207,6 +230,8 @@ typedef SHA2_CTX archive_sha256_ctx; typedef SHA256_CTX archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) typedef CC_SHA256_CTX archive_sha256_ctx; +#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) +typedef mbedtls_sha256_context archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE) typedef struct sha256_ctx archive_sha256_ctx; #elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) @@ -225,6 +250,8 @@ typedef SHA384_CTX archive_sha384_ctx; typedef SHA2_CTX archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) typedef CC_SHA512_CTX archive_sha384_ctx; +#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) +typedef mbedtls_sha512_context archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE) typedef struct sha384_ctx archive_sha384_ctx; #elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) @@ -245,6 +272,8 @@ typedef SHA2_CTX archive_sha512_ctx; typedef SHA512_CTX archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) typedef CC_SHA512_CTX archive_sha512_ctx; +#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) +typedef mbedtls_sha512_context archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE) typedef struct sha512_ctx archive_sha512_ctx; #elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) @@ -259,6 +288,7 @@ typedef unsigned char archive_sha512_ctx; #if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\ defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \ defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\ defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_MD5_WIN) @@ -272,6 +302,7 @@ typedef unsigned char archive_sha512_ctx; __archive_digest.md5update(ctx, buf, n) #if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\ + defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\ defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) #define ARCHIVE_HAS_RMD160 @@ -286,6 +317,7 @@ typedef unsigned char archive_sha512_ctx; #if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\ defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \ defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA1_WIN) @@ -303,6 +335,7 @@ typedef unsigned char archive_sha512_ctx; defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\ defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA256_WIN) @@ -319,6 +352,7 @@ typedef unsigned char archive_sha512_ctx; defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\ defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA384_WIN) @@ -336,6 +370,7 @@ typedef unsigned char archive_sha512_ctx; defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\ defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\ + defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) ||\ defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\ defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\ defined(ARCHIVE_CRYPTO_SHA512_WIN) diff --git a/contrib/libarchive/libarchive/archive_endian.h b/contrib/libarchive/libarchive/archive_endian.h index 7906a425a..77c987031 100644 --- a/contrib/libarchive/libarchive/archive_endian.h +++ b/contrib/libarchive/libarchive/archive_endian.h @@ -28,16 +28,15 @@ * Borrowed from FreeBSD's */ -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif +#ifndef ARCHIVE_ENDIAN_H_INCLUDED +#define ARCHIVE_ENDIAN_H_INCLUDED /* Note: This is a purely internal header! */ /* Do not use this outside of libarchive internal code! */ -#ifndef ARCHIVE_ENDIAN_H_INCLUDED -#define ARCHIVE_ENDIAN_H_INCLUDED - +#ifndef __LIBARCHIVE_BUILD +#error This header is only to be used internally to libarchive. +#endif /* * Disabling inline keyword for compilers known to choke on it: diff --git a/contrib/libarchive/libarchive/archive_entry.c b/contrib/libarchive/libarchive/archive_entry.c index fa662dd61..72fcb2a0b 100644 --- a/contrib/libarchive/libarchive/archive_entry.c +++ b/contrib/libarchive/libarchive/archive_entry.c @@ -1699,7 +1699,7 @@ static const struct flag { const wchar_t *wname; unsigned long set; unsigned long clear; -} flags[] = { +} fileflags[] = { /* Preferred (shorter) names per flag first, all prefixed by "no" */ #ifdef SF_APPEND { "nosappnd", L"nosappnd", SF_APPEND, 0}, @@ -1876,7 +1876,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear) bits = bitset | bitclear; length = 0; - for (flag = flags; flag->name != NULL; flag++) + for (flag = fileflags; flag->name != NULL; flag++) if (bits & (flag->set | flag->clear)) { length += strlen(flag->name) + 1; bits &= ~(flag->set | flag->clear); @@ -1889,7 +1889,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear) return (NULL); dp = string; - for (flag = flags; flag->name != NULL; flag++) { + for (flag = fileflags; flag->name != NULL; flag++) { if (bitset & flag->set || bitclear & flag->clear) { sp = flag->name + 2; } else if (bitset & flag->clear || bitclear & flag->set) { @@ -1941,7 +1941,7 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp) *end != ' ' && *end != ',') end++; length = end - start; - for (flag = flags; flag->name != NULL; flag++) { + for (flag = fileflags; flag->name != NULL; flag++) { size_t flag_length = strlen(flag->name); if (length == flag_length && memcmp(start, flag->name, length) == 0) { @@ -2009,7 +2009,7 @@ ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp) *end != L' ' && *end != L',') end++; length = end - start; - for (flag = flags; flag->wname != NULL; flag++) { + for (flag = fileflags; flag->wname != NULL; flag++) { size_t flag_length = wcslen(flag->wname); if (length == flag_length && wmemcmp(start, flag->wname, length) == 0) { diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h index 5a6df1ad6..4daf36d28 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 3004000 +#define ARCHIVE_VERSION_NUMBER 3004002 /* * Note: archive_entry.h is for use outside of libarchive; the @@ -524,9 +524,6 @@ __LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type __LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */, int * /* type */, int * /* permset */, int * /* tag */, int * /* qual */, const char ** /* name */); -__LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */, - int * /* type */, int * /* permset */, int * /* tag */, - int * /* qual */, const wchar_t ** /* name */); /* * Construct a text-format ACL. The flags argument is a bitmask that diff --git a/contrib/libarchive/libarchive/archive_entry_acl.3 b/contrib/libarchive/libarchive/archive_entry_acl.3 index 7dcc5854c..50dd642c2 100644 --- a/contrib/libarchive/libarchive/archive_entry_acl.3 +++ b/contrib/libarchive/libarchive/archive_entry_acl.3 @@ -34,7 +34,6 @@ .Nm archive_entry_acl_from_text , .Nm archive_entry_acl_from_text_w , .Nm archive_entry_acl_next , -.Nm archive_entry_acl_next_w , .Nm archive_entry_acl_reset , .Nm archive_entry_acl_to_text , .Nm archive_entry_acl_to_text_w , @@ -89,16 +88,6 @@ Streaming Archive Library (libarchive, -larchive) .Fa "const char **ret_name" .Fc .Ft int -.Fo archive_entry_acl_next_w -.Fa "struct archive_entry *a" -.Fa "int type" -.Fa "int *ret_type" -.Fa "int *ret_permset" -.Fa "int *ret_tag" -.Fa "int *ret_qual" -.Fa "const wchar_t **ret_name" -.Fc -.Ft int .Fn archive_entry_acl_reset "struct archive_entry *a" "int type" .Ft char * .Fo archive_entry_acl_to_text @@ -349,8 +338,6 @@ character are skipped. .Pp .Fn archive_entry_acl_next -and -.Fn archive_entry_acl_next_w return the next entry of the ACL list. This functions may only be called after .Fn archive_entry_acl_reset @@ -358,9 +345,7 @@ has indicated the presence of extended ACL entries. .Pp .Fn archive_entry_acl_reset prepare reading the list of ACL entries with -.Fn archive_entry_acl_next -or -.Fn archive_entry_acl_next_w . +.Fn archive_entry_acl_next . The function returns 0 if no non-extended ACLs are found. In this case, the access permissions should be obtained by .Xr archive_entry_mode 3 @@ -447,9 +432,7 @@ if all entries were successfully parsed and if one or more entries were invalid or non-parseable. .Pp .Fn archive_entry_acl_next -and -.Fn archive_entry_acl_next_w -return +returns .Dv ARCHIVE_OK on success, .Dv ARCHIVE_EOF diff --git a/contrib/libarchive/libarchive/archive_entry_locale.h b/contrib/libarchive/libarchive/archive_entry_locale.h index 44550c51e..803c0368b 100644 --- a/contrib/libarchive/libarchive/archive_entry_locale.h +++ b/contrib/libarchive/libarchive/archive_entry_locale.h @@ -25,13 +25,13 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED +#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED -#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED - struct archive_entry; struct archive_string_conv; diff --git a/contrib/libarchive/libarchive/archive_entry_private.h b/contrib/libarchive/libarchive/archive_entry_private.h index d6206a066..89e8dfd2f 100644 --- a/contrib/libarchive/libarchive/archive_entry_private.h +++ b/contrib/libarchive/libarchive/archive_entry_private.h @@ -25,13 +25,13 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED +#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED -#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED - #include "archive_acl_private.h" #include "archive_string.h" diff --git a/contrib/libarchive/libarchive/archive_getdate.c b/contrib/libarchive/libarchive/archive_getdate.c index 030c083ce..3ec5bba88 100644 --- a/contrib/libarchive/libarchive/archive_getdate.c +++ b/contrib/libarchive/libarchive/archive_getdate.c @@ -27,6 +27,7 @@ ** This code is in the public domain and has no copyright. */ +#include "archive_platform.h" #ifdef __FreeBSD__ #include __FBSDID("$FreeBSD$"); @@ -694,8 +695,16 @@ Convert(time_t Month, time_t Day, time_t Year, signed char DaysInMonth[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - time_t Julian; - int i; + time_t Julian; + int i; + struct tm *ltime; +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif if (Year < 69) Year += 2000; @@ -722,21 +731,64 @@ Convert(time_t Month, time_t Day, time_t Year, Julian *= DAY; Julian += Timezone; Julian += Hours * HOUR + Minutes * MINUTE + Seconds; +#if defined(HAVE_LOCALTIME_R) + ltime = localtime_r(&Julian, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = Julian; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; +#else + ltime = localtime(&Julian); +#endif if (DSTmode == DSTon - || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst)) + || (DSTmode == DSTmaybe && ltime->tm_isdst)) Julian -= HOUR; return Julian; } - static time_t DSTcorrect(time_t Start, time_t Future) { - time_t StartDay; - time_t FutureDay; + time_t StartDay; + time_t FutureDay; + struct tm *ltime; +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif - StartDay = (localtime(&Start)->tm_hour + 1) % 24; - FutureDay = (localtime(&Future)->tm_hour + 1) % 24; +#if defined(HAVE_LOCALTIME_R) + ltime = localtime_r(&Start, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = Start; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; +#else + ltime = localtime(&Start); +#endif + StartDay = (ltime->tm_hour + 1) % 24; +#if defined(HAVE_LOCALTIME_R) + ltime = localtime_r(&Future, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = Future; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; +#else + ltime = localtime(&Future); +#endif + FutureDay = (ltime->tm_hour + 1) % 24; return (Future - Start) + (StartDay - FutureDay) * HOUR; } @@ -747,9 +799,27 @@ RelativeDate(time_t Start, time_t zone, int dstmode, { struct tm *tm; time_t t, now; +#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__GMTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif t = Start - zone; +#if defined(HAVE_GMTIME_R) + tm = gmtime_r(&t, &tmbuf); +#elif defined(HAVE__GMTIME64_S) + tmptime = t; + terr = _gmtime64_s(&tmbuf, &tmptime); + if (terr) + tm = NULL; + else + tm = &tmbuf; +#else tm = gmtime(&t); +#endif now = Start; now += DAY * ((DayNumber - tm->tm_wday + 7) % 7); now += 7 * DAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); @@ -765,10 +835,28 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth) struct tm *tm; time_t Month; time_t Year; +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif if (RelMonth == 0) return 0; +#if defined(HAVE_LOCALTIME_R) + tm = localtime_r(&Start, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = Start; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + tm = NULL; + else + tm = &tmbuf; +#else tm = localtime(&Start); +#endif Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth; Year = Month / 12; Month = Month % 12 + 1; @@ -905,6 +993,10 @@ __archive_get_date(time_t now, const char *p) time_t Start; time_t tod; long tzone; +#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif /* Clear out the parsed token array. */ memset(tokens, 0, sizeof(tokens)); @@ -913,20 +1005,44 @@ __archive_get_date(time_t now, const char *p) gds = &_gds; /* Look up the current time. */ +#if defined(HAVE_LOCALTIME_R) + tm = localtime_r(&now, &local); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = now; + terr = _localtime64_s(&local, &tmptime); + if (terr) + tm = NULL; + else + tm = &local; +#else memset(&local, 0, sizeof(local)); - tm = localtime (&now); + tm = localtime(&now); +#endif if (tm == NULL) return -1; +#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S) local = *tm; +#endif /* Look up UTC if we can and use that to determine the current * timezone offset. */ +#if defined(HAVE_GMTIME_R) + gmt_ptr = gmtime_r(&now, &gmt); +#elif defined(HAVE__GMTIME64_S) + tmptime = now; + terr = _gmtime64_s(&gmt, &tmptime); + if (terr) + gmt_ptr = NULL; + else + gmt_ptr = &gmt; +#else memset(&gmt, 0, sizeof(gmt)); - gmt_ptr = gmtime (&now); + gmt_ptr = gmtime(&now); if (gmt_ptr != NULL) { /* Copy, in case localtime and gmtime use the same buffer. */ gmt = *gmt_ptr; } +#endif if (gmt_ptr != NULL) tzone = difftm (&gmt, &local); else @@ -960,7 +1076,18 @@ __archive_get_date(time_t now, const char *p) * time components instead of the local timezone. */ if (gds->HaveZone && gmt_ptr != NULL) { now -= gds->Timezone; - gmt_ptr = gmtime (&now); +#if defined(HAVE_GMTIME_R) + gmt_ptr = gmtime_r(&now, &gmt); +#elif defined(HAVE__GMTIME64_S) + tmptime = now; + terr = _gmtime64_s(&gmt, &tmptime); + if (terr) + gmt_ptr = NULL; + else + gmt_ptr = &gmt; +#else + gmt_ptr = gmtime(&now); +#endif if (gmt_ptr != NULL) local = *gmt_ptr; now += gds->Timezone; diff --git a/contrib/libarchive/libarchive/archive_getdate.h b/contrib/libarchive/libarchive/archive_getdate.h index 666ff5ff7..900a8f692 100644 --- a/contrib/libarchive/libarchive/archive_getdate.h +++ b/contrib/libarchive/libarchive/archive_getdate.h @@ -25,13 +25,13 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_GETDATE_H_INCLUDED +#define ARCHIVE_GETDATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_GETDATE_H_INCLUDED -#define ARCHIVE_GETDATE_H_INCLUDED - #include time_t __archive_get_date(time_t now, const char *); diff --git a/contrib/libarchive/libarchive/archive_hmac.c b/contrib/libarchive/libarchive/archive_hmac.c index 392916de5..2a9d04c8d 100644 --- a/contrib/libarchive/libarchive/archive_hmac.c +++ b/contrib/libarchive/libarchive/archive_hmac.c @@ -83,7 +83,9 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) static int __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) { +#ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wcast-qual" +#endif BCRYPT_ALG_HANDLE hAlg; BCRYPT_HASH_HANDLE hHash; DWORD hash_len; @@ -148,6 +150,53 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) } } +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H) + +static int +__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) +{ + const mbedtls_md_info_t *info; + int ret; + + mbedtls_md_init(ctx); + info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + if (info == NULL) { + mbedtls_md_free(ctx); + return (-1); + } + ret = mbedtls_md_setup(ctx, info, 1); + if (ret != 0) { + mbedtls_md_free(ctx); + return (-1); + } + ret = mbedtls_md_hmac_starts(ctx, key, key_len); + if (ret != 0) { + mbedtls_md_free(ctx); + return (-1); + } + return 0; +} + +static void +__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, + size_t data_len) +{ + mbedtls_md_hmac_update(ctx, data, data_len); +} + +static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) +{ + (void)out_len; /* UNUSED */ + + mbedtls_md_hmac_finish(ctx, out); +} + +static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) +{ + mbedtls_md_free(ctx); + memset(ctx, 0, sizeof(*ctx)); +} + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H) static int @@ -199,6 +248,7 @@ static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) { unsigned int len = (unsigned int)*out_len; + HMAC_Final(*ctx, out, &len); *out_len = len; } diff --git a/contrib/libarchive/libarchive/archive_hmac_private.h b/contrib/libarchive/libarchive/archive_hmac_private.h index eb45c4ef2..13a67d495 100644 --- a/contrib/libarchive/libarchive/archive_hmac_private.h +++ b/contrib/libarchive/libarchive/archive_hmac_private.h @@ -23,13 +23,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - #ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED #define ARCHIVE_HMAC_PRIVATE_H_INCLUDED +#ifndef __LIBARCHIVE_BUILD +#error This header is only to be used internally to libarchive. +#endif /* * On systems that do not support any recognized crypto libraries, * the archive_hmac.c file is expected to define no usable symbols. @@ -64,6 +63,11 @@ typedef struct { } archive_hmac_sha1_ctx; +#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H) +#include + +typedef mbedtls_md_context_t archive_hmac_sha1_ctx; + #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H) #include diff --git a/contrib/libarchive/libarchive/archive_openssl_evp_private.h b/contrib/libarchive/libarchive/archive_openssl_evp_private.h index 43a3ccc52..ebb06702d 100644 --- a/contrib/libarchive/libarchive/archive_openssl_evp_private.h +++ b/contrib/libarchive/libarchive/archive_openssl_evp_private.h @@ -22,9 +22,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #ifndef ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED #define ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED +#ifndef __LIBARCHIVE_BUILD +#error This header is only to be used internally to libarchive. +#endif + #include #include diff --git a/contrib/libarchive/libarchive/archive_openssl_hmac_private.h b/contrib/libarchive/libarchive/archive_openssl_hmac_private.h index 921249bb9..25c8dda65 100644 --- a/contrib/libarchive/libarchive/archive_openssl_hmac_private.h +++ b/contrib/libarchive/libarchive/archive_openssl_hmac_private.h @@ -22,9 +22,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #ifndef ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED #define ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED +#ifndef __LIBARCHIVE_BUILD +#error This header is only to be used internally to libarchive. +#endif + #include #include diff --git a/contrib/libarchive/libarchive/archive_options_private.h b/contrib/libarchive/libarchive/archive_options_private.h index 6ef0165af..9a7f8080d 100644 --- a/contrib/libarchive/libarchive/archive_options_private.h +++ b/contrib/libarchive/libarchive/archive_options_private.h @@ -23,6 +23,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED +#define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED + #include "archive_platform.h" __FBSDID("$FreeBSD$"); @@ -45,3 +48,4 @@ _archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v, option_handler use_format_option, option_handler use_filter_option); +#endif diff --git a/contrib/libarchive/libarchive/archive_pack_dev.c b/contrib/libarchive/libarchive/archive_pack_dev.c index a5e57ac20..f8286d821 100644 --- a/contrib/libarchive/libarchive/archive_pack_dev.c +++ b/contrib/libarchive/libarchive/archive_pack_dev.c @@ -57,11 +57,12 @@ __RCSID("$NetBSD$"); #ifdef HAVE_SYS_STAT_H #include #endif -#ifdef HAVE_SYS_SYSMACROS_H -#include -#endif -#ifdef HAVE_SYS_MKDEV_H +#if MAJOR_IN_MKDEV #include +#define HAVE_MAJOR +#elif MAJOR_IN_SYSMACROS +#include +#define HAVE_MAJOR #endif #ifdef HAVE_UNISTD_H #include diff --git a/contrib/libarchive/libarchive/archive_pack_dev.h b/contrib/libarchive/libarchive/archive_pack_dev.h index 749fd3d2c..eaf23e388 100644 --- a/contrib/libarchive/libarchive/archive_pack_dev.h +++ b/contrib/libarchive/libarchive/archive_pack_dev.h @@ -31,8 +31,8 @@ /* Originally from NetBSD's mknod(8) source. */ -#ifndef _PACK_DEV_H -#define _PACK_DEV_H +#ifndef ARCHIVE_PACK_DEV_H +#define ARCHIVE_PACK_DEV_H typedef dev_t pack_t(int, unsigned long [], const char **); @@ -46,4 +46,4 @@ pack_t pack_native; (((y) << 12) & 0xfff00000) | \ (((y) << 0) & 0x000000ff))) -#endif /* _PACK_DEV_H */ +#endif /* ARCHIVE_PACK_DEV_H */ diff --git a/contrib/libarchive/libarchive/archive_pathmatch.h b/contrib/libarchive/libarchive/archive_pathmatch.h index e6901774d..999514292 100644 --- a/contrib/libarchive/libarchive/archive_pathmatch.h +++ b/contrib/libarchive/libarchive/archive_pathmatch.h @@ -26,15 +26,15 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_PATHMATCH_H +#define ARCHIVE_PATHMATCH_H + #ifndef __LIBARCHIVE_BUILD #ifndef __LIBARCHIVE_TEST #error This header is only to be used internally to libarchive. #endif #endif -#ifndef ARCHIVE_PATHMATCH_H -#define ARCHIVE_PATHMATCH_H - /* Don't anchor at beginning unless the pattern starts with "^" */ #define PATHMATCH_NO_ANCHOR_START 1 /* Don't anchor at end unless the pattern ends with "$" */ diff --git a/contrib/libarchive/libarchive/archive_platform_acl.h b/contrib/libarchive/libarchive/archive_platform_acl.h index 3498f78b3..264e6de37 100644 --- a/contrib/libarchive/libarchive/archive_platform_acl.h +++ b/contrib/libarchive/libarchive/archive_platform_acl.h @@ -30,6 +30,12 @@ #ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED #define ARCHIVE_PLATFORM_ACL_H_INCLUDED +#ifndef __LIBARCHIVE_BUILD +#ifndef __LIBARCHIVE_TEST_COMMON +#error This header is only to be used internally to libarchive. +#endif +#endif + /* * Determine what ACL types are supported */ diff --git a/contrib/libarchive/libarchive/archive_platform_xattr.h b/contrib/libarchive/libarchive/archive_platform_xattr.h index 4edfecfdb..ad4b90ab7 100644 --- a/contrib/libarchive/libarchive/archive_platform_xattr.h +++ b/contrib/libarchive/libarchive/archive_platform_xattr.h @@ -30,6 +30,12 @@ #ifndef ARCHIVE_PLATFORM_XATTR_H_INCLUDED #define ARCHIVE_PLATFORM_XATTR_H_INCLUDED +#ifndef __LIBARCHIVE_BUILD +#ifndef __LIBARCHIVE_TEST_COMMON +#error This header is only to be used internally to libarchive. +#endif +#endif + /* * Determine if we support extended attributes */ diff --git a/contrib/libarchive/libarchive/archive_ppmd7.c b/contrib/libarchive/libarchive/archive_ppmd7.c index d0bacc68c..4029395b4 100644 --- a/contrib/libarchive/libarchive/archive_ppmd7.c +++ b/contrib/libarchive/libarchive/archive_ppmd7.c @@ -1000,7 +1000,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p) static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total) { - p->Low += start * (p->Range /= total); + p->Low += (UInt64)start * (UInt64)(p->Range /= total); p->Range *= size; while (p->Range < kTopValue) { diff --git a/contrib/libarchive/libarchive/archive_ppmd7_private.h b/contrib/libarchive/libarchive/archive_ppmd7_private.h index 577d6fb43..71b954458 100644 --- a/contrib/libarchive/libarchive/archive_ppmd7_private.h +++ b/contrib/libarchive/libarchive/archive_ppmd7_private.h @@ -6,13 +6,13 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ +#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED +#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED -#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED - #include "archive_ppmd_private.h" #define PPMD7_MIN_ORDER 2 diff --git a/contrib/libarchive/libarchive/archive_ppmd8_private.h b/contrib/libarchive/libarchive/archive_ppmd8_private.h index 534927860..454b75f41 100644 --- a/contrib/libarchive/libarchive/archive_ppmd8_private.h +++ b/contrib/libarchive/libarchive/archive_ppmd8_private.h @@ -4,8 +4,8 @@ This code is based on: PPMd var.I (2002): Dmitry Shkarin : Public domain Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ -#ifndef __PPMD8_H -#define __PPMD8_H +#ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED +#define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED #include "archive_ppmd_private.h" diff --git a/contrib/libarchive/libarchive/archive_ppmd_private.h b/contrib/libarchive/libarchive/archive_ppmd_private.h index a83b8514d..582803e5f 100644 --- a/contrib/libarchive/libarchive/archive_ppmd_private.h +++ b/contrib/libarchive/libarchive/archive_ppmd_private.h @@ -2,13 +2,13 @@ 2010-03-12 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ +#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED +#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED -#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED - #include #include "archive_read_private.h" diff --git a/contrib/libarchive/libarchive/archive_private.h b/contrib/libarchive/libarchive/archive_private.h index cbd779442..154d1c292 100644 --- a/contrib/libarchive/libarchive/archive_private.h +++ b/contrib/libarchive/libarchive/archive_private.h @@ -25,13 +25,13 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_PRIVATE_H_INCLUDED +#define ARCHIVE_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_PRIVATE_H_INCLUDED -#define ARCHIVE_PRIVATE_H_INCLUDED - #if HAVE_ICONV_H #include #endif @@ -153,6 +153,11 @@ void __archive_errx(int retvalue, const char *msg) __LA_DEAD; void __archive_ensure_cloexec_flag(int fd); int __archive_mktemp(const char *tmpdir); +#if defined(_WIN32) && !defined(__CYGWIN__) +int __archive_mkstemp(wchar_t *template); +#else +int __archive_mkstemp(char *template); +#endif int __archive_clean(struct archive *); diff --git a/contrib/libarchive/libarchive/archive_random_private.h b/contrib/libarchive/libarchive/archive_random_private.h index c414779f8..08b91b3b7 100644 --- a/contrib/libarchive/libarchive/archive_random_private.h +++ b/contrib/libarchive/libarchive/archive_random_private.h @@ -23,13 +23,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED +#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED -#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED - /* Random number generator. */ int archive_random(void *buf, size_t nbytes); diff --git a/contrib/libarchive/libarchive/archive_rb.h b/contrib/libarchive/libarchive/archive_rb.h index 4562e9ebc..8851f1081 100644 --- a/contrib/libarchive/libarchive/archive_rb.h +++ b/contrib/libarchive/libarchive/archive_rb.h @@ -28,8 +28,9 @@ * * Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp */ -#ifndef ARCHIVE_RB_H_ -#define ARCHIVE_RB_H_ + +#ifndef ARCHIVE_RB_H_INCLUDED +#define ARCHIVE_RB_H_INCLUDED struct archive_rb_node { struct archive_rb_node *rb_nodes[2]; @@ -48,12 +49,24 @@ struct archive_rb_node { __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT) #define ARCHIVE_RB_TREE_MAX(T) \ __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT) +#define ARCHIVE_RB_TREE_NEXT(T, N) \ + __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT) +#define ARCHIVE_RB_TREE_PREV(T, N) \ + __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT) #define ARCHIVE_RB_TREE_FOREACH(N, T) \ for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \ - (N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT)) + (N) = ARCHIVE_RB_TREE_NEXT((T), (N))) #define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \ for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \ - (N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT)) + (N) = ARCHIVE_RB_TREE_PREV((T), (N))) +#define ARCHIVE_RB_TREE_FOREACH_SAFE(N, T, S) \ + for ((N) = ARCHIVE_RB_TREE_MIN(T); \ + (N) && ((S) = ARCHIVE_RB_TREE_NEXT((T), (N)), 1); \ + (N) = (S)) +#define ARCHIVE_RB_TREE_FOREACH_REVERSE_SAFE(N, T, S) \ + for ((N) = ARCHIVE_RB_TREE_MAX(T); \ + (N) && ((S) = ARCHIVE_RB_TREE_PREV((T), (N)), 1); \ + (N) = (S)) /* * archive_rbto_compare_nodes_fn: diff --git a/contrib/libarchive/libarchive/archive_read.c b/contrib/libarchive/libarchive/archive_read.c index 18dd73e01..31802ce8c 100644 --- a/contrib/libarchive/libarchive/archive_read.c +++ b/contrib/libarchive/libarchive/archive_read.c @@ -433,7 +433,7 @@ archive_read_add_callback_data(struct archive *_a, void *client_data, return ARCHIVE_FATAL; } a->client.dataset = (struct archive_read_data_node *)p; - for (i = a->client.nodes - 1; i > iindex && i > 0; i--) { + for (i = a->client.nodes - 1; i > iindex; i--) { a->client.dataset[i].data = a->client.dataset[i-1].data; a->client.dataset[i].begin_position = -1; a->client.dataset[i].total_size = -1; diff --git a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c index 45417e9ac..2a8cec8d1 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c @@ -249,11 +249,11 @@ archive_read_disk_entry_from_file(struct archive *_a, #if defined(HAVE_READLINK) || defined(HAVE_READLINKAT) if (S_ISLNK(st->st_mode)) { - size_t linkbuffer_len = st->st_size + 1; + size_t linkbuffer_len = st->st_size; char *linkbuffer; int lnklen; - linkbuffer = malloc(linkbuffer_len); + linkbuffer = malloc(linkbuffer_len + 1); if (linkbuffer == NULL) { archive_set_error(&a->archive, ENOMEM, "Couldn't read link data"); @@ -280,7 +280,7 @@ archive_read_disk_entry_from_file(struct archive *_a, free(linkbuffer); return (ARCHIVE_FAILED); } - linkbuffer[lnklen] = 0; + linkbuffer[lnklen] = '\0'; archive_entry_set_symlink(entry, linkbuffer); free(linkbuffer); } diff --git a/contrib/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libarchive/libarchive/archive_read_disk_posix.c index 87963c3c7..52fec7bb4 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_read_disk_posix.c @@ -694,6 +694,7 @@ _archive_read_data_block(struct archive *_a, const void **buff, struct tree *t = a->tree; int r; ssize_t bytes; + int64_t sparse_bytes; size_t buffbytes; int empty_sparse_region = 0; @@ -728,27 +729,23 @@ _archive_read_data_block(struct archive *_a, const void **buff, if ((t->flags & needsRestoreTimes) != 0 && t->restore_time.noatime == 0) flags |= O_NOATIME; - do { #endif - t->entry_fd = open_on_current_dir(t, - tree_current_access_path(t), flags); - __archive_ensure_cloexec_flag(t->entry_fd); + t->entry_fd = open_on_current_dir(t, + tree_current_access_path(t), flags); + __archive_ensure_cloexec_flag(t->entry_fd); #if defined(O_NOATIME) - /* - * When we did open the file with O_NOATIME flag, - * if successful, set 1 to t->restore_time.noatime - * not to restore an atime of the file later. - * if failed by EPERM, retry it without O_NOATIME flag. - */ - if (flags & O_NOATIME) { - if (t->entry_fd >= 0) - t->restore_time.noatime = 1; - else if (errno == EPERM) { - flags &= ~O_NOATIME; - continue; - } - } - } while (0); + /* + * When we did open the file with O_NOATIME flag, + * if successful, set 1 to t->restore_time.noatime + * not to restore an atime of the file later. + * if failed by EPERM, retry it without O_NOATIME flag. + */ + if (flags & O_NOATIME) { + if (t->entry_fd >= 0) + t->restore_time.noatime = 1; + else if (errno == EPERM) + flags &= ~O_NOATIME; + } #endif if (t->entry_fd < 0) { archive_set_error(&a->archive, errno, @@ -792,9 +789,9 @@ _archive_read_data_block(struct archive *_a, const void **buff, a->archive.state = ARCHIVE_STATE_FATAL; goto abort_read_data; } - bytes = t->current_sparse->offset - t->entry_total; - t->entry_remaining_bytes -= bytes; - t->entry_total += bytes; + sparse_bytes = t->current_sparse->offset - t->entry_total; + t->entry_remaining_bytes -= sparse_bytes; + t->entry_total += sparse_bytes; } /* @@ -1109,8 +1106,7 @@ next_entry(struct archive_read_disk *a, struct tree *t, "%s", delayed_str.s); } } - if (!archive_string_empty(&delayed_str)) - archive_string_free(&delayed_str); + archive_string_free(&delayed_str); return (r); } @@ -2172,7 +2168,7 @@ tree_reopen(struct tree *t, const char *path, int restore_time) #elif defined(O_SEARCH) /* SunOS */ const int o_flag = O_SEARCH; -#elif defined(O_EXEC) +#elif defined(__FreeBSD__) && defined(O_EXEC) /* FreeBSD */ const int o_flag = O_EXEC; #endif @@ -2198,7 +2194,8 @@ tree_reopen(struct tree *t, const char *path, int restore_time) t->stack->flags = needsFirstVisit; t->maxOpenCount = t->openCount = 1; t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC); -#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC) +#if defined(O_PATH) || defined(O_SEARCH) || \ + (defined(__FreeBSD__) && defined(O_EXEC)) /* * Most likely reason to fail opening "." is that it's not readable, * so try again for execute. The consequences of not opening this are diff --git a/contrib/libarchive/libarchive/archive_read_disk_private.h b/contrib/libarchive/libarchive/archive_read_disk_private.h index 34691fc1e..15c2864c5 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_private.h +++ b/contrib/libarchive/libarchive/archive_read_disk_private.h @@ -26,13 +26,13 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED +#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED -#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED - #include "archive_platform_acl.h" struct tree; diff --git a/contrib/libarchive/libarchive/archive_read_private.h b/contrib/libarchive/libarchive/archive_read_private.h index f29d95d62..6198e8935 100644 --- a/contrib/libarchive/libarchive/archive_read_private.h +++ b/contrib/libarchive/libarchive/archive_read_private.h @@ -25,15 +25,15 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED +#define ARCHIVE_READ_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #ifndef __LIBARCHIVE_TEST #error This header is only to be used internally to libarchive. #endif #endif -#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED -#define ARCHIVE_READ_PRIVATE_H_INCLUDED - #include "archive.h" #include "archive_string.h" #include "archive_private.h" diff --git a/contrib/libarchive/libarchive/archive_read_set_options.3 b/contrib/libarchive/libarchive/archive_read_set_options.3 index d23f028b0..78d99999c 100644 --- a/contrib/libarchive/libarchive/archive_read_set_options.3 +++ b/contrib/libarchive/libarchive/archive_read_set_options.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 2, 2012 +.Dd January 31, 2020 .Dt ARCHIVE_READ_OPTIONS 3 .Os .Sh NAME @@ -180,6 +180,18 @@ only to modules whose name matches .\" .Sh OPTIONS .Bl -tag -compact -width indent +.It Format cab +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file names. +.El +.It Format cpio +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file names. +.El .It Format iso9660 .Bl -tag -compact -width indent .It Cm joliet @@ -193,6 +205,24 @@ Defaults to enabled, use .Cm !rockridge to disable. .El +.It Format lha +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file names. +.El +.It Format mtree +.Bl -tag -compact -width indent +.It Cm checkfs +Allow reading information missing from the mtree from the file system. +Disabled by default. +.El +.It Format rar +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file names. +.El .It Format tar .Bl -tag -compact -width indent .It Cm compat-2x @@ -202,7 +232,7 @@ This option mimics the libarchive 2.x filename handling so that such archives can be read correctly. .It Cm hdrcharset The value is used as a character set name that will be -used when translating filenames. +used when translating file names. .It Cm mac-ext Support Mac OS metadata extension that records data in special files beginning with a period and underscore. diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_uu.c b/contrib/libarchive/libarchive/archive_read_support_filter_uu.c index 641297990..67ddffb06 100644 --- a/contrib/libarchive/libarchive/archive_read_support_filter_uu.c +++ b/contrib/libarchive/libarchive/archive_read_support_filter_uu.c @@ -574,14 +574,13 @@ read_more: while (l > 0) { int n = 0; - if (l > 0) { - if (!uuchar[b[0]] || !uuchar[b[1]]) - break; - n = UUDECODE(*b++) << 18; - n |= UUDECODE(*b++) << 12; - *out++ = n >> 16; total++; - --l; - } + if (!uuchar[b[0]] || !uuchar[b[1]]) + break; + n = UUDECODE(*b++) << 18; + n |= UUDECODE(*b++) << 12; + *out++ = n >> 16; total++; + --l; + if (l > 0) { if (!uuchar[b[0]]) break; @@ -626,14 +625,13 @@ read_more: while (l > 0) { int n = 0; - if (l > 0) { - if (!base64[b[0]] || !base64[b[1]]) - break; - n = base64num[*b++] << 18; - n |= base64num[*b++] << 12; - *out++ = n >> 16; total++; - l -= 2; - } + if (!base64[b[0]] || !base64[b[1]]) + break; + n = base64num[*b++] << 18; + n |= base64num[*b++] << 12; + *out++ = n >> 16; total++; + l -= 2; + if (l > 0) { if (*b == '=') break; diff --git a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c index 8ca422ec0..6ce9d1a0e 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c @@ -1086,10 +1086,17 @@ init_decompression(struct archive_read *a, struct _7zip *zip, zip->bcj_state = 0; break; case _7Z_DELTA: + if (coder2->propertiesSize != 1) { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_MISC, + "Invalid Delta parameter"); + return (ARCHIVE_FAILED); + } filters[fi].id = LZMA_FILTER_DELTA; memset(&delta_opt, 0, sizeof(delta_opt)); delta_opt.type = LZMA_DELTA_TYPE_BYTE; - delta_opt.dist = 1; + delta_opt.dist = + (uint32_t)coder2->properties[0] + 1; filters[fi].options = &delta_opt; fi++; break; @@ -1787,7 +1794,7 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi) return (0); } - if (*p != kSize) + if (*p != kCRC) return (-1); if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0) diff --git a/contrib/libarchive/libarchive/archive_read_support_format_lha.c b/contrib/libarchive/libarchive/archive_read_support_format_lha.c index 95c99bb1f..bff0f01f4 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_lha.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_lha.c @@ -175,7 +175,9 @@ struct lha { struct archive_string gname; uint16_t header_crc; uint16_t crc; - struct archive_string_conv *sconv; + /* dirname and filename could be in different codepages */ + struct archive_string_conv *sconv_dir; + struct archive_string_conv *sconv_fname; struct archive_string_conv *opt_sconv; struct archive_string dirname; @@ -232,8 +234,8 @@ static time_t lha_dos_time(const unsigned char *); static time_t lha_win_time(uint64_t, long *); static unsigned char lha_calcsum(unsigned char, const void *, int, size_t); -static int lha_parse_linkname(struct archive_string *, - struct archive_string *); +static int lha_parse_linkname(struct archive_wstring *, + struct archive_wstring *); static int lha_read_data_none(struct archive_read *, const void **, size_t *, int64_t *); static int lha_read_data_lzh(struct archive_read *, const void **, @@ -473,13 +475,15 @@ static int archive_read_format_lha_read_header(struct archive_read *a, struct archive_entry *entry) { - struct archive_string linkname; - struct archive_string pathname; + struct archive_wstring linkname; + struct archive_wstring pathname; struct lha *lha; const unsigned char *p; const char *signature; int err; - + struct archive_mstring conv_buffer; + const wchar_t *conv_buffer_p; + lha_crc16_init(); a->archive.archive_format = ARCHIVE_FORMAT_LHA; @@ -561,10 +565,13 @@ archive_read_format_lha_read_header(struct archive_read *a, archive_string_empty(&lha->dirname); archive_string_empty(&lha->filename); lha->dos_attr = 0; - if (lha->opt_sconv != NULL) - lha->sconv = lha->opt_sconv; - else - lha->sconv = NULL; + if (lha->opt_sconv != NULL) { + lha->sconv_dir = lha->opt_sconv; + lha->sconv_fname = lha->opt_sconv; + } else { + lha->sconv_dir = NULL; + lha->sconv_fname = NULL; + } switch (p[H_LEVEL_OFFSET]) { case 0: @@ -594,12 +601,54 @@ archive_read_format_lha_read_header(struct archive_read *a, return (truncated_error(a)); /* - * Make a pathname from a dirname and a filename. - */ - archive_string_concat(&lha->dirname, &lha->filename); + * Make a pathname from a dirname and a filename, after converting to Unicode. + * This is because codepages might differ between dirname and filename. + */ archive_string_init(&pathname); archive_string_init(&linkname); - archive_string_copy(&pathname, &lha->dirname); + archive_string_init(&conv_buffer.aes_mbs); + archive_string_init(&conv_buffer.aes_mbs_in_locale); + archive_string_init(&conv_buffer.aes_utf8); + archive_string_init(&conv_buffer.aes_wcs); + if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->dirname.s, lha->dirname.length, lha->sconv_dir)) { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, + "Pathname cannot be converted " + "from %s to Unicode.", + archive_string_conversion_charset_name(lha->sconv_dir)); + err = ARCHIVE_FATAL; + } else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p)) + err = ARCHIVE_FATAL; + if (err == ARCHIVE_FATAL) { + archive_mstring_clean(&conv_buffer); + archive_wstring_free(&pathname); + archive_wstring_free(&linkname); + return (err); + } + archive_wstring_copy(&pathname, &conv_buffer.aes_wcs); + + archive_string_empty(&conv_buffer.aes_mbs); + archive_string_empty(&conv_buffer.aes_mbs_in_locale); + archive_string_empty(&conv_buffer.aes_utf8); + archive_wstring_empty(&conv_buffer.aes_wcs); + if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->filename.s, lha->filename.length, lha->sconv_fname)) { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, + "Pathname cannot be converted " + "from %s to Unicode.", + archive_string_conversion_charset_name(lha->sconv_fname)); + err = ARCHIVE_FATAL; + } + else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p)) + err = ARCHIVE_FATAL; + if (err == ARCHIVE_FATAL) { + archive_mstring_clean(&conv_buffer); + archive_wstring_free(&pathname); + archive_wstring_free(&linkname); + return (err); + } + archive_wstring_concat(&pathname, &conv_buffer.aes_wcs); + archive_mstring_clean(&conv_buffer); if ((lha->mode & AE_IFMT) == AE_IFLNK) { /* @@ -610,8 +659,8 @@ archive_read_format_lha_read_header(struct archive_read *a, archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Unknown symlink-name"); - archive_string_free(&pathname); - archive_string_free(&linkname); + archive_wstring_free(&pathname); + archive_wstring_free(&linkname); return (ARCHIVE_FAILED); } } else { @@ -629,39 +678,13 @@ archive_read_format_lha_read_header(struct archive_read *a, /* * Set basic file parameters. */ - if (archive_entry_copy_pathname_l(entry, pathname.s, - pathname.length, lha->sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted " - "from %s to current locale.", - archive_string_conversion_charset_name(lha->sconv)); - err = ARCHIVE_WARN; - } - archive_string_free(&pathname); + archive_entry_copy_pathname_w(entry, pathname.s); + archive_wstring_free(&pathname); if (archive_strlen(&linkname) > 0) { - if (archive_entry_copy_symlink_l(entry, linkname.s, - linkname.length, lha->sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Linkname cannot be converted " - "from %s to current locale.", - archive_string_conversion_charset_name(lha->sconv)); - err = ARCHIVE_WARN; - } + archive_entry_copy_symlink_w(entry, linkname.s); } else archive_entry_set_symlink(entry, NULL); - archive_string_free(&linkname); + archive_wstring_free(&linkname); /* * When a header level is 0, there is a possibility that * a pathname and a symlink has '\' character, a directory @@ -1208,6 +1231,27 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha, archive_strncpy(&lha->filename, (const char *)extdheader, datasize); break; + case EXT_UTF16_FILENAME: + if (datasize == 0) { + /* maybe directory header */ + archive_string_empty(&lha->filename); + break; + } else if (datasize & 1) { + /* UTF-16 characters take always 2 or 4 bytes */ + goto invalid; + } + if (extdheader[0] == '\0') + goto invalid; + archive_string_empty(&lha->filename); + archive_array_append(&lha->filename, + (const char *)extdheader, datasize); + /* Setup a string conversion for a filename. */ + lha->sconv_fname = + archive_string_conversion_from_charset(&a->archive, + "UTF-16LE", 1); + if (lha->sconv_fname == NULL) + return (ARCHIVE_FATAL); + break; case EXT_DIRECTORY: if (datasize == 0 || extdheader[0] == '\0') /* no directory name data. exit this case. */ @@ -1228,6 +1272,50 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha, /* invalid directory data */ goto invalid; break; + case EXT_UTF16_DIRECTORY: + /* UTF-16 characters take always 2 or 4 bytes */ + if (datasize == 0 || (datasize & 1) || + extdheader[0] == '\0') { + /* no directory name data. exit this case. */ + goto invalid; + } + + archive_string_empty(&lha->dirname); + archive_array_append(&lha->dirname, + (const char *)extdheader, datasize); + lha->sconv_dir = + archive_string_conversion_from_charset(&a->archive, + "UTF-16LE", 1); + if (lha->sconv_dir == NULL) + return (ARCHIVE_FATAL); + else { + /* + * Convert directory delimiter from 0xFFFF + * to '/' for local system. + */ + uint16_t dirSep; + uint16_t d = 1; + if (archive_be16dec(&d) == 1) + dirSep = 0x2F00; + else + dirSep = 0x002F; + + /* UTF-16LE character */ + uint16_t *utf16name = + (uint16_t *)lha->dirname.s; + for (i = 0; i < lha->dirname.length / 2; i++) { + if (utf16name[i] == 0xFFFF) { + utf16name[i] = dirSep; + } + } + /* Is last character directory separator? */ + if (utf16name[lha->dirname.length / 2 - 1] != + dirSep) { + /* invalid directory data */ + goto invalid; + } + } + break; case EXT_DOS_ATTR: if (datasize == 2) lha->dos_attr = (unsigned char) @@ -1276,11 +1364,16 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha, charset = cp.s; break; } - lha->sconv = + lha->sconv_dir = + archive_string_conversion_from_charset( + &(a->archive), charset, 1); + lha->sconv_fname = archive_string_conversion_from_charset( &(a->archive), charset, 1); archive_string_free(&cp); - if (lha->sconv == NULL) + if (lha->sconv_dir == NULL) + return (ARCHIVE_FATAL); + if (lha->sconv_fname == NULL) return (ARCHIVE_FATAL); } break; @@ -1336,8 +1429,7 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha, } break; case EXT_TIMEZONE: /* Not supported */ - case EXT_UTF16_FILENAME: /* Not supported */ - case EXT_UTF16_DIRECTORY: /* Not supported */ + break; default: break; } @@ -1600,19 +1692,19 @@ archive_read_format_lha_cleanup(struct archive_read *a) * then a archived pathname is 'xxx/bbb|aaa/bb/cc' */ static int -lha_parse_linkname(struct archive_string *linkname, - struct archive_string *pathname) +lha_parse_linkname(struct archive_wstring *linkname, + struct archive_wstring *pathname) { - char * linkptr; + wchar_t * linkptr; size_t symlen; - linkptr = strchr(pathname->s, '|'); + linkptr = wcschr(pathname->s, L'|'); if (linkptr != NULL) { - symlen = strlen(linkptr + 1); - archive_strncpy(linkname, linkptr+1, symlen); + symlen = wcslen(linkptr + 1); + archive_wstrncpy(linkname, linkptr+1, symlen); *linkptr = 0; - pathname->length = strlen(pathname->s); + pathname->length = wcslen(pathname->s); return (1); } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c index 35d8a4d47..35b1df6aa 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c @@ -258,6 +258,7 @@ archive_read_support_format_mtree(struct archive *_a) "Can't allocate mtree data"); return (ARCHIVE_FATAL); } + mtree->checkfs = 0; mtree->fd = -1; __archive_rb_tree_init(&mtree->rbtree, &rb_ops); diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar.c b/contrib/libarchive/libarchive/archive_read_support_format_rar.c index 3a87a7042..1b3ea0e77 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_rar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_rar.c @@ -148,6 +148,9 @@ #define FILE_ATTRIBUTE_DIRECTORY 0x10 #endif +#undef minimum +#define minimum(a, b) ((a)<(b)?(a):(b)) + /* Fields common to all headers */ struct rar_header { @@ -1715,6 +1718,13 @@ read_exttime(const char *p, struct rar *rar, const char *endp) struct tm *tm; time_t t; long nsec; +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif if (p + 2 > endp) return (-1); @@ -1746,7 +1756,18 @@ read_exttime(const char *p, struct rar *rar, const char *endp) rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8); p++; } +#if defined(HAVE_LOCALTIME_R) + tm = localtime_r(&t, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = t; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + tm = NULL; + else + tm = &tmbuf; +#else tm = localtime(&t); +#endif nsec = tm->tm_sec + rem / NS_UNIT; if (rmode & 4) { @@ -2440,8 +2461,11 @@ create_code(struct archive_read *a, struct huffman_code *code, if (add_value(a, code, j, codebits, i) != ARCHIVE_OK) return (ARCHIVE_FATAL); codebits++; - if (--symbolsleft <= 0) { break; break; } + if (--symbolsleft <= 0) + break; } + if (symbolsleft <= 0) + break; codebits <<= 1; } return (ARCHIVE_OK); @@ -2451,7 +2475,8 @@ static int add_value(struct archive_read *a, struct huffman_code *code, int value, int codebits, int length) { - int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode; + int lastnode, bitpos, bit; + /* int repeatpos, repeatnode, nextnode; */ free(code->table); code->table = NULL; @@ -2461,6 +2486,9 @@ add_value(struct archive_read *a, struct huffman_code *code, int value, if(length < code->minlength) code->minlength = length; + /* + * Dead code, repeatpos was is -1 + * repeatpos = -1; if (repeatpos == 0 || (repeatpos >= 0 && (((codebits >> (repeatpos - 1)) & 3) == 0 @@ -2470,6 +2498,7 @@ add_value(struct archive_read *a, struct huffman_code *code, int value, "Invalid repeat position"); return (ARCHIVE_FATAL); } + */ lastnode = 0; for (bitpos = length - 1; bitpos >= 0; bitpos--) @@ -2485,9 +2514,12 @@ add_value(struct archive_read *a, struct huffman_code *code, int value, return (ARCHIVE_FATAL); } + /* + * Dead code, repeatpos was -1, bitpos >=0 + * if (bitpos == repeatpos) { - /* Open branch check */ + * Open branch check * if (!(code->tree[lastnode].branches[bit] < 0)) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, @@ -2506,16 +2538,17 @@ add_value(struct archive_read *a, struct huffman_code *code, int value, return (ARCHIVE_FATAL); } - /* Set branches */ + * Set branches * code->tree[lastnode].branches[bit] = repeatnode; code->tree[repeatnode].branches[bit] = repeatnode; code->tree[repeatnode].branches[bit^1] = nextnode; lastnode = nextnode; - bitpos++; /* terminating bit already handled, skip it */ + bitpos++; * terminating bit already handled, skip it * } else { + */ /* Open branch check */ if (code->tree[lastnode].branches[bit] < 0) { @@ -2529,7 +2562,7 @@ add_value(struct archive_read *a, struct huffman_code *code, int value, /* set to branch */ lastnode = code->tree[lastnode].branches[bit]; - } + /* } */ } if (!(code->tree[lastnode].branches[0] == -1 @@ -2613,11 +2646,15 @@ make_table_recurse(struct archive_read *a, struct huffman_code *code, int node, table[i].value = code->tree[node].branches[0]; } } + /* + * Dead code, node >= 0 + * else if (node < 0) { for(i = 0; i < currtablesize; i++) table[i].length = -1; } + */ else { if(depth == maxdepth) @@ -2649,6 +2686,10 @@ expand(struct archive_read *a, int64_t end) 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 }; + static const int lengthb_min = minimum( + (int)(sizeof(lengthbases)/sizeof(lengthbases[0])), + (int)(sizeof(lengthbits)/sizeof(lengthbits[0])) + ); static const unsigned int offsetbases[] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, @@ -2666,6 +2707,10 @@ expand(struct archive_read *a, int64_t end) 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; + static const int offsetb_min = minimum( + (int)(sizeof(offsetbases)/sizeof(offsetbases[0])), + (int)(sizeof(offsetbits)/sizeof(offsetbits[0])) + ); static const unsigned char shortbases[] = { 0, 4, 8, 16, 32, 64, 128, 192 }; static const unsigned char shortbits[] = @@ -2745,9 +2790,7 @@ expand(struct archive_read *a, int64_t end) if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0) goto bad_data; - if (lensymbol > (int)(sizeof(lengthbases)/sizeof(lengthbases[0]))) - goto bad_data; - if (lensymbol > (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))) + if (lensymbol > lengthb_min) goto bad_data; len = lengthbases[lensymbol] + 2; if (lengthbits[lensymbol] > 0) { @@ -2779,9 +2822,7 @@ expand(struct archive_read *a, int64_t end) } else { - if (symbol-271 > (int)(sizeof(lengthbases)/sizeof(lengthbases[0]))) - goto bad_data; - if (symbol-271 > (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))) + if (symbol-271 > lengthb_min) goto bad_data; len = lengthbases[symbol-271]+3; if(lengthbits[symbol-271] > 0) { @@ -2793,9 +2834,7 @@ expand(struct archive_read *a, int64_t end) if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0) goto bad_data; - if (offssymbol > (int)(sizeof(offsetbases)/sizeof(offsetbases[0]))) - goto bad_data; - if (offssymbol > (int)(sizeof(offsetbits)/sizeof(offsetbits[0]))) + if (offssymbol > offsetb_min) goto bad_data; offs = offsetbases[offssymbol]+1; if(offsetbits[offssymbol] > 0) diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c index e58cbbf6d..82729bdcd 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c @@ -63,6 +63,7 @@ #if defined DEBUG #define DEBUG_CODE if(1) +#define LOG(...) do { printf("rar5: " __VA_ARGS__); puts(""); } while(0) #else #define DEBUG_CODE if(0) #endif @@ -72,15 +73,14 @@ * 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00 * "Rar!→•☺·\x00" * - * It's stored in `rar5_signature` after XOR'ing it with 0xA1, because I don't + * Retrieved with `rar5_signature()` by XOR'ing it with 0xA1, because I don't * want to put this magic sequence in each binary that uses libarchive, so * applications that scan through the file for this marker won't trigger on * this "false" one. * * The array itself is decrypted in `rar5_init` function. */ -static unsigned char rar5_signature[] = { 243, 192, 211, 128, 187, 166, 160, 161 }; -static const ssize_t rar5_signature_size = sizeof(rar5_signature); +static unsigned char rar5_signature_xor[] = { 243, 192, 211, 128, 187, 166, 160, 161 }; static const size_t g_unpack_window_size = 0x20000; /* These could have been static const's, but they aren't, because of @@ -115,6 +115,8 @@ struct file_header { /* Optional redir fields */ uint64_t redir_type; uint64_t redir_flags; + + ssize_t solid_window_size; /* Used in file format check. */ }; enum EXTRA { @@ -208,7 +210,7 @@ struct comp_state { or just a part of it. */ uint8_t block_parsing_finished : 1; - int notused : 4; + signed int notused : 4; int flags; /* Uncompression flags. */ int method; /* Uncompression algorithm method. */ @@ -354,6 +356,7 @@ struct rar5 { /* Forward function declarations. */ +static void rar5_signature(char *buf); static int verify_global_checksums(struct archive_read* a); static int rar5_read_data_skip(struct archive_read *a); static int push_data_ready(struct archive_read* a, struct rar5* rar, @@ -381,7 +384,7 @@ static int cdeque_init(struct cdeque* d, int max_capacity_power_of_2) { d->cap_mask = max_capacity_power_of_2 - 1; d->arr = NULL; - if((max_capacity_power_of_2 & d->cap_mask) > 0) + if((max_capacity_power_of_2 & d->cap_mask) != 0) return CDE_PARAM; cdeque_clear(d); @@ -878,10 +881,10 @@ static inline int get_archive_read(struct archive* a, static int read_ahead(struct archive_read* a, size_t how_many, const uint8_t** ptr) { + ssize_t avail = -1; if(!ptr) return 0; - ssize_t avail = -1; *ptr = __archive_read_ahead(a, how_many, &avail); if(*ptr == NULL) { return 0; @@ -1083,11 +1086,14 @@ static int read_u64(struct archive_read* a, uint64_t* pvalue) { static int bid_standard(struct archive_read* a) { const uint8_t* p; + char signature[sizeof(rar5_signature_xor)]; - if(!read_ahead(a, rar5_signature_size, &p)) + rar5_signature(signature); + + if(!read_ahead(a, sizeof(rar5_signature_xor), &p)) return -1; - if(!memcmp(rar5_signature, p, rar5_signature_size)) + if(!memcmp(signature, p, sizeof(rar5_signature_xor))) return 30; return -1; @@ -1147,14 +1153,14 @@ static int process_main_locator_extra_block(struct archive_read* a, { uint64_t locator_flags; - if(!read_var(a, &locator_flags, NULL)) { - return ARCHIVE_EOF; - } - enum LOCATOR_FLAGS { QLIST = 0x01, RECOVERY = 0x02, }; + if(!read_var(a, &locator_flags, NULL)) { + return ARCHIVE_EOF; + } + if(locator_flags & QLIST) { if(!read_var(a, &rar->qlist_offset, NULL)) { return ARCHIVE_EOF; @@ -1177,9 +1183,13 @@ static int process_main_locator_extra_block(struct archive_read* a, static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar, ssize_t* extra_data_size) { - size_t hash_type; + size_t hash_type = 0; size_t value_len; + enum HASH_TYPE { + BLAKE2sp = 0x00 + }; + if(!read_var_sized(a, &hash_type, &value_len)) return ARCHIVE_EOF; @@ -1188,10 +1198,6 @@ static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar, return ARCHIVE_EOF; } - enum HASH_TYPE { - BLAKE2sp = 0x00 - }; - /* The file uses BLAKE2sp checksum algorithm instead of plain old * CRC32. */ if(hash_type == BLAKE2sp) { @@ -1254,6 +1260,7 @@ static int parse_file_extra_version(struct archive_read* a, size_t value_len = 0; struct archive_string version_string; struct archive_string name_utf8_string; + const char* cur_filename; /* Flags are ignored. */ if(!read_var_sized(a, &flags, &value_len)) @@ -1272,7 +1279,7 @@ static int parse_file_extra_version(struct archive_read* a, /* extra_data_size should be zero here. */ - const char* cur_filename = archive_entry_pathname_utf8(e); + cur_filename = archive_entry_pathname_utf8(e); if(cur_filename == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, "Version entry without file name"); @@ -1303,7 +1310,7 @@ static int parse_file_extra_htime(struct archive_read* a, struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size) { char unix_time = 0; - size_t flags; + size_t flags = 0; size_t value_len; enum HTIME_FLAGS { @@ -1583,6 +1590,25 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, char name_utf8_buf[MAX_NAME_IN_BYTES]; const uint8_t* p; + enum FILE_FLAGS { + DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004, + UNKNOWN_UNPACKED_SIZE = 0x0008, + }; + + enum FILE_ATTRS { + ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4, + ATTR_DIRECTORY = 0x10, + }; + + enum COMP_INFO_FLAGS { + SOLID = 0x0040, + }; + + enum HOST_OS { + HOST_WINDOWS = 0, + HOST_UNIX = 1, + }; + archive_entry_clear(entry); /* Do not reset file context if we're switching archives. */ @@ -1612,20 +1638,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, return ARCHIVE_FATAL; } - enum FILE_FLAGS { - DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004, - UNKNOWN_UNPACKED_SIZE = 0x0008, - }; - - enum FILE_ATTRS { - ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4, - ATTR_DIRECTORY = 0x10, - }; - - enum COMP_INFO_FLAGS { - SOLID = 0x0040, - }; - if(!read_var_sized(a, &file_flags, NULL)) return ARCHIVE_EOF; @@ -1665,6 +1677,17 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, g_unpack_window_size << ((compression_info >> 10) & 15); rar->cstate.method = c_method; rar->cstate.version = c_version + 50; + rar->file.solid = (compression_info & SOLID) > 0; + + /* Archives which declare solid files without initializing the window + * buffer first are invalid. */ + + if(rar->file.solid > 0 && rar->cstate.window_buf == NULL) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Declared solid file, but no window buffer " + "initialized yet."); + return ARCHIVE_FATAL; + } /* Check if window_size is a sane value. Also, if the file is not * declared as a directory, disallow window_size == 0. */ @@ -1676,22 +1699,41 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, return ARCHIVE_FATAL; } - /* Values up to 64M should fit into ssize_t on every - * architecture. */ - rar->cstate.window_size = (ssize_t) window_size; + if(rar->file.solid > 0) { + /* Re-check if current window size is the same as previous + * window size (for solid files only). */ + if(rar->file.solid_window_size > 0 && + rar->file.solid_window_size != (ssize_t) window_size) + { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Window size for this solid file doesn't match " + "the window size used in previous solid file. "); + return ARCHIVE_FATAL; + } + } + + /* If we're currently switching volumes, ignore the new definition of + * window_size. */ + if(rar->cstate.switch_multivolume == 0) { + /* Values up to 64M should fit into ssize_t on every + * architecture. */ + rar->cstate.window_size = (ssize_t) window_size; + } + + if(rar->file.solid > 0 && rar->file.solid_window_size == 0) { + /* Solid files have to have the same window_size across + whole archive. Remember the window_size parameter + for first solid file found. */ + rar->file.solid_window_size = rar->cstate.window_size; + } + init_window_mask(rar); - rar->file.solid = (compression_info & SOLID) > 0; rar->file.service = 0; if(!read_var_sized(a, &host_os, NULL)) return ARCHIVE_EOF; - enum HOST_OS { - HOST_WINDOWS = 0, - HOST_UNIX = 1, - }; - if(host_os == HOST_WINDOWS) { /* Host OS is Windows */ @@ -1783,12 +1825,16 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, int ret = process_head_file_extra(a, entry, rar, extra_data_size); - /* Sanity check. */ + /* + * TODO: rewrite or remove useless sanity check + * as extra_data_size is not passed as a pointer + * if(extra_data_size < 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, "File extra data size is not zero"); return ARCHIVE_FATAL; } + */ if(ret != ARCHIVE_OK) return ret; @@ -1853,14 +1899,28 @@ static int process_head_service(struct archive_read* a, struct rar5* rar, static int process_head_main(struct archive_read* a, struct rar5* rar, struct archive_entry* entry, size_t block_flags) { - (void) entry; - int ret; size_t extra_data_size = 0; size_t extra_field_size = 0; size_t extra_field_id = 0; size_t archive_flags = 0; + enum MAIN_FLAGS { + VOLUME = 0x0001, /* multi-volume archive */ + VOLUME_NUMBER = 0x0002, /* volume number, first vol doesn't + * have it */ + SOLID = 0x0004, /* solid archive */ + PROTECT = 0x0008, /* contains Recovery info */ + LOCK = 0x0010, /* readonly flag, not used */ + }; + + enum MAIN_EXTRA { + // Just one attribute here. + LOCATOR = 0x01, + }; + + (void) entry; + if(block_flags & HFL_EXTRA_DATA) { if(!read_var_sized(a, &extra_data_size, NULL)) return ARCHIVE_EOF; @@ -1872,15 +1932,6 @@ static int process_head_main(struct archive_read* a, struct rar5* rar, return ARCHIVE_EOF; } - enum MAIN_FLAGS { - VOLUME = 0x0001, /* multi-volume archive */ - VOLUME_NUMBER = 0x0002, /* volume number, first vol doesn't - * have it */ - SOLID = 0x0004, /* solid archive */ - PROTECT = 0x0008, /* contains Recovery info */ - LOCK = 0x0010, /* readonly flag, not used */ - }; - rar->main.volume = (archive_flags & VOLUME) > 0; rar->main.solid = (archive_flags & SOLID) > 0; @@ -1932,11 +1983,6 @@ static int process_head_main(struct archive_read* a, struct rar5* rar, return ARCHIVE_FATAL; } - enum MAIN_EXTRA { - // Just one attribute here. - LOCATOR = 0x01, - }; - switch(extra_field_id) { case LOCATOR: ret = process_main_locator_extra_block(a, rar); @@ -2042,6 +2088,8 @@ static int scan_for_signature(struct archive_read* a); static int process_base_block(struct archive_read* a, struct archive_entry* entry) { + const size_t SMALLEST_RAR5_BLOCK_SIZE = 3; + struct rar5* rar = get_context(a); uint32_t hdr_crc, computed_crc; size_t raw_hdr_size = 0, hdr_size_len, hdr_size; @@ -2050,6 +2098,12 @@ static int process_base_block(struct archive_read* a, const uint8_t* p; int ret; + enum HEADER_TYPE { + HEAD_MARK = 0x00, HEAD_MAIN = 0x01, HEAD_FILE = 0x02, + HEAD_SERVICE = 0x03, HEAD_CRYPT = 0x04, HEAD_ENDARC = 0x05, + HEAD_UNKNOWN = 0xff, + }; + /* Skip any unprocessed data for this file. */ ret = skip_unprocessed_bytes(a); if(ret != ARCHIVE_OK) @@ -2065,15 +2119,26 @@ static int process_base_block(struct archive_read* a, return ARCHIVE_EOF; } + hdr_size = raw_hdr_size + hdr_size_len; + /* Sanity check, maximum header size for RAR5 is 2MB. */ - if(raw_hdr_size > (2 * 1024 * 1024)) { + if(hdr_size > (2 * 1024 * 1024)) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Base block header is too large"); return ARCHIVE_FATAL; } - hdr_size = raw_hdr_size + hdr_size_len; + /* Additional sanity checks to weed out invalid files. */ + if(raw_hdr_size == 0 || hdr_size_len == 0 || + hdr_size < SMALLEST_RAR5_BLOCK_SIZE) + { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Too small block encountered (%zu bytes)", + raw_hdr_size); + + return ARCHIVE_FATAL; + } /* Read the whole header data into memory, maximum memory use here is * 2MB. */ @@ -2108,12 +2173,6 @@ static int process_base_block(struct archive_read* a, rar->main.endarc = 0; /* Those are possible header ids in RARv5. */ - enum HEADER_TYPE { - HEAD_MARK = 0x00, HEAD_MAIN = 0x01, HEAD_FILE = 0x02, - HEAD_SERVICE = 0x03, HEAD_CRYPT = 0x04, HEAD_ENDARC = 0x05, - HEAD_UNKNOWN = 0xff, - }; - switch(header_id) { case HEAD_MAIN: ret = process_head_main(a, rar, entry, header_flags); @@ -2226,7 +2285,7 @@ static int rar5_read_header(struct archive_read *a, } if(rar->skipped_magic == 0) { - if(ARCHIVE_OK != consume(a, rar5_signature_size)) { + if(ARCHIVE_OK != consume(a, sizeof(rar5_signature_xor))) { return ARCHIVE_EOF; } @@ -2498,12 +2557,10 @@ static int parse_tables(struct archive_read* a, struct rar5* rar, /* 0..15: store directly */ table[i] = (uint8_t) num; i++; - continue; - } - - if(num < 18) { + } else if(num < 18) { /* 16..17: repeat previous code */ uint16_t n; + if(ARCHIVE_OK != read_bits_16(rar, p, &n)) return ARCHIVE_EOF; @@ -2529,27 +2586,26 @@ static int parse_tables(struct archive_read* a, struct rar5* rar, "huffman tables"); return ARCHIVE_FATAL; } + } else { + /* other codes: fill with zeroes `n` times */ + uint16_t n; - continue; - } + if(ARCHIVE_OK != read_bits_16(rar, p, &n)) + return ARCHIVE_EOF; - /* other codes: fill with zeroes `n` times */ - uint16_t n; - if(ARCHIVE_OK != read_bits_16(rar, p, &n)) - return ARCHIVE_EOF; + if(num == 18) { + n >>= 13; + n += 3; + skip_bits(rar, 3); + } else { + n >>= 9; + n += 11; + skip_bits(rar, 7); + } - if(num == 18) { - n >>= 13; - n += 3; - skip_bits(rar, 3); - } else { - n >>= 9; - n += 11; - skip_bits(rar, 7); + while(n-- > 0 && i < HUFF_TABLE_SIZE) + table[i++] = 0; } - - while(n-- > 0 && i < HUFF_TABLE_SIZE) - table[i++] = 0; } ret = create_decode_tables(&table[idx], &rar->cstate.ld, HUFF_NC); @@ -2594,6 +2650,7 @@ static int parse_tables(struct archive_read* a, struct rar5* rar, static int parse_block_header(struct archive_read* a, const uint8_t* p, ssize_t* block_size, struct compressed_block_header* hdr) { + uint8_t calculated_cksum; memcpy(hdr, p, sizeof(struct compressed_block_header)); if(bf_byte_count(hdr) > 2) { @@ -2632,7 +2689,7 @@ static int parse_block_header(struct archive_read* a, const uint8_t* p, /* Verify the block header checksum. 0x5A is a magic value and is * always * constant. */ - uint8_t calculated_cksum = 0x5A + calculated_cksum = 0x5A ^ (uint8_t) hdr->block_flags_u8 ^ (uint8_t) *block_size ^ (uint8_t) (*block_size >> 8) @@ -2706,6 +2763,7 @@ static int is_valid_filter_block_start(struct rar5* rar, static int parse_filter(struct archive_read* ar, const uint8_t* p) { uint32_t block_start, block_length; uint16_t filter_type; + struct filter_info* filt = NULL; struct rar5* rar = get_context(ar); /* Read the parameters from the input stream. */ @@ -2736,7 +2794,7 @@ static int parse_filter(struct archive_read* ar, const uint8_t* p) { } /* Allocate a new filter. */ - struct filter_info* filt = add_new_filter(rar); + filt = add_new_filter(rar); if(filt == NULL) { archive_set_error(&ar->archive, ENOMEM, "Can't allocate memory for a filter descriptor."); @@ -3005,7 +3063,8 @@ static int do_uncompress_block(struct archive_read* a, const uint8_t* p) { } continue; - } else if(num < 262) { + } else { + /* num < 262 */ const int idx = num - 258; const int dist = dist_cache_touch(rar, idx); @@ -3041,6 +3100,7 @@ static int scan_for_signature(struct archive_read* a) { const uint8_t* p; const int chunk_size = 512; ssize_t i; + char signature[sizeof(rar5_signature_xor)]; /* If we're here, it means we're on an 'unknown territory' data. * There's no indication what kind of data we're reading here. @@ -3054,19 +3114,23 @@ static int scan_for_signature(struct archive_read* a) { * end of the file? If so, it would be a better approach than the * current implementation of this function. */ + rar5_signature(signature); + while(1) { if(!read_ahead(a, chunk_size, &p)) return ARCHIVE_EOF; - for(i = 0; i < chunk_size - rar5_signature_size; i++) { - if(memcmp(&p[i], rar5_signature, - rar5_signature_size) == 0) { + for(i = 0; i < chunk_size - (int)sizeof(rar5_signature_xor); + i++) { + if(memcmp(&p[i], signature, + sizeof(rar5_signature_xor)) == 0) { /* Consume the number of bytes we've used to * search for the signature, as well as the * number of bytes used by the signature * itself. After this we should be standing * on a valid base block header. */ - (void) consume(a, i + rar5_signature_size); + (void) consume(a, + i + sizeof(rar5_signature_xor)); return ARCHIVE_OK; } } @@ -3276,6 +3340,8 @@ static int process_block(struct archive_read* a) { if(rar->cstate.block_parsing_finished) { ssize_t block_size; + ssize_t to_skip; + ssize_t cur_block_size; /* The header size won't be bigger than 6 bytes. */ if(!read_ahead(a, 6, &p)) { @@ -3299,7 +3365,7 @@ static int process_block(struct archive_read* a) { /* Skip block header. Next data is huffman tables, * if present. */ - ssize_t to_skip = sizeof(struct compressed_block_header) + + to_skip = sizeof(struct compressed_block_header) + bf_byte_count(&rar->last_block_hdr) + 1; if(ARCHIVE_OK != consume(a, to_skip)) @@ -3313,7 +3379,7 @@ static int process_block(struct archive_read* a) { * bigger than the actual data stored in this file. Remaining * part of the data will be in another file. */ - ssize_t cur_block_size = + cur_block_size = rar5_min(rar->file.bytes_remaining, block_size); if(block_size > rar->file.bytes_remaining) { @@ -3641,6 +3707,7 @@ static int uncompress_file(struct archive_read* a) { static int do_unstore_file(struct archive_read* a, struct rar5* rar, const void** buf, size_t* size, int64_t* offset) { + size_t to_read; const uint8_t* p; if(rar->file.bytes_remaining == 0 && rar->main.volume > 0 && @@ -3659,7 +3726,7 @@ static int do_unstore_file(struct archive_read* a, } } - size_t to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024); + to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024); if(to_read == 0) { return ARCHIVE_EOF; } @@ -3828,6 +3895,18 @@ static int verify_global_checksums(struct archive_read* a) { return verify_checksums(a); } +/* + * Decryption function for the magic signature pattern. Check the comment near + * the `rar5_signature_xor` symbol to read the rationale behind this. + */ +static void rar5_signature(char *buf) { + size_t i; + + for(i = 0; i < sizeof(rar5_signature_xor); i++) { + buf[i] = rar5_signature_xor[i] ^ 0xA1; + } +} + static int rar5_read_data(struct archive_read *a, const void **buff, size_t *size, int64_t *offset) { int ret; @@ -3974,19 +4053,8 @@ static int rar5_has_encrypted_entries(struct archive_read *_a) { } static int rar5_init(struct rar5* rar) { - ssize_t i; - memset(rar, 0, sizeof(struct rar5)); - /* Decrypt the magic signature pattern. Check the comment near the - * `rar5_signature` symbol to read the rationale behind this. */ - - if(rar5_signature[0] == 243) { - for(i = 0; i < rar5_signature_size; i++) { - rar5_signature[i] ^= 0xA1; - } - } - if(CDE_OK != cdeque_init(&rar->cstate.filters, 8192)) return ARCHIVE_FATAL; diff --git a/contrib/libarchive/libarchive/archive_read_support_format_warc.c b/contrib/libarchive/libarchive/archive_read_support_format_warc.c index f076e48c4..6a0f31143 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_warc.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_warc.c @@ -621,7 +621,8 @@ _warc_rdver(const char *buf, size_t bsz) if (ver >= 1200U) { if (memcmp(c, "\r\n", 2U) != 0) ver = 0U; - } else if (ver < 1200U) { + } else { + /* ver < 1200U */ if (*c != ' ' && *c != '\t') ver = 0U; } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_xar.c b/contrib/libarchive/libarchive/archive_read_support_format_xar.c index 34253a52f..7f8be398c 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_xar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_xar.c @@ -2613,15 +2613,14 @@ strappend_base64(struct xar *xar, while (l > 0) { int n = 0; - if (l > 0) { - if (base64[b[0]] < 0 || base64[b[1]] < 0) - break; - n = base64[*b++] << 18; - n |= base64[*b++] << 12; - *out++ = n >> 16; - len++; - l -= 2; - } + if (base64[b[0]] < 0 || base64[b[1]] < 0) + break; + n = base64[*b++] << 18; + n |= base64[*b++] << 12; + *out++ = n >> 16; + len++; + l -= 2; + if (l > 0) { if (base64[*b] < 0) break; diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c index 2e2fbb30a..77cd69b44 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c @@ -1797,6 +1797,23 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff, "lzma data error (error %d)", (int) lz_ret); return (ARCHIVE_FATAL); + /* This case is optional in lzma alone format. It can happen, + * but most of the files don't have it. (GitHub #1257) */ + case LZMA_STREAM_END: + lzma_end(&zip->zipx_lzma_stream); + zip->zipx_lzma_valid = 0; + if((int64_t) zip->zipx_lzma_stream.total_in != + zip->entry_bytes_remaining) + { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_MISC, + "lzma alone premature end of stream"); + return (ARCHIVE_FATAL); + } + + zip->end_of_entry = 1; + break; + case LZMA_OK: break; diff --git a/contrib/libarchive/libarchive/archive_string.c b/contrib/libarchive/libarchive/archive_string.c index 4444ea226..cbf055ded 100644 --- a/contrib/libarchive/libarchive/archive_string.c +++ b/contrib/libarchive/libarchive/archive_string.c @@ -75,6 +75,9 @@ __FBSDID("$FreeBSD$"); #define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t)) #endif +#undef max +#define max(a, b) ((a)>(b)?(a):(b)) + struct archive_string_conv { struct archive_string_conv *next; char *from_charset; @@ -591,7 +594,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, * No single byte will be more than one wide character, * so this length estimate will always be big enough. */ - size_t wcs_length = len; + // size_t wcs_length = len; size_t mbs_length = len; const char *mbs = p; wchar_t *wcs; @@ -600,7 +603,11 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, memset(&shift_state, 0, sizeof(shift_state)); #endif - if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1)) + /* + * As we decided to have wcs_length == mbs_length == len + * we can use len here instead of wcs_length + */ + if (NULL == archive_wstring_ensure(dest, dest->length + len + 1)) return (-1); wcs = dest->s + dest->length; /* @@ -609,6 +616,12 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, * multi bytes. */ while (*mbs && mbs_length > 0) { + /* + * The buffer we allocated is always big enough. + * Keep this code path in a comment if we decide to choose + * smaller wcs_length in the future + */ +/* if (wcs_length == 0) { dest->length = wcs - dest->s; dest->s[dest->length] = L'\0'; @@ -618,24 +631,20 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest, return (-1); wcs = dest->s + dest->length; } +*/ #if HAVE_MBRTOWC - r = mbrtowc(wcs, mbs, wcs_length, &shift_state); + r = mbrtowc(wcs, mbs, mbs_length, &shift_state); #else - r = mbtowc(wcs, mbs, wcs_length); + r = mbtowc(wcs, mbs, mbs_length); #endif if (r == (size_t)-1 || r == (size_t)-2) { ret_val = -1; - if (errno == EILSEQ) { - ++mbs; - --mbs_length; - continue; - } else - break; + break; } if (r == 0 || r > mbs_length) break; wcs++; - wcs_length--; + // wcs_length--; mbs += r; mbs_length -= r; } @@ -735,7 +744,8 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as, else dp = &defchar_used; count = WideCharToMultiByte(to_cp, 0, ws, wslen, - as->s + as->length, (int)as->buffer_length-1, NULL, dp); + as->s + as->length, + (int)as->buffer_length - as->length - 1, NULL, dp); if (count == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { /* Expand the MBS buffer and retry. */ @@ -798,7 +808,8 @@ archive_string_append_from_wcs(struct archive_string *as, as->s[as->length] = '\0'; /* Re-allocate buffer for MBS. */ if (archive_string_ensure(as, - as->length + len * 2 + 1) == NULL) + as->length + max(len * 2, + (size_t)MB_CUR_MAX) + 1) == NULL) return (-1); p = as->s + as->length; end = as->s + as->buffer_length - MB_CUR_MAX -1; @@ -3440,7 +3451,8 @@ strncat_from_utf8_libarchive2(struct archive_string *as, as->length = p - as->s; /* Re-allocate buffer for MBS. */ if (archive_string_ensure(as, - as->length + len * 2 + 1) == NULL) + as->length + max(len * 2, + (size_t)MB_CUR_MAX) + 1) == NULL) return (-1); p = as->s + as->length; end = as->s + as->buffer_length - MB_CUR_MAX -1; diff --git a/contrib/libarchive/libarchive/archive_string.h b/contrib/libarchive/libarchive/archive_string.h index f5953d008..4d4dbec36 100644 --- a/contrib/libarchive/libarchive/archive_string.h +++ b/contrib/libarchive/libarchive/archive_string.h @@ -26,15 +26,15 @@ * */ +#ifndef ARCHIVE_STRING_H_INCLUDED +#define ARCHIVE_STRING_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #ifndef __LIBARCHIVE_TEST #error This header is only to be used internally to libarchive. #endif #endif -#ifndef ARCHIVE_STRING_H_INCLUDED -#define ARCHIVE_STRING_H_INCLUDED - #include #ifdef HAVE_STDLIB_H #include /* required for wchar_t on some systems */ diff --git a/contrib/libarchive/libarchive/archive_string_composition.h b/contrib/libarchive/libarchive/archive_string_composition.h index 8902ac1f7..d0ac34096 100644 --- a/contrib/libarchive/libarchive/archive_string_composition.h +++ b/contrib/libarchive/libarchive/archive_string_composition.h @@ -34,13 +34,13 @@ * See also http://unicode.org/report/tr15/ */ +#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED +#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED -#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED - struct unicode_composition_table { uint32_t cp1; uint32_t cp2; diff --git a/contrib/libarchive/libarchive/archive_util.c b/contrib/libarchive/libarchive/archive_util.c index 913c83f86..eb7566237 100644 --- a/contrib/libarchive/libarchive/archive_util.c +++ b/contrib/libarchive/libarchive/archive_util.c @@ -218,8 +218,8 @@ __archive_errx(int retvalue, const char *msg) * Also Windows version of mktemp family including _mktemp_s * are not secure. */ -int -__archive_mktemp(const char *tmpdir) +static int +__archive_mktempx(const char *tmpdir, wchar_t *template) { static const wchar_t prefix[] = L"libarchive_"; static const wchar_t suffix[] = L"XXXXXXXXXX"; @@ -243,64 +243,76 @@ __archive_mktemp(const char *tmpdir) hProv = (HCRYPTPROV)NULL; fd = -1; ws = NULL; - archive_string_init(&temp_name); - /* Get a temporary directory. */ - if (tmpdir == NULL) { - size_t l; - wchar_t *tmp; + if (template == NULL) { + archive_string_init(&temp_name); - l = GetTempPathW(0, NULL); - if (l == 0) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } - tmp = malloc(l*sizeof(wchar_t)); - if (tmp == NULL) { - errno = ENOMEM; - goto exit_tmpfile; - } - GetTempPathW((DWORD)l, tmp); - archive_wstrcpy(&temp_name, tmp); - free(tmp); - } else { - if (archive_wstring_append_from_mbs(&temp_name, tmpdir, - strlen(tmpdir)) < 0) - goto exit_tmpfile; - if (temp_name.s[temp_name.length-1] != L'/') - archive_wstrappend_wchar(&temp_name, L'/'); - } + /* Get a temporary directory. */ + if (tmpdir == NULL) { + size_t l; + wchar_t *tmp; - /* Check if temp_name is a directory. */ - attr = GetFileAttributesW(temp_name.s); - if (attr == (DWORD)-1) { - if (GetLastError() != ERROR_FILE_NOT_FOUND) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } - ws = __la_win_permissive_name_w(temp_name.s); - if (ws == NULL) { - errno = EINVAL; - goto exit_tmpfile; + l = GetTempPathW(0, NULL); + if (l == 0) { + la_dosmaperr(GetLastError()); + goto exit_tmpfile; + } + tmp = malloc(l*sizeof(wchar_t)); + if (tmp == NULL) { + errno = ENOMEM; + goto exit_tmpfile; + } + GetTempPathW((DWORD)l, tmp); + archive_wstrcpy(&temp_name, tmp); + free(tmp); + } else { + if (archive_wstring_append_from_mbs(&temp_name, tmpdir, + strlen(tmpdir)) < 0) + goto exit_tmpfile; + if (temp_name.s[temp_name.length-1] != L'/') + archive_wstrappend_wchar(&temp_name, L'/'); } - attr = GetFileAttributesW(ws); + + /* Check if temp_name is a directory. */ + attr = GetFileAttributesW(temp_name.s); if (attr == (DWORD)-1) { - la_dosmaperr(GetLastError()); + if (GetLastError() != ERROR_FILE_NOT_FOUND) { + la_dosmaperr(GetLastError()); + goto exit_tmpfile; + } + ws = __la_win_permissive_name_w(temp_name.s); + if (ws == NULL) { + errno = EINVAL; + goto exit_tmpfile; + } + attr = GetFileAttributesW(ws); + if (attr == (DWORD)-1) { + la_dosmaperr(GetLastError()); + goto exit_tmpfile; + } + } + if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) { + errno = ENOTDIR; goto exit_tmpfile; } - } - if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) { - errno = ENOTDIR; - goto exit_tmpfile; - } - /* - * Create a temporary file. - */ - archive_wstrcat(&temp_name, prefix); - archive_wstrcat(&temp_name, suffix); - ep = temp_name.s + archive_strlen(&temp_name); - xp = ep - wcslen(suffix); + /* + * Create a temporary file. + */ + archive_wstrcat(&temp_name, prefix); + archive_wstrcat(&temp_name, suffix); + ep = temp_name.s + archive_strlen(&temp_name); + xp = ep - wcslen(suffix); + template = temp_name.s; + } else { + xp = wcschr(template, L'X'); + if (xp == NULL) /* No X, programming error */ + abort(); + for (ep = xp; *ep == L'X'; ep++) + continue; + if (*ep) /* X followed by non X, programming error */ + abort(); + } if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { @@ -323,20 +335,24 @@ __archive_mktemp(const char *tmpdir) *p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))]; free(ws); - ws = __la_win_permissive_name_w(temp_name.s); + ws = __la_win_permissive_name_w(template); if (ws == NULL) { errno = EINVAL; goto exit_tmpfile; } - /* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to - * delete this temporary file immediately when this - * file closed. */ + if (template == temp_name.s) { + attr = FILE_ATTRIBUTE_TEMPORARY | + FILE_FLAG_DELETE_ON_CLOSE; + } else { + /* mkstemp */ + attr = FILE_ATTRIBUTE_NORMAL; + } h = CreateFileW(ws, GENERIC_READ | GENERIC_WRITE | DELETE, 0,/* Not share */ NULL, CREATE_NEW,/* Create a new file only */ - FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + attr, NULL); if (h == INVALID_HANDLE_VALUE) { /* The same file already exists. retry with @@ -358,10 +374,23 @@ exit_tmpfile: if (hProv != (HCRYPTPROV)NULL) CryptReleaseContext(hProv, 0); free(ws); - archive_wstring_free(&temp_name); + if (template == temp_name.s) + archive_wstring_free(&temp_name); return (fd); } +int +__archive_mktemp(const char *tmpdir) +{ + return __archive_mktempx(tmpdir, NULL); +} + +int +__archive_mkstemp(wchar_t *template) +{ + return __archive_mktempx(NULL, template); +} + #else static int @@ -414,14 +443,24 @@ exit_tmpfile: return (fd); } -#else +int +__archive_mkstemp(char *template) +{ + int fd = -1; + fd = mkstemp(template); + if (fd >= 0) + __archive_ensure_cloexec_flag(fd); + return (fd); +} + +#else /* !HAVE_MKSTEMP */ /* * We use a private routine. */ -int -__archive_mktemp(const char *tmpdir) +static int +__archive_mktempx(const char *tmpdir, char *template) { static const char num[] = { '0', '1', '2', '3', '4', '5', '6', '7', @@ -439,26 +478,37 @@ __archive_mktemp(const char *tmpdir) char *tp, *ep; fd = -1; - archive_string_init(&temp_name); - if (tmpdir == NULL) { - if (get_tempdir(&temp_name) != ARCHIVE_OK) + if (template == NULL) { + archive_string_init(&temp_name); + if (tmpdir == NULL) { + if (get_tempdir(&temp_name) != ARCHIVE_OK) + goto exit_tmpfile; + } else + archive_strcpy(&temp_name, tmpdir); + if (temp_name.s[temp_name.length-1] == '/') { + temp_name.s[temp_name.length-1] = '\0'; + temp_name.length --; + } + if (la_stat(temp_name.s, &st) < 0) goto exit_tmpfile; - } else - archive_strcpy(&temp_name, tmpdir); - if (temp_name.s[temp_name.length-1] == '/') { - temp_name.s[temp_name.length-1] = '\0'; - temp_name.length --; - } - if (la_stat(temp_name.s, &st) < 0) - goto exit_tmpfile; - if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - goto exit_tmpfile; + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + goto exit_tmpfile; + } + archive_strcat(&temp_name, "/libarchive_"); + tp = temp_name.s + archive_strlen(&temp_name); + archive_strcat(&temp_name, "XXXXXXXXXX"); + ep = temp_name.s + archive_strlen(&temp_name); + template = temp_name.s; + } else { + tp = strchr(template, 'X'); + if (tp == NULL) /* No X, programming error */ + abort(); + for (ep = tp; *ep == 'X'; ep++) + continue; + if (*ep) /* X followed by non X, programming error */ + abort(); } - archive_strcat(&temp_name, "/libarchive_"); - tp = temp_name.s + archive_strlen(&temp_name); - archive_strcat(&temp_name, "XXXXXXXXXX"); - ep = temp_name.s + archive_strlen(&temp_name); do { char *p; @@ -469,19 +519,33 @@ __archive_mktemp(const char *tmpdir) int d = *((unsigned char *)p) % sizeof(num); *p++ = num[d]; } - fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, + fd = open(template, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0600); } while (fd < 0 && errno == EEXIST); if (fd < 0) goto exit_tmpfile; __archive_ensure_cloexec_flag(fd); - unlink(temp_name.s); + if (template == temp_name.s) + unlink(temp_name.s); exit_tmpfile: - archive_string_free(&temp_name); + if (template == temp_name.s) + archive_string_free(&temp_name); return (fd); } -#endif /* HAVE_MKSTEMP */ +int +__archive_mktemp(const char *tmpdir) +{ + return __archive_mktempx(tmpdir, NULL); +} + +int +__archive_mkstemp(char *template) +{ + return __archive_mktempx(NULL, template); +} + +#endif /* !HAVE_MKSTEMP */ #endif /* !_WIN32 || __CYGWIN__ */ /* diff --git a/contrib/libarchive/libarchive/archive_write.c b/contrib/libarchive/libarchive/archive_write.c index 2c3f9a75d..f74fdaed6 100644 --- a/contrib/libarchive/libarchive/archive_write.c +++ b/contrib/libarchive/libarchive/archive_write.c @@ -212,6 +212,7 @@ __archive_write_allocate_filter(struct archive *_a) f = calloc(1, sizeof(*f)); f->archive = _a; + f->state = ARCHIVE_WRITE_FILTER_STATE_NEW; if (a->filter_first == NULL) a->filter_first = f; else @@ -228,6 +229,9 @@ __archive_write_filter(struct archive_write_filter *f, const void *buff, size_t length) { int r; + /* Never write to non-open filters */ + if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN) + return(ARCHIVE_FATAL); if (length == 0) return(ARCHIVE_OK); if (f->write == NULL) @@ -240,27 +244,70 @@ __archive_write_filter(struct archive_write_filter *f, } /* - * Open a filter. + * Recursive function for opening the filter chain + * Last filter is opened first */ -int +static int __archive_write_open_filter(struct archive_write_filter *f) { - if (f->open == NULL) + int ret; + + ret = ARCHIVE_OK; + if (f->next_filter != NULL) + ret = __archive_write_open_filter(f->next_filter); + if (ret != ARCHIVE_OK) + return (ret); + if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW) + return (ARCHIVE_FATAL); + if (f->open == NULL) { + f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; return (ARCHIVE_OK); - return (f->open)(f); + } + ret = (f->open)(f); + if (ret == ARCHIVE_OK) + f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; + else + f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; + return (ret); } /* - * Close a filter. + * Open all filters */ -int -__archive_write_close_filter(struct archive_write_filter *f) +static int +__archive_write_filters_open(struct archive_write *a) { - if (f->close != NULL) - return (f->close)(f); - if (f->next_filter != NULL) - return (__archive_write_close_filter(f->next_filter)); - return (ARCHIVE_OK); + return (__archive_write_open_filter(a->filter_first)); +} + +/* + * Close all filtes + */ +static int +__archive_write_filters_close(struct archive_write *a) +{ + struct archive_write_filter *f; + int ret, ret1; + ret = ARCHIVE_OK; + for (f = a->filter_first; f != NULL; f = f->next_filter) { + /* Do not close filters that are not open */ + if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) { + if (f->close != NULL) { + ret1 = (f->close)(f); + if (ret1 < ret) + ret = ret1; + if (ret1 == ARCHIVE_OK) { + f->state = + ARCHIVE_WRITE_FILTER_STATE_CLOSED; + } else { + f->state = + ARCHIVE_WRITE_FILTER_STATE_FATAL; + } + } else + f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; + } + } + return (ret); } int @@ -292,6 +339,7 @@ archive_write_client_open(struct archive_write_filter *f) struct archive_none *state; void *buffer; size_t buffer_size; + int ret; f->bytes_per_block = archive_write_get_bytes_per_block(f->archive); f->bytes_in_last_block = @@ -316,7 +364,13 @@ archive_write_client_open(struct archive_write_filter *f) if (a->client_opener == NULL) return (ARCHIVE_OK); - return (a->client_opener(f->archive, a->client_data)); + ret = a->client_opener(f->archive, a->client_data); + if (ret != ARCHIVE_OK) { + free(state->buffer); + free(state); + f->data = NULL; + } + return (ret); } static int @@ -439,8 +493,6 @@ archive_write_client_close(struct archive_write_filter *f) (*a->client_closer)(&a->archive, a->client_data); free(state->buffer); free(state); - /* Clear the close handler myself not to be called again. */ - f->close = NULL; a->client_data = NULL; /* Clear passphrase. */ if (a->passphrase != NULL) { @@ -448,6 +500,8 @@ archive_write_client_close(struct archive_write_filter *f) free(a->passphrase); a->passphrase = NULL; } + /* Clear the close handler myself not to be called again. */ + f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; return (ret); } @@ -477,9 +531,10 @@ archive_write_open(struct archive *_a, void *client_data, client_filter->write = archive_write_client_write; client_filter->close = archive_write_client_close; - ret = __archive_write_open_filter(a->filter_first); + ret = __archive_write_filters_open(a); if (ret < ARCHIVE_WARN) { - r1 = __archive_write_close_filter(a->filter_first); + r1 = __archive_write_filters_close(a); + __archive_write_filters_free(_a); return (r1 < ret ? r1 : ret); } @@ -521,7 +576,7 @@ _archive_write_close(struct archive *_a) } /* Finish the compression and close the stream. */ - r1 = __archive_write_close_filter(a->filter_first); + r1 = __archive_write_filters_close(a); if (r1 < r) r = r1; diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c b/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c index b46b19a0c..87fdb73ec 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c @@ -149,11 +149,6 @@ archive_filter_b64encode_open(struct archive_write_filter *f) { struct private_b64encode *state = (struct private_b64encode *)f->data; size_t bs = 65536, bpb; - int ret; - - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { /* Buffer size should be a multiple number of the of bytes @@ -266,7 +261,6 @@ static int archive_filter_b64encode_close(struct archive_write_filter *f) { struct private_b64encode *state = (struct private_b64encode *)f->data; - int ret, ret2; /* Flush remaining bytes. */ if (state->hold_len != 0) @@ -274,12 +268,8 @@ archive_filter_b64encode_close(struct archive_write_filter *f) archive_string_sprintf(&state->encoded_buff, "====\n"); /* Write the last block */ archive_write_set_bytes_in_last_block(f->archive, 1); - ret = __archive_write_filter(f->next_filter, + return __archive_write_filter(f->next_filter, state->encoded_buff.s, archive_strlen(&state->encoded_buff)); - ret2 = __archive_write_close_filter(f->next_filter); - if (ret > ret2) - ret = ret2; - return (ret); } static int diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c b/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c index 68ed9579b..7001e9c6b 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c @@ -167,10 +167,6 @@ archive_compressor_bzip2_open(struct archive_write_filter *f) struct private_data *data = (struct private_data *)f->data; int ret; - ret = __archive_write_open_filter(f->next_filter); - if (ret != 0) - return (ret); - if (data->compressed == NULL) { size_t bs = 65536, bpb; if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { @@ -262,7 +258,7 @@ static int archive_compressor_bzip2_close(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; - int ret, r1; + int ret; /* Finish compression cycle. */ ret = drive_compressor(f, data, 1); @@ -281,9 +277,7 @@ archive_compressor_bzip2_close(struct archive_write_filter *f) "Failed to clean up compressor"); ret = ARCHIVE_FATAL; } - - r1 = __archive_write_close_filter(f->next_filter); - return (r1 < ret ? r1 : ret); + return ret; } static int diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_compress.c b/contrib/libarchive/libarchive/archive_write_add_filter_compress.c index 26fcef4d4..d404fae7d 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_compress.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_compress.c @@ -146,17 +146,12 @@ archive_write_add_filter_compress(struct archive *_a) static int archive_compressor_compress_open(struct archive_write_filter *f) { - int ret; struct private_data *state; size_t bs = 65536, bpb; f->code = ARCHIVE_FILTER_COMPRESS; f->name = "compress"; - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); - state = (struct private_data *)calloc(1, sizeof(*state)); if (state == NULL) { archive_set_error(f->archive, ENOMEM, @@ -426,30 +421,27 @@ static int archive_compressor_compress_close(struct archive_write_filter *f) { struct private_data *state = (struct private_data *)f->data; - int ret, ret2; + int ret; ret = output_code(f, state->cur_code); if (ret != ARCHIVE_OK) - goto cleanup; + return ret; ret = output_flush(f); if (ret != ARCHIVE_OK) - goto cleanup; + return ret; /* Write the last block */ ret = __archive_write_filter(f->next_filter, state->compressed, state->compressed_offset); -cleanup: - ret2 = __archive_write_close_filter(f->next_filter); - if (ret > ret2) - ret = ret2; - free(state->compressed); - free(state); return (ret); } static int archive_compressor_compress_free(struct archive_write_filter *f) { - (void)f; /* UNUSED */ + struct private_data *state = (struct private_data *)f->data; + + free(state->compressed); + free(state); return (ARCHIVE_OK); } diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c b/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c index e4b3435e4..8670d5ca7 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c @@ -184,10 +184,6 @@ archive_compressor_gzip_open(struct archive_write_filter *f) struct private_data *data = (struct private_data *)f->data; int ret; - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); - if (data->compressed == NULL) { size_t bs = 65536, bpb; if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { @@ -307,7 +303,7 @@ archive_compressor_gzip_close(struct archive_write_filter *f) { unsigned char trailer[8]; struct private_data *data = (struct private_data *)f->data; - int ret, r1; + int ret; /* Finish compression cycle */ ret = drive_compressor(f, data, 1); @@ -338,8 +334,7 @@ archive_compressor_gzip_close(struct archive_write_filter *f) "Failed to clean up compressor"); ret = ARCHIVE_FATAL; } - r1 = __archive_write_close_filter(f->next_filter); - return (r1 < ret ? r1 : ret); + return ret; } /* diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c b/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c index 15fd494a4..cf19fadd5 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c @@ -223,16 +223,11 @@ static int archive_filter_lz4_open(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; - int ret; size_t required_size; static size_t const bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024, 4 * 1024 * 1024 }; size_t pre_block_size; - ret = __archive_write_open_filter(f->next_filter); - if (ret != 0) - return (ret); - if (data->block_maximum_size < 4) data->block_size = bkmap[0]; else @@ -343,7 +338,7 @@ static int archive_filter_lz4_close(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; - int ret, r1; + int ret; /* Finish compression cycle. */ ret = (int)lz4_write_one_block(f, NULL, 0); @@ -366,9 +361,7 @@ archive_filter_lz4_close(struct archive_write_filter *f) ret = __archive_write_filter(f->next_filter, data->out_buffer, data->out - data->out_buffer); } - - r1 = __archive_write_close_filter(f->next_filter); - return (r1 < ret ? r1 : ret); + return ret; } static int diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_lzop.c b/contrib/libarchive/libarchive/archive_write_add_filter_lzop.c index ad705c4a0..3bd9062e4 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_lzop.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_lzop.c @@ -228,11 +228,6 @@ static int archive_write_lzop_open(struct archive_write_filter *f) { struct write_lzop *data = (struct write_lzop *)f->data; - int ret; - - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); switch (data->compression_level) { case 1: @@ -439,10 +434,7 @@ archive_write_lzop_close(struct archive_write_filter *f) } /* Write a zero uncompressed size as the end mark of the series of * compressed block. */ - r = __archive_write_filter(f->next_filter, &endmark, sizeof(endmark)); - if (r != ARCHIVE_OK) - return (r); - return (__archive_write_close_filter(f->next_filter)); + return __archive_write_filter(f->next_filter, &endmark, sizeof(endmark)); } #else diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_program.c b/contrib/libarchive/libarchive/archive_write_add_filter_program.c index 660f693f2..a4bc1d90e 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_program.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_program.c @@ -212,11 +212,6 @@ __archive_write_program_open(struct archive_write_filter *f, struct archive_write_program_data *data, const char *cmd) { pid_t child; - int ret; - - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); if (data->child_buf == NULL) { data->child_buf_len = 65536; @@ -353,11 +348,11 @@ int __archive_write_program_close(struct archive_write_filter *f, struct archive_write_program_data *data) { - int ret, r1, status; + int ret, status; ssize_t bytes_read; if (data->child == 0) - return __archive_write_close_filter(f->next_filter); + return ARCHIVE_OK; ret = 0; close(data->child_stdin); @@ -409,7 +404,6 @@ cleanup: "Error closing program: %s", data->program_name); ret = ARCHIVE_FATAL; } - r1 = __archive_write_close_filter(f->next_filter); - return (r1 < ret ? r1 : ret); + return ret; } diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_uuencode.c b/contrib/libarchive/libarchive/archive_write_add_filter_uuencode.c index 23d9c150d..1ad458921 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_uuencode.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_uuencode.c @@ -138,11 +138,6 @@ archive_filter_uuencode_open(struct archive_write_filter *f) { struct private_uuencode *state = (struct private_uuencode *)f->data; size_t bs = 65536, bpb; - int ret; - - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { /* Buffer size should be a multiple number of the of bytes @@ -257,7 +252,6 @@ static int archive_filter_uuencode_close(struct archive_write_filter *f) { struct private_uuencode *state = (struct private_uuencode *)f->data; - int ret, ret2; /* Flush remaining bytes. */ if (state->hold_len != 0) @@ -265,12 +259,8 @@ archive_filter_uuencode_close(struct archive_write_filter *f) archive_string_sprintf(&state->encoded_buff, "`\nend\n"); /* Write the last block */ archive_write_set_bytes_in_last_block(f->archive, 1); - ret = __archive_write_filter(f->next_filter, + return __archive_write_filter(f->next_filter, state->encoded_buff.s, archive_strlen(&state->encoded_buff)); - ret2 = __archive_write_close_filter(f->next_filter); - if (ret > ret2) - ret = ret2; - return (ret); } static int diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_xz.c b/contrib/libarchive/libarchive/archive_write_add_filter_xz.c index 0f7c8cfc3..8c1ebb805 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_xz.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_xz.c @@ -309,10 +309,6 @@ archive_compressor_xz_open(struct archive_write_filter *f) struct private_data *data = f->data; int ret; - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); - if (data->compressed == NULL) { size_t bs = 65536, bpb; if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { @@ -448,7 +444,7 @@ static int archive_compressor_xz_close(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; - int ret, r1; + int ret; ret = drive_compressor(f, data, 1); if (ret == ARCHIVE_OK) { @@ -466,8 +462,7 @@ archive_compressor_xz_close(struct archive_write_filter *f) } } lzma_end(&(data->stream)); - r1 = __archive_write_close_filter(f->next_filter); - return (r1 < ret ? r1 : ret); + return ret; } static int diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c index 671fc6aff..4c91551ed 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c @@ -172,11 +172,6 @@ static int archive_compressor_zstd_open(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; - int ret; - - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); if (data->out.dst == NULL) { size_t bs = ZSTD_CStreamOutSize(), bpb; @@ -238,14 +233,9 @@ static int archive_compressor_zstd_close(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; - int r1, r2; /* Finish zstd frame */ - r1 = drive_compressor(f, data, 1, NULL, 0); - - r2 = __archive_write_close_filter(f->next_filter); - - return r1 < r2 ? r1 : r2; + return drive_compressor(f, data, 1, NULL, 0); } /* diff --git a/contrib/libarchive/libarchive/archive_write_disk.3 b/contrib/libarchive/libarchive/archive_write_disk.3 index ff8e1a36a..2fa016e45 100644 --- a/contrib/libarchive/libarchive/archive_write_disk.3 +++ b/contrib/libarchive/libarchive/archive_write_disk.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 3, 2017 +.Dd January 19, 2020 .Dt ARCHIVE_WRITE_DISK 3 .Os .Sh NAME @@ -139,6 +139,11 @@ is not specified, then SUID and SGID bits will only be restored if the default user and group IDs of newly-created objects on disk happen to match those specified in the archive entry. By default, only basic permissions are restored, and umask is obeyed. +.It Cm ARCHIVE_EXTRACT_SAFE_WRITES +Extract files atomically, by first creating a unique temporary file and then +renaming it to its required destination name. +This avoids a race where an application might see a partial file (or no +file) during extraction. .It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS Refuse to extract an absolute path. The default is to not refuse such paths. diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c index cc0edb77c..a0234bc78 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c @@ -253,6 +253,8 @@ struct archive_write_disk { struct archive_entry *entry; /* Entry being extracted. */ char *name; /* Name of entry, possibly edited. */ struct archive_string _name_data; /* backing store for 'name' */ + char *tmpname; /* Temporary name * */ + struct archive_string _tmpname_data; /* backing store for 'tmpname' */ /* Tasks remaining for this object. */ int todo; /* Tasks deferred until end-of-archive. */ @@ -354,6 +356,7 @@ struct archive_write_disk { static int la_opendirat(int, const char *); +static int la_mktemp(struct archive_write_disk *); static void fsobj_error(int *, struct archive_string *, int, const char *, const char *); static int check_symlinks_fsobj(char *, int *, struct archive_string *, @@ -406,6 +409,30 @@ static ssize_t _archive_write_disk_data(struct archive *, const void *, static ssize_t _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t); +static int +la_mktemp(struct archive_write_disk *a) +{ + int oerrno, fd; + mode_t mode; + + archive_string_empty(&a->_tmpname_data); + archive_string_sprintf(&a->_tmpname_data, "%s.XXXXXX", a->name); + a->tmpname = a->_tmpname_data.s; + + fd = __archive_mkstemp(a->tmpname); + if (fd == -1) + return -1; + + mode = a->mode & 0777 & ~a->user_umask; + if (fchmod(fd, mode) == -1) { + oerrno = errno; + close(fd); + errno = oerrno; + return -1; + } + return fd; +} + static int la_opendirat(int fd, const char *path) { const int flags = O_CLOEXEC @@ -419,7 +446,7 @@ la_opendirat(int fd, const char *path) { | O_PATH #elif defined(O_SEARCH) | O_SEARCH -#elif defined(O_EXEC) +#elif defined(__FreeBSD__) && defined(O_EXEC) | O_EXEC #else | O_RDONLY @@ -1810,6 +1837,14 @@ finish_metadata: if (a->fd >= 0) { close(a->fd); a->fd = -1; + if (a->tmpname) { + if (rename(a->tmpname, a->name) == -1) { + archive_set_error(&a->archive, errno, + "rename failed"); + ret = ARCHIVE_FATAL; + } + a->tmpname = NULL; + } } /* If there's an entry, we can release it now. */ archive_entry_free(a->entry); @@ -2087,17 +2122,28 @@ restore_entry(struct archive_write_disk *a) } if (!S_ISDIR(a->st.st_mode)) { - /* A non-dir is in the way, unlink it. */ if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) (void)clear_nochange_fflags(a); - if (unlink(a->name) != 0) { - archive_set_error(&a->archive, errno, - "Can't unlink already-existing object"); - return (ARCHIVE_FAILED); + + if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) && + S_ISREG(a->st.st_mode)) { + /* Use a temporary file to extract */ + if ((a->fd = la_mktemp(a)) == -1) + return ARCHIVE_FAILED; + a->pst = NULL; + en = 0; + } else { + /* A non-dir is in the way, unlink it. */ + if (unlink(a->name) != 0) { + archive_set_error(&a->archive, errno, + "Can't unlink already-existing " + "object"); + return (ARCHIVE_FAILED); + } + a->pst = NULL; + /* Try again. */ + en = create_filesystem_object(a); } - a->pst = NULL; - /* Try again. */ - en = create_filesystem_object(a); } else if (!S_ISDIR(a->mode)) { /* A dir is in the way of a non-dir, rmdir it. */ if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) @@ -2199,6 +2245,13 @@ create_filesystem_object(struct archive_write_disk *a) } free(linkname_copy); archive_string_free(&error_string); + /* + * Unlinking and linking here is really not atomic, + * but doing it right, would require us to construct + * an mktemplink() function, and then use rename(2). + */ + if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) + unlink(a->name); r = link(linkname, a->name) ? errno : 0; /* * New cpio and pax formats allow hardlink entries @@ -2237,6 +2290,13 @@ create_filesystem_object(struct archive_write_disk *a) linkname = archive_entry_symlink(a->entry); if (linkname != NULL) { #if HAVE_SYMLINK + /* + * Unlinking and linking here is really not atomic, + * but doing it right, would require us to construct + * an mktempsymlink() function, and then use rename(2). + */ + if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) + unlink(a->name); return symlink(linkname, a->name) ? errno : 0; #else return (EPERM); @@ -2263,6 +2323,7 @@ create_filesystem_object(struct archive_write_disk *a) /* POSIX requires that we fall through here. */ /* FALLTHROUGH */ case AE_IFREG: + a->tmpname = NULL; a->fd = open(a->name, O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, mode); __archive_ensure_cloexec_flag(a->fd); @@ -2424,6 +2485,7 @@ _archive_write_disk_free(struct archive *_a) archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL); archive_entry_free(a->entry); archive_string_free(&a->_name_data); + archive_string_free(&a->_tmpname_data); archive_string_free(&a->archive.error_string); archive_string_free(&a->path_safe); a->archive.magic = 0; diff --git a/contrib/libarchive/libarchive/archive_write_disk_private.h b/contrib/libarchive/libarchive/archive_write_disk_private.h index d4c9535d8..7c5e6f815 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_private.h +++ b/contrib/libarchive/libarchive/archive_write_disk_private.h @@ -26,13 +26,13 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED +#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED -#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED - #include "archive_platform_acl.h" #include "archive_acl_private.h" #include "archive_entry.h" diff --git a/contrib/libarchive/libarchive/archive_write_private.h b/contrib/libarchive/libarchive/archive_write_private.h index 208d9b8be..5529809b2 100644 --- a/contrib/libarchive/libarchive/archive_write_private.h +++ b/contrib/libarchive/libarchive/archive_write_private.h @@ -25,19 +25,24 @@ * $FreeBSD$ */ +#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED +#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #ifndef __LIBARCHIVE_TEST #error This header is only to be used internally to libarchive. #endif #endif -#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED -#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED - #include "archive.h" #include "archive_string.h" #include "archive_private.h" +#define ARCHIVE_WRITE_FILTER_STATE_NEW 1U +#define ARCHIVE_WRITE_FILTER_STATE_OPEN 2U +#define ARCHIVE_WRITE_FILTER_STATE_CLOSED 4U +#define ARCHIVE_WRITE_FILTER_STATE_FATAL 0x8000U + struct archive_write; struct archive_write_filter { @@ -55,6 +60,7 @@ struct archive_write_filter { int code; int bytes_per_block; int bytes_in_last_block; + int state; }; #if ARCHIVE_VERSION < 4000000 @@ -66,8 +72,6 @@ struct archive_write_filter *__archive_write_allocate_filter(struct archive *); int __archive_write_output(struct archive_write *, const void *, size_t); int __archive_write_nulls(struct archive_write *, size_t); int __archive_write_filter(struct archive_write_filter *, const void *, size_t); -int __archive_write_open_filter(struct archive_write_filter *); -int __archive_write_close_filter(struct archive_write_filter *); struct archive_write { struct archive archive; diff --git a/contrib/libarchive/libarchive/archive_write_set_format.c b/contrib/libarchive/libarchive/archive_write_set_format.c index a454b5816..dc22bf458 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format.c +++ b/contrib/libarchive/libarchive/archive_write_set_format.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include "archive.h" #include "archive_private.h" +#include "archive_write_set_format_private.h" /* A table that maps format codes to functions. */ static const @@ -76,3 +77,47 @@ archive_write_set_format(struct archive *a, int code) archive_set_error(a, EINVAL, "No such format"); return (ARCHIVE_FATAL); } + +void +__archive_write_entry_filetype_unsupported(struct archive *a, + struct archive_entry *entry, const char *format) +{ + const char *name = NULL; + + switch (archive_entry_filetype(entry)) { + /* + * All formats should be able to archive regular files (AE_IFREG) + */ + case AE_IFDIR: + name = "directories"; + break; + case AE_IFLNK: + name = "symbolic links"; + break; + case AE_IFCHR: + name = "character devices"; + break; + case AE_IFBLK: + name = "block devices"; + break; + case AE_IFIFO: + name = "named pipes"; + break; + case AE_IFSOCK: + name = "sockets"; + break; + default: + break; + } + + if (name != NULL) { + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, + "%s: %s format cannot archive %s", + archive_entry_pathname(entry), format, name); + } else { + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, + "%s: %s format cannot archive files with mode 0%lo", + archive_entry_pathname(entry), format, + (unsigned long)archive_entry_mode(entry)); + } +} diff --git a/contrib/libarchive/libarchive/archive_write_set_format_7zip.c b/contrib/libarchive/libarchive/archive_write_set_format_7zip.c index 92a87f74e..fb7697f65 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_7zip.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_7zip.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include "archive_rb.h" #include "archive_string.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" /* * Codec ID @@ -164,7 +165,7 @@ struct file { mode_t mode; uint32_t crc32; - int dir:1; + signed int dir:1; }; struct _7zip { diff --git a/contrib/libarchive/libarchive/archive_write_set_format_ar.c b/contrib/libarchive/libarchive/archive_write_set_format_ar.c index afae4af7d..b25ffbcc4 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_ar.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_ar.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include "archive_entry.h" #include "archive_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" struct ar_w { uint64_t entry_bytes_remaining; diff --git a/contrib/libarchive/libarchive/archive_write_set_format_cpio.c b/contrib/libarchive/libarchive/archive_write_set_format_cpio.c index ba68f6d0d..6491f3d51 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_cpio.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_cpio.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include "archive_entry_locale.h" #include "archive_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" static ssize_t archive_write_cpio_data(struct archive_write *, const void *buff, size_t s); diff --git a/contrib/libarchive/libarchive/archive_write_set_format_cpio_newc.c b/contrib/libarchive/libarchive/archive_write_set_format_cpio_newc.c index 6d414af13..2828141f5 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_cpio_newc.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_cpio_newc.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include "archive_entry_locale.h" #include "archive_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" static ssize_t archive_write_newc_data(struct archive_write *, const void *buff, size_t s); diff --git a/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c b/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c index e7757c22b..ec29c5c41 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 19157 #include "archive_entry_locale.h" #include "archive_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" struct gnutar { uint64_t entry_bytes_remaining; @@ -534,17 +535,9 @@ archive_write_gnutar_header(struct archive_write *a, case AE_IFBLK: tartype = '4' ; break; case AE_IFDIR: tartype = '5' ; break; case AE_IFIFO: tartype = '6' ; break; - case AE_IFSOCK: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive socket"); - ret = ARCHIVE_FAILED; - goto exit_write_header; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive this (mode=0%lo)", - (unsigned long)archive_entry_mode(entry)); + default: /* AE_IFSOCK and unknown */ + __archive_write_entry_filetype_unsupported( + &a->archive, entry, "gnutar"); ret = ARCHIVE_FAILED; goto exit_write_header; } diff --git a/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c b/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c index c57b1fdb5..f01029464 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c @@ -289,12 +289,12 @@ struct isoent { struct extr_rec *current; } extr_rec_list; - int virtual:1; + signed int virtual:1; /* If set to one, this file type is a directory. * A convenience flag to be used as * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR". */ - int dir:1; + signed int dir:1; }; struct hardlink { @@ -755,9 +755,9 @@ struct iso9660 { /* Used for making zisofs. */ struct { - int detect_magic:1; - int making:1; - int allzero:1; + signed int detect_magic:1; + signed int making:1; + signed int allzero:1; unsigned char magic_buffer[64]; int magic_cnt; @@ -5094,13 +5094,11 @@ isofile_init_hardlinks(struct iso9660 *iso9660) static void isofile_free_hardlinks(struct iso9660 *iso9660) { - struct archive_rb_node *n, *next; + struct archive_rb_node *n, *tmp; - for (n = ARCHIVE_RB_TREE_MIN(&(iso9660->hardlink_rbtree)); n;) { - next = __archive_rb_tree_iterate(&(iso9660->hardlink_rbtree), - n, ARCHIVE_RB_DIR_RIGHT); + ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(iso9660->hardlink_rbtree), tmp) { + __archive_rb_tree_remove_node(&(iso9660->hardlink_rbtree), n); free(n); - n = next; } } @@ -7801,8 +7799,8 @@ struct zisofs_extract { uint64_t pz_uncompressed_size; size_t uncompressed_buffer_size; - int initialized:1; - int header_passed:1; + signed int initialized:1; + signed int header_passed:1; uint32_t pz_offset; unsigned char *block_pointers; diff --git a/contrib/libarchive/libarchive/archive_write_set_format_pax.c b/contrib/libarchive/libarchive/archive_write_set_format_pax.c index bb99f1fff..b1933e81e 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_pax.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_pax.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include "archive_entry_locale.h" #include "archive_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" struct sparse_block { struct sparse_block *next; @@ -199,6 +200,28 @@ archive_write_pax_options(struct archive_write *a, const char *key, archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "pax: invalid charset name"); return (ret); + } else if (strcmp(key, "xattrheader") == 0) { + if (val == NULL || val[0] == 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "pax: xattrheader requires a value"); + } else if (strcmp(val, "ALL") == 0 || + strcmp(val, "all") == 0) { + pax->flags |= WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR; + ret = ARCHIVE_OK; + } else if (strcmp(val, "SCHILY") == 0 || + strcmp(val, "schily") == 0) { + pax->flags |= WRITE_SCHILY_XATTR; + pax->flags &= ~WRITE_LIBARCHIVE_XATTR; + ret = ARCHIVE_OK; + } else if (strcmp(val, "LIBARCHIVE") == 0 || + strcmp(val, "libarchive") == 0) { + pax->flags |= WRITE_LIBARCHIVE_XATTR; + pax->flags &= ~WRITE_SCHILY_XATTR; + ret = ARCHIVE_OK; + } else + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "pax: invalid xattr header name"); + return (ret); } /* Note: The "warn" return is just to inform the options @@ -689,17 +712,9 @@ archive_write_pax_header(struct archive_write *a, } break; } - case AE_IFSOCK: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive socket"); - return (ARCHIVE_FAILED); - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive this (type=0%lo)", - (unsigned long) - archive_entry_filetype(entry_original)); + default: /* AE_IFSOCK and unknown */ + __archive_write_entry_filetype_unsupported( + &a->archive, entry_original, "pax"); return (ARCHIVE_FAILED); } } @@ -835,13 +850,16 @@ archive_write_pax_header(struct archive_write *a, * them do. */ r = get_entry_pathname(a, entry_main, &path, &path_length, sconv); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); - else if (r != ARCHIVE_OK) { + } else if (r != ARCHIVE_OK) { r = get_entry_pathname(a, entry_main, &path, &path_length, NULL); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); + } archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Can't translate pathname '%s' to %s", path, archive_string_conversion_charset_name(sconv)); @@ -849,12 +867,15 @@ archive_write_pax_header(struct archive_write *a, sconv = NULL;/* The header charset switches to binary mode. */ } r = get_entry_uname(a, entry_main, &uname, &uname_length, sconv); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); - else if (r != ARCHIVE_OK) { + } else if (r != ARCHIVE_OK) { r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); + } archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Can't translate uname '%s' to %s", uname, archive_string_conversion_charset_name(sconv)); @@ -862,12 +883,15 @@ archive_write_pax_header(struct archive_write *a, sconv = NULL;/* The header charset switches to binary mode. */ } r = get_entry_gname(a, entry_main, &gname, &gname_length, sconv); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); - else if (r != ARCHIVE_OK) { + } else if (r != ARCHIVE_OK) { r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); + } archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Can't translate gname '%s' to %s", gname, archive_string_conversion_charset_name(sconv)); @@ -879,13 +903,16 @@ archive_write_pax_header(struct archive_write *a, if (linkpath == NULL) { r = get_entry_symlink(a, entry_main, &linkpath, &linkpath_length, sconv); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); - else if (r != ARCHIVE_OK) { + } else if (r != ARCHIVE_OK) { r = get_entry_symlink(a, entry_main, &linkpath, &linkpath_length, NULL); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); + } archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Can't translate linkname '%s' to %s", linkpath, @@ -901,21 +928,29 @@ archive_write_pax_header(struct archive_write *a, if (hardlink != NULL) { r = get_entry_hardlink(a, entry_main, &hardlink, &hardlink_length, NULL); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); + } linkpath = hardlink; linkpath_length = hardlink_length; } r = get_entry_pathname(a, entry_main, &path, &path_length, NULL); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); + } r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); + } r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL); - if (r == ARCHIVE_FATAL) + if (r == ARCHIVE_FATAL) { + archive_entry_free(entry_main); return (r); + } } /* Store the header encoding first, to be nice to readers. */ @@ -1172,24 +1207,33 @@ archive_write_pax_header(struct archive_write *a, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA | ARCHIVE_ENTRY_ACL_STYLE_COMPACT); - if (ret == ARCHIVE_FATAL) + if (ret == ARCHIVE_FATAL) { + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (ARCHIVE_FATAL); + } } if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) { ret = add_pax_acl(a, entry_original, pax, ARCHIVE_ENTRY_ACL_TYPE_ACCESS | ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA); - if (ret == ARCHIVE_FATAL) + if (ret == ARCHIVE_FATAL) { + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (ARCHIVE_FATAL); + } } if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) { ret = add_pax_acl(a, entry_original, pax, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT | ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA); - if (ret == ARCHIVE_FATAL) + if (ret == ARCHIVE_FATAL) { + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (ARCHIVE_FATAL); + } } /* We use GNU-tar-compatible sparse attributes. */ @@ -1328,8 +1372,11 @@ archive_write_pax_header(struct archive_write *a, * numeric fields, though they're less critical. */ if (__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0, - NULL) == ARCHIVE_FATAL) + NULL) == ARCHIVE_FATAL) { + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (ARCHIVE_FATAL); + } /* If we built any extended attributes, write that entry first. */ if (archive_strlen(&(pax->pax_header)) > 0) { @@ -1394,6 +1441,8 @@ archive_write_pax_header(struct archive_write *a, archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "archive_write_pax_header: " "'x' header failed?! This can't happen.\n"); + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (ARCHIVE_FATAL); } else if (r < ret) ret = r; @@ -1402,6 +1451,8 @@ archive_write_pax_header(struct archive_write *a, sparse_list_clear(pax); pax->entry_bytes_remaining = 0; pax->entry_padding = 0; + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (ARCHIVE_FATAL); } @@ -1413,12 +1464,16 @@ archive_write_pax_header(struct archive_write *a, archive_strlen(&(pax->pax_header))); if (r != ARCHIVE_OK) { /* If a write fails, we're pretty much toast. */ + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (ARCHIVE_FATAL); } /* Pad out the end of the entry. */ r = __archive_write_nulls(a, (size_t)pax->entry_padding); if (r != ARCHIVE_OK) { /* If a write fails, we're pretty much toast. */ + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (ARCHIVE_FATAL); } pax->entry_bytes_remaining = pax->entry_padding = 0; @@ -1426,8 +1481,11 @@ archive_write_pax_header(struct archive_write *a, /* Write the header for main entry. */ r = __archive_write_output(a, ustarbuff, 512); - if (r != ARCHIVE_OK) + if (r != ARCHIVE_OK) { + archive_entry_free(entry_main); + archive_string_free(&entry_name); return (r); + } /* * Inform the client of the on-disk size we're using, so diff --git a/contrib/libarchive/libarchive/archive_write_set_format_private.h b/contrib/libarchive/libarchive/archive_write_set_format_private.h new file mode 100644 index 000000000..e20022755 --- /dev/null +++ b/contrib/libarchive/libarchive/archive_write_set_format_private.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2020 Martin Matuska + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED +#define ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED + +#ifndef __LIBARCHIVE_BUILD +#ifndef __LIBARCHIVE_TEST +#error This header is only to be used internally to libarchive. +#endif +#endif + +#include "archive.h" +#include "archive_entry.h" + +void __archive_write_entry_filetype_unsupported(struct archive *a, + struct archive_entry *entry, const char *format); +#endif diff --git a/contrib/libarchive/libarchive/archive_write_set_format_shar.c b/contrib/libarchive/libarchive/archive_write_set_format_shar.c index 0543b9d73..625a86475 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_shar.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_shar.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include "archive_entry.h" #include "archive_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" struct shar { int dump; @@ -194,8 +195,8 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry) archive_entry_set_size(entry, 0); if (archive_entry_hardlink(entry) == NULL && archive_entry_symlink(entry) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "shar format cannot archive this"); + __archive_write_entry_filetype_unsupported( + &a->archive, entry, "shar"); return (ARCHIVE_WARN); } } diff --git a/contrib/libarchive/libarchive/archive_write_set_format_ustar.c b/contrib/libarchive/libarchive/archive_write_set_format_ustar.c index 10fcda919..b1536dc97 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_ustar.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_ustar.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include "archive_entry_locale.h" #include "archive_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" struct ustar { uint64_t entry_bytes_remaining; @@ -512,9 +513,11 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512], } if (copy_length > 0) { if (copy_length > USTAR_uname_size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Username too long"); - ret = ARCHIVE_FAILED; + if (tartype != 'x') { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_MISC, "Username too long"); + ret = ARCHIVE_FAILED; + } copy_length = USTAR_uname_size; } memcpy(h + USTAR_uname_offset, p, copy_length); @@ -535,9 +538,11 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512], } if (copy_length > 0) { if (strlen(p) > USTAR_gname_size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Group name too long"); - ret = ARCHIVE_FAILED; + if (tartype != 'x') { + archive_set_error(&a->archive, + ARCHIVE_ERRNO_MISC, "Group name too long"); + ret = ARCHIVE_FAILED; + } copy_length = USTAR_gname_size; } memcpy(h + USTAR_gname_offset, p, copy_length); @@ -609,16 +614,9 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512], case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break; case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break; case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break; - case AE_IFSOCK: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive socket"); - return (ARCHIVE_FAILED); - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive this (mode=0%lo)", - (unsigned long)archive_entry_mode(entry)); + default: /* AE_IFSOCK and unknown */ + __archive_write_entry_filetype_unsupported( + &a->archive, entry, "ustar"); ret = ARCHIVE_FAILED; } } diff --git a/contrib/libarchive/libarchive/archive_write_set_format_v7tar.c b/contrib/libarchive/libarchive/archive_write_set_format_v7tar.c index 1fdaafd2a..599407144 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_v7tar.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_v7tar.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include "archive_entry_locale.h" #include "archive_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" struct v7tar { uint64_t entry_bytes_remaining; @@ -491,31 +492,11 @@ format_header_v7tar(struct archive_write *a, char h[512], case AE_IFLNK: h[V7TAR_typeflag_offset] = '2'; break; - case AE_IFCHR: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive character device"); - return (ARCHIVE_FAILED); - case AE_IFBLK: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive block device"); - return (ARCHIVE_FAILED); - case AE_IFIFO: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive fifo"); - return (ARCHIVE_FAILED); - case AE_IFSOCK: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive socket"); - return (ARCHIVE_FAILED); default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "tar format cannot archive this (mode=0%lo)", - (unsigned long)archive_entry_mode(entry)); + /* AE_IFBLK, AE_IFCHR, AE_IFIFO, AE_IFSOCK + * and unknown */ + __archive_write_entry_filetype_unsupported( + &a->archive, entry, "v7tar"); ret = ARCHIVE_FAILED; } } diff --git a/contrib/libarchive/libarchive/archive_write_set_format_warc.c b/contrib/libarchive/libarchive/archive_write_set_format_warc.c index edad072cf..46b057341 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_warc.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_warc.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include "archive_private.h" #include "archive_random_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" struct warc_s { unsigned int omit_warcinfo:1; @@ -259,10 +260,8 @@ _warc_header(struct archive_write *a, struct archive_entry *entry) return (ARCHIVE_OK); } /* just resort to erroring as per Tim's advice */ - archive_set_error( - &a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "WARC can only process regular files"); + __archive_write_entry_filetype_unsupported( + &a->archive, entry, "WARC"); return (ARCHIVE_FAILED); } @@ -332,6 +331,10 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t) struct tm *rt; #if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S) struct tm timeHere; +#endif +#if defined(HAVE__GMTIME64_S) + errno_t terr; + __time64_t tmptime; #endif char strtime[100]; size_t len; @@ -340,7 +343,12 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t) if ((rt = gmtime_r(&t, &timeHere)) == NULL) return; #elif defined(HAVE__GMTIME64_S) - _gmtime64_s(&timeHere, &t); + tmptime = t; + terr = _gmtime64_s(&timeHere, &tmptime); + if (terr) + rt = NULL; + else + rt = &timeHere; #else if ((rt = gmtime(&t)) == NULL) return; diff --git a/contrib/libarchive/libarchive/archive_write_set_format_xar.c b/contrib/libarchive/libarchive/archive_write_set_format_xar.c index 5b8ce1a07..5fbf4a2f4 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_xar.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_xar.c @@ -212,8 +212,8 @@ struct file { struct heap_data data; struct archive_string script; - int virtual:1; - int dir:1; + signed int virtual:1; + signed int dir:1; }; struct hardlink { @@ -411,6 +411,8 @@ xar_options(struct archive_write *a, const char *key, const char *value) if (strcmp(key, "checksum") == 0) { if (value == NULL) xar->opt_sumalg = CKSUM_NONE; + else if (strcmp(value, "none") == 0) + xar->opt_sumalg = CKSUM_NONE; else if (strcmp(value, "sha1") == 0) xar->opt_sumalg = CKSUM_SHA1; else if (strcmp(value, "md5") == 0) @@ -429,6 +431,8 @@ xar_options(struct archive_write *a, const char *key, const char *value) if (value == NULL) xar->opt_compression = NONE; + else if (strcmp(value, "none") == 0) + xar->opt_compression = NONE; else if (strcmp(value, "gzip") == 0) xar->opt_compression = GZIP; else if (strcmp(value, "bzip2") == 0) @@ -482,6 +486,8 @@ xar_options(struct archive_write *a, const char *key, const char *value) if (strcmp(key, "toc-checksum") == 0) { if (value == NULL) xar->opt_toc_sumalg = CKSUM_NONE; + else if (strcmp(value, "none") == 0) + xar->opt_toc_sumalg = CKSUM_NONE; else if (strcmp(value, "sha1") == 0) xar->opt_toc_sumalg = CKSUM_SHA1; else if (strcmp(value, "md5") == 0) @@ -696,13 +702,37 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s) else run = ARCHIVE_Z_FINISH; /* Compress file data. */ - r = compression_code(&(a->archive), &(xar->stream), run); - if (r != ARCHIVE_OK && r != ARCHIVE_EOF) - return (ARCHIVE_FATAL); + for (;;) { + r = compression_code(&(a->archive), &(xar->stream), + run); + if (r != ARCHIVE_OK && r != ARCHIVE_EOF) + return (ARCHIVE_FATAL); + if (xar->stream.avail_out == 0 || + run == ARCHIVE_Z_FINISH) { + size = sizeof(xar->wbuff) - + xar->stream.avail_out; + checksum_update(&(xar->a_sumwrk), xar->wbuff, + size); + xar->cur_file->data.length += size; + if (write_to_temp(a, xar->wbuff, + size) != ARCHIVE_OK) + return (ARCHIVE_FATAL); + if (r == ARCHIVE_OK) { + /* Output buffer was full */ + xar->stream.next_out = xar->wbuff; + xar->stream.avail_out = + sizeof(xar->wbuff); + } else { + /* ARCHIVE_EOF - We are done */ + break; + } + } else { + /* Compressor wants more input */ + break; + } + } rsize = s - xar->stream.avail_in; checksum_update(&(xar->e_sumwrk), buff, rsize); - size = sizeof(xar->wbuff) - xar->stream.avail_out; - checksum_update(&(xar->a_sumwrk), xar->wbuff, size); } #if !defined(_WIN32) || defined(__CYGWIN__) if (xar->bytes_remaining == @@ -739,12 +769,9 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s) if (xar->cur_file->data.compression == NONE) { if (write_to_temp(a, buff, size) != ARCHIVE_OK) return (ARCHIVE_FATAL); - } else { - if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK) - return (ARCHIVE_FATAL); + xar->cur_file->data.length += size; } xar->bytes_remaining -= rsize; - xar->cur_file->data.length += size; return (rsize); } @@ -878,11 +905,15 @@ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer, { char timestr[100]; struct tm tm; +#if defined(HAVE__GMTIME64_S) + __time64_t tmptime; +#endif #if defined(HAVE_GMTIME_R) gmtime_r(&t, &tm); #elif defined(HAVE__GMTIME64_S) - _gmtime64_s(&tm, &t); + tmptime = t; + _gmtime64_s(&tm, &tmptime); #else memcpy(&tm, gmtime(&t), sizeof(tm)); #endif @@ -2103,7 +2134,7 @@ file_gen_utility_names(struct archive_write *a, struct file *file) while (len > 0) { size_t ll = len; - if (len > 0 && p[len-1] == '/') { + if (p[len-1] == '/') { p[len-1] = '\0'; len--; } @@ -2532,13 +2563,11 @@ file_init_hardlinks(struct xar *xar) static void file_free_hardlinks(struct xar *xar) { - struct archive_rb_node *n, *next; + struct archive_rb_node *n, *tmp; - for (n = ARCHIVE_RB_TREE_MIN(&(xar->hardlink_rbtree)); n;) { - next = __archive_rb_tree_iterate(&(xar->hardlink_rbtree), - n, ARCHIVE_RB_DIR_RIGHT); + ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) { + __archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n); free(n); - n = next; } } diff --git a/contrib/libarchive/libarchive/archive_write_set_format_zip.c b/contrib/libarchive/libarchive/archive_write_set_format_zip.c index 991d0dadf..78528ea33 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_zip.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_zip.c @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include "archive_private.h" #include "archive_random_private.h" #include "archive_write_private.h" +#include "archive_write_set_format_private.h" #ifndef HAVE_ZLIB_H #include "archive_crc32.h" @@ -526,8 +527,8 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry) /* Ignore types of entries that we don't support. */ type = archive_entry_filetype(entry); if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Filetype not supported"); + __archive_write_entry_filetype_unsupported( + &a->archive, entry, "zip"); return ARCHIVE_FAILED; }; @@ -1372,10 +1373,28 @@ dos_time(const time_t unix_time) { struct tm *t; unsigned int dt; +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif /* This will not preserve time when creating/extracting the archive * on two systems with different time zones. */ +#if defined(HAVE_LOCALTIME_R) + t = localtime_r(&unix_time, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = unix_time; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + t = NULL; + else + t = &tmbuf; +#else t = localtime(&unix_time); +#endif /* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */ if (t->tm_year < 1980 - 1900) @@ -1402,18 +1421,17 @@ path_length(struct archive_entry *entry) { mode_t type; const char *path; + size_t len; type = archive_entry_filetype(entry); path = archive_entry_pathname(entry); if (path == NULL) return (0); - if (type == AE_IFDIR && - (path[0] == '\0' || path[strlen(path) - 1] != '/')) { - return strlen(path) + 1; - } else { - return strlen(path); - } + len = strlen(path); + if (type == AE_IFDIR && (path[0] == '\0' || path[len - 1] != '/')) + ++len; /* Space for the trailing / */ + return len; } static int @@ -1461,10 +1479,8 @@ copy_path(struct archive_entry *entry, unsigned char *p) memcpy(p, path, pathlen); /* Folders are recognized by a trailing slash. */ - if ((type == AE_IFDIR) & (path[pathlen - 1] != '/')) { + if ((type == AE_IFDIR) && (path[pathlen - 1] != '/')) p[pathlen] = '/'; - p[pathlen + 1] = '\0'; - } } diff --git a/contrib/libarchive/libarchive/archive_write_set_options.3 b/contrib/libarchive/libarchive/archive_write_set_options.3 index a9f70a664..cffe571e9 100644 --- a/contrib/libarchive/libarchive/archive_write_set_options.3 +++ b/contrib/libarchive/libarchive/archive_write_set_options.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 27, 2019 +.Dd January 31, 2020 .Dt ARCHIVE_WRITE_OPTIONS 3 .Os .Sh NAME @@ -170,33 +170,125 @@ only to modules whose name matches .\" .Sh OPTIONS .Bl -tag -compact -width indent +.It Filter b64encode +.Bl -tag -compact -width indent +.It Cm mode +The value is interpreted as octal digits specifying the file mode. +.It Cm name +The value specifies the file name. +.El +.It Filter bzip2 +.Bl -tag -compact -width indent +.It Cm compression-level +The value is interpreted as a decimal integer specifying the +bzip2 compression level. Supported values are from 1 to 9. +.El .It Filter gzip .Bl -tag -compact -width indent .It Cm compression-level The value is interpreted as a decimal integer specifying the -gzip compression level. +gzip compression level. Supported values are from 0 to 9. +.It Cm timestamp +Store timestamp. This is enabled by default. +.El +.It Filter lrzip +.Bl -tag -compact -width indent +.It Cm compression Ns = Ns Ar type +Use +.Ar type +as compression method. +Supported values are +.Dq bzip2 , +.Dq gzipi , +.Dq lzo +.Pq ultra fast , +and +.Dq zpaq +.Pq best, extremely slow . +.It Cm compression-level +The value is interpreted as a decimal integer specifying the +lrzip compression level. Supported values are from 1 to 9. +.El +.It Filter lz4 +.Bl -tag -compact -width indent +.It Cm compression-level +The value is interpreted as a decimal integer specifying the +lz4 compression level. Supported values are from 0 to 9. +.It Cm stream-checksum +Enable stream checksum. This is enabled by default. +.It Cm block-checksum +Enable block checksum. This is disabled by default. +.It Cm block-size +The value is interpreted as a decimal integer specifying the +lz4 compression block size. Supported values are from 4 to 7 +.Pq default . +.It Cm block-dependence +Use the previous block of the block being compressed for +a compression dictionary to improve compression ratio. +This is disabled by default. +.El +.It Filter lzop +.Bl -tag -compact -width indent +.It Cm compression-level +The value is interpreted as a decimal integer specifying the +lzop compression level. Supported values are from 1 to 9. +.El +.It Filter uuencode +.Bl -tag -compact -width indent +.It Cm mode +The value is interpreted as octal digits specifying the file mode. +.It Cm name +The value specifies the file name. .El .It Filter xz .Bl -tag -compact -width indent .It Cm compression-level The value is interpreted as a decimal integer specifying the +compression level. Supported values are from 0 to 9. +.It Cm threads +The value is interpreted as a decimal integer specifying the +number of threads for multi-threaded lzma compression. +If supported, the default value is read from +.Fn lzma_cputhreads . +.El +.It Filter zstd +.Bl -tag -compact -width indent +.It Cm compression-level +The value is interpreted as a decimal integer specifying the +compression level. Supported values are from 1 to 22. +.El +.It Format 7zip +.Bl -tag -compact -width indent +.It Cm compression +The value is one of +.Dq store , +.Dq deflate , +.Dq bzip2 , +.Dq lzma1 , +.Dq lzma2 +or +.Dq ppmd +to indicate how the following entries should be compressed. +Note that this setting is ignored for directories, symbolic links, +and other special entries. +.It Cm compression-level +The value is interpreted as a decimal integer specifying the compression level. +Values between 0 and 9 are supported. +The interpretation of the compression level depends on the chosen +compression method. .El -.It Format mtree +.It Format cpio .Bl -tag -compact -width indent -.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname -Enable a particular keyword in the mtree output. -Prefix with an exclamation mark to disable the corresponding keyword. -The default is equivalent to -.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname . -.It Cm all -Enables all of the above keywords. -.It Cm use-set -Enables generation of -.Cm /set -lines that specify default values for the following files and/or directories. -.It Cm indent -XXX needs explanation XXX +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file names. +.El +.It Format gnutar +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file, group and user names. .El .It Format iso9660 - volume metadata These options are used to set standard ISO9660 metadata. @@ -404,26 +496,110 @@ Specifies a filename that should not be compressed when using This option can be provided multiple times to suppress compression on many files. .El -.It Format 7zip +.It Format mtree .Bl -tag -compact -width indent -.It Cm compression +.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname +Enable a particular keyword in the mtree output. +Prefix with an exclamation mark to disable the corresponding keyword. +The default is equivalent to +.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname . +.It Cm all +Enables all of the above keywords. +.It Cm use-set +Enables generation of +.Cm /set +lines that specify default values for the following files and/or directories. +.It Cm indent +XXX needs explanation XXX +.El +.It Format newc +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file names. +.El +.It Format pax +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file, group and user names. The value is one of -.Dq store , -.Dq deflate , -.Dq bzip2 , -.Dq lzma1 , -.Dq lzma2 +.Dq BINARY or -.Dq ppmd -to indicate how the following entries should be compressed. -Note that this setting is ignored for directories, symbolic links, -and other special entries. -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -compression level. -Values between 0 and 9 are supported. -The interpretation of the compression level depends on the chosen -compression method. +.Dq UTF-8 . +With +.Dq BINARY +there is no character conversion, with +.Dq UTF-8 +names are converted to UTF-8. +.It Cm xattrheader +When storing extended attributes, this option configures which +headers should be written. The value is one of +.Dq all , +.Dq LIBARCHIVE , +or +.Dq SCHILY . +By default, both +.Dq LIBARCHIVE.xattr +and +.Dq SCHILY.xattr +headers are written. +.El +.It Format ustar +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file, group and user names. +.El +.It Format v7tar +.Bl -tag -compact -width indent +.It Cm hdrcharset +The value is used as a character set name that will be +used when translating file, group and user names. +.El +.It Format warc +.Bl -tag -compact -width indent +.It Cm omit-warcinfo +Set to +.Dq true +to disable output of the warcinfo record. +.El +.It Format xar +.Bl -tag -compact -width indent +.It Cm checksum Ns = Ns Ar type +Use +.Ar type +as file checksum method. +Supported values are +.Dq none , +.Dq md5 , +and +.Dq sha1 +.Pq default . +.It Cm compression Ns = Ns Ar type +Use +.Ar type +as compression method. +Supported values are +.Dq none , +.Dq bzip2 , +.Dq gzip +.Pq default , +.Dq lzma +and +.Dq xz . +.It Cm compression_level +The value is a decimal integer from 1 to 9 specifying the compression level. +.It Cm toc-checksum Ns = Ns Ar type +Use +.Ar type +as table of contents checksum method. +Supported values are +.Dq none , +.Dq md5 +and +.Dq sha1 +.Pq default . .El .It Format zip .Bl -tag -compact -width indent @@ -444,6 +620,20 @@ A compression level of 0 switches the compression method to other values will enable .Dq deflate compression with the given level. +.It Cm encryption +Enable encryption using traditional zip encryption. +.It Cm encryption Ns = Ns Ar type +Use +.Ar type +as encryption type. +Supported values are +.Dq zipcrypt +.Pq traditional zip encryption , +.Dq aes128 +.Pq WinZip AES-128 encryption +and +.Dq aes256 +.Pq WinZip AES-256 encryption . .It Cm experimental This boolean option enables or disables experimental Zip features that may not be compatible with other Zip implementations. @@ -452,7 +642,8 @@ This boolean option disables CRC calculations. All CRC fields are set to zero. It should not be used except for testing purposes. .It Cm hdrcharset -This sets the character set used for filenames. +The value is used as a character set name that will be +used when translating file names. .It Cm zip64 Zip64 extensions provide additional file size information for entries larger than 4 GiB. diff --git a/contrib/libarchive/libarchive/archive_xxhash.h b/contrib/libarchive/libarchive/archive_xxhash.h index 427241641..1c7131ca1 100644 --- a/contrib/libarchive/libarchive/archive_xxhash.h +++ b/contrib/libarchive/libarchive/archive_xxhash.h @@ -24,12 +24,13 @@ * */ +#ifndef ARCHIVE_XXHASH_H_INCLUDED +#define ARCHIVE_XXHASH_H_INCLUDED + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef ARCHIVE_XXHASH_H -#define ARCHIVE_XXHASH_H typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; diff --git a/contrib/libarchive/libarchive/filter_fork.h b/contrib/libarchive/libarchive/filter_fork.h index 0891d2dfa..487e3cb23 100644 --- a/contrib/libarchive/libarchive/filter_fork.h +++ b/contrib/libarchive/libarchive/filter_fork.h @@ -25,13 +25,13 @@ * $FreeBSD$ */ +#ifndef FILTER_FORK_H +#define FILTER_FORK_H + #ifndef __LIBARCHIVE_BUILD #error This header is only to be used internally to libarchive. #endif -#ifndef FILTER_FORK_H -#define FILTER_FORK_H - pid_t __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout); diff --git a/contrib/libarchive/libarchive/test/test_archive_write_set_format_filter_by_ext.c b/contrib/libarchive/libarchive/test/test_archive_write_set_format_filter_by_ext.c index 4fe18e18c..223450386 100644 --- a/contrib/libarchive/libarchive/test/test_archive_write_set_format_filter_by_ext.c +++ b/contrib/libarchive/libarchive/test/test_archive_write_set_format_filter_by_ext.c @@ -30,7 +30,7 @@ __FBSDID("$FreeBSD$"); static void test_format_filter_by_ext(const char *output_file, - int format_id, int filter_id, int dot_stored, char * def_ext) + int format_id, int filter_id, int dot_stored, const char * def_ext) { struct archive_entry *ae; struct archive *a; diff --git a/contrib/libarchive/libarchive/test/test_compat_zip.c b/contrib/libarchive/libarchive/test/test_compat_zip.c index e32588efa..898d3e5ce 100644 --- a/contrib/libarchive/libarchive/test/test_compat_zip.c +++ b/contrib/libarchive/libarchive/test/test_compat_zip.c @@ -156,7 +156,7 @@ DEFINE_TEST(test_compat_zip_4) size_t s; extract_reference_file(refname); - p = slurpfile(&s, refname); + p = slurpfile(&s, "%s", refname); /* SFX files require seek support. */ assert((a = archive_read_new()) != NULL); @@ -214,7 +214,7 @@ DEFINE_TEST(test_compat_zip_5) size_t s; extract_reference_file(refname); - p = slurpfile(&s, refname); + p = slurpfile(&s, "%s", refname); /* Verify with seek support. * Everything works correctly here. */ @@ -370,7 +370,7 @@ DEFINE_TEST(test_compat_zip_6) size_t s; extract_reference_file(refname); - p = slurpfile(&s, refname); + p = slurpfile(&s, "%s", refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); @@ -402,7 +402,7 @@ DEFINE_TEST(test_compat_zip_7) int i; extract_reference_file(refname); - p = slurpfile(&s, refname); + p = slurpfile(&s, "%s", refname); for (i = 1; i < 1000; ++i) { assert((a = archive_read_new()) != NULL); @@ -436,7 +436,7 @@ DEFINE_TEST(test_compat_zip_8) size_t s; extract_reference_file(refname); - p = slurpfile(&s, refname); + p = slurpfile(&s, "%s", refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); diff --git a/contrib/libarchive/libarchive/test/test_fuzz.c b/contrib/libarchive/libarchive/test/test_fuzz.c index a9be5ee1c..b8391cb7d 100644 --- a/contrib/libarchive/libarchive/test/test_fuzz.c +++ b/contrib/libarchive/libarchive/test/test_fuzz.c @@ -119,7 +119,8 @@ test_fuzz(const struct files *filesets) for (i = 0; filesets[n].names[i] != NULL; ++i) { char *newraw; - tmp = slurpfile(&size, filesets[n].names[i]); + tmp = slurpfile(&size, "%s", + filesets[n].names[i]); newraw = realloc(rawimage, oldsize + size); if (!assert(newraw != NULL)) { diff --git a/contrib/libarchive/libarchive/test/test_open_failure.c b/contrib/libarchive/libarchive/test/test_open_failure.c index 845486cf9..5316a872b 100644 --- a/contrib/libarchive/libarchive/test/test_open_failure.c +++ b/contrib/libarchive/libarchive/test/test_open_failure.c @@ -160,11 +160,11 @@ DEFINE_TEST(test_open_failure) archive_write_open(a, &private, my_open, my_write, my_close)); assertEqualInt(1, private.open_called); assertEqualInt(0, private.write_called); - assertEqualInt(1, private.close_called); + assertEqualInt(0, private.close_called); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); assertEqualInt(1, private.open_called); assertEqualInt(0, private.write_called); - assertEqualInt(1, private.close_called); + assertEqualInt(0, private.close_called); memset(&private, 0, sizeof(private)); private.magic = MAGIC; @@ -177,11 +177,11 @@ DEFINE_TEST(test_open_failure) archive_write_open(a, &private, my_open, my_write, my_close)); assertEqualInt(1, private.open_called); assertEqualInt(0, private.write_called); - assertEqualInt(1, private.close_called); + assertEqualInt(0, private.close_called); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); assertEqualInt(1, private.open_called); assertEqualInt(0, private.write_called); - assertEqualInt(1, private.close_called); + assertEqualInt(0, private.close_called); memset(&private, 0, sizeof(private)); private.magic = MAGIC; @@ -193,11 +193,11 @@ DEFINE_TEST(test_open_failure) archive_write_open(a, &private, my_open, my_write, my_close)); assertEqualInt(1, private.open_called); assertEqualInt(0, private.write_called); - assertEqualInt(1, private.close_called); + assertEqualInt(0, private.close_called); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); assertEqualInt(1, private.open_called); assertEqualInt(0, private.write_called); - assertEqualInt(1, private.close_called); + assertEqualInt(0, private.close_called); memset(&private, 0, sizeof(private)); private.magic = MAGIC; @@ -209,10 +209,10 @@ DEFINE_TEST(test_open_failure) archive_write_open(a, &private, my_open, my_write, my_close)); assertEqualInt(1, private.open_called); assertEqualInt(0, private.write_called); - assertEqualInt(1, private.close_called); + assertEqualInt(0, private.close_called); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); assertEqualInt(1, private.open_called); assertEqualInt(0, private.write_called); - assertEqualInt(1, private.close_called); + assertEqualInt(0, private.close_called); } diff --git a/contrib/libarchive/libarchive/test/test_open_fd.c b/contrib/libarchive/libarchive/test/test_open_fd.c index 4fbf87ac1..da5eeafcb 100644 --- a/contrib/libarchive/libarchive/test/test_open_fd.c +++ b/contrib/libarchive/libarchive/test/test_open_fd.c @@ -42,6 +42,7 @@ DEFINE_TEST(test_open_fd) struct archive_entry *ae; struct archive *a; int fd; + const char *skip_open_fd_err_test; #if defined(__BORLANDC__) fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY); @@ -116,16 +117,18 @@ DEFINE_TEST(test_open_fd) assertEqualInt(ARCHIVE_OK, archive_read_free(a)); close(fd); - - /* - * Verify some of the error handling. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - /* FD 100 shouldn't be open. */ - assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_open_fd(a, 100, 512)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + skip_open_fd_err_test = getenv("SKIP_OPEN_FD_ERR_TEST"); + if(skip_open_fd_err_test == NULL) { + /* + * Verify some of the error handling. + */ + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + /* FD 100 shouldn't be open. */ + assertEqualIntA(a, ARCHIVE_FATAL, + archive_read_open_fd(a, 100, 512)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + } } diff --git a/contrib/libarchive/libarchive/test/test_pax_xattr_header.c b/contrib/libarchive/libarchive/test/test_pax_xattr_header.c new file mode 100644 index 000000000..d0394aa09 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_pax_xattr_header.c @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2019 Martin Matuska + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +static struct archive_entry* +create_archive_entry(void) { + struct archive_entry *ae; + + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 20); + archive_entry_set_ctime(ae, 4, 40); + archive_entry_set_mtime(ae, 5, 50); + archive_entry_copy_pathname(ae, "file"); + archive_entry_set_mode(ae, AE_IFREG | 0755); + archive_entry_set_nlink(ae, 2); + archive_entry_set_size(ae, 8); + archive_entry_xattr_add_entry(ae, "user.data1", "ABCDEFG", 7); + archive_entry_xattr_add_entry(ae, "user.data2", "XYZ", 3); + + return (ae); +} + +DEFINE_TEST(test_pax_xattr_header) +{ + static const char *reffiles[] = { + "test_pax_xattr_header_all.tar", + "test_pax_xattr_header_libarchive.tar", + "test_pax_xattr_header_schily.tar", + NULL + }; + struct archive *a; + struct archive_entry *ae; + + extract_reference_files(reffiles); + + /* First archive, no options */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, 0, archive_write_set_format_pax(a)); + assertEqualIntA(a, 0, archive_write_add_filter_none(a)); + assertEqualInt(0, + archive_write_open_filename(a, "test1.tar")); + ae = create_archive_entry(); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); + + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assertEqualFile("test1.tar","test_pax_xattr_header_all.tar"); + + /* Second archive, xattrheader=SCHILY */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, 0, archive_write_set_format_pax(a)); + assertEqualIntA(a, 0, archive_write_add_filter_none(a)); + assertEqualIntA(a, 0, archive_write_set_options(a, + "xattrheader=SCHILY")); + assertEqualInt(0, + archive_write_open_filename(a, "test2.tar")); + + ae = create_archive_entry(); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); + + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assertEqualFile("test2.tar","test_pax_xattr_header_schily.tar"); + + /* Third archive, xattrheader=LIBARCHIVE */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, 0, archive_write_set_format_pax(a)); + assertEqualIntA(a, 0, archive_write_add_filter_none(a)); + assertEqualIntA(a, 0, archive_write_set_options(a, + "xattrheader=LIBARCHIVE")); + assertEqualInt(0, + archive_write_open_filename(a, "test3.tar")); + + ae = create_archive_entry(); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); + + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assertEqualFile("test3.tar","test_pax_xattr_header_libarchive.tar"); + + /* Fourth archive, xattrheader=ALL */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, 0, archive_write_set_format_pax(a)); + assertEqualIntA(a, 0, archive_write_add_filter_none(a)); + assertEqualIntA(a, 0, archive_write_set_options(a, "xattrheader=ALL")); + assertEqualInt(0, + archive_write_open_filename(a, "test4.tar")); + + ae = create_archive_entry(); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); + + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assertEqualFile("test4.tar","test_pax_xattr_header_all.tar"); +} diff --git a/contrib/libarchive/libarchive/test/test_pax_xattr_header_all.tar.uu b/contrib/libarchive/libarchive/test/test_pax_xattr_header_all.tar.uu new file mode 100644 index 000000000..086428e71 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_pax_xattr_header_all.tar.uu @@ -0,0 +1,72 @@ +begin 644 test_pax_xattr_header_all.tar +M4&%X2&5A9&5R+V9I;&4````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````#`P,#``````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````!U*%14J=_<,7#6T/3RFH$9!9G6HOBE'E<0M' +M0-5!6&]I9Q(LNP>FO1,4C"0-HJF]E+UO?$`OP,0L]9]-?IRQ"#_84'^\-:$G +MT3JIHJE5;*\M)]-TIEK1=3?[2#(5!+N!_HL=H!H_R)BU+F9HX\D5.\?T=(M` +M=9=W4SJW579?/KS>1Y+'M^%0#4C+X<'3U$3C&%='!5[\EF[@4#2B9^U]FY)? +M`J8B_0+7B.I$N.X)PP3;'V&J*6VY.!&;Q7R,;M8N$$GCE7A'DD("6>XDN+^7 +M'[7.>5XJAT[)1$"IP%"H\ENNG?(IVD$"4B#R#;E,KWX0"(+I)G\I;FDXUW0: +MG\77W)*"$2C1DY7G2A@X<7?HF<0(324$@RQ94+EXCPV;A\!J_=-IO`PB]JI0O;215>3NFC>&L@A8ZVO8G: +M(Z+'4*>R53SX'U!L=#-R5/?1CX"K49RW+6#"?:O9#&F-VU+]XA>-H/+P67D. +MZN0JL3&7/ST/0,:N;-K'@%MH5*U@'\5C)M\[!]I6*3,C]3NA^OCP?_.^L? +M=17`;X\L"SHC@$#^"05.3&=DUY$\848Q-SC.@/%KQ:P`5J3YZ^,Q\-/Y(6LQ +MP?6TCO52!37-BUF`NWYVMM2?O%GP33Q3P%?#">B/A68F2MV1P'FKVPF);5);K1B +M>8HI`'2@,V/:[^SK\W]3Z;KMD.*+:9B<=!"$;J;;UE5*DM)][UB? +M]6V.JGB<\EVIL3WF^NX79\"D2_^:2*;[&U%K7_@JZDKEF1,3>-*2=:I*Z6Q%6C)N$U>TY[(C`P/L=7ANK-S3-TT\L:SL.T*&Y0>E +M.GQ/D;-/0XPRM5SL()'1_^7U(H`O&?G,YY4X%=>F@:@Z-KF"#'$:)WGH[<$, +M.1GS0RT6+#EYTEZ8W(/*D52"P-B('Z;VJ('L\]V;[3YB+264VOM'M9 +M/U7+D0$Z>XTTR0PP685OJ%/<& +MJ2F(<2MA[/"%RY6$59Q4^<^.2E4`K*^\*=EF4`D<\@V"R2>@9+%ND3R*?DVC +MY?U5RIHO)]4_)8R<3XLHQ:ARO&7:7!:VK==FV^WJ;$;UM<&(,B#=E*6P*"V"T5QBA@I +M!4R$!8.UO\`TE@9K9&W_'H:$?K3:4(%MF):*_OVK^A>=63C@11U@T1I"1Q?# +M6CJRJNUTIW9D'7P=!P341-$$(0GVW+S/D5NL-H62CQW"4(";.>F1#VI1`SN^2//BUZ2!*N-S5?\L%+&&+]KQ%-VW#[C)/0LX@$90T;HK*16"?-10DTO0 +M>).+H4UE!^5"8EZY\AI;S5W!&-W_GR_7YP*YD*]*(84G3+C"6?R[@K<$M+8" +M'9V'M]T:$P]LZQ6A3#<)_X2D.=BY9BP7WN:17-HZ=K8E9V9>'#%.R$L/'`U2 +M%RBA6\@>;DV"%M-2Z_VL]=$Z/^)=`$-)$CDP#?3I3M&Q"21C?*R@#L:;1=** +M>6J6M\$JO&[IM%E1\K(KV#CK]1!0:?M>([H%FUMVGTU,`#D*,+%)&$FT""V` +M3=1]S*'&PDK^6@#Z,&X][V6I0Z^[B8*7P?4_5N'E9`)5*.4!K2G`=(U@/RV> +M"C?],9@_Q]#\G67)I_,)+$U?R>51LS+,1<0/C$RW$8A_)U)K0:!3GQA004^( +M:U*X8T!*T_1#W1V4@6DMD&89Q$$,KQ\3F%!52496 +M3-!]GJ5^KWZP[LWX!PPEUI'YM$#^I_KLT9X0#)6@K!PWB_NF@ +MWT8/RU2Z8]AY4K"=0@6$,M"\?8/]ZFR2&1&`_!3U=IC.6Y0BN!TA.6C(>Y)E +MI%0?'CJGYHT2-)@CS.KV"@Y<=3%Z4N%FE7E--^Y651G3+2.IEL@BMU6O&1?8 +MX45]0!(O%9X!M:1>K`YGV^_O%/GM_5>+640WA4F9R0420YS.DVJ\99T+VE?TO``CRDOS!&U(=)T6!7O'S!QZ!/&Z+KD=FN8U)\$M19IA^ +ME8N&#-K%0\KB=RE(0WMKCWNFP/9(//7_,0.J@:`(8F,M63OAJPG&`F/$\U>\ +ME?3``?\,Q!FODDU".=+F\0>6-QN([3HC%L$7E(5*FNR9B/R`O\&8;<:8U"H- +ML?X;3TE6(>O0>/9T)7AX+(SZ6/D?FA(.D-JE)"38_Z9*0\%&R+`7Y%"/I@__ +MWF;"!AYKPC`NQ$A]4AFT!ZXW6G-CK3HE&(*Y:LP^FG8;+QYXJBN"!P9@CWYC +MNX@XHZ>]I0YW[,6RH'.JY%\J&"UI8,UC!6+9BR$8ISK9U>KC)*JZYH[[*XDY9`UXU/1_KC'"'5G'Y"&QDW`4H^?0 +M0ZOI`F$V4_#7+OH<),CK;&JU[^F#;AL<5FW0%]&2.AG#K,3E8:ZIWK+P[/`-['JND8[[^DAI`"ZV>]]YO#83_2-Z63 +M%G!2V?XI;66V?((CDM$I#793L`;V]-/[,8_!%6_S2H=/G`\M6 +MQU;]^=M/BMU/?,EQBMJY>6@=21H3LPE5LF9XL/AB4+8E.WGE6X2T!O\'-(WM +MEO'%E0`NU;*PKPV$PR-M9Y%1`&/MC941*O9L=CM/9_A8#*38Y6[=4E-`I +M(M2?3[;8&3''0#RMMF'CW$_6L@E1\V%9^U]/F&G=&[-!=R-XO]=I0O55K3CBY:66KWS>^MJQ\9$VL_2VBB\1W1^A>=][1UMIL$].A,T,W?A5IA:W@/'.WAF: +M2*K;Y']X8D/,;&X,YW-(C:O>"*@5_EZP#J]'/X,'`OZU=@2/&;O@ZX(!^?H\7>I'OPXHV(.@N6[6&;7[*G'YH*M+W>S84F&^UQP/>!^$/*J6#8P);S!S3ALHDN3_BL+3>:8#XL,V3. +M:69'F<4LN!:2(9RP#:V#A)'<`%`CMNJ[^WMKOCK^K.%J_T`@RA.`LPH:_W`3 +M-#"&2!B6PZ&30#4F:E.)@1&KRIB,&JIR13OQY'R]Y(%?K\"/VL'(M&JII +M'VO>J3U#_:[LB-JQZ9>*2.D]2_@U1`>CDQ"L3M0W(D09XTJ$>+T)\6[8[0.P +MPWSWY$R7A.VC[]3SC&-%I$,#)0V$A_%KF."AMKSX/IG2T%BRNZHN$2`W]O[,:4=$*F=AM(#HRD(`[!&`Y3>]="+V`@C<5[5D6J?GMYQ<" +MDEL"N&A@L)PW_T=K7L6HBC3@-5W`S9W2DU9A5/'LQGM4*9TW[;#=LDKA[Q`H +M(XK*DP6REW[4U@-<@"%&K4^-I5Q]W>)[+33W#8X5-LY0(6)P"*H]IT$=PL2; +MV7]>=7S>WGG?H%DV>=ROMC->C]68@]YF;!!6F53BEQ_L +M`0$I*5WKS*W7G>]2YHHA1A)DI11RZNU3 +M(HXMRO2C5)*;!Z4_Z_S;E66MJ%"%X@KZ)>2,IA:E+O:9F4EHL#'D0U](# +MZ$1=A(5"RQPB"W:DCM$M957$TTX]?;_"W]'#,6[#T%:=BU%45@G>`(0W8HH;2WP.:> +M7X.^L`0,QC6'QB.4'<:H_;?[HH55KK+ZZ(K(;#4BU/6 +MM]A-C0R[-7?A!\A$XV)ZV<;3>(#PWJ'G`A1H^M73&2TBW80SG"6\;_OXLLVX +MYX"RW]>A3W+`BH'-7?H)$L"JS&0PLA@6NZ_KV+$G$NV'N&&+PN)M'G5`7X^S +MMS8K5ANE%#L&\;1RA3@"QV;B\,S=(VM7*6P.8;7>YK]SQZ5)/T5IW\X7J/F) +MNH5RK0RF!YFU;``:"/K48?)96)H:VL/WCSBK@FI: +MEG7O*9+W1\`4#U^CUUD)[A!W)[`::QDFW6+FWM>5AA5A[NZ/@G]K[-;E=Q/+VX04AU1D3SFJ35+AHSQ.:LL*B@;,;S@)LR> +M(C]7B^7VTH$RLX+1JGD;-V!+R,*5G%7QYY`>AG>9RA"1YQOM]^O*Z# +M^.F?[5K(S6HC:U-CI\J@^=LXH<]U0=.?[:QWLN2_*H:.S/\_)XG%V<6-"3:+ +M\(K_EQVPN-IU^YY=#6Q+')ZE(BAR.DE[]QV?,&/$]UVN:H$VV&H!3S]=(Y88 +M^?CP.6IHOHQ&NT/)MOK%$E90.VO&>3\%W`0*6I@[$&"OKU1/Q,"7YI)EYL2Y461?+1& +MM2<\%E#K*'87RWDOF@X<;E4-LEBB$0?(CH5(ULI^S.D9:)O9D\52XM*N7>?_ +M&UEV@C3$3(!N;`>4-CU_ZCX?WFHBV"K[,!:08Q[@@`Z%).)!O>(H__Y12NQO +MV+%>&TZS;9\1Q@D3WF_'37E%S"6@N;K@^&PS;2PQY\,DRW>;X^MK/*[QW(:@ +M-`IW$&7U>3@IG%W\HDOMTO*UU>->\P).[R-8?@JD?K.5T:8`V,N8_^@0 +MC=YQ'VNPS%3#"4\BVSY5-VJ&*D6Q(C1_0B#@<7A?>/-_Y:F^S;O4J8-0->_C +ME`/I>\%4@M:.9?:,@/`*M6]4[_H#":*BPKM&-*.XBF\WHW,P,D71^62[3?"9 +M0>H01XC.;&/,& +MY1^?\5W9A*]LMIDHV:MDE@%?@SG"L)XLS]6;!X8B-#.%83SI.T-!WH_OZ*]6.6"(DJZB8:+4[# +MBI35;.F)C)J#^-Y1G_\/1-2Z%/^WML]Y`U`(!\%AO+R*+ROH'68P#W$]LNW4 +MN$23ZM0$*FWW>5==F.;B1#(4J&&7G;4?$7KD[4_0Y-S;G`<%O5PS_M[2\-]A +M4-EF1&L$-Q)`*YG38`;^"` +MQ$&?&V04*(>I(MSZJU>0BGD$KM,FR7P5Q[#/HCE9-_]AY)VF?;R%-I!%14OB]F^RU,^&Q-2>*XPN!&O""WQHB?EB7MV +M"*:BJ"UO6@U5(I]FX^]WAR+(*+TWZY(07;Z4;JMJ/35+;LRL*`0;'E87GUX1 +MXXBG5K!JQN^86V)%,-@BZR([\L(;]/"@FT*\#TS]UJ9&="`[]&@CSZ!CU9]Y8>(V&PIMKA*-%[A +M.67]I'72](-.H6+$I]S=NVIW&?Y9CMBGC'^U.[=+F9W5IW?X:BY$Q&7VE5VM +M."JPM-ZU!X?$YEQ#SCP3=H.3WDSV'JL[*^ZBU)2:QC=4$)*LG\18N&6#B&.) +MSF`5A9(^F60I>/Y7)YC:\(HQWGPH1@I?8*&>QP5[T*!'9^EMJ`[I9^%_[>G8 +M.$Y1V9$HT_(QKYGJ(Q=,;J0:<]2/0.4D[5M#XB\("W)S?WHS&%5W\Q0*)24B +MW47>9%4PG-92JL+CJHF("1+\P\??,G2>F"LZR360WKT.5XQDK@/Q@U0- +MMH2GF"N[F,E`U%L/3>U.^+SOM)/[Y!#H8(WNN56"1M)7)+9 +MZX^`QY$)VYV&C4A@5$MV6)N5QO5N[,XFLTN5(_Z/W.V2(MCY_4U9 +MIU'0<=YJOE&61^+4(+]"K%=,748Y;3;C(SRFD*LA,`Y\6%4DL!^'FUY8A-L1 +M'A)`Z#TQ@VO28XW:]>[$--59(S74PX(BG7CH3N:@MK<*!Y5*.77(A@:>[^FTV$+8V(Z[4+?PC-,N^K%$@->=:5KJ:(4\,*H6:W#Q87-,*CL\45D1I +MZ-BH)<:H'4=BMW(;TV+LNXVB`&U-JGZ)9"1_1ZC#T-+E@,QT][:&5UOYS^Q__\X[:=U5C&&: +MYL?V6CRK"/?%X=\K&]FRL\WD*$I@M8W=LTVS@EHN"BH,`&/65-=R2M6F,'&H +M&C=6_(_'8,6H5_55K>K#]2Q$82F7NP1[ULZOQH/Y$K[I-5A!=P?E1?;("/:_ +M=K^,`P316_*N15(@$('MM6YT^>[-&<\01RX!A_]AW?NVY%T;Q:,O8&"A&$\0 +M)C`VM8:WDF"6>H8JHDE&JL1!D]Y:50%*>`?_Y759$N'X8%38HE4P:<'N_DL. +M:E<2\AHV_WNS-O?Z=IZ].=Q$&Y4H.UK^.08H_V6/@LPF2'G2XMK#U]$I7NE[ +M2-ALYI2\T$TRJKUG1(BOH/"JEWN\O4AF3O)O0&J#796>G&/`5Z$/%]8Z(0.' +MS6T2$U5H=9/6>/9UR>'3NX\7\T:9F>I`2[!9>1:[PU"U(]\9DL8I[,YI]IMA +MN,8K3-\IIPCNL;*93)O"Z+*>_K%9]KYKY1O*,IF0@#V6E_:]3+1`>0IHIAVI!\T@MGNU7BK43RFW^X>!9-'$VON:PR,#VU]^!"O6V)V%*\OX +M80:!WXNCD!!SGY!E[,C)SK::L-;*TB7S'WNS62B1&)[PC>U.Z;EA"H16D<#Z +M1"C/>M8$_ZR*#;#\>*DO))@"]4Q;K?[W>?2\#B)9&YH&&1#*4)FXIV_7-.FV +M-EF]2(:P=SUY3G]8)6KO"J'#(.7L'W"^#SYQN!I`DCF4>4-!'`C/*/`%23(Y +M3O=L^=4*9VE-#4"46RX(!\_7L8'%,;'G".''P\#FK=7C#D>*[,3I?%LS=8H6 +MD>]BOWEC@)*B=YI)M;#!]<(!6"SM(`HS*7>1R(,]:S +MIXBX8:"N7'.PR2<.)P=%[(/N6R(C:!=!&D.O4LCN[ +M$0U4^%:/8&>*MF/8G>+`]+D0%1W=LR&O#\BPED>!L%)0@)9C][;4@>XSM\9. +M:)@-;`P;C2R[(9V``#!;2B#!((RQ_=Z6A8FC13AC)KPFS,2C#KC@0,,!=4?R +MNT"$]8]=HQTZL(EN1[58BJV!V[57>%W%7X>JOLBE`M$2#H$]D*^XG5$W&.Z" +M,UMY\(ZZ?PZ2Q8I97T1HY31%^T?DEJD<3B#IQ[R'N(RF;7Y5?FA:X>SN +M(7R,Y(H;,A)1F"=-US`;XC%_I3B;D?T7FD;8![YAU#I-;%CXW7JK^PX\LV7F +MA2=25.UV$OSP6%60;NVVTJ4.A4_NXC%ZG +M@OV7P!"@KL+@[/0U@YU0RLHH(\`D2/S8NE73/1759@?VG-[#^5K)-V( +MKC6BB"B-J9LJ?F(BIO&UP^-/FN6/E+:U3+;`=]/`ZK5#%!T+@O#UKQQ$3>V` +M#?N3<3,8.])L;@N:L%8V +M%G.KOPN7][!"[<'*KR+>`%0ZO_69&2QU.UUBS4>G2\R`)1#0[B9[]O"E4N)/X +M/RH)DT><1X-KU`4F93].H>N,X2VLZ]+;::6/Q72]V6FY42.I'7X@@09-A],I +M3!,:C#/^]1Z>LS"7-]A3=Z.>]>)V>F1T\KH9=\5.07;*4JCJA"%Z`\C>PA3V +MS>5?9UUE[S7/+R7B>K_&UGZ!Y7%0@A(T?$I=:6GZDM:)'2;2-S9/LO8OQ31K +M(M^>-'.XA.G'!TF$BW7LCL,IF@6.0JR#Y.\(P;V!X74=#QH1T0%T%C&SCI$* +M^'_2-=-9JNC"#ZJ",4\]LE*,%0[5'OKA9P\,%&QZ%F +MX`35=#VBJ>BXGVQA2XH#.SYX`),GM0SI9](2TZX1LH!+S*$BXB()*)C5L;LD +MEB6YHX1"HN4=2%H*$Y:LNC^=5-M>#$I5YA)@WM].QN[0];"PJ&F#?,.BVJRM +M27FN=O8,P?\`P=*M!EM!DGG[H_UZ8<,B>%`A%P!,O[/%@[8_5"DYRX51)=.` +M\PHFMJ90"*@XI.^8F,9'T%FYMW\E%H5.4L`XRO\.=X.+42F7Z?%=UH.#\WWG +MJ#_"]0F<4,V6G#T<7-ZA*MP+`CZ:N`KRI$N5NP1N%\2=SNAY40I2%KO\6QHG +MQF4KH'C;5@VCGO(394SKUP$USQF?(B`3ZU:FP9BR)&K,KC1`$X./> +MF-TOJ2C,?Y!9K!B:J`Z''=?RG,I%\TB)I;KUTT-A66=SHB=B`D57L*\B9X:Y +M]7CA-Z&[`7"=9Y`<"1V08NK?,;CS*5A#>0SOT29]?W+:$2WP(IR`6#;7(U"U +M5?H&ZQM#?;Q$RJ0!JKC2I#K3/(!P6;2EU!O,1:,2B%@4-;YL>TXPH0)@I7`P+BM<:Z +MD'A$\_+O7XXGNHD20)0N--U#>LA+8IBW&@FWGG%SU[A%"$$L2560DF&G&SS- +M9'V/_$0KPRN_X[QMJ^@2SK,YT4RYG,Y[19OVYO,1[RM8HV4X+<>8GD%0#9>. +M\[9%/ZMK<@#&:I79^69,&>(IMYR7E>\;$&:&@S;'?%=7X3)7J$BT>)0U_TYQ +M9ZE9!;>)S@$)V(2M7+YD#U6:R9XKNH58$`Y0[?!,!E_%;P$@9M[J4!2V;?7J9KR@DK_5&0Z4D%.>R% +MZ):(=I#:@8@P47-WUYI]GC3)=ZHM-RGW3DV4RF-N:;/ZC;F,`%XF:J3$DR^- +MUO.%(6\"F@9D]+N>"M+.`UPM7OEQ]FL +M=+*8#`?/-V6:^@Y%SEG(<..;Y;(H^$H,G%&\,DFEB?*"!6]@VYG!GOOC!NCP +M3GP'Y[:+1P$N#*F?6(UV)A?.XYS62=)&BQR:)TO^'6L6:O?TNGOHF>AE>VW3 +MQ+^7)L[9\V>8!"AT@0/(5?/]9""`>7U]FAMD(3>IHQ +MFM)CGJ,V"3X.3!Y`BWH9:/`L%%IV03`3"CB*>Q[@>,M.GO%(M,16IR[4N-H7 +M0_F1S`[>>ZR>0L8I041N/:1`ON +M)P)JZ15?2%&?).C&0JD<30`?_:NO=WD!HX_O;?[SFKQE1X-)C%\Z\("^ +M.SP??@UG)[9(>E$''Z.VX4CG=W5`"XDM.(ZO43K*UNWT/9:2?8AT(),]T]8S +M(D-VQM8A9O)O0Z%6U-FQA`CSH)+QSN1O#H]&B%7JS5]TDHP%/><[;6B +MV#FVW&`*ZQGAFSV!#"#H/B=8Q&%J\"SR8@&8R;`P1+6\A(\8QC/%$/.?1ITG^19+V--7 +M7A8J0;PBPT,)1REB/^984W3T;E'-EF6/QO\N<>WJ-M6\MK//H)=__J-E`'17 +M:M=Y]>J5K`:?=";=62H6^%BEO%*IF.JF`/4N_R7<1IW&[@#EJYZ"_S\W<^%B +MDRHSI!"+1=?<+J0,I-+A,Q?:K.?FGHOT-M#2;F\(-L_L:"48C+`"W#!ZU&0J +M^B)6X;P)5=7&#^E5`-:Y>[.UFGM#3X+KP1-W>^F,Q:;@T:YOV?Y]J4CIVM2L +MO(/=LOCHY@R&HP3IP9LR))TK:`OW/A=H4-HSPI."(I`[)R&CI6[4)!1J3"3F +ML;%]WD8X8O^[L1T$1#(2V;+(X&L$\F\8:>>KQ8:IB#.F).O(1L3JB^MW&%F`99/EXP1-^>*@"NT3'^,,:C>*E=#?-$'-P+W*?DFGG+RV(V7Y1DD%^13&2K\[( +MW6&D;*IGQGN@/@75IQI3B\.R$[WG%`][8JZONR"G!MD>;DO`M#S7.#F+2*EP +M\)D<(Z)5E6_\NXRI#.8FPSMY[SR1 +M_Q!M@A"1["=3C!MC$\I=D&4_,LZ6.VB#9(R-0:RC7N#H)8`X;.R(OOI>%0(- +MA^G"&8WSYE=:$LH&KI0R8\A\(245F%S>,>*@!\DIFN2D8>UUFRG,DY/3B"QY +M%R^8%]#BE*SP\LA-J#*BHOP^KL!#4'S@7K:BXOM6>]K(\:Q-Y#9M&:0''!W1 +M2).:.8;W=B;:*A7[8UE/I^#OS#!+K-%75./$>*Z/-R$5FY_2"9%Q%+IGF-,8 +M.*!/U+B49C6!7B9CFH3^#$0IUM\_EL[I;^:[K^$7E\.0B/0U::D"<)>I!H=4 +MT#D:R$E]*;2(U2?8>I2IO<-9=&##O32K$-T=0#`6I@L3"W*;&YZ21.V`TE." +M&42I%D-,[&UY!L>A:]Z)MW,9(#X)6@3*40H\EU5C!:"1]KT_2Q+9W9)HD):2 +M==I=*F'KQUX_VQB00Z2)COJ$;..3>7=7="`"^CY+(%/>)=4@"<1L;*;0`D_2 +M[PS93J2SI=MS)=:M=P`7"*CE@##"6 +MJZ&B:%LTQI65O^3"$0@KN6.+'+98S#SRV?B;N/Z3833[SOG(O]W?(!3SSB'C +MU7R"-#6+C'Z^/>6D/4Z"<\%G;E:.+1#F/4R.=BU3_1&FE**#EX6'J4E?-)\- +M"O*X52TK19<%1A'L$4O:<"H"D;RD[`>S3ARV(4)/F%J;! +M\I$,R!+>M8+'/K3SSZD/"3Y(01+;E1L,G1YU-?,T^"4:!!^$PKA7T[ENIM$P +M]888.#/ZFXZ9Q8&&BNJ]O68EJ^6D12?)S1HDFSH:C$\'LW"DB%7QB;=I$X'F +M,#-2AV!Y:FS]=QDPR51@_7=7,H,P_X6AR#'*VQC$3@?/;KZ@$RT%+>)?!"1K +M5XH^VQ&9SQE^1NL[GQ +MWX4^.,=&6A()!6RP1%Q+U"K)'U8C:BC`Q1"_NKW_Y#R@='88JUY7_"F##Z&5 +M94Q?2'(A"$PQ%%\;_\2:3:ZFA6%?8PY97Y9N;2`+BG@0;>B[[`;7MH$T7XB_ +M>M]K821YHVV6#)5`2CQW.EK4:LPGE.!4J:W#X13RQOA7"NY$)-%M]\R'VH1< +M3GYYF"S2`%941%][8L@\,,VZT\+0#:?FNF'-ZV*->]#M3PN2>M'7ZA!2V*`& +M`J@;^%INM4.S]N+M@TXT9[]P6]Y!3-4\VC^MM)E]GMP)'D+1&R\FAS'C2S,P +M3/SNG2`;)J9(`HJ&#XJ^(T81,J2[H4Y"!($_@$X4!+E0`(:7F_'=A4Z5YLF( +M3L%Q.UKWM%E$$YD<=JZVX2:3`6F2@M(O"&T_"/!5&'-E3=++;:#0D1=?U*_Q +M?]5%7@%IJ3R=)`0TDKU"D=SG"[K1'M5R/710FDWP[',9W$JLL)-,?LK4;\Y2B/&2"XF?9MK[48':8.M^0Y/H-Q(H>00X.;">\'%$"@;DL.)[:*R5]V!W*N4")7 +M**KA;-."B]"3`R4)5TMDL$Z=BUGN^'/UJ.,&N-T:(E$'X"HFS'.(F7U%N@]2 +MRP4&YHX`8\^M)$$[#?U,&WK68/#!.[]+Y`+;Q@DXORL?,"^]*I;[I]YDMX&Z +M2%/6I]O,]R>\&JA^Y%Z@WFL]TMS/VX]*VJQ)FQ>(N&'@$WW7VHC5/ZK,QL3A +M`D[`7@WAN34HL2U:U?I[&O$1^,(-]$6(!E56K&>](Y%IYD:-'L!:.^A][3AY +MBX+Y;0A`W-)")Z^PM!W4(3&M\1K!42/KVXK?&`_#>$(+)N";"DQ;S9A\0%+N +M4LP93U4+7)B];I)0,SR"9^BU"H9H!%F='-GP(=5>U:7@D>ITZG&0SPI9"@:$ +M(;D.M$PIWS]._CP#+!L<&!@K/&QW\>'&\DAZ14_EV"FT0RL9U!;G`.&G$5'Q +M*H<;>XEOE+M?```ZPK@`B.JJ]H]EB+!K>0-;.2-,>[(V1T0-'NIXE'OD%]TZ+>2:"TE?K1#Y:&=@0@ +M0<8"CL@H)5G*2_8GG&B6UN[&]?B)]O_D>2%)UIU_';T.!GV+=4(NH1YJ"5.R +MK6VT]E)]M%&H*,9-H1^S&J)ZD?P@P_=:/BF7`2V0BZ^GV?O#8^F58L:)OPXS +MT#X'.''TMY!JTO-(C6YUWA68@2VX6@+UQB[3#QIZ +MGZO?T9/<_!I,F[MV(=L+3R-@,63-I,1XX>?[N9!BR0=O-Z@&0TW&B7[VM'Q< +MDS,^-V\NCX:D!F;?7Z\6?`J@3-S'Q)>HU"10U;L^^;0'X!N*BLI[`%X^/X;D +M![C/25?/J8J1$PW6D[UJ[C0LV6<(QV*(L-LPG/!,_^\C1J7YYOE_O'>9,LI! +M!@YK6$%OD\O,>HRNU=KFN(7#2U8WTF_PS^*%C+O>-*NN0P0$'%>QQHA]Q;)B +MF*J!C4?H,CAB><5PO"E>@FT0@+VEJY?F.^GD8P28:?QJ`8*GZQ.I9P"V"APO +M/_7RBZ\VNE=ZW.@J4;21,]B$=33[D21X`-]08D;V+'[I4K<.0QLX,D@"9<(- +M^Z#1#-&\.)4[6DX]^@=-;'NT`1.^N@N*LGW&9E>DYBAX4N4\6\T_T'ITL6^= +M83<]PJP560@+SXZ\S++[:V@R[C9G;K"E.R5BUC@BX#X$1,R5]L'*HLO2+(:+ +M8:=@06<]YQA"U&>&7%ML#I?*Y3(SO$1!B`3_+P!X\9GO4B$M"(S=;F;_UU9T*`FOU>O)\/_$4"M@C1K7K^)_4CBMCK0M3B].-[>G0) +MZZVJ/=4.8Z>?(248O?);T8WJAMTCN0[%PTWU[.-CUO'5>4$T75'Q)O5".',A +MGT!WALW&R8DV>TY,J6^NQ?*=BLL^?G,#U3'U;#1NN,RZ7'HC@#5?(D:X!;Y` +M\&6!WI[+ODO46HR("Z.4'3LK^KO&$ZFS,WE?,DYJ>#DK4';BH'!]D&?X]\YC +ML>[%;DF;E$"#%"@M8LQ#H2]K.E2K^Z"ZG8YC$\IN88<0E>>;``"ZH1*XN8)D +MX*'L[KI)>'W6L__0P*T(I_4693<;@A%\-#A6\H*XGJ#/2T46JOAK+^YGH`;F +MI=\"5S +M0"FO5T"UX#J-Y#.SW'\YOS/@H6I('!`YJXDZT&`K$"A7USET[I3/+RU#9]ZL +M6,(TT&9!TY,]1FG=_^:X987GD_2DY[[GWK19QP.39)F7:#P9`&=(.K5Y`CC" +MDWW/9"P%48&0'VD8$%HTHNVG.Q%O]/.<^_)P0J\C(.IAY/;-!]6(=#/O'C2\ +MIBR:31K8@[[QY<;Q\1=A5[QSR"8B2-A/F1)3G$?91>KY_[94@'N33WWK%.M$ +MPR-G$YCMD;W7S[?]<2V4^=NS!V0SG8%&!T-^5&QL]BLV49Q+21RT7-<@&M;& +M;B^Y$&YDVO301F&2C2_?`7=#ZFGY'TDZO;AF9_\9)65?9]V#>`NK:&'^?!"I +M\/W08`7$K?_^S=FA3-2_H.^K1.%[X%VBHIMRS924QBI5M29].U@D[CR>\LY9 +MFCH"/RB?/8KRL7>1K?D;!CK +M2JFRV+?#2"/_X5W]-J('=:Y=YXT>)V*&&^\]E$Z*?W"N+H1_S+2)"H3&@;4/ +M*](.UZR,;LITE-#=%EIO@6%T%VR9)*LCQV=&T_7S%_;%%L_JSSM4YW'=$C^' +M(]#AS$97_A3&IZ"$+':9E%^'7]1?^:'!@U7[Z5$IXAPZFLR^ZC+=0H+(Z&M[ +M4WH0O\;*[V%&.:C-W.1Q;].Z>PWGQM/Y!=`?/+!#[B]:3839+81=@GM//`3BP$']S^^2NH^K"Q[AZT"AK36LR\;WPW."@%Y_F +MT3>FH?8UMQCKAO]LV%%IK2:_C@.;@6"LT_IV2K!2EYX(!K]6027B#J#P4C+; +M[;>%TLKN3']+5?HCUK'Z5Q4DO!61L0H>D4'1^9&M'Q?E"MSHE/-4,=8MJ/$2 +M(C&0OV6H`*50KKOLVM-XB_5>-]==):(Z'$ZF3%COR%=S,7Z7/&9K=3/7>R`( +M#I$$ZF_YC]W%\%J#$%R"/`5#0-V_6S-^C5EV9*;%L)G::QU\GY]D(H@5AC3Y +M4R*.IX/!N"R99ZFT?@3$7D@>P]]=,\#"WTH$EB,Y[H0_0\Z_H<7[Q/<%($H8 +M\RZ3@,Q[!SKSV4]QXCB*3GIZR;M>OZT,YGZ$@?QT<;CSYT4*!!)F9F3-^\!Z +M(EFOXEYT&%J8U<%T"HNK'$9AQ=D)Q90RC4!OJ]-1.Q0EGQ1QY<,QX\A;J2XL +M@(@5#\!`)/)88#'LT$IT?\F8*%_&@1W^N&(PSJ$+<)M[`F@NVC91DB7)+;3' +MZ'K4Q=ZQWU8YRVC_VR;'EA@%8U]=#2G)W(2XE0`AU(\%/OC9H5"/;&7KXE\W +M?.8XVL<-,[,I\)HD=MS=Y2THV(3)!9-(E+.NU.DWMSN]L_/#NVH+?XJSH_0A +M@8%X-`4)9ZL`J_A78C'DF;G"VB"?P$O&ZQ=Q.0%'6P`N\GOZC0*)=4L'JVO; +M[-8=?M`X>;>X'ZO42T*L'SVG26!RP%RFHTXITO7+J8%U_U;6]2K#?8BB;JS; +MT:%^:II9#9NP`&"(M*-G;17!KI]F28/&7+TLGK"6?\4=@T/>TPH$5F(FPD"]OW-9JX@E$!`V0L1:-'V3Y% +M/-P1(CGA/<#AS@)>J+:>E?K,$S=\WS+#W^KIDQ>>YXE80`\NTRO%0%F?DL@O9.'[8HK&NW. +MJ-U"#/7M=^=+H1@.R48J4L&BPI,+7UJ/X%"W]K[%K2*`&5_9387H7!P'SL(O +M@+]D4VV'`$]+\!"'M.FT!@5XVZ(]!$$]4,/;Z90?;94YG%5D(0"PSRIDG(]_ +M!404$.3*!<^K"A^IN?(-?#M2F-U,5_W`(B9E+MTAY%-5CRLQ^(.H*0PW/1R=]4)?8MVX(N1 +MT0'<,8)MN9_Y3_&G!V,YHH$!<_:>=;HA^AYX`KLQ^097HXMTQC-ZPC>!P*W$ +M"G$]P0K%2R!NI6;K??%9@$A?&>7-:<-W1TB;V0]U=$6HT@5@V]EAI(F#:W=T:HH#2G44M_AZS.IHW4E +MQ]?O%PPW9S&1?%5F@JHU@AX5T8$A(L:RP]A41DR`@<;V++D!O'G21X],J*MM +M?8JF).WJU!H'X5:L\?JAF(=`^2:$DW6V=+84UTU>%5_\@:3KH\02U!LM^M3% +M:)_4/GM"^_=M?]=>!K^L\R_<^VU!FDS]Y*,PF>NB"IR@!NVP'3@A*7VA%VA0 +M/XX(;+U[82(4]!.:]?2\SA,3BYL]I5DO5*NB3(N$E=C;.A$O+9(-8HD\<)ZTJP!O#0\LV*%!3*)Z>\KUXQR +M5/VO#I"EAZ6[2^=M@3B4W[`"-+^69K#M*/UN)=P;*$PRK;8); +M*&-+!7WXR4ZW;\2?2X?0M?@77]Y9IGT#LIQ0SCI>G=3($J +M%#M3&-6[J"N'BA1/T*=AW1N\8IXP)ZZ>"CJ;$KZU3-FDZ\:ZZ4^7`\$#-38V!_53T>Y<#VN7TL4!-#1#OSMC +M9Z#15ND>K9:PI@(KN=/GBSH4%S`&]2+3_8^#E\$3OBQWH'MWU6T;\Q=EP@_# +MH>O6BB#6M^"MN3!^=RE]MRZ"VEWQ'$D>@++.[("^\LQ,T*SX`6?\!+7*`*7? +M)]B=1!^YI&86T*6-0.GM[.*7M(>QE[HO'8,%S)947!AAL$+3%*]9Q.>TZLE#68 +M2XK1;PK=54+\A4J[L'=#`@2$XV'.6)DCM7*!+-I=LEGZO'+O3"B5@&=#-MP? +MIXE5:9*Q%S$#0+3OYZ#:GU,#ZA'*H6H"9S#%8='*\L%2)=QG?AB+[Q\CFIQ^ +M&^GX_?+E=EIL_=UM"@F58*?A*`YO`X?O4<#+Z!R`Z#,HD_<@3.W:]T"4_$>3 +M@[.U&%JEV-%KZ(L<-X?*5AEO2#F&@"YXX!=T)Q+HO2*T*,[<[O9VLTVTKD9R +ML:4S"ER16"LL+0(MC&_*DSQ?MZ1.G)2LAFM";J;(RE1>!<$-=GR&6]JN;T/D +M:'#_JP004=/^\0WT`J8T?(V05T_<["1R9KGA1WP@YBF85J;6R"9R^0=;3T6/ +M0L/M7[8S7Y4/B%[:L_-`$'G(#9E<^DS_,HE14SH&;%`F!<8(%[%W$9],MG>' +M-%6S!I<*40F<$$*85-P6Q!9B]&"VU^R&K$LLQF_&\Q^H-?=05=-H&25;A<5@ +MFKGV5>BK_JOD]'8DYH1C&>8?S(X4,.AK7*(0B86_\`T'&'=D62W;(.=92\<^ +MQPNGQ<$QDL>PVLPJ0"Q!71D)]MM!JV?"!,GOMMI+]ZK=85$Z"4V<<8'RT<2, +MX%W@\GJRS/B4_W4XS-8N%.J#$,6LT2)V>X?I3H?*K*83&3J=-<@A7%N'6#QG +M[*XC&=@%O=^!AJZTE$>VCH5%B$,%,,YS!UB3K\:[__U_/?W_L^9=+$0[]%34 +M$%2A`I$X_W$51X*$Y]?)/CQX'%U'2W`E#Z&.'5)\N^35,U"1;LY%E*C6[(NX +MNI%F&E9B(R19Y]:6\_A/!(>;^%9]LF./CM)1G`TT"Y=]=(8/X5N.70L*B$*; +M.8/6-;0\5)V^)[P(ON +MAA0'%ZWQG,!H&+GT"UYVTWI#G'6J:H`LK]COP.Q-+1Q)9N8]8YYYD^I+K;^R +MU`7(;"V/W//3P5I:!AX'0>XL:H`*B*>:.^LA0W'"I5YI;T+Q6+1(%+[VJ+)9 +MN^7\BFZ^U"$2)%5*7BK9-VI2N06O@'1 +M\')`*S#DBK>)L],YQ!G$#2#?*#E+K]?(?@;JW1@]6N1XNW&USE=O`IRR$#%_S(^ +MLQ.?0ZVF@+88#8L>CE[7&[I;2\I2=%DR+MR$-:4QV#A94_)A&,+FQ=UN6_>P +M989E%2:S:SVHZ2#*#`+*,X*NAX>"NF4YS9;V$<#)'L\R_8;51*F1>3X`,L8S +MM]]V4(%%6D1WU\7>+)7*/+EOW@S!/D57QR9#R3M:&N6SJB!B.5%AY20`P\UP +M12;DPNX'ER`G4E,87<\@D(.0#:7.%-H+V'&"M[!JAM&<:4P,F[,3*)CK>5KUU^MZCY>>NH`H'[3A'K]=&Z6 +M!?G>SAB]^W8W0HK)%-\4LG?10`A,G0;XZ]1S'[-7(T^>16]B0LC!;`3D.DEN+^"6'X[=A2O5D5;IU-M,KP^N783S%ZE\C,*\X;@P5X:QV^;T1Y#)%* +MLC@7GEE.\,]*4<[3!;`7GH#8/E]72:C]TCTEL:;387`2P+CB-^H*J!1^[C@4 +M%!55-B[<$[F!I*EX]=<5W0W=NP9ICH*JN4V6O1ZA4Z=4H_&GR`PS1]7GE:AO +M]?39:FOK'Q%GNE)%^FH>-98O$#/U?2`B@GD.G&L4_7`B`41A..V_D!!G3_8^ +M>G^$CBM*_#@W@>@0\#W#5\X1\&C*R#&=EZ(HU`90ZB6^9I*4Z'FH_\,L_5*= +M!$IL#Q7A3S!IYO!P]T5%9EMB7DM:A_78]9YN_[]+RZFJ4V>J@0SA#[NP-D#1 +M:C"-(%KC&'R>WHUS>%I2?_`H,_NJQ.C'4QLJS'XVE\)HT#0_.?[$2%/[!=K2 +MHK47V@L3JAGSL0&6M_HO>!KX61&'6#G;RZ? +M!%%NBHU2-_V7X.*[9ZK;\N0N=9M\=$>EL7#]NHAD\7*FJKU.^E:()]6(2ZR! +M3PPIS`"1YC$SY8Z/])K`#883#9&Z8:`W63_'WC1\^#.6!H\='78>HD(7]:M% +M]K(`0J,F>L/0N2LE$+;>/(89ZDD\U6W+CA<+.S'I_G+-S,*@N,HYR3:4#@,@ +M`MG2V"[EA$K`^P:O`^(.:(.B'FK@-M[`S"I$9W/**,=?C>5;I/!L0OST&X.D +M(&ZI*&\4M8D5B3-S,33)*R>/*X4I<8!V0>6YW'57OY? +M@S$?1(MILODT@KL2K2^^_L(;43,(W==PA>",I\?COZUI5C^UB6&B,[(<^_$+ +MYKU8,9";R/_2@+9D#WQ=@^0G*EM'TC-58)&V8JBD=]VJUMURJQH2=RE]&2WB +MN^;BIA!)ROUGE4Q"T3`@"TK6XT8E,^W0'N<*(4;R +ME=TAXS8SQMYES6>SPIVB!EOVR0I36T/D1_]WL5W#5N<`=^C(QRWIE?N@3?TG +M_Y8__>U%Z?BL^N9Z;F\<Y53SON2&L61A<]!T_4?%:EC9&GU84U/1A-[?4#[-9J%Y +MPD30#+9`6#_G+]%`";]Y\D6(OWXAZ)]]K%`D[B*+H]V2=^]M&[:Y_^L?94I= +M=M2U@)%LT]N%GV]=\A3GBB-K>A2PTBJE%<,<4XPGA)C(/1+S1*(E3&P +MA@6$5)V",Q[0E6;-*E0=*A6T5U.KY^_C66Y'44^BP35>=31^5S>,T3;IH^"$4%^3OM/P796=[G_HXE!"5@1+V#?H6"# +M[49)5#Z-6K_XMB;K;,MGSN_&I4"VT%%A9#$J&FMN>8)_\(G6@-]ERD58.OQ" +M_PZ@>Y'+TPY0Y2T3%TMN/,V\.16J8&X"5;AMM)85SNS$6Q[_8+2A9^V[>0T4 +MZNHACJ&`])R!9R7BFS=:[OL:HPQ@V'KC?/.[0-)\/2GV<5=TTD@X$``!!`8` +M`0G`648`!PL!``(C`P$!!5T`@```(0,!`P$`#,#K:\#K:P`("@$6V^8W```% +M`1D)````````````$0T`9@!I`&P`90`Q````%`H!```M0RMQLYT!%08!`""` +$I($````` +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu b/contrib/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu new file mode 100644 index 000000000..951da15ec --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu @@ -0,0 +1,407 @@ +begin 664 test_read_format_7zip_delta4_lzma2.7z +M-WJ\KR<<``1,P\W78$8```````!B`````````-6%26G@:^I&6%T`)QO*P@;2 +M+(;6`.G?97%G65J_4ERCV:^K1%6D4`M822)8PY*%14J=_<,7#6T/3RFH$9!9G6HOBE'E<0M'0-5!6&]I9Q(LNP>FO1,4C"0-HJF]E+UO?$`OP,0L]9]-?IRQ"#_8 +M4'^\-:$GT3JIHJE5;*\M)]-TIEK1=3?[2#(5!+N!_HL=H!H_R)BU+F9HX\D5 +M.\?T=(M`=9=W4SJW579?/KS>1Y+'M^%0#4C+X<'3U$3C&%='!5[\EF[@4#2B +M9^U]FY)?`J8B_0+7B.I$N.X)PP3;'V&J*6VY.!&;Q7R,;M8N$$GCE7A'DD(" +M6>XDN+^7'[7.>5XJAT[)1$"IP%"H\ENNG?(IVD$"4B#R#;E,KWX0"(+I)G\I +M;FDXUW0:G\77W)*"$2C1DY7G2A@X<7?HF<0(324$@RQ94+EXCPV;A\!J_=-I +MO`PB]JI0O;215>3NFC>&L@ +MA8ZVO8G:(Z+'4*>R53SX'U!L=#-R5/?1CX"K49RW+6#"?:O9#&F-VU+]XA>- +MH/+P67D.ZN0JL3&7/ST/0,:N;-K'@%MH5*U@'\5C)M\[!]I6*3,C]3NA^O +MCP?_.^L?=17`;X\L"SHC@$#^"05.3&=DUY$\848Q-SC.@/%KQ:P`5J3YZ^,Q +M\-/Y(6LQP?6TCO52!37-BUF`NWYVMM2?O%GP33Q3P%?#">B/A68F2MV1P'FKVPF +M);5);K1B>8HI`'2@,V/:[^SK\W]3Z;KMD.*+:9B<=!"$;J;;UE5* +MDM)][UB?]6V.JGB<\EVIL3WF^NX79\"D2_^:2*;[&U%K7_@JZDKEF1,3>-*< +M/L@/V:2=:I*Z6Q%6C)N$U>TY[(C`P/L=7ANK-S3-TT\L:SL +M.T*&Y0>E.GQ/D;-/0XPRM5SL()'1_^7U(H`O&?G,YY4X%=>F@:@Z-KF"#'$: +M)WGH[<$,.1GS0RT6+#EYTEZ8W(/*D52"P-B('Z;VJ('L\]V;[3YB+2 +M64VOM'M9/U7+D0$Z>XTTR0PP6 +M85OJ%/<&J2F(<2MA[/"%RY6$59Q4^<^.2E4`K*^\*=EF4`D<\@V"R2>@9+%N +MD3R*?DVCY?U5RIHO)]4_)8R<3XLHQ< +MU*%_PKX_M,LTP$2ITA\+->:ARO&7:7!:VK==FV^WJ;$;UM<&(,B#=E*6P*"V +M"T5QBA@I!4R$!8.UO\`TE@9K9&W_'H:$?K3:4(%MF):*_OVK^A>=63C@11U@ +MT1I"1Q?#6CJRJNUTIW9D'7P=!P341-$$(0GVW+S/D5NL-H62CQW"4(";.>F1 +M#VI1`SN^2//BUZ2!*N-S5?\L%+&&+]KQ%-VW#[C)/0LX@$90T;HK*16" +M?-10DTO0>).+H4UE!^5"8EZY\AI;S5W!&-W_GR_7YP*YD*]*(84G3+C"6?R[ +M@K<$M+8"'9V'M]T:$P]LZQ6A3#<)_X2D.=BY9BP7WN:17-HZ=K8E9V9>'#%. +MR$L/'`U2%RBA6\@>;DV"%M-2Z_VL]=$Z/^)=`$-)$CDP#?3I3M&Q"21C?*R@ +M#L:;1=**>6J6M\$JO&[IM%E1\K(KV#CK]1!0:?M>([H%FUMVGTU,`#D*,+%) +M&$FT""V`3=1]S*'&PDK^6@#Z,&X][V6I0Z^[B8*7P?4_5N'E9`)5*.4!K2G` +M=(U@/RV>"C?],9@_Q]#\G67)I_,)+$U?R>51LS+,1<0/C$RW$8A_)U)K0:!3 +MGQA004^(:U*X8T!*T_1#W1V4@6DMD&89Q$$,KQ\3 +MF%!524963-!]GJ5^KWZP[LWX!PPEUI'YM$#^I_KLT9X0#)6@K!PWB_NF@WT8/RU2Z8]AY4K"=0@6$,M"\?8/]ZFR2&1&`_!3U=IC.6Y0BN!TA +M.6C(>Y)EI%0?'CJGYHT2-)@CS.KV"@Y<=3%Z4N%FE7E--^Y651G3+2.IEL@B +MMU6O&1?8X45]0!(O%9X!M:1>K`YGV^_O%/GM_5>+640WA4F9R0420YS.DVJ\99T+VE?TO``CRDOS!&U(=)T6!7O'S!QZ!/&Z+KD=FN8U) +M\$M19IA^E8N&#-K%0\KB=RE(0WMKCWNFP/9(//7_,0.J@:`(8F,M63OAJPG& +M`F/$\U>\E?3``?\,Q!FODDU".=+F\0>6-QN([3HC%L$7E(5*FNR9B/R`O\&8 +M;<:8U"H-L?X;3TE6(>O0>/9T)7AX+(SZ6/D?FA(.D-JE)"38_Z9*0\%&R+`7 +MY%"/I@__WF;"!AYKPC`NQ$A]4AFT!ZXW6G-CK3HE&(*Y:LP^FG8;+QYXJBN" +M!P9@CWYCNX@XHZ>]I0YW[,6RH'.JY%\J&"UI8,UC!6+9BR$8ISK9U>KC)*JZ +MYH[[*XDY9`UXU/1_KC'"'5G'Y"&Q +MDW`4H^?00ZOI`F$V4_#7+OH<),CK;&JU[^F#;AL<5FW0%]&2.AG#K,3E8:ZI +MWK+P[/`-['JND8[[^DAI`"ZV>]]YO# +M83_2-Z63%G!2V?XI;66V?((CDM$I#793L`;V]-/[,8_!%6_S2H=/G`\M6QU;]^=M/BMU/?,EQBMJY>6@=21H3LPE5LF9XL/AB4+8E.WGE6X2T +M!O\'-(WMEO'%E0`NU;*PKPV$PR-M9Y%1`&/MC941*O9L=CM/9_A8#*38Y +M6[=4E-`I(M2?3[;8&3''0#RMMF'CW$_6L@E1\V%9^U]/F&G=&[-!=R-XO]=I +M0O55K3CBY:66KWS>^MJQ\9$VL_2VBB\1W1^A>=][1UMIL$].A,T,W?A5IA:W +M@/'.WAF:2*K;Y']X8D/,;&X,YW-(C:O>"*@5_EZP#J]'/X,'`OZU=@2/&;O@ +MZX(!^?H\7>I'OPXHV(.@N6 +M[6&;7[
*G'YH*M+W>S84F&^UQP/>!^$/*J6#8P);S!S3ALHDN3_BL+3>: +M8#XL,V3.:69'F<4LN!:2(9RP#:V#A)'<`%`CMNJ[^WMKOCK^K.%J_T`@RA.` +MLPH:_W`3-#"&2!B6PZ&30#4F:E.)@1&KRIB,&JIR13OQY'R]Y(%?K\"/V +ML'(M&JII'VO>J3U#_:[LB-JQZ9>*2.D]2_@U1`>CDQ"L3M0W(D09XTJ$>+T) +M\6[8[0.PPWSWY$R7A.VC[]3SC&-%I$,#)0V$A_%KF."AMKSX/IG2T%BRNZHN +M$2`W]O[,:4=$*F=AM(#HRD(`[!&`Y3>]="+V`@C<5[5D6 +MJ?GMYQ<"DEL"N&A@L)PW_T=K7L6HBC3@-5W`S9W2DU9A5/'LQGM4*9TW[;#= +MLDKA[Q`H(XK*DP6REW[4U@-<@"%&K4^-I5Q]W>)[+33W#8X5-LY0(6)P"*H] +MIT$=PL2;V7]>=7S>WGG?H%DV>=ROMC->C]68@]YF;!!6 +MF53BEQ_L`0$I*5WKS*W7G>]2YHHA1A)D +MI11RZNU3(HXMRO2C5)*;!Z4_Z_S;E66MJ%"%X@KZ)>2,IA:E+O:9F4EHL +M#'D0U](#Z$1=A(5"RQPB"W:DCM$M957$TTX]?;_"W]'#,6[#T%:=BU%45@G>`(0W8H +MH;2WP.:>7X.^L`0,QC6'QB.4'<:H_;?[HH55KK+ZZ(K(;#4BU/6M]A-C0R[-7?A!\A$XV)ZV<;3>(#PWJ'G`A1H^M73&2TBW80SG"6\ +M;_OXLLVXYX"RW]>A3W+`BH'-7?H)$L"JS&0PLA@6NZ_KV+$G$NV'N&&+PN)M +M'G5`7X^SMS8K5ANE%#L&\;1RA3@"QV;B\,S=(VM7*6P.8;7>YK]SQZ5)/T5I +MW\X7J/F)NH5RK0RF!YFU;``:"/K48?)96)H:VL/W +MCSBK@FI:EG7O*9+W1\`4#U^CUUD)[A!W)[`::QDFW6+FWM>5AA5A[NZ/@G]K[-;E=Q/+VX04AU1D3SFJ35+AHSQ.:LL*B@; +M,;S@)LR>(C]7B^7VTH$RLX+1JGD;-V!+R,*5G%7QYY`>AG>9RA"1YQ +MOM]^O*Z#^.F?[5K(S6HC:U-CI\J@^=LXH<]U0=.?[:QWLN2_*H:.S/\_)XG% +MV<6-"3:+\(K_EQVPN-IU^YY=#6Q+')ZE(BAR.DE[]QV?,&/$]UVN:H$VV&H! +M3S]=(Y88^?CP.6IHOHQ&NT/)MOK%$E90.VO&>3\%W`0*6I@[$&"OKU1/Q,"7YI)EYL2 +MY461?+1&M2<\%E#K*'87RWDOF@X<;E4-LEBB$0?(CH5(ULI^S.D9:)O9D\52 +MXM*N7>?_&UEV@C3$3(!N;`>4-CU_ZCX?WFHBV"K[,!:08Q[@@`Z%).)!O>(H +M__Y12NQOV+%>&TZS;9\1Q@D3WF_'37E%S"6@N;K@^&PS;2PQY\,DRW>;X^MK +M/*[QW(:@-`IW$&7U>3@IG%W\HDOMTO*UU>->\P).[R-8?@JD?K.5T:8` +MV,N8_^@0C=YQ'VNPS%3#"4\BVSY5-VJ&*D6Q(C1_0B#@<7A?>/-_Y:F^S;O4 +MJ8-0->_CE`/I>\%4@M:.9?:,@/`*M6]4[_H#":*BPKM&-*.XBF\WHW,P,D71 +M^62[3?"90>H01 +MXC.;&/,&Y1^?\5W9A*]LMIDHV:MDE@%?@SG"L)XLS]6;!X8B-#.%83SI.T-!WH_OZ*]6.6"(DJ +MZB8:+4[#BI35;.F)C)J#^-Y1G_\/1-2Z%/^WML]Y`U`(!\%AO+R*+ROH'68P +M#W$]LNW4N$23ZM0$*FWW>5==F.;B1#(4J&&7G;4?$7KD[4_0Y-S;G`<%O5PS +M_M[2\-]A4-EF1&L$-Q)`*Y +MG38`;^"`Q$&?&V04*(>I(MSZJU>0BGD$KM,FR7P5Q[#/HCE9-_]AY)VF?;R%-I!%14OB]F^RU, +M^&Q-2>*XPN!&O""WQ +MHB?EB7MV"*:BJ"UO6@U5(I]FX^]WAR+(*+TWZY(07;Z4;JMJ/35+;LRL*`0; +M'E87GUX1XXBG5K!JQN^86V)%,-@BZR([\L(;]/"@FT*\#TS]UJ9&="`[]&@CSZ!CU9]Y8>(V&PI +MMKA*-%[A.67]I'72](-.H6+$I]S=NVIW&?Y9CMBGC'^U.[=+F9W5IW?X:BY$ +MQ&7VE5VM."JPM-ZU!X?$YEQ#SCP3=H.3WDSV'JL[*^ZBU)2:QC=4$)*LG\18 +MN&6#B&.)SF`5A9(^F60I>/Y7)YC:\(HQWGPH1@I?8*&>QP5[T*!'9^EMJ`[I +M9^%_[>G8.$Y1V9$HT_(QKYGJ(Q=,;J0:<]2/0.4D[5M#XB\("W)S?WHS&%5W +M\Q0*)24BW47>9%4PG-92JL+CJHF("1+\P\??,G2>F"LZR360WKT.5XQD +MK@/Q@U0-MH2GF"N[F,E`U%L/3>U.^+SOM)/[Y!#H8(WNN56 +M"1M)7)+9ZX^`QY$)VYV&C4A@5$MV6)N5QO5N[,XFLTN5(_Z/W.V2 +M(MCY_4U9IU'0<=YJOE&61^+4(+]"K%=,748Y;3;C(SRFD*LA,`Y\6%4DL!^' +MFUY8A-L1'A)`Z#TQ@VO28XW:]>[$--59(S74PX(BG7CH3N:@MK<*!Y5*.77( +MA@:>[^FTV$+8V(Z[4+?PC-,N^K%$@->=:5KJ:(4\,*H6:W#Q87-,* +MCL\45D1IZ-BH)<:H'4=BMW(;TV+LNXVB`&U-JGZ)9"1_1 +MZC#T-+E@,QT][:&5UOYS^Q__\X[ +M:=U5C&&:YL?V6CRK"/?%X=\K&]FRL\WD*$I@M8W=LTVS@EHN"BH,`&/65-=R +M2M6F,'&H&C=6_(_'8,6H5_55K>K#]2Q$82F7NP1[ULZOQH/Y$K[I-5A!=P?E +M1?;("/:_=K^,`P316_*N15(@$('MM6YT^>[-&<\01RX!A_]AW?NVY%T;Q:,O +M8&"A&$\0)C`VM8:WDF"6>H8JHDE&JL1!D]Y:50%*>`?_Y759$N'X8%38HE4P +M:<'N_DL.:E<2\AHV_WNS-O?Z=IZ].=Q$&Y4H.UK^.08H_V6/@LPF2'G2XMK# +MU]$I7NE[2-ALYI2\T$TRJKUG1(BOH/"JEWN\O4AF3O)O0&J#796>G&/`5Z$/ +M%]8Z(0.'S6T2$U5H=9/6>/9UR>'3NX\7\T:9F>I`2[!9>1:[PU"U(]\9DL8I +M[,YI]IMAN,8K3-\IIPCNL;*93)O"Z+*>_K%9]KYKY1O*,IF0@#V6E_:]3 +M+1`>0IHIAVI!\T@MGNU7BK43RFW^X>!9-'$VON:PR,#VU]^!"O6 +MV)V%*\OX80:!WXNCD!!SGY!E[,C)SK::L-;*TB7S'WNS62B1&)[PC>U.Z;EA +M"H16D<#Z1"C/>M8$_ZR*#;#\>*DO))@"]4Q;K?[W>?2\#B)9&YH&&1#*4)FX +MIV_7-.FV-EF]2(:P=SUY3G]8)6KO"J'#(.7L'W"^#SYQN!I`DCF4>4-!'`C/ +M*/`%23(Y3O=L^=4*9VE-#4"46RX(!\_7L8'%,;'G".''P\#FK=7C#D>*[,3I +M?%LS=8H6D>]BOWEC@)*B=YI)M;#!]<(!6"SM(`HS*7 +M>1R(,]:SIXBX8:"N7'.PR2<.)P=%[(/N6R(C:!=!& +MD.O4LCN[$0U4^%:/8&>*MF/8G>+`]+D0%1W=LR&O#\BPED>!L%)0@)9C][;4 +M@>XSM\9.:)@-;`P;C2R[(9V``#!;2B#!((RQ_=Z6A8FC13AC)KPFS,2C#KC@ +M0,,!=4?RNT"$]8]=HQTZL(EN1[58BJV!V[57>%W%7X>JOLBE`M$2#H$]D*^X +MG5$W&.Z",UMY\(ZZ?PZ2Q8I97T1HY31%^T?DEJD<3B#IQ[R'N(RF;7Y5 +M?FA:X>SN(7R,Y(H;,A)1F"=-US`;XC%_I3B;D?T7FD;8![YAU#I-;%CXW7JK +M^PX\LV7FA2=25.UV$OSP6%60;NVVTJ4.A +M4_NXC%ZG@OV7P!"@KL+@[/0U@YU0RLHH(\`D2/S8NE73/1759@?VG-[ +M#^5K)-V(KC6BB"B-J9LJ?F(BIO&UP^-/FN6/E+:U3+;`=]/`ZK5#%!T+@O#U +MKQQ$3>V`#?N3<3,8.])L;@N:L%8V%G.KOPN7][!"[<'*KR+>`%0ZO_69&2QU.UUBS4>G2\R`)1#0[B9[] +MO"E4N)/X/RH)DT><1X-KU`4F93].H>N,X2VLZ]+;::6/Q72]V6FY42.I'7X@ +M@09-A],I3!,:C#/^]1Z>LS"7-]A3=Z.>]>)V>F1T\KH9=\5.07;*4JCJA"%Z +M`\C>PA3VS>5?9UUE[S7/+R7B>K_&UGZ!Y7%0@A(T?$I=:6GZDM:)'2;2-S9/ +MLO8OQ31K(M^>-'.XA.G'!TF$BW7LCL,IF@6.0JR#Y.\(P;V!X74=#QH1T0%T +M%C&SCI$*^'_2-=-9JNC"#ZJ",4\]LE*,%0[5'OKA9P +M\,%&QZ%FX`35=#VBJ>BXGVQA2XH#.SYX`),GM0SI9](2TZX1LH!+S*$BXB() +M*)C5L;LDEB6YHX1"HN4=2%H*$Y:LNC^=5-M>#$I5YA)@WM].QN[0];"PJ&F# +M?,.BVJRM27FN=O8,P?\`P=*M!EM!DGG[H_UZ8<,B>%`A%P!,O[/%@[8_5"DY +MRX51)=.`\PHFMJ90"*@XI.^8F,9'T%FYMW\E%H5.4L`XRO\.=X.+42F7Z?%= +MUH.#\WWGJ#_"]0F<4,V6G#T<7-ZA*MP+`CZ:N`KRI$N5NP1N%\2=SNAY40I2 +M%KO\6QHGQF4KH'C;5@VCGO(394SKUP$USQF?(B`3ZU:FP9BR)&K,K +MC1`$X./>F-TOJ2C,?Y!9K!B:J`Z''=?RG,I%\TB)I;KUTT-A66=SHB=B`D57 +ML*\B9X:Y]7CA-Z&[`7"=9Y`<"1V08NK?,;CS*5A#>0SOT29]?W+:$2WP(IR` +M6#;7(U"U5?H&ZQM#?;Q$RJ0!JKC2I#K3/(!P6;2EU!O,1:,2B%@4-;YL>TXPH0)@I7 +M`P+BM<:ZD'A$\_+O7XXGNHD20)0N--U#>LA+8IBW&@FWGG%SU[A%"$$L2560 +MDF&G&SS-9'V/_$0KPRN_X[QMJ^@2SK,YT4RYG,Y[19OVYO,1[RM8HV4X+<>8 +MGD%0#9>.\[9%/ZMK<@#&:I79^69,&>(IMYR7E>\;$&:&@S;'?%=7X3)7J$BT +M>)0U_TYQ9ZE9!;>)S@$)V(2M7+YD#U6:R9XKNH58$`Y0[?!,!E_%;P$@9M[J4!2V;?7J9KR@DK_5&0 +MZ4D%.>R%Z):(=I#:@8@P47-WUYI]GC3)=ZHM-RGW3DV4RF-N:;/ZC;F,`%XF +M:J3$DR^-UO.%(6\"F@9D]+N>"M+.`UP +MM7OEQ]FL=+*8#`?/-V6:^@Y%SEG(<..;Y;(H^$H,G%&\,DFEB?*"!6]@VYG! +MGOOC!NCP3GP'Y[:+1P$N#*F?6(UV)A?.XYS62=)&BQR:)TO^'6L6:O?TNGOH +MF>AE>VW3Q+^7)L[9\V>8!"AT@0/(5?/]9""`>7U]FA +MMD(3>IHQFM)CGJ,V"3X.3!Y`BWH9:/`L%%IV03`3"CB*>Q[@>,M.GO%(M,16 +MIR[4N-H70_F1S`[>>ZR>0L8I04 +M1N/:1`ON)P)JZ15?2%&?).C&0JD<30`?_:NO=WD!HX_O;?[SFKQE1X-)C%\Z\("^.SP??@UG)[9(>E$''Z.VX4CG=W5`"XDM.(ZO43K*UNWT/9:2?8AT +M(),]T]8S(D-VQM8A9O)O0Z%6U-FQA`CSH)+QSN1O#H]&B%7JS5]TDHP%/><[ +M;6BV#FVW&`*ZQGAFSV!#"#H/B=8Q&%J\"SR8@&8R;`P1+6\A(\8QC/%$/.?1ITG +M^19+V--77A8J0;PBPT,)1REB/^984W3T;E'-EF6/QO\N<>WJ-M6\MK//H)=_ +M_J-E`'17:M=Y]>J5K`:?=";=62H6^%BEO%*IF.JF`/4N_R7<1IW&[@#EJYZ" +M_S\W<^%BDRHSI!"+1=?<+J0,I-+A,Q?:K.?FGHOT-M#2;F\(-L_L:"48C+`" +MW#!ZU&0J^B)6X;P)5=7&#^E5`-:Y>[.UFGM#3X+KP1-W>^F,Q:;@T:YOV?Y] +MJ4CIVM2LO(/=LOCHY@R&HP3IP9LR))TK:`OW/A=H4-HSPI."(I`[)R&CI6[4 +M)!1J3"3FL;%]WD8X8O^[L1T$1#(2V;+(X&L$\F\8:>>KQ8:IB#.F).O(1L3J +MB^MW&%F`99/EXP1-^>*@"NT3'^,,:C>*E=#?-$'-P+W*?DFGG+RV(V7Y1DD%^ +M13&2K\[(W6&D;*IGQGN@/@75IQI3B\.R$[WG%`][8JZONR"G!MD>;DO`M#S7 +M.#F+2*EP\)D<(Z)5E6_\NXRI#.8F +MPSMY[SR1_Q!M@A"1["=3C!MC$\I=D&4_,LZ6.VB#9(R-0:RC7N#H)8`X;.R( +MOOI>%0(-A^G"&8WSYE=:$LH&KI0R8\A\(245F%S>,>*@!\DIFN2D8>UUFRG, +MDY/3B"QY%R^8%]#BE*SP\LA-J#*BHOP^KL!#4'S@7K:BXOM6>]K(\:Q-Y#9M +M&:0''!W12).:.8;W=B;:*A7[8UE/I^#OS#!+K-%75./$>*Z/-R$5FY_2"9%Q +M%+IGF-,8.*!/U+B49C6!7B9CFH3^#$0IUM\_EL[I;^:[K^$7E\.0B/0U::D" +M<)>I!H=4T#D:R$E]*;2(U2?8>I2IO<-9=&##O32K$-T=0#`6I@L3"W*;&YZ2 +M1.V`TE."&42I%D-,[&UY!L>A:]Z)MW,9(#X)6@3*40H\EU5C!:"1]KT_2Q+9 +MW9)HD):2==I=*F'KQUX_VQB00Z2)COJ$;..3>7=7="`"^CY+(%/>)=4@"<1L +M;*;0`D_2[PS93J2SI=MS)=:M=P`7" +M*CE@##"6JZ&B:%LTQI65O^3"$0@KN6.+'+98S#SRV?B;N/Z3833[SOG(O]W? +M(!3SSB'CU7R"-#6+C'Z^/>6D/4Z"<\%G;E:.+1#F/4R.=BU3_1&FE**#EX6' +MJ4E?-)\-"O*X52TK19<%1A'L$4O:<"H"D;RD[`>S3ARV(4)/F%J;!\I$,R!+>M8+'/K3SSZD/"3Y(01+;E1L,G1YU-?,T^"4:!!^$PKA7 +MT[ENIM$P]888.#/ZFXZ9Q8&&BNJ]O68EJ^6D12?)S1HDFSH:C$\'LW"DB%7Q +MB;=I$X'F,#-2AV!Y:FS]=QDPR51@_7=7,H,P_X6AR#'*VQC$3@?/;KZ@$RT% +M+>)?!"1K5XH^VQ&9SQ +ME^1NL[GQWX4^.,=&6A()!6RP1%Q+U"K)'U8C:BC`Q1"_NKW_Y#R@='88JUY7 +M_"F##Z&594Q?2'(A"$PQ%%\;_\2:3:ZFA6%?8PY97Y9N;2`+BG@0;>B[[`;7 +MMH$T7XB_>M]K821YHVV6#)5`2CQW.EK4:LPGE.!4J:W#X13RQOA7"NY$)-%M +M]\R'VH1<3GYYF"S2`%941%][8L@\,,VZT\+0#:?FNF'-ZV*->]#M3PN2>M'7 +MZA!2V*`&`J@;^%INM4.S]N+M@TXT9[]P6]Y!3-4\VC^MM)E]GMP)'D+1&R\F +MAS'C2S,P3/SNG2`;)J9(`HJ&#XJ^(T81,J2[H4Y"!($_@$X4!+E0`(:7F_'= +MA4Z5YLF(3L%Q.UKWM%E$$YD<=JZVX2:3`6F2@M(O"&T_"/!5&'-E3=++;:#0 +MD1=?U*_Q?]5%7@%IJ3R=)`0TDKU"D=SG"[K1'M5R/710FDWP[',9W$JLL)-, +M?LK4;\Y2B/&2"XF?9MK[48':8.M^0Y/H-Q(H>00X.;">\'%$"@;DL.)[:*R5]V +M!W*N4")7**KA;-."B]"3`R4)5TMDL$Z=BUGN^'/UJ.,&N-T:(E$'X"HFS'.( +MF7U%N@]2RP4&YHX`8\^M)$$[#?U,&WK68/#!.[]+Y`+;Q@DXORL?,"^]*I;[ +MI]YDMX&Z2%/6I]O,]R>\&JA^Y%Z@WFL]TMS/VX]*VJQ)FQ>(N&'@$WW7VHC5 +M/ZK,QL3A`D[`7@WAN34HL2U:U?I[&O$1^,(-]$6(!E56K&>](Y%IYD:-'L!: +M.^A][3AYBX+Y;0A`W-)")Z^PM!W4(3&M\1K!42/KVXK?&`_#>$(+)N";"DQ; +MS9A\0%+N4LP93U4+7)B];I)0,SR"9^BU"H9H!%F='-GP(=5>U:7@D>ITZG&0 +MSPI9"@:$(;D.M$PIWS]._CP#+!L<&!@K/&QW\>'&\DAZ14_EV"FT0RL9U!;G +M`.&G$5'Q*H<;>XEOE+M?```ZPK@`B.JJ]H]EB+!K>0-;.2-,>[(V1T0-'NIXE'OD%]TZ+>2:"TE?K1 +M#Y:&=@0@0<8"CL@H)5G*2_8GG&B6UN[&]?B)]O_D>2%)UIU_';T.!GV+=4(N +MH1YJ"5.RK6VT]E)]M%&H*,9-H1^S&J)ZD?P@P_=:/BF7`2V0BZ^GV?O#8^F5 +M8L:)OPXST#X'.''TMY!JTO-(C6YUWA68@2VX6@+U +MQB[3#QIZGZO?T9/<_!I,F[MV(=L+3R-@,63-I,1XX>?[N9!BR0=O-Z@&0TW& +MB7[VM'QHU"10U;L^^;0'X!N*BLI[ +M`%X^/X;D![C/25?/J8J1$PW6D[UJ[C0LV6<(QV*(L-LPG/!,_^\C1J7YYOE_ +MO'>9,LI!!@YK6$%OD\O,>HRNU=KFN(7#2U8WTF_PS^*%C+O>-*NN0P0$'%>Q +MQHA]Q;)BF*J!C4?H,CAB><5PO"E>@FT0@+VEJY?F.^GD8P28:?QJ`8*GZQ.I +M9P"V"APO/_7RBZ\VNE=ZW.@J4;21,]B$=33[D21X`-]08D;V+'[I4K<.0QLX +M,D@"9<(-^Z#1#-&\.)4[6DX]^@=-;'NT`1.^N@N*LGW&9E>DYBAX4N4\6\T_ +MT'ITL6^=83<]PJP560@+SXZ\S++[:V@R[C9G;K"E.R5BUC@BX#X$1,R5]L'* +MHLO2+(:+8:=@06<]YQA"U&>&7%ML#I?*Y3(SO$1!B`3_+P!X\9GO4B$M"(S= +M;F;_UU9T*`FOU>O)\/_$4"M@C1K7K^)_4CBMCK0M3B +M].-[>G0)ZZVJ/=4.8Z>?(248O?);T8WJAMTCN0[%PTWU[.-CUO'5>4$T75'Q +M)O5".',AGT!WALW&R8DV>TY,J6^NQ?*=BLL^?G,#U3'U;#1NN,RZ7'HC@#5? +M(D:X!;Y`\&6!WI[+ODO46HR("Z.4'3LK^KO&$ZFS,WE?,DYJ>#DK4';BH'!] +MD&?X]\YCL>[%;DF;E$"#%"@M8LQ#H2]K.E2K^Z"ZG8YC$\IN88<0E>>;``"Z +MH1*XN8)DX*'L[KI)>'W6L__0P*T(I_4693<;@A%\-#A6\H*XGJ#/2T46JOAK +M+^YGH`;FI=\"5S0"FO5T"UX#J-Y#.SW'\YOS/@H6I('!`YJXDZT&`K$"A7USET[I3/ +M+RU#9]ZL6,(TT&9!TY,]1FG=_^:X987GD_2DY[[GWK19QP.39)F7:#P9`&=( +M.K5Y`CC"DWW/9"P%48&0'VD8$%HTHNVG.Q%O]/.<^_)P0J\C(.IAY/;-!]6( +M=#/O'C2\IBR:31K8@[[QY<;Q\1=A5[QSR"8B2-A/F1)3G$?91>KY_[94@'N3 +M3WWK%.M$PR-G$YCMD;W7S[?]<2V4^=NS!V0SG8%&!T-^5&QL]BLV49Q+21RT +M7-<@&M;&;B^Y$&YDVO301F&2C2_?`7=#ZFGY'TDZO;AF9_\9)65?9]V#>`NK +M:&'^?!"I\/W08`7$K?_^S=FA3-2_H.^K1.%[X%VBHIMRS924QBI5M29].U@D +M[CR>\LY9FCH"/RB?/8KRL7>1K?D;!CK2JFRV+?#2"/_X5W]-J('=:Y=YXT>)V*&&^\]E$Z*?W"N+H1_S+2) +M"H3&@;4/*](.UZR,;LITE-#=%EIO@6%T%VR9)*LCQV=&T_7S%_;%%L_JSSM4 +MYW'=$C^'(]#AS$97_A3&IZ"$+':9E%^'7]1?^:'!@U7[Z5$IXAPZFLR^ZC+= +M0H+(Z&M[4WH0O\;*[V%&.:C-W.1Q;].Z>PWGQM/Y!=`?/+!#[B]:3839+81= +M@GM//`3BP$']S^^2NH^K"Q[AZT"AK36LR\;WP +MW."@%Y_FT3>FH?8UMQCKAO]LV%%IK2:_C@.;@6"LT_IV2K!2EYX(!K]6027B +M#J#P4C+;[;>%TLKN3']+5?HCUK'Z5Q4DO!61L0H>D4'1^9&M'Q?E"MSHE/-4 +M,=8MJ/$2(C&0OV6H`*50KKOLVM-XB_5>-]==):(Z'$ZF3%COR%=S,7Z7/&9K +M=3/7>R`(#I$$ZF_YC]W%\%J#$%R"/`5#0-V_6S-^C5EV9*;%L)G::QU\GY]D +M(H@5AC3Y4R*.IX/!N"R99ZFT?@3$7D@>P]]=,\#"WTH$EB,Y[H0_0\Z_H<7[ +MQ/<%($H8\RZ3@,Q[!SKSV4]QXCB*3GIZR;M>OZT,YGZ$@?QT<;CSYT4*!!)F +M9F3-^\!Z(EFOXEYT&%J8U<%T"HNK'$9AQ=D)Q90RC4!OJ]-1.Q0EGQ1QY<,Q +MX\A;J2XL@(@5#\!`)/)88#'LT$IT?\F8*%_&@1W^N&(PSJ$+<)M[`F@NVC91 +MDB7)+;3'Z'K4Q=ZQWU8YRVC_VR;'EA@%8U]=#2G)W(2XE0`AU(\%/OC9H5"/ +M;&7KXE\W?.8XVL<-,[,I\)HD=MS=Y2THV(3)!9-(E+.NU.DWMSN]L_/#NVH+ +M?XJSH_0A@8%X-`4)9ZL`J_A78C'DF;G"VB"?P$O&ZQ=Q.0%'6P`N\GOZC0*) +M=4L'JVO;[-8=?M`X>;>X'ZO42T*L'SVG26!RP%RFHTXITO7+J8%U_U;6]2K# +M?8BB;JS;T:%^:II9#9NP`&"(M*-G;17!KI]F28/&7+TLGK"6?\4=@T/>TPH$5F(FPD"]OW-9JX@E$!`V0L +M1:-'V3Y%/-P1(CGA/<#AS@)>J+:>E?K,$S=\WS+#W^KIDQ>>YXE80`\NTRO%0%F?DL@O9.' +M[8HK&NW.J-U"#/7M=^=+H1@.R48J4L&BPI,+7UJ/X%"W]K[%K2*`&5_9387H +M7!P'SL(O@+]D4VV'`$]+\!"'M.FT!@5XVZ(]!$$]4,/;Z90?;94YG%5D(0"P +MSRIDG(]_!404$.3*!<^K"A^IN?(-?#M2F-U,5_W`(B9E+MTAY%-5CRLQ^(.H*0PW/1R=]4) +M?8MVX(N1T0'<,8)MN9_Y3_&G!V,YHH$!<_:>=;HA^AYX`KLQ^097HXMTQC-Z +MPC>!P*W$"G$]P0K%2R!NI6;K??%9@$A?&>7-:<-W1TB;V0]U=$6HT@5@V +M]EAI(F#:W=T:HH#2G44M_A +MZS.IHW4EQ]?O%PPW9S&1?%5F@JHU@AX5T8$A(L:RP]A41DR`@<;V++D!O'G2 +M1X],J*MM?8JF).WJU!H'X5:L\?JAF(=`^2:$DW6V=+84UTU>%5_\@:3KH\02 +MU!LM^M3%:)_4/GM"^_=M?]=>!K^L\R_<^VU!FDS]Y*,PF>NB"IR@!NVP'3@A +M*7VA%VA0/XX(;+U[82(4]!.:]?2\SA,3BYL]I5DO5*NB3(N$E=C;.A$O+9(-8HD\<)ZTJP!O#0\LV*%!3*) +MZ>\KUXQR5/VO#I"EAZ6[2^=M@3B4W[`"-+^69K#M*/UN)=P;* +M$PRK;8);*&-+!7WXR4ZW;\2?2X?0M?@77]Y9IGT#LIQ0SC +MI>G=3($J%#M3&-6[J"N'BA1/T*=AW1N\8IXP)ZZ>"CJ;$KZU3-FDZ\:ZZ4^7`\$#-38V!_53T>Y<#VN7TL4! +M-#1#OSMC9Z#15ND>K9:PI@(KN=/GBSH4%S`&]2+3_8^#E\$3OBQWH'MWU6T; +M\Q=EP@_#H>O6BB#6M^"MN3!^=RE]MRZ"VEWQ'$D>@++.[("^\LQ,T*SX`6?\ +M!+7*`*7?)]B=1!^YI&86T*6-0.GM[.*7M(>QE[HO'8,%S)947!AAL$+3%*]9 +MQ.>TZLE#682XK1;PK=54+\A4J[L'=#`@2$XV'.6)DCM7*!+-I=LEGZO'+O3"B5 +M@&=#-MP?IXE5:9*Q%S$#0+3OYZ#:GU,#ZA'*H6H"9S#%8='*\L%2)=QG?AB+ +M[Q\CFIQ^&^GX_?+E=EIL_=UM"@F58*?A*`YO`X?O4<#+Z!R`Z#,HD_<@3.W: +M]T"4_$>3@[.U&%JEV-%KZ(L<-X?*5AEO2#F&@"YXX!=T)Q+HO2*T*,[<[O9V +MLTVTKD9RL:4S"ER16"LL+0(MC&_*DSQ?MZ1.G)2LAFM";J;(RE1>!<$-=GR& +M6]JN;T/D:'#_JP004=/^\0WT`J8T?(V05T_<["1R9KGA1WP@YBF85J;6R"9R +M^0=;3T6/0L/M7[8S7Y4/B%[:L_-`$'G(#9E<^DS_,HE14SH&;%`F!<8(%[%W +M$9],MG>'-%6S!I<*40F<$$*85-P6Q!9B]&"VU^R&K$LLQF_&\Q^H-?=05=-H +M&25;A<5@FKGV5>BK_JOD]'8DYH1C&>8?S(X4,.AK7*(0B86_\`T'&'=D62W; +M(.=92\<^QPNGQ<$QDL>PVLPJ0"Q!71D)]MM!JV?"!,GOMMI+]ZK=85$Z"4V< +M<8'RT<2,X%W@\GJRS/B4_W4XS-8N%.J#$,6LT2)V>X?I3H?*K*83&3J=-<@A +M7%N'6#QG[*XC&=@%O=^!AJZTE$>VCH5%B$,%,,YS!UB3K\:[__U_/?W_L^9= +M+$0[]%34$%2A`I$X_W$51X*$Y]?)/CQX'%U'2W`E#Z&.'5)\N^35,U"1;LY% +ME*C6[(NXNI%F&E9B(R19Y]:6\_A/!(>;^%9]LF./CM)1G`TT"Y=]=(8/X5N. +M70L*B$*;.8/6-;0\5) +MV^)[P(ONAA0'%ZWQG,!H&+GT"UYVTWI#G'6J:H`LK]COP.Q-+1Q)9N8]8YYY +MD^I+K;^RU`7(;"V/W//3P5I:!AX'0>XL:H`*B*>:.^LA0W'"I5YI;T+Q6+1( +M%+[VJ+)9N^7\BFZ^U"$2)%5*7BK9-VI +M2N06O@'1\')`*S#DBK>)L],YQ!G$#2#?*#E+K]?(?@;JW1@]6N1XNW&USE=O +M`IR +MR$#%_S(^LQ.?0ZVF@+88#8L>CE[7&[I;2\I2=%DR+MR$-:4QV#A94_)A&,+F +MQ=UN6_>P989E%2:S:SVHZ2#*#`+*,X*NAX>"NF4YS9;V$<#)'L\R_8;51*F1 +M>3X`,L8SM]]V4(%%6D1WU\7>+)7*/+EOW@S!/D57QR9#R3M:&N6SJB!B.5%A +MY20`P\UP12;DPNX'ER`G4E,87<\@D(.0#:7.%-H+V'&"M[!JAM&<:4P,F[,3*)CK>5KUU^MZCY>>NH`H'[3 +MA'K]=&Z6!?G>SAB]^W8W0HK)%-\4LG?10`A,G0;XZ]1S'[-7(T^>16]B0LC! +M;`3D.D +ME;'FEC90`JK::$Y[8`U(2T6H@BUF`)8-PPZ`/`4+NB +M,Q5;.$^QD+O=>N+^"6'X[=A2O5D5;IU-M,KP^N783S%ZE\C,*\X;@P5X:QV^ +M;T1Y#)%*LC@7GEE.\,]*4<[3!;`7GH#8/E]72:C]TCTEL:;387`2P+CB-^H* +MJ!1^[C@4%!55-B[<$[F!I*EX]=<5W0W=NP9ICH*JN4V6O1ZA4Z=4H_&GR`PS +M1]7GE:AO]?39:FOK'Q%GNE)%^FH>-98O$#/U?2`B@GD.G&L4_7`B`41A..V_ +MD!!G3_8^>G^$CBM*_#@W@>@0\#W#5\X1\&C*R#&=EZ(HU`90ZB6^9I*4Z'FH +M_\,L_5*=!$IL#Q7A3S!IYO!P]T5%9EMB7DM:A_78]9YN_[]+RZFJ4V>J@0SA +M#[NP-D#1:C"-(%KC&'R>WHUS>%I2?_`H,_NJQ.C'4QLJS'XVE\)HT#0_.?[$ +M2%/[!=K2HK47V@L3JAGSL0&6M_HO>!KX61&'6#G;RZ?!%%NBHU2-_V7X.*[9ZK;\N0N=9M\=$>EL7#]NHAD\7*FJKU.^E:( +M)]6(2ZR!3PPIS`"1YC$SY8Z/])K`#883#9&Z8:`W63_'WC1\^#.6!H\='78> +MHD(7]:M%]K(`0J,F>L/0N2LE$+;>/(89ZDD\U6W+CA<+.S'I_G+-S,*@N,HY +MR3:4#@,@`MG2V"[EA$K`^P:O`^(.:(.B'FK@-M[`S"I$9W/**,=?C>5;I/!L +M0OST&X.D(&ZI*&\4M8D5B3-S,33)*R>/*X4I<8!V0>6YW'57OY?@S$?1(MILODT@KL2K2^^_L(;43,(W==PA>",I\?COZUI5C^UB6&B +M,[(<^_$+YKU8,9";R/_2@+9D#WQ=@^0G*EM'TC-58)&V8JBD=]VJUMURJQH2 +M=RE]&2WBN^;BIA!)ROUGE4Q"T3`@"TK6XT8E,^W0 +M'N<*(4;RE=TAXS8SQMYES6>SPIVB!EOVR0I36T/D1_]WL5W#5N<`=^C(QRWI +ME?N@3?TG_Y8__>U%Z?BL^N9Z;F\<Y53SON2&L61A<]!T_4?%:EC9&GU84U/1A-[? +M4#[-9J%YPD30#+9`6#_G+]%`";]Y\D6(OWXAZ)]]K%`D[B*+H]V2=^]M&[:Y +M_^L?94I==M2U@)%LT]N%GV]=\A3GBB-K>A2PTBJE%<,<4XPGA)C(/1+ +MS1*(E3&PA@6$5)V",Q[0E6;-*E0=*A6T5U.KY^_C66Y'44^BP35>=31^5S>,T3;IH^"$4%^3OM/P796=[G_HXE!"5@1 +M+V#?H6"#[49)5#Z-6K_XMB;K;,MGSN_&I4"VT%%A9#$J&FMN>8)_\(G6@-]E +MRD58.OQ"_PZ@>Y'+TPY0Y2T3%TMN/,V\.16J8&X"5;AMM)85SNS$6Q[_8+2A +M9^V[>0T4ZNHACJ&`])R!9R7BFS=:[OL:HPQ@V'KC?/.[0-)\/2GV<5=TTD@X +M$````00&``$)P&!&``<+`0`"(2$!!B$#`0,!``S`ZVO`ZVL`"`H!%MOF-P`` +M!0$9#P```````````````````!$-`&8`:0!L`&4`,0```!0*`0``+4,K<;.= ++`14&`0`@@*2!```` +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu b/contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu new file mode 100644 index 000000000..4c216170a --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu @@ -0,0 +1,7 @@ +begin 644 test_read_format_7zip_packinfo_digests.7z +M-WJ\KR<<``*^Y_3?$`````````!E`````````&/C(9T!``-A86$*``$``V)B +M8@H``00&``()"`@*`5\J+KLX07WL``<+`@`!(2$!%@$A(0$6#`0$"@&57?AW +MX1\F3``(```%`A$9`&$`+@!T`'@`=````&(`+@!T`'@`=````!02`0"`FYCT +.W+;5`8";F/3 + +static void +test_read_format_lha_filename_UTF16_UTF8(const char *refname) +{ + struct archive *a; + struct archive_entry *ae; + + /* + * Read LHA filename in en_US.UTF-8. + */ + if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { + skipping("en_US.UTF-8 locale not available on this system."); + return; + } + /* + * Create a read object only for a test that platform support + * a character-set conversion because we can read a character-set + * of filenames from the header of an lha archive file and so we + * want to test that it works well. + */ + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + skipping("This system cannot convert character-set" + " from CP932 to UTF-8."); + return; + } + if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-16")) { + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + skipping("This system cannot convert character-set" + " from UTF-16 to UTF-8."); + return; + } + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Note that usual Japanese filenames are tested in other cases */ +#if defined(__APPLE__) + /* NFD normalization */ + /* U:O:A:u:o:a: */ + #define UMLAUT_DIRNAME "\x55\xcc\x88\x4f\xcc\x88\x41\xcc\x88\x75\xcc\x88\x6f"\ + "\xcc\x88\x61\xcc\x88/" + /* a:o:u:A:O:U:.txt */ + #define UMLAUT_FNAME "\x61\xcc\x88\x6f\xcc\x88\x75\xcc\x88\x41\xcc\x88"\ + "\x4f\xcc\x88\x55\xcc\x88.txt" +#else + /* NFC normalization */ + /* U:O:A:u:o:a: */ + #define UMLAUT_DIRNAME "\xc3\x9c\xc3\x96\xc3\x84\xc3\xbc\xc3\xb6\xc3\xa4/" + /* a:o:u:A:O:U:.txt */ + #define UMLAUT_FNAME "\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c.txt" +#endif + +/* "Test" in Japanese Katakana */ +#define KATAKANA_FNAME "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt" +#define KATAKANA_DIRNAME "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88/" + + /* Verify regular file. U:O:A:u:o:a:/a:o:u:A:O:U:.txt */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString(UMLAUT_DIRNAME UMLAUT_FNAME, archive_entry_pathname(ae)); + assertEqualInt(12, archive_entry_size(ae)); + + /* Verify directory. U:O:A:u:o:a:/ */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString(UMLAUT_DIRNAME, archive_entry_pathname(ae)); + assertEqualInt(0, archive_entry_size(ae)); + + /* Verify regular file. U:O:A:u:o:a:/("Test" in Japanese).txt */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString(UMLAUT_DIRNAME KATAKANA_FNAME, + archive_entry_pathname(ae)); + assertEqualInt(25, archive_entry_size(ae)); + + /* Verify regular file. ("Test" in Japanese)/a:o:u:A:O:U:.txt */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString(KATAKANA_DIRNAME UMLAUT_FNAME, + archive_entry_pathname(ae)); + assertEqualInt(12, archive_entry_size(ae)); + + /* Verify directory. ("Test" in Japanese)/ */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString(KATAKANA_DIRNAME, archive_entry_pathname(ae)); + assertEqualInt(0, archive_entry_size(ae)); + + /* Verify regular file. a:o:u:A:O:U:.txt */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString(UMLAUT_FNAME, archive_entry_pathname(ae)); + assertEqualInt(12, archive_entry_size(ae)); + + /* End of archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); + assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a)); + + /* Close the archive. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_lha_filename_UTF16) +{ + /* A sample file was created with Unlha32.dll. */ + const char *refname = "test_read_format_lha_filename_utf16.lzh"; + extract_reference_file(refname); + + test_read_format_lha_filename_UTF16_UTF8(refname); +} + diff --git a/contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu b/contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu new file mode 100644 index 000000000..ca5da7a64 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu @@ -0,0 +1,19 @@ +begin 644 test_read_format_lha_filename_utf16.lzh +M@0`M;&@P+0P````,````L/5872`"IW%-!P!&I`,```T``5]?7U]?7RYT>'0* +M``)?7U]?7U__%P!$Y`#V`/P`Q`#6`-P`+@!T`'@`=``1`$7<`-8`Q`#\`/8` +MY`#__QL`078S9B"U0$H^DQ_F(+5 +M`2CZ3'^8@M4!!@``GW<'``!J`"UL:#`M&0```!D```!V)L1=(`*CNTT'`$:D +M`P``#0`!@V6#6(-G+G1X=`H``E]?7U]?7_\1`$7<`-8`Q`#\`/8`Y`#__QL` +M00IF#4J@E-4!L"5C?'65U0&P)6-\=975`08``$%^!P``5&5S="!I;B!*87!A +M;F5S92!+871A:V%N87L`+6QH,"T,````#````+#U6%T@`J=Q30<`1J0#```- +M``%?7U]?7U\N='AT"@`"@V6#6(-G_Q<`1.0`]@#\`,0`U@#<`"X`=`!X`'0` +M"P!%QC"Y,,@P__\;`$'D5O!-H)35`?4-F(*15=4!Y%;P3:"4U0$&``"A+0<` +M`,.DP[;#O,.$PY;#G%0`+6QH9"T``````````-3`PET@`@``30<`1J0#```# +M``$*``*#98-8@V?_!0!`$``;`$%%!\Y.H)35`3/_]%&@E-4!,__T4:"4U0$& +M``!>;@<``&8`+6QH,"T,````#````+#U6%T@`J=Q30<`1J0#```-``%?7U]? +M7U\N='AT%P!$Y`#V`/P`Q`#6`-P`+@!T`'@`=``;`$'D5O!-H)35`?4-F(*1 +@5=4!Y%;P3:"4U0$&``"M>`<``,.DP[;#O,.$PY;#G`#D +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5.c b/contrib/libarchive/libarchive/test/test_read_format_rar5.c index b4ef29e46..f91521e72 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_rar5.c +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5.c @@ -969,13 +969,12 @@ DEFINE_TEST(test_read_format_rar5_readtables_overflow) PROLOGUE("test_read_format_rar5_readtables_overflow.rar"); - assertA(0 == archive_read_next_header(a, &ae)); /* This archive is invalid. However, processing it shouldn't cause any * buffer overflow errors during reading rar5 tables. */ - assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); - /* This test only cares about not returning success here. */ - assertA(ARCHIVE_OK != archive_read_next_header(a, &ae)); + (void) archive_read_next_header(a, &ae); + (void) archive_read_data(a, buf, sizeof(buf)); + (void) archive_read_next_header(a, &ae); EPILOGUE(); } @@ -986,13 +985,12 @@ DEFINE_TEST(test_read_format_rar5_leftshift1) PROLOGUE("test_read_format_rar5_leftshift1.rar"); - assertA(0 == archive_read_next_header(a, &ae)); /* This archive is invalid. However, processing it shouldn't cause any * errors related to undefined operations when using -fsanitize. */ - assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); - /* This test only cares about not returning success here. */ - assertA(ARCHIVE_OK != archive_read_next_header(a, &ae)); + (void) archive_read_next_header(a, &ae); + (void) archive_read_data(a, buf, sizeof(buf)); + (void) archive_read_next_header(a, &ae); EPILOGUE(); } @@ -1003,14 +1001,12 @@ DEFINE_TEST(test_read_format_rar5_leftshift2) PROLOGUE("test_read_format_rar5_leftshift2.rar"); - assertA(0 == archive_read_next_header(a, &ae)); - /* This archive is invalid. However, processing it shouldn't cause any * errors related to undefined operations when using -fsanitize. */ - assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); - /* This test only cares about not returning success here. */ - assertA(ARCHIVE_OK != archive_read_next_header(a, &ae)); + (void) archive_read_next_header(a, &ae); + (void) archive_read_data(a, buf, sizeof(buf)); + (void) archive_read_next_header(a, &ae); EPILOGUE(); } @@ -1021,14 +1017,12 @@ DEFINE_TEST(test_read_format_rar5_truncated_huff) PROLOGUE("test_read_format_rar5_truncated_huff.rar"); - assertA(0 == archive_read_next_header(a, &ae)); - /* This archive is invalid. However, processing it shouldn't cause any * errors related to undefined operations when using -fsanitize. */ - assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); - /* This test only cares about not returning success here. */ - assertA(ARCHIVE_OK != archive_read_next_header(a, &ae)); + (void) archive_read_next_header(a, &ae); + (void) archive_read_data(a, buf, sizeof(buf)); + (void) archive_read_next_header(a, &ae); EPILOGUE(); } @@ -1058,14 +1052,12 @@ DEFINE_TEST(test_read_format_rar5_distance_overflow) PROLOGUE("test_read_format_rar5_distance_overflow.rar"); - assertA(0 == archive_read_next_header(a, &ae)); - /* This archive is invalid. However, processing it shouldn't cause any * errors related to variable overflows when using -fsanitize. */ - assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); - /* This test only cares about not returning success here. */ - assertA(ARCHIVE_OK != archive_read_next_header(a, &ae)); + (void) archive_read_next_header(a, &ae); + (void) archive_read_data(a, buf, sizeof(buf)); + (void) archive_read_next_header(a, &ae); EPILOGUE(); } @@ -1076,14 +1068,12 @@ DEFINE_TEST(test_read_format_rar5_nonempty_dir_stream) PROLOGUE("test_read_format_rar5_nonempty_dir_stream.rar"); - assertA(0 == archive_read_next_header(a, &ae)); - /* This archive is invalid. However, processing it shouldn't cause any * errors related to buffer overflows when using -fsanitize. */ - assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); - /* This test only cares about not returning success here. */ - assertA(ARCHIVE_OK != archive_read_next_header(a, &ae)); + (void) archive_read_next_header(a, &ae); + (void) archive_read_data(a, buf, sizeof(buf)); + (void) archive_read_next_header(a, &ae); EPILOGUE(); } @@ -1205,13 +1195,13 @@ DEFINE_TEST(test_read_format_rar5_different_window_size) * errors during processing. */ (void) archive_read_next_header(a, &ae); - while(0 != archive_read_data(a, buf, sizeof(buf))) {} + while(0 < archive_read_data(a, buf, sizeof(buf))) {} (void) archive_read_next_header(a, &ae); - while(0 != archive_read_data(a, buf, sizeof(buf))) {} + while(0 < archive_read_data(a, buf, sizeof(buf))) {} (void) archive_read_next_header(a, &ae); - while(0 != archive_read_data(a, buf, sizeof(buf))) {} + while(0 < archive_read_data(a, buf, sizeof(buf))) {} EPILOGUE(); } @@ -1226,7 +1216,58 @@ DEFINE_TEST(test_read_format_rar5_arm_filter_on_window_boundary) * errors during processing. */ (void) archive_read_next_header(a, &ae); - while(0 != archive_read_data(a, buf, sizeof(buf))) {} + while(0 < archive_read_data(a, buf, sizeof(buf))) {} + + EPILOGUE(); +} + +DEFINE_TEST(test_read_format_rar5_different_solid_window_size) +{ + char buf[4096]; + PROLOGUE("test_read_format_rar5_different_solid_window_size.rar"); + + /* Return codes of those calls are ignored, because this sample file + * is invalid. However, the unpacker shouldn't produce any SIGSEGV + * errors during processing. */ + + (void) archive_read_next_header(a, &ae); + while(0 < archive_read_data(a, buf, sizeof(buf))) {} + + (void) archive_read_next_header(a, &ae); + while(0 < archive_read_data(a, buf, sizeof(buf))) {} + + (void) archive_read_next_header(a, &ae); + while(0 < archive_read_data(a, buf, sizeof(buf))) {} + + EPILOGUE(); +} + +DEFINE_TEST(test_read_format_rar5_different_winsize_on_merge) +{ + char buf[4096]; + PROLOGUE("test_read_format_rar5_different_winsize_on_merge.rar"); + + /* Return codes of those calls are ignored, because this sample file + * is invalid. However, the unpacker shouldn't produce any SIGSEGV + * errors during processing. */ + + (void) archive_read_next_header(a, &ae); + while(0 < archive_read_data(a, buf, sizeof(buf))) {} + + EPILOGUE(); +} + +DEFINE_TEST(test_read_format_rar5_block_size_is_too_small) +{ + char buf[4096]; + PROLOGUE("test_read_format_rar5_block_size_is_too_small.rar"); + + /* This file is damaged, so those functions should return failure. + * Additionally, SIGSEGV shouldn't be raised during execution + * of those functions. */ + + assertA(archive_read_next_header(a, &ae) != ARCHIVE_OK); + assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); EPILOGUE(); } diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu new file mode 100644 index 000000000..5cad2194e --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu @@ -0,0 +1,8 @@ +begin 644 test_read_format_rar5_block_size_is_too_small.rar +M4F%R(1H'`0"-[P+2``+'(!P,("`@N`,!`B`@("`@("`@("`@("`@("#_("`@ +M("`@("`@("`@((:Q;2!4-'-^4B`!((WO`M(``O\@$/\@-R`@("`@("`@("`@ +M``X@("`@("`@____("`@("`@(/\@("`@("`@("`@("#_(+6U,2"UM;6UM[CU +M)B`@*(0G(`!.`#D\3R``(/__(,+_````-0#_($&%*/HE=C+N`"```"```"`D +J`)$#("#_("#__P`@__\@_R#_("`@("`@("#_("#__R`@(/__("#__R`" +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu new file mode 100644 index 000000000..b131e6f00 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu @@ -0,0 +1,73 @@ +begin 644 test_read_format_rar5_different_solid_window_size.rar +M4F%R(1H'`0"-[P+2``'#M#P\7P$'`0"-[P+2``7#````1H68F`#___\````` +M```0^OKZ^OJ%F)B8F)A)`)@"F-(%87)4`,.T/#Q?`0\"T@`"QP\`"7(A +MFC$!$AHCTBT``B@A4F%2(1H'&.D````!`(WO`M(`!<-%````1A?'#P`)\"T@`"QP\`"7(AFC$! +M$AHCTBT``B@A4F%2(1H'&.D````!`(WO`M(`!<-%````1A?'#P`)7!E/6P*+@HN"BYT+G0@='G^6_]P9\"T@`"TGX!M,-'4CQ2:7`)20`&`````````(WO`M(``0!R(8WO`M(``0!R +M(8WO`M(``0!R(8WO`M(`M`%?C>\"T@`"TGX!M,-'4CQ:!@!I`'`)20`````` +M`(WO`M(``0!R(8WO`M(``0!R(8WO`M(``0!R(8WO`M(`M`%?C>^NT@`"TGX! +MM%)A\"T@`"PP<<@`<`_O__T?___^@@JP#_Q00``B$<`0(`#@`` +M`0``_@C2(`$>____"```_?__$`#_W5A04)#_!&R&;;%DS,RWL0!)`(/__P#_ +M`/\`^?__\&3/)#)(L0!)`#J#+O_______REH%PHHV#!="0"N)$%SF_J;$___ +M_YP#%9,I````_________Q/_____________________________________ +M_RC_____`P````````#_____*/]!04%!0=U891/_9?]0/2[_______\I:!<* +M*-@P70D`KB1!\"T@`````````````` +` +end diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu new file mode 100644 index 000000000..85391fa4e --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu @@ -0,0 +1,16 @@ +begin 644 test_read_format_rar5_different_winsize_on_merge.rar.uu +M4F%R(1H'`0"-[P+2``+''QP,!`H``"0`N)$#`0(H$"<"``X`/3Q/`0"V```` +MQ@$````V`/^%02`H^B7&,NX``"F&AK%M-50O\"T@`"_[6U,1"U +MM;6UM[BU45)AXM5%287*U +MM;6UM;2UM0``//_____W______________\`!F$`C>\"TM(``](?________ +M`+3#6@0&D0,!`B@0)P(`#@`]/$\!`+8```#&`0```#8`_X5!("CZ)<8R[@`` +M*8:&L6TU5"]S?E(````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````type != END) { if (s->type == HOLE) { @@ -282,7 +282,7 @@ create_sparse_file(const char *path, const struct sparse *s) { char buff[1024]; int fd; - size_t total_size = 0; + uint64_t total_size = 0; const struct sparse *cur = s; memset(buff, ' ', sizeof(buff)); @@ -430,7 +430,7 @@ verify_sparse_file(struct archive *a, const char *path, assert(sparse->type == END); assertEqualInt(expected_offset, archive_entry_size(ae)); - failure(path); + failure("%s", path); assertEqualInt(holes_seen, expected_holes); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); @@ -466,13 +466,13 @@ verify_sparse_file2(struct archive *a, const char *path, /* Verify the number of holes only, not its offset nor its * length because those alignments are deeply dependence on * its filesystem. */ - failure(path); + failure("%s", path); assertEqualInt(blocks, archive_entry_sparse_count(ae)); archive_entry_free(ae); } static void -test_sparse_whole_file_data() +test_sparse_whole_file_data(void) { struct archive_entry *ae; int64_t offset; @@ -555,6 +555,12 @@ DEFINE_TEST(test_sparse_basic) { HOLE, 1 }, { DATA, 10240 }, { END, 0 } }; + const struct sparse sparse_file4[] = { + { DATA, 4096 }, { HOLE, 0xc0000000 }, + /* This hole overflows the offset if stored in 32 bits. */ + { DATA, 4096 }, { HOLE, 0x50000000 }, + { END, 0 } + }; /* * Test for the case that sparse data indicates just the whole file @@ -596,6 +602,7 @@ DEFINE_TEST(test_sparse_basic) verify_sparse_file(a, "file2", sparse_file2, 20); /* Encoded non sparse; expect a data block but no sparse entries. */ verify_sparse_file(a, "file3", sparse_file3, 0); + verify_sparse_file(a, "file4", sparse_file4, 2); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); diff --git a/contrib/libarchive/libarchive/test/test_write_disk.c b/contrib/libarchive/libarchive/test/test_write_disk.c index d7d439474..00b9e45af 100644 --- a/contrib/libarchive/libarchive/test/test_write_disk.c +++ b/contrib/libarchive/libarchive/test/test_write_disk.c @@ -186,7 +186,7 @@ static void create_reg_file4(struct archive_entry *ae, const char *msg) #if !defined(_WIN32) || defined(__CYGWIN__) assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK)); #endif - failure(msg); + failure("%s", msg); assertEqualInt(st.st_size, sizeof(data)); } diff --git a/contrib/libarchive/libarchive/test/test_write_format_cpio_empty.c b/contrib/libarchive/libarchive/test/test_write_format_cpio_empty.c index ee174536d..4b5a84c36 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_cpio_empty.c +++ b/contrib/libarchive/libarchive/test/test_write_format_cpio_empty.c @@ -64,7 +64,7 @@ DEFINE_TEST(test_write_format_cpio_empty) assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - failure("Empty cpio archive should be exactly 87 bytes, was %d.", used); + failure("Empty cpio archive should be exactly 87 bytes, was %zu.", used); assert(used == 87); failure("Empty cpio archive is incorrectly formatted."); assertEqualMem(buff, ref, 87); diff --git a/contrib/libarchive/libarchive/test/test_write_format_pax.c b/contrib/libarchive/libarchive/test/test_write_format_pax.c index 41a423a96..4538aac82 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_pax.c +++ b/contrib/libarchive/libarchive/test/test_write_format_pax.c @@ -104,6 +104,28 @@ DEFINE_TEST(test_write_format_pax) assertEqualIntA(a, 1024, archive_write_data(a, nulls, 1024)); assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); + /* + * "file4" is similar to "file1" but has a large uid, large gid, + * uname and gname are longer than 32 characters + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 20); + archive_entry_set_birthtime(ae, 3, 30); + archive_entry_set_ctime(ae, 4, 40); + archive_entry_set_mtime(ae, 5, 50); + archive_entry_copy_pathname(ae, "file4"); + archive_entry_set_mode(ae, S_IFREG | 0755); + archive_entry_set_size(ae, 8); + archive_entry_copy_uname(ae, + "long-uname123456789012345678901234567890"); + archive_entry_copy_gname(ae, + "long-gname123456789012345678901234567890"); + archive_entry_set_uid(ae, 536870912); + archive_entry_set_gid(ae, 536870913); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); + /* * XXX TODO XXX Archive directory, other file types. * Archive extended attributes, ACLs, other metadata. @@ -198,6 +220,30 @@ DEFINE_TEST(test_write_format_pax) assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); assertEqualMem(buff2, "12345678", 8); + /* + * Read "file4 + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(2, archive_entry_atime(ae)); + assertEqualInt(20, archive_entry_atime_nsec(ae)); + assertEqualInt(3, archive_entry_birthtime(ae)); + assertEqualInt(30, archive_entry_birthtime_nsec(ae)); + assertEqualInt(4, archive_entry_ctime(ae)); + assertEqualInt(40, archive_entry_ctime_nsec(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualInt(50, archive_entry_mtime_nsec(ae)); + assertEqualString("file4", archive_entry_pathname(ae)); + assertEqualString("long-uname123456789012345678901234567890", + archive_entry_uname(ae)); + assertEqualString("long-gname123456789012345678901234567890", + archive_entry_gname(ae)); + assertEqualInt(536870912, archive_entry_uid(ae)); + assertEqualInt(536870913, archive_entry_gid(ae)); + assert((S_IFREG | 0755) == archive_entry_mode(ae)); + assertEqualInt(8, archive_entry_size(ae)); + assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); + assertEqualMem(buff2, "12345678", 8); + /* * Verify the end of the archive. */ diff --git a/contrib/libarchive/libarchive/test/test_write_format_shar_empty.c b/contrib/libarchive/libarchive/test/test_write_format_shar_empty.c index ccd971ce5..3ca6cceed 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_shar_empty.c +++ b/contrib/libarchive/libarchive/test/test_write_format_shar_empty.c @@ -49,6 +49,6 @@ DEFINE_TEST(test_write_format_shar_empty) assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - failure("Empty shar archive should be exactly 0 bytes, was %d.", used); + failure("Empty shar archive should be exactly 0 bytes, was %zu.", used); assert(used == 0); } diff --git a/contrib/libarchive/libarchive/test/test_write_format_tar.c b/contrib/libarchive/libarchive/test/test_write_format_tar.c index 00ae51781..1d607bdb0 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_tar.c +++ b/contrib/libarchive/libarchive/test/test_write_format_tar.c @@ -81,7 +81,7 @@ DEFINE_TEST(test_write_format_tar) /* This calculation gives "the smallest multiple of * the block size that is at least 2048 bytes". */ - failure("blocksize=%d", blocksize); + failure("blocksize=%zu", blocksize); assertEqualInt(((2048 - 1)/blocksize+1)*blocksize, used); /* diff --git a/contrib/libarchive/libarchive/test/test_write_format_tar_sparse.c b/contrib/libarchive/libarchive/test/test_write_format_tar_sparse.c index cc725a9a7..54ac00988 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_tar_sparse.c +++ b/contrib/libarchive/libarchive/test/test_write_format_tar_sparse.c @@ -94,7 +94,7 @@ test_1(void) /* This calculation gives "the smallest multiple of * the block size that is at least 11264 bytes". */ - failure("blocksize=%d", blocksize); + failure("blocksize=%zu", blocksize); assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used); /* @@ -229,7 +229,7 @@ test_2(void) /* This calculation gives "the smallest multiple of * the block size that is at least 11264 bytes". */ - failure("blocksize=%d", blocksize); + failure("blocksize=%zu", blocksize); assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used); /* diff --git a/contrib/libarchive/libarchive/test/test_write_format_xar.c b/contrib/libarchive/libarchive/test/test_write_format_xar.c index 7cfdbcf4d..02fd2c0e3 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_xar.c +++ b/contrib/libarchive/libarchive/test/test_write_format_xar.c @@ -279,6 +279,7 @@ DEFINE_TEST(test_write_format_xar) /* Disable TOC checksum. */ test_xar("!toc-checksum"); + test_xar("toc-checksum=none"); /* Specify TOC checksum type to sha1. */ test_xar("toc-checksum=sha1"); /* Specify TOC checksum type to md5. */ @@ -286,6 +287,7 @@ DEFINE_TEST(test_write_format_xar) /* Disable file checksum. */ test_xar("!checksum"); + test_xar("checksum=none"); /* Specify file checksum type to sha1. */ test_xar("checksum=sha1"); /* Specify file checksum type to md5. */ @@ -293,6 +295,7 @@ DEFINE_TEST(test_write_format_xar) /* Disable compression. */ test_xar("!compression"); + test_xar("compression=none"); /* Specify compression type to gzip. */ test_xar("compression=gzip"); test_xar("compression=gzip,compression-level=1"); diff --git a/contrib/libarchive/libarchive/test/test_write_format_zip_file.c b/contrib/libarchive/libarchive/test/test_write_format_zip_file.c index e27b23b4b..9ac0126e5 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_zip_file.c +++ b/contrib/libarchive/libarchive/test/test_write_format_zip_file.c @@ -84,7 +84,7 @@ DEFINE_TEST(test_write_format_zip_file) unsigned char *central_header, *local_header, *eocd, *eocd_record; unsigned char *extension_start, *extension_end; char file_data[] = {'1', '2', '3', '4', '5', '6', '7', '8'}; - char *file_name = "file"; + const char *file_name = "file"; #ifndef HAVE_ZLIB_H zip_version = 10; diff --git a/contrib/libarchive/libarchive/test/test_write_format_zip_file_zip64.c b/contrib/libarchive/libarchive/test/test_write_format_zip_file_zip64.c index 7bba50d29..4e6344fb5 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_zip_file_zip64.c +++ b/contrib/libarchive/libarchive/test/test_write_format_zip_file_zip64.c @@ -86,7 +86,7 @@ DEFINE_TEST(test_write_format_zip_file_zip64) unsigned char *central_header, *local_header, *eocd, *eocd_record; unsigned char *extension_start, *extension_end; char file_data[] = {'1', '2', '3', '4', '5', '6', '7', '8'}; - char *file_name = "file"; + const char *file_name = "file"; #ifndef HAVE_ZLIB_H zip_compression = 0; diff --git a/contrib/libarchive/libarchive_fe/err.h b/contrib/libarchive/libarchive_fe/err.h index 7b6a3ec86..2f84c2fe6 100644 --- a/contrib/libarchive/libarchive_fe/err.h +++ b/contrib/libarchive/libarchive_fe/err.h @@ -37,9 +37,14 @@ #if defined(__GNUC__) && (__GNUC__ > 2 || \ (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) -#define __LA_PRINTFLIKE(f,a) __attribute__((__format__(__printf__, f, a))) +# ifdef __MINGW_PRINTF_FORMAT +# define __LA_PRINTF_FORMAT __MINGW_PRINTF_FORMAT +# else +# define __LA_PRINTF_FORMAT __printf__ +# endif +# define __LA_PRINTFLIKE(f,a) __attribute__((__format__(__LA_PRINTF_FORMAT, f, a))) #else -#define __LA_PRINTFLIKE(f,a) +# define __LA_PRINTFLIKE(f,a) #endif void lafe_warnc(int code, const char *fmt, ...) __LA_PRINTFLIKE(2, 3); diff --git a/contrib/libarchive/tar/bsdtar.1 b/contrib/libarchive/tar/bsdtar.1 index 04b56553c..f15742349 100644 --- a/contrib/libarchive/tar/bsdtar.1 +++ b/contrib/libarchive/tar/bsdtar.1 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 3, 2019 +.Dd January 31, 2020 .Dt TAR 1 .Os .Sh NAME @@ -209,15 +209,16 @@ specified on the command line. .It Fl Fl exclude-vcs Do not process files or directories internally used by the version control systems +.Sq Arch , +.Sq Bazaar , .Sq CVS , +.Sq Darcs , +.Sq Mercurial , .Sq RCS , .Sq SCCS , -.Sq SVN , -.Sq Arch , -.Sq Bazaar , -.Sq Mercurial +.Sq SVN and -.Sq Darcs . +.Sq git . .It Fl Fl fflags (c, r, u, x modes only) Archive or extract platform-specific file attributes or file flags. @@ -469,6 +470,13 @@ This is the reverse of and the default behavior if .Nm is run as non-root in x mode. +.It Fl Fl no-safe-writes +(x mode only) +Do not create temporary files and use +.Xr rename 2 +to replace the original ones. +This is the reverse of +.Fl Fl safe-writes . .It Fl Fl no-same-owner (x mode only) Do not extract owner and group IDs. @@ -567,7 +575,14 @@ As above, but the corresponding key and value will be provided only to modules whose name matches .Ar module . .El -The currently supported modules and keys are: +.Pp +The complete list of supported modules and keys +for create and append modes is in +.Xr archive_write_set_options 3 +and for extract and list modes in +.Xr archive_read_set_options 3 . +.Pp +Examples of supported options: .Bl -tag -compact -width indent .It Cm iso9660:joliet Support Joliet extensions. @@ -756,6 +771,26 @@ The default is .Ar hrs which applies substitutions to all names. In particular, it is never necessary to specify h, r, or s. +.It Fl Fl safe-writes +(x mode only) +Extract files atomically. +By default +.Nm +unlinks the original file with the same name as the extracted file (if it +exists), and then creates it immediately under the same name and writes to +it. +For a short period of time, applications trying to access the file might +not find it, or see incomplete results. +If +.Fl Fl safe-writes +is enabled, +.Nm +first creates a unique temporary file, then writes the new contents to +the temporary file, and finally renames the temporary file to its final +name atomically using +.Xr rename 2 . +This guarantees that an application accessing the file, will either see +the old contents or the new contents at all times. .It Fl Fl same-owner (x mode only) Extract owner and group IDs. diff --git a/contrib/libarchive/tar/bsdtar.c b/contrib/libarchive/tar/bsdtar.c index 20a121a4b..d421fa033 100644 --- a/contrib/libarchive/tar/bsdtar.c +++ b/contrib/libarchive/tar/bsdtar.c @@ -542,6 +542,9 @@ main(int argc, char **argv) bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA; bsdtar->flags |= OPTFLAG_NO_MAC_METADATA; break; + case OPTION_NO_SAFE_WRITES: + bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_SAFE_WRITES; + break; case OPTION_NO_SAME_OWNER: /* GNU tar */ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; break; @@ -658,6 +661,9 @@ main(int argc, char **argv) usage(); #endif break; + case OPTION_SAFE_WRITES: + bsdtar->extract_flags |= ARCHIVE_EXTRACT_SAFE_WRITES; + break; case OPTION_SAME_OWNER: /* GNU tar */ bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER; break; diff --git a/contrib/libarchive/tar/bsdtar.h b/contrib/libarchive/tar/bsdtar.h index 82f8462d8..2d61e256c 100644 --- a/contrib/libarchive/tar/bsdtar.h +++ b/contrib/libarchive/tar/bsdtar.h @@ -25,6 +25,9 @@ * $FreeBSD$ */ +#ifndef BSDTAR_H_INCLUDED +#define BSDTAR_H_INCLUDED + #include "bsdtar_platform.h" #include @@ -161,6 +164,7 @@ enum { OPTION_NO_ACLS, OPTION_NO_FFLAGS, OPTION_NO_MAC_METADATA, + OPTION_NO_SAFE_WRITES, OPTION_NO_SAME_OWNER, OPTION_NO_SAME_PERMISSIONS, OPTION_NO_XATTRS, @@ -174,6 +178,7 @@ enum { OPTION_OPTIONS, OPTION_PASSPHRASE, OPTION_POSIX, + OPTION_SAFE_WRITES, OPTION_SAME_OWNER, OPTION_STRIP_COMPONENTS, OPTION_TOTALS, @@ -224,3 +229,5 @@ const char * passphrase_callback(struct archive *, void *); void passphrase_free(char *); void list_item_verbose(struct bsdtar *, FILE *, struct archive_entry *); + +#endif diff --git a/contrib/libarchive/tar/cmdline.c b/contrib/libarchive/tar/cmdline.c index 21558e12d..b80937ffc 100644 --- a/contrib/libarchive/tar/cmdline.c +++ b/contrib/libarchive/tar/cmdline.c @@ -123,6 +123,7 @@ static const struct bsdtar_option { { "no-fflags", 0, OPTION_NO_FFLAGS }, { "no-mac-metadata", 0, OPTION_NO_MAC_METADATA }, { "no-recursion", 0, 'n' }, + { "no-safe-writes", 0, OPTION_NO_SAFE_WRITES }, { "no-same-owner", 0, OPTION_NO_SAME_OWNER }, { "no-same-permissions", 0, OPTION_NO_SAME_PERMISSIONS }, { "no-xattr", 0, OPTION_NO_XATTRS }, @@ -144,6 +145,7 @@ static const struct bsdtar_option { { "posix", 0, OPTION_POSIX }, { "preserve-permissions", 0, 'p' }, { "read-full-blocks", 0, 'B' }, + { "safe-writes", 0, OPTION_SAFE_WRITES }, { "same-owner", 0, OPTION_SAME_OWNER }, { "same-permissions", 0, 'p' }, { "strip-components", 1, OPTION_STRIP_COMPONENTS }, diff --git a/contrib/libarchive/tar/test/test_basic.c b/contrib/libarchive/tar/test/test_basic.c index c483b673f..16c0eafcb 100644 --- a/contrib/libarchive/tar/test/test_basic.c +++ b/contrib/libarchive/tar/test/test_basic.c @@ -96,7 +96,7 @@ run_tar(const char *target, const char *pack_options, /* Use the tar program to create an archive. */ r = systemf("%s cf - %s %s >%s/archive 2>%s/pack.err", testprog, pack_options, flist, target, target); - failure("Error invoking %s cf -", testprog, pack_options); + failure("Error invoking %s cf -%s", testprog, pack_options); assertEqualInt(r, 0); assertChdir(target); diff --git a/contrib/libarchive/tar/test/test_copy.c b/contrib/libarchive/tar/test/test_copy.c index 43ea24faf..5d0c68718 100644 --- a/contrib/libarchive/tar/test/test_copy.c +++ b/contrib/libarchive/tar/test/test_copy.c @@ -256,13 +256,13 @@ verify_tree(size_t limit) continue; switch(dp[0]) { case 'l': case 'm': case 'd': - failure("strlen(p)=%d", strlen(p)); + failure("strlen(p)=%zu", strlen(p)); assert(strlen(p) < limit); assertEqualString(p, filenames[strlen(p)]); break; case 'f': case 's': - failure("strlen(p)=%d", strlen(p)); + failure("strlen(p)=%zu", strlen(p)); assert(strlen(p) < limit + 1); assertEqualString(p, filenames[strlen(p)]); diff --git a/contrib/libarchive/tar/test/test_option_C_upper.c b/contrib/libarchive/tar/test/test_option_C_upper.c index dae985446..538890f58 100644 --- a/contrib/libarchive/tar/test/test_option_C_upper.c +++ b/contrib/libarchive/tar/test/test_option_C_upper.c @@ -117,7 +117,7 @@ DEFINE_TEST(test_option_C_upper) assertMakeDir("test6", 0755); assertChdir("test6"); r = systemf("%s -cf archive.tar -C XXX -C ../d1 file1 2>write.err", - testprog, testworkdir); + testprog); assert(r != 0); assertNonEmptyFile("write.err"); assertEqualInt(0, diff --git a/contrib/libarchive/tar/test/test_option_s.c b/contrib/libarchive/tar/test/test_option_s.c index d9cfd9e53..ceed9fb1f 100644 --- a/contrib/libarchive/tar/test/test_option_s.c +++ b/contrib/libarchive/tar/test/test_option_s.c @@ -92,10 +92,8 @@ DEFINE_TEST(test_option_s) * Test 5: Name-switching substitutions when extracting archive. */ assertMakeDir("test5", 0755); - systemf("%s -cf test5.tar in/d1/foo in/d1/bar", - testprog, testprog); - systemf("%s -xf test5.tar -s /foo/bar/ -s }bar}foo} -C test5", - testprog, testprog); + systemf("%s -cf test5.tar in/d1/foo in/d1/bar", testprog); + systemf("%s -xf test5.tar -s /foo/bar/ -s }bar}foo} -C test5", testprog); assertFileContents("foo", 3, "test5/in/d1/bar"); assertFileContents("bar", 3, "test5/in/d1/foo"); diff --git a/contrib/libarchive/tar/test/test_option_safe_writes.c b/contrib/libarchive/tar/test/test_option_safe_writes.c new file mode 100644 index 000000000..8edf5c69f --- /dev/null +++ b/contrib/libarchive/tar/test/test_option_safe_writes.c @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 2020 Martin Matuska + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +DEFINE_TEST(test_option_safe_writes) +{ + /* Create files */ + assertMakeDir("in", 0755); + assertEqualInt(0, chdir("in")); + assertMakeFile("f", 0644, "a"); + assertMakeFile("fh", 0644, "b"); + assertMakeFile("d", 0644, "c"); + assertMakeFile("fs", 0644, "d"); + assertMakeFile("ds", 0644, "e"); + assertEqualInt(0, chdir("..")); + + /* Tar files up */ + assertEqualInt(0, + systemf("%s -c -C in -f t.tar f fh d fs ds " + ">pack.out 2>pack.err", testprog)); + + /* Verify that nothing went to stdout or stderr. */ + assertEmptyFile("pack.err"); + assertEmptyFile("pack.out"); + + /* Create various objects */ + assertMakeDir("out", 0755); + assertEqualInt(0, chdir("out")); + assertMakeFile("f", 0644, "a"); + assertMakeHardlink("fh", "f"); + assertMakeDir("d", 0755); + if (canSymlink()) { + assertMakeSymlink("fs", "f", 0); + assertMakeSymlink("ds", "d", 1); + } + assertEqualInt(0, chdir("..")); + + /* Extract created archive withe safe writes */ + assertEqualInt(0, + systemf("%s -x -C out --safe-writes -f t.tar " + ">unpack.out 2>unpack.err", testprog)); + + /* Verify that nothing went to stdout or stderr. */ + assertEmptyFile("unpack.err"); + assertEmptyFile("unpack.out"); + + /* Verify that files were overwritten properly */ + assertEqualInt(0, chdir("out")); + assertTextFileContents("a","f"); + assertTextFileContents("b","fh"); + assertTextFileContents("c","d"); + assertTextFileContents("d","fs"); + assertTextFileContents("e","ds"); +} diff --git a/contrib/libarchive/tar/util.c b/contrib/libarchive/tar/util.c index 7b52e4081..9d59e1a65 100644 --- a/contrib/libarchive/tar/util.c +++ b/contrib/libarchive/tar/util.c @@ -666,6 +666,14 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry) const char *fmt; time_t tim; static time_t now; + struct tm *ltime; +#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) + struct tm tmbuf; +#endif +#if defined(HAVE__LOCALTIME64_S) + errno_t terr; + __time64_t tmptime; +#endif /* * We avoid collecting the entire list in memory at once by @@ -737,7 +745,19 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry) fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y"; else fmt = bsdtar->day_first ? DAY_FMT " %b %H:%M" : "%b " DAY_FMT " %H:%M"; - strftime(tmp, sizeof(tmp), fmt, localtime(&tim)); +#if defined(HAVE_LOCALTIME_R) + ltime = localtime_r(&tim, &tmbuf); +#elif defined(HAVE__LOCALTIME64_S) + tmptime = tim; + terr = _localtime64_s(&tmbuf, &tmptime); + if (terr) + ltime = NULL; + else + ltime = &tmbuf; +#else + ltime = localtime(&tim); +#endif + strftime(tmp, sizeof(tmp), fmt, ltime); fprintf(out, " %s ", tmp); safe_fprintf(out, "%s", archive_entry_pathname(entry)); diff --git a/contrib/libarchive/test_utils/test_common.h b/contrib/libarchive/test_utils/test_common.h index 7538d8cb7..80d54f0a4 100644 --- a/contrib/libarchive/test_utils/test_common.h +++ b/contrib/libarchive/test_utils/test_common.h @@ -38,6 +38,9 @@ #elif defined(__FreeBSD__) /* Building as part of FreeBSD system requires a pre-built config.h. */ #include "config_freebsd.h" +#elif defined(__NetBSD__) +/* Building as part of NetBSD system requires a pre-built config.h. */ +#include "config_netbsd.h" #elif defined(_WIN32) && !defined(__CYGWIN__) /* Win32 can't run the 'configure' script. */ #include "config_windows.h" @@ -112,6 +115,19 @@ #pragma warn -8068 /* Constant out of range in comparison. */ #endif + +#if defined(__GNUC__) && (__GNUC__ > 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) +# ifdef __MINGW_PRINTF_FORMAT +# define __LA_PRINTF_FORMAT __MINGW_PRINTF_FORMAT +# else +# define __LA_PRINTF_FORMAT __printf__ +# endif +# define __LA_PRINTFLIKE(f,a) __attribute__((__format__(__LA_PRINTF_FORMAT, f, a))) +#else +# define __LA_PRINTFLIKE(f,a) +#endif + /* Haiku OS and QNX */ #if defined(__HAIKU__) || defined(__QNXNTO__) /* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */ @@ -132,6 +148,10 @@ #define O_BINARY 0 #endif +#ifndef __LIBARCHIVE_TEST_COMMON +#define __LIBARCHIVE_TEST_COMMON +#endif + #include "archive_platform_acl.h" #define ARCHIVE_TEST_ACL_TYPE_POSIX1E 1 #define ARCHIVE_TEST_ACL_TYPE_NFS4 2 @@ -259,7 +279,7 @@ skipping_setup(__FILE__, __LINE__);test_skipping /* Function declarations. These are defined in test_utility.c. */ -void failure(const char *fmt, ...); +void failure(const char *fmt, ...) __LA_PRINTFLIKE(1, 2); int assertion_assert(const char *, int, int, const char *, void *); int assertion_chdir(const char *, int, const char *); int assertion_compare_fflags(const char *, int, const char *, const char *, @@ -302,10 +322,10 @@ int assertion_utimes(const char *, int, const char *, long, long, long, long ); int assertion_version(const char*, int, const char *, const char *); void skipping_setup(const char *, int); -void test_skipping(const char *fmt, ...); +void test_skipping(const char *fmt, ...) __LA_PRINTFLIKE(1, 2); /* Like sprintf, then system() */ -int systemf(const char * fmt, ...); +int systemf(const char *fmt, ...) __LA_PRINTFLIKE(1, 2); /* Delay until time() returns a value after this. */ void sleepUntilAfter(time_t); @@ -368,7 +388,7 @@ void *sunacl_get(int cmd, int *aclcnt, int fd, const char *path); /* Suck file into string allocated via malloc(). Call free() when done. */ /* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */ -char *slurpfile(size_t *, const char *fmt, ...); +char *slurpfile(size_t *, const char *fmt, ...) __LA_PRINTFLIKE(2, 3); /* Dump block of bytes to a file. */ void dumpfile(const char *filename, void *, size_t); diff --git a/contrib/libarchive/test_utils/test_main.c b/contrib/libarchive/test_utils/test_main.c index 1b9af9a9c..7b8aa70fa 100644 --- a/contrib/libarchive/test_utils/test_main.c +++ b/contrib/libarchive/test_utils/test_main.c @@ -388,7 +388,7 @@ static const char *refdir; */ static int log_console = 0; static FILE *logfile; -static void +static void __LA_PRINTFLIKE(1, 0) vlogprintf(const char *fmt, va_list ap) { #ifdef va_copy @@ -406,7 +406,7 @@ vlogprintf(const char *fmt, va_list ap) #endif } -static void +static void __LA_PRINTFLIKE(1, 2) logprintf(const char *fmt, ...) { va_list ap; @@ -478,7 +478,7 @@ static struct line { const char *failed_filename; /* Count this failure, setup up log destination and handle initial report. */ -static void +static void __LA_PRINTFLIKE(3, 4) failure_start(const char *filename, int line, const char *fmt, ...) { va_list ap; @@ -751,7 +751,7 @@ static void strdump(const char *e, const char *p, int ewidth, int utf8) logprintf("]"); logprintf(" (count %d", cnt); if (n < 0) { - logprintf(",unknown %d bytes", len); + logprintf(",unknown %zu bytes", len); } logprintf(")"); @@ -1167,7 +1167,7 @@ assertion_text_file_contents(const char *filename, int line, const char *buff, c logprintf(" file=\"%s\"\n", fn); if (n > 0) { hexdump(contents, buff, n, 0); - logprintf(" expected\n", fn); + logprintf(" expected\n"); hexdump(buff, contents, s, 0); } else { logprintf(" File empty, contents should be:\n"); @@ -1497,7 +1497,7 @@ assertion_file_time(const char *file, int line, } } else if (filet != t || filet_nsec != nsec) { failure_start(file, line, - "File %s has %ctime %lld.%09lld, expected %lld.%09lld", + "File %s has %ctime %lld.%09lld, expected %ld.%09ld", pathname, type, filet, filet_nsec, t, nsec); failure_finish(NULL); return (0); @@ -1593,8 +1593,8 @@ assertion_file_nlinks(const char *file, int line, r = my_GetFileInformationByName(pathname, &bhfi); if (r != 0 && bhfi.nNumberOfLinks == (DWORD)nlinks) return (1); - failure_start(file, line, "File %s has %d links, expected %d", - pathname, bhfi.nNumberOfLinks, nlinks); + failure_start(file, line, "File %s has %jd links, expected %d", + pathname, (intmax_t)bhfi.nNumberOfLinks, nlinks); failure_finish(NULL); return (0); #else @@ -1605,8 +1605,8 @@ assertion_file_nlinks(const char *file, int line, r = lstat(pathname, &st); if (r == 0 && (int)st.st_nlink == nlinks) return (1); - failure_start(file, line, "File %s has %d links, expected %d", - pathname, st.st_nlink, nlinks); + failure_start(file, line, "File %s has %jd links, expected %d", + pathname, (intmax_t)st.st_nlink, nlinks); failure_finish(NULL); return (0); #endif @@ -1863,7 +1863,7 @@ is_symlink(const char *file, int line, return (0); if (contents == NULL) return (1); - linklen = readlink(pathname, buff, sizeof(buff)); + linklen = readlink(pathname, buff, sizeof(buff) - 1); if (linklen < 0) { failure_start(file, line, "Can't read symlink %s", pathname); failure_finish(NULL); @@ -2480,7 +2480,7 @@ canBzip2(void) static int tested = 0, value = 0; if (!tested) { tested = 1; - if (systemf("bzip2 -d -V %s", redirectArgs) == 0) + if (systemf("bzip2 --help %s", redirectArgs) == 0) value = 1; } return (value); @@ -2510,7 +2510,7 @@ canGzip(void) static int tested = 0, value = 0; if (!tested) { tested = 1; - if (systemf("gzip -V %s", redirectArgs) == 0) + if (systemf("gzip --help %s", redirectArgs) == 0) value = 1; } return (value); @@ -2552,7 +2552,7 @@ canLz4(void) static int tested = 0, value = 0; if (!tested) { tested = 1; - if (systemf("lz4 -V %s", redirectArgs) == 0) + if (systemf("lz4 --help %s", redirectArgs) == 0) value = 1; } return (value); @@ -2567,7 +2567,7 @@ canZstd(void) static int tested = 0, value = 0; if (!tested) { tested = 1; - if (systemf("zstd -V %s", redirectArgs) == 0) + if (systemf("zstd --help %s", redirectArgs) == 0) value = 1; } return (value); @@ -2582,7 +2582,7 @@ canLzip(void) static int tested = 0, value = 0; if (!tested) { tested = 1; - if (systemf("lzip -V %s", redirectArgs) == 0) + if (systemf("lzip --help %s", redirectArgs) == 0) value = 1; } return (value); @@ -2597,7 +2597,7 @@ canLzma(void) static int tested = 0, value = 0; if (!tested) { tested = 1; - if (systemf("lzma -V %s", redirectArgs) == 0) + if (systemf("lzma %s", redirectArgs) == 0) value = 1; } return (value); @@ -2612,7 +2612,7 @@ canLzop(void) static int tested = 0, value = 0; if (!tested) { tested = 1; - if (systemf("lzop -V %s", redirectArgs) == 0) + if (systemf("lzop --help %s", redirectArgs) == 0) value = 1; } return (value); @@ -2627,7 +2627,7 @@ canXz(void) static int tested = 0, value = 0; if (!tested) { tested = 1; - if (systemf("xz -V %s", redirectArgs) == 0) + if (systemf("xz --help %s", redirectArgs) == 0) value = 1; } return (value); @@ -3271,7 +3271,7 @@ assertion_entry_set_acls(const char *file, int line, struct archive_entry *ae, acls[i].qual, acls[i].name); if (r != 0) { ret = 1; - failure_start(file, line, "type=%#010x, ", + failure_start(file, line, "type=%#010x, " "permset=%#010x, tag=%d, qual=%d name=%s", acls[i].type, acls[i].permset, acls[i].tag, acls[i].qual, acls[i].name); @@ -3499,9 +3499,9 @@ static int test_run(int i, const char *tmpdir) { #ifdef PATH_MAX - char workdir[PATH_MAX]; + char workdir[PATH_MAX * 2]; #else - char workdir[1024]; + char workdir[1024 * 2]; #endif char logfilename[64]; int failures_before = failures; diff --git a/lib/libarchive/tests/Makefile b/lib/libarchive/tests/Makefile index 8c4a79053..bbbb31c6e 100644 --- a/lib/libarchive/tests/Makefile +++ b/lib/libarchive/tests/Makefile @@ -96,6 +96,7 @@ TESTS_SRCS= \ test_open_file.c \ test_open_filename.c \ test_pax_filename_encoding.c \ + test_pax_xattr_header.c \ test_read_data_large.c \ test_read_disk.c \ test_read_disk_directory_traversals.c \ @@ -115,6 +116,7 @@ TESTS_SRCS= \ test_read_format_7zip_encryption_header.c \ test_read_format_7zip_encryption_partially.c \ test_read_format_7zip_malformed.c \ + test_read_format_7zip_packinfo_digests.c \ test_read_format_ar.c \ test_read_format_cab.c \ test_read_format_cab_filename.c \ @@ -155,6 +157,7 @@ TESTS_SRCS= \ test_read_format_lha.c \ test_read_format_lha_bugfix_0.c \ test_read_format_lha_filename.c \ + test_read_format_lha_filename_utf16.c \ test_read_format_mtree.c \ test_read_format_mtree_crash747.c \ test_read_format_pax_bz2.c \ @@ -384,6 +387,9 @@ FILES+= test_fuzz.cab.uu FILES+= test_fuzz.lzh.uu FILES+= test_fuzz_1.iso.Z.uu FILES+= test_pax_filename_encoding.tar.uu +FILES+= test_pax_xattr_header_all.tar.uu +FILES+= test_pax_xattr_header_libarchive.tar.uu +FILES+= test_pax_xattr_header_schily.tar.uu FILES+= test_rar_multivolume_multiple_files.part1.rar.uu FILES+= test_rar_multivolume_multiple_files.part2.rar.uu FILES+= test_rar_multivolume_multiple_files.part3.rar.uu @@ -427,6 +433,8 @@ FILES+= test_read_format_7zip_copy_2.7z.uu FILES+= test_read_format_7zip_deflate.7z.uu FILES+= test_read_format_7zip_delta_lzma1.7z.uu FILES+= test_read_format_7zip_delta_lzma2.7z.uu +FILES+= test_read_format_7zip_delta4_lzma1.7z.uu +FILES+= test_read_format_7zip_delta4_lzma2.7z.uu FILES+= test_read_format_7zip_empty_archive.7z.uu FILES+= test_read_format_7zip_empty_file.7z.uu FILES+= test_read_format_7zip_encryption.7z.uu @@ -438,6 +446,7 @@ FILES+= test_read_format_7zip_lzma1_lzma2.7z.uu FILES+= test_read_format_7zip_lzma2.7z.uu FILES+= test_read_format_7zip_malformed.7z.uu FILES+= test_read_format_7zip_malformed2.7z.uu +FILES+= test_read_format_7zip_packinfo_digests.7z.uu FILES+= test_read_format_7zip_ppmd.7z.uu FILES+= test_read_format_7zip_symbolic_name.7z.uu FILES+= test_read_format_ar.ar.uu @@ -479,6 +488,7 @@ FILES+= test_read_format_iso_xorriso.iso.Z.uu FILES+= test_read_format_iso_zisofs.iso.Z.uu FILES+= test_read_format_lha_bugfix_0.lzh.uu FILES+= test_read_format_lha_filename_cp932.lzh.uu +FILES+= test_read_format_lha_filename_utf16.lzh.uu FILES+= test_read_format_lha_header0.lzh.uu FILES+= test_read_format_lha_header1.lzh.uu FILES+= test_read_format_lha_header2.lzh.uu @@ -517,8 +527,11 @@ FILES+= test_read_format_rar_windows.rar.uu FILES+= test_read_format_rar5_arm.rar.uu FILES+= test_read_format_rar5_arm_filter_on_window_boundary.rar.uu FILES+= test_read_format_rar5_blake2.rar.uu +FILES+= test_read_format_rar5_block_size_is_too_small.rar.uu FILES+= test_read_format_rar5_compressed.rar.uu +FILES+= test_read_format_rar5_different_solid_window_size.rar.uu FILES+= test_read_format_rar5_different_window_size.rar.uu +FILES+= test_read_format_rar5_different_winsize_on_merge.rar.uu FILES+= test_read_format_rar5_distance_overflow.rar.uu FILES+= test_read_format_rar5_extra_field_version.rar.uu FILES+= test_read_format_rar5_fileattr.rar.uu diff --git a/usr.bin/bsdcat/Makefile b/usr.bin/bsdcat/Makefile index f088c1a2c..deeefb7c7 100644 --- a/usr.bin/bsdcat/Makefile +++ b/usr.bin/bsdcat/Makefile @@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive _LIBARCHIVECONFDIR= ${SRCTOP}/lib/libarchive PROG= bsdcat -BSDCAT_VERSION_STRING= 3.4.0 +BSDCAT_VERSION_STRING= 3.4.2 .PATH: ${_LIBARCHIVEDIR}/cat SRCS= bsdcat.c cmdline.c diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile index cf3970e7b..a892b6f9c 100644 --- a/usr.bin/cpio/Makefile +++ b/usr.bin/cpio/Makefile @@ -6,7 +6,7 @@ LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive LIBARCHIVECONFDIR= ${.CURDIR}/../../lib/libarchive PROG= bsdcpio -BSDCPIO_VERSION_STRING= 3.4.0 +BSDCPIO_VERSION_STRING= 3.4.2 .PATH: ${LIBARCHIVEDIR}/cpio SRCS= cpio.c cmdline.c diff --git a/usr.bin/tar/Makefile b/usr.bin/tar/Makefile index 844c5ee1a..76498986d 100644 --- a/usr.bin/tar/Makefile +++ b/usr.bin/tar/Makefile @@ -4,7 +4,7 @@ LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive PROG= bsdtar -BSDTAR_VERSION_STRING= 3.4.0 +BSDTAR_VERSION_STRING= 3.4.2 .PATH: ${LIBARCHIVEDIR}/tar SRCS= bsdtar.c \ diff --git a/usr.bin/tar/tests/Makefile b/usr.bin/tar/tests/Makefile index 74a4d4bce..7e5960642 100644 --- a/usr.bin/tar/tests/Makefile +++ b/usr.bin/tar/tests/Makefile @@ -73,6 +73,7 @@ TESTS_SRCS= \ test_option_q.c \ test_option_r.c \ test_option_s.c \ + test_option_safe_writes.c \ test_option_uid_uname.c \ test_option_uuencode.c \ test_option_xattrs.c \ -- 2.42.0