Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Dec 2019 00:05:06 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r356212 - in head: contrib/libarchive contrib/libarchive/libarchive contrib/libarchive/libarchive/test contrib/libarchive/test_utils lib/libarchive/tests usr.bin/bsdcat usr.bin/cpio usr...
Message-ID:  <201912310005.xBV056p8074062@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Tue Dec 31 00:05:06 2019
New Revision: 356212
URL: https://svnweb.freebsd.org/changeset/base/356212

Log:
  MFV r356163,r356197:
  Update libarchive to 3.4.1
  
  Relevant vendor changes since last update:
    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)
  
  MFC after:	2 weeks

Added:
  head/contrib/libarchive/libarchive/test/test_pax_xattr_header.c
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_pax_xattr_header.c
  head/contrib/libarchive/libarchive/test/test_pax_xattr_header_all.tar.uu
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_pax_xattr_header_all.tar.uu
  head/contrib/libarchive/libarchive/test/test_pax_xattr_header_libarchive.tar.uu
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_pax_xattr_header_libarchive.tar.uu
  head/contrib/libarchive/libarchive/test/test_pax_xattr_header_schily.tar.uu
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_pax_xattr_header_schily.tar.uu
  head/contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu
  head/contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.c
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_7zip_packinfo_digests.c
  head/contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.c
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_lha_filename_utf16.c
  head/contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu
  head/contrib/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu
  head/contrib/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu
     - copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu
Modified:
  head/contrib/libarchive/NEWS
  head/contrib/libarchive/libarchive/archive.h
  head/contrib/libarchive/libarchive/archive_entry.h
  head/contrib/libarchive/libarchive/archive_entry_acl.3
  head/contrib/libarchive/libarchive/archive_hmac.c
  head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
  head/contrib/libarchive/libarchive/archive_read_disk_posix.c
  head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
  head/contrib/libarchive/libarchive/archive_read_support_format_lha.c
  head/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
  head/contrib/libarchive/libarchive/archive_read_support_format_zip.c
  head/contrib/libarchive/libarchive/archive_string.c
  head/contrib/libarchive/libarchive/archive_write.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_lzop.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_program.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_uuencode.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_xz.c
  head/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c
  head/contrib/libarchive/libarchive/archive_write_disk_posix.c
  head/contrib/libarchive/libarchive/archive_write_private.h
  head/contrib/libarchive/libarchive/archive_write_set_format_pax.c
  head/contrib/libarchive/libarchive/archive_write_set_format_zip.c
  head/contrib/libarchive/libarchive/archive_write_set_options.3
  head/contrib/libarchive/libarchive/test/test_open_failure.c
  head/contrib/libarchive/libarchive/test/test_open_fd.c
  head/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
  head/contrib/libarchive/libarchive/test/test_read_format_rar5.c
  head/contrib/libarchive/libarchive/test/test_sparse_basic.c
  head/contrib/libarchive/test_utils/test_main.c
  head/lib/libarchive/tests/Makefile
  head/usr.bin/bsdcat/Makefile
  head/usr.bin/cpio/Makefile
  head/usr.bin/tar/Makefile
Directory Properties:
  head/contrib/libarchive/   (props changed)

Modified: head/contrib/libarchive/NEWS
==============================================================================
--- head/contrib/libarchive/NEWS	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/NEWS	Tue Dec 31 00:05:06 2019	(r356212)
@@ -1,3 +1,9 @@
+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

Modified: head/contrib/libarchive/libarchive/archive.h
==============================================================================
--- head/contrib/libarchive/libarchive/archive.h	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive.h	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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 3004001
 
 #include <sys/stat.h>
 #include <stddef.h>  /* 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.1"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 

Modified: head/contrib/libarchive/libarchive/archive_entry.h
==============================================================================
--- head/contrib/libarchive/libarchive/archive_entry.h	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_entry.h	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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 3004001
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
@@ -524,9 +524,6 @@ __LA_DECL int	 archive_entry_acl_reset(struct archive_
 __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

Modified: head/contrib/libarchive/libarchive/archive_entry_acl.3
==============================================================================
--- head/contrib/libarchive/libarchive/archive_entry_acl.3	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_entry_acl.3	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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

Modified: head/contrib/libarchive/libarchive/archive_hmac.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_hmac.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_hmac.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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;

Modified: head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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);
 	}

Modified: head/contrib/libarchive/libarchive/archive_read_disk_posix.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_disk_posix.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_read_disk_posix.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -694,6 +694,7 @@ _archive_read_data_block(struct archive *_a, const voi
 	struct tree *t = a->tree;
 	int r;
 	ssize_t bytes;
+	int64_t sparse_bytes;
 	size_t buffbytes;
 	int empty_sparse_region = 0;
 
@@ -792,9 +793,9 @@ _archive_read_data_block(struct archive *_a, const voi
 			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;
 	}
 
 	/*
@@ -2172,7 +2173,7 @@ tree_reopen(struct tree *t, const char *path, int rest
 #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 +2199,8 @@ tree_reopen(struct tree *t, const char *path, int rest
 	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

Modified: head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -1787,7 +1787,7 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_
 		return (0);
 	}
 
-	if (*p != kSize)
+	if (*p != kCRC)
 		return (-1);
 
 	if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)

Modified: head/contrib/libarchive/libarchive/archive_read_support_format_lha.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_support_format_lha.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_read_support_format_lha.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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_rea
 	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,13 +601,55 @@ archive_read_format_lha_read_header(struct archive_rea
 		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) {
 		/*
 	 	 * Extract the symlink-name if it's included in the pathname.
@@ -610,8 +659,8 @@ archive_read_format_lha_read_header(struct archive_rea
 			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_rea
 	/*
 	 * 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,26 @@ lha_read_file_extended_header(struct archive_read *a, 
 			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 +1271,36 @@ lha_read_file_extended_header(struct archive_read *a, 
 				/* 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 0xFF
+				 * to '/' for local system.
+				 */
+				/* 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] = L'/';
+				}
+				/* Is last character directory separator? */
+				if (utf16name[lha->dirname.length / 2 - 1] != L'/')
+					/* invalid directory data */
+					goto invalid;
+			}
+			break;
 		case EXT_DOS_ATTR:
 			if (datasize == 2)
 				lha->dos_attr = (unsigned char)
@@ -1276,12 +1349,17 @@ lha_read_file_extended_header(struct archive_read *a, 
 					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;
 		case EXT_UNIX_MODE:
@@ -1336,8 +1414,7 @@ lha_read_file_extended_header(struct archive_read *a, 
 			}
 			break;
 		case EXT_TIMEZONE:		/* Not supported */
-		case EXT_UTF16_FILENAME:	/* Not supported */
-		case EXT_UTF16_DIRECTORY:	/* Not supported */
+			break;
 		default:
 			break;
 		}
@@ -1600,19 +1677,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);
 	}

Modified: head/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_support_format_rar5.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_read_support_format_rar5.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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
@@ -115,6 +116,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 {
@@ -1177,7 +1180,7 @@ static int process_main_locator_extra_block(struct arc
 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;
 
 	if(!read_var_sized(a, &hash_type, &value_len))
@@ -1303,7 +1306,7 @@ static int parse_file_extra_htime(struct archive_read*
     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 {
@@ -1665,7 +1668,18 @@ static int process_head_file(struct archive_read* a, s
 		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. */
 	if(window_size > (64 * 1024 * 1024) ||
@@ -1676,12 +1690,36 @@ static int process_head_file(struct archive_read* a, s
 		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))

Modified: head/contrib/libarchive/libarchive/archive_read_support_format_zip.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_support_format_zip.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_read_support_format_zip.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -1797,6 +1797,23 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, 
 			    "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;
 

Modified: head/contrib/libarchive/libarchive/archive_string.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_string.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_string.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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
 	 * 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
 
 	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
 	 * 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
 				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;
 	}
@@ -798,7 +807,8 @@ archive_string_append_from_wcs(struct archive_string *
 			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 +3450,8 @@ strncat_from_utf8_libarchive2(struct archive_string *a
 			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;

Modified: head/contrib/libarchive/libarchive/archive_write.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_write.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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,29 +244,72 @@ __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
 __archive_write_output(struct archive_write *a, const void *buff, size_t length)
 {
@@ -440,7 +487,7 @@ archive_write_client_close(struct archive_write_filter
 	free(state->buffer);
 	free(state);
 	/* Clear the close handler myself not to be called again. */
-	f->close = NULL;
+	f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
 	a->client_data = NULL;
 	/* Clear passphrase. */
 	if (a->passphrase != NULL) {
@@ -477,9 +524,10 @@ archive_write_open(struct archive *_a, void *client_da
 	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 +569,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;
 

Modified: head/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -149,12 +149,7 @@ archive_filter_b64encode_open(struct archive_write_fil
 {
 	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
 		 * per block for performance. */
@@ -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_fi
 	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

Modified: head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -167,10 +167,6 @@ archive_compressor_bzip2_open(struct archive_write_fil
 	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_fi
 		    "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

Modified: head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -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);
 }

Modified: head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c	Mon Dec 30 23:20:46 2019	(r356211)
+++ head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c	Tue Dec 31 00:05:06 2019	(r356212)
@@ -184,10 +184,6 @@ archive_compressor_gzip_open(struct archive_write_filt
 	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_fil
 {
 	unsigned char trailer[8];
 	struct private_data *data = (struct private_data *)f->data;
-	int ret, r1;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201912310005.xBV056p8074062>