git: df4e99bb8847 - stable/15 - libarchive: merge from vendor branch

From: Martin Matuska <mm_at_FreeBSD.org>
Date: Thu, 15 Jan 2026 20:03:50 UTC
The branch stable/15 has been updated by mm:

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

commit df4e99bb884786eb0554e2a259795c44a5295154
Author:     Martin Matuska <mm@FreeBSD.org>
AuthorDate: 2026-01-05 20:14:54 +0000
Commit:     Martin Matuska <mm@FreeBSD.org>
CommitDate: 2026-01-15 20:03:15 +0000

    libarchive: merge from vendor branch
    
    libarchive 3.8.5
    
    Important bugfixes:
     #2809 bsdtar: fix regression from 3.8.4 zero-length pattern issue bugfix
    
    Obtained from:  libarchive
    Vendor commit:  dd897a78c662a2c7a003e7ec158cea7909557bee
    MFC after:      1 week
    
    (cherry picked from commit 4b047c3af3fec1607ba1cfe04e1d442a17fc1cf6)
---
 contrib/libarchive/NEWS                               |  2 ++
 contrib/libarchive/README.md                          |  4 ++--
 contrib/libarchive/cpio/cpio.c                        |  2 +-
 contrib/libarchive/libarchive/archive.h               |  4 ++--
 contrib/libarchive/libarchive/archive_entry.h         |  2 +-
 .../libarchive/archive_read_support_filter_uu.c       |  8 ++++----
 .../libarchive/archive_read_support_format_cab.c      |  2 +-
 .../libarchive/archive_read_support_format_cpio.c     |  6 +++---
 .../libarchive/archive_read_support_format_lha.c      |  2 +-
 .../libarchive/archive_read_support_format_mtree.c    | 12 ++++++------
 contrib/libarchive/libarchive/archive_string.c        |  4 ++--
 contrib/libarchive/libarchive/archive_util.c          |  2 +-
 contrib/libarchive/libarchive/archive_write_open_fd.c |  6 +-----
 .../libarchive/libarchive/archive_write_open_file.c   |  6 +-----
 .../libarchive/libarchive/archive_write_open_memory.c |  6 +-----
 .../libarchive/archive_write_set_format_shar.c        |  5 ++++-
 .../libarchive/archive_write_set_format_ustar.c       |  2 +-
 contrib/libarchive/libarchive/test/test_compat_lzip.c |  4 ++--
 contrib/libarchive/libarchive_fe/line_reader.c        |  2 ++
 contrib/libarchive/tar/subst.c                        | 16 ++++++++--------
 contrib/libarchive/tar/write.c                        |  5 ++---
 contrib/libarchive/test_utils/test_main.c             | 19 ++++++++++++++++---
 contrib/libarchive/unzip/bsdunzip.c                   |  4 ++--
 contrib/libarchive/unzip/la_queue.h                   |  2 +-
 24 files changed, 67 insertions(+), 60 deletions(-)

diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS
index fbbb65440b39..be14de445b57 100644
--- a/contrib/libarchive/NEWS
+++ b/contrib/libarchive/NEWS
@@ -1,3 +1,5 @@
+Jan 05, 2026: libarchive 3.8.5 released
+
 Dec 01, 2025: libarchive 3.8.4 released
 
 Nov 17, 2025: libarchive 3.8.3 released
diff --git a/contrib/libarchive/README.md b/contrib/libarchive/README.md
index 0d63357292ec..e9691f1b710b 100644
--- a/contrib/libarchive/README.md
+++ b/contrib/libarchive/README.md
@@ -191,7 +191,7 @@ questions we are asked about libarchive:
   libraries.  This also reduces the size of statically-linked
   binaries in environments where that matters.
 
-* The library is generally _thread safe_ depending on the platform:
+* The library is generally _thread-safe_ depending on the platform:
   it does not define any global variables of its own.  However, some
   platforms do not provide fully thread-safe versions of key C library
   functions.  On those platforms, libarchive will use the non-thread-safe
@@ -214,7 +214,7 @@ questions we are asked about libarchive:
   multiple threads.  Of course, those modules are completely
   optional and you can use the rest of libarchive without them.
 
-* The library is _not_ thread aware, however.  It does no locking
+* The library is _not_ thread-aware, however.  It does no locking
   or thread management of any kind.  If you create a libarchive
   object and need to access it from multiple threads, you will
   need to provide your own locking.
diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c
index 262db510568b..77eefe809f37 100644
--- a/contrib/libarchive/cpio/cpio.c
+++ b/contrib/libarchive/cpio/cpio.c
@@ -725,7 +725,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
 
 	if (cpio->uid_override >= 0)
 		archive_entry_set_uid(entry, cpio->uid_override);
-	if (cpio->gname_override != NULL)
+	if (cpio->uname_override != NULL)
 		archive_entry_set_uname(entry, cpio->uname_override);
 	if (cpio->gid_override >= 0)
 		archive_entry_set_gid(entry, cpio->gid_override);
diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h
index 0eda822ae6bf..a9d34beb4f5a 100644
--- a/contrib/libarchive/libarchive/archive.h
+++ b/contrib/libarchive/libarchive/archive.h
@@ -34,7 +34,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3008004
+#define	ARCHIVE_VERSION_NUMBER 3008005
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -177,7 +177,7 @@ __LA_DECL int		archive_version_number(void);
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.8.4"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.8.5"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h
index 74466f394c4a..b43435692c27 100644
--- a/contrib/libarchive/libarchive/archive_entry.h
+++ b/contrib/libarchive/libarchive/archive_entry.h
@@ -28,7 +28,7 @@
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3008004
+#define	ARCHIVE_VERSION_NUMBER 3008005
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_uu.c b/contrib/libarchive/libarchive/archive_read_support_filter_uu.c
index d722fe343657..acb8feb79b2d 100644
--- a/contrib/libarchive/libarchive/archive_read_support_filter_uu.c
+++ b/contrib/libarchive/libarchive/archive_read_support_filter_uu.c
@@ -232,8 +232,8 @@ bid_get_line(struct archive_read_filter *filter,
 		size_t nbytes_req = (*ravail+1023) & ~1023U;
 		ssize_t tested;
 
-		/* Increase reading bytes if it is not enough to at least
-		 * new two lines. */
+		/* Increase reading bytes if it is not enough for at least
+		 * two new lines. */
 		if (nbytes_req < (size_t)*ravail + 160)
 			nbytes_req <<= 1;
 
@@ -411,7 +411,7 @@ ensure_in_buff_size(struct archive_read_filter *self,
 
 		/*
 		 * Calculate a new buffer size for in_buff.
-		 * Increase its value until it has enough size we need.
+		 * Increase its value until it is enough for our needs.
 		 */
 		newsize = uudecode->in_allocated;
 		do {
@@ -494,7 +494,7 @@ read_more:
 		}
 		/*
 		 * If there is remaining data which is saved by
-		 * previous calling, use it first.
+		 * a previous call, use it first.
 		 */
 		if (ensure_in_buff_size(self, uudecode,
 		    avail_in + uudecode->in_cnt) != ARCHIVE_OK)
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_cab.c b/contrib/libarchive/libarchive/archive_read_support_format_cab.c
index a96f7d313951..63755ef9e579 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_cab.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_cab.c
@@ -2813,7 +2813,7 @@ lzx_decode_blocks(struct lzx_stream *strm, int last)
 					      lzx_br_bits(&bre, mt_max_bits));
 					lzx_br_consume(&bre, mt_bitlen[c]);
 				}
-				if (c > UCHAR_MAX)
+				if ((unsigned int)c > UCHAR_MAX)
 					break;
 				/*
 				 * 'c' is exactly literal code.
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_cpio.c b/contrib/libarchive/libarchive/archive_read_support_format_cpio.c
index 74f3549d159e..526096b39f75 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_cpio.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_cpio.c
@@ -825,9 +825,9 @@ header_odc(struct archive_read *a, struct cpio *cpio,
 }
 
 /*
- * NOTE: if a filename suffix is ".z", it is the file gziped by afio.
- * it would be nice that we can show uncompressed file size and we can
- * uncompressed file contents automatically, unfortunately we have nothing
+ * NOTE: if a filename suffix is ".z", it is a file gzipped by afio.
+ * it would be nice if we could show uncompressed file size and
+ * uncompress file contents automatically, unfortunately we have nothing
  * to get a uncompressed file size while reading each header. It means
  * we also cannot uncompress file contents under our framework.
  */
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_lha.c b/contrib/libarchive/libarchive/archive_read_support_format_lha.c
index abf8b8799636..cf6a147abda6 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_lha.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_lha.c
@@ -2374,7 +2374,7 @@ lzh_decode_blocks(struct lzh_stream *strm, int last)
 					lzh_br_consume(&bre, lt_bitlen[c]);
 				}
 				blocks_avail--;
-				if (c > UCHAR_MAX)
+				if ((unsigned int)c > UCHAR_MAX)
 					/* Current block is a match data. */
 					break;
 				/*
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
index 96d2c71f4c4f..10c07b05d965 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
@@ -392,8 +392,8 @@ next_line(struct archive_read *a,
 		if (len >= MAX_LINE_LEN)
 			return (-1);
 
-		/* Increase reading bytes if it is not enough to at least
-		 * new two lines. */
+		/* Increase reading bytes if it is not enough for at least
+		 * two new lines. */
 		if (nbytes_req < (size_t)*ravail + 160)
 			nbytes_req <<= 1;
 
@@ -568,8 +568,8 @@ bid_keyword_list(const char *p,  ssize_t len, int unset, int last_is_path)
 				--len;
 				value = 1;
 			}
-			/* A keyword should have a its value unless
-			 * "/unset" operation. */ 
+			/* A keyword should have a value unless this is
+			 * an "/unset" operation. */ 
 			if (!unset && value == 0)
 				return (-1);
 		}
@@ -752,7 +752,7 @@ detect_form(struct archive_read *a, int *is_form_d)
 				} else if (form_D == 1) {
 					if (!last_is_path && keywords > 0)
 						/* This this is not `form D'
-						 * and We cannot accept mixed
+						 * and we cannot accept mixed
 						 * format. */
 						break;
 				}
@@ -805,7 +805,7 @@ detect_form(struct archive_read *a, int *is_form_d)
  * to read the entire mtree file into memory up front.
  *
  * The parsing is done in two steps.  First, it is decided if a line
- * changes the global defaults and if it is, processed accordingly.
+ * changes the global defaults and if it does, it is processed accordingly.
  * Otherwise, the options of the line are merged with the current
  * global options.
  */
diff --git a/contrib/libarchive/libarchive/archive_string.c b/contrib/libarchive/libarchive/archive_string.c
index 740308b6e4e3..a776dc85c688 100644
--- a/contrib/libarchive/libarchive/archive_string.c
+++ b/contrib/libarchive/libarchive/archive_string.c
@@ -3573,7 +3573,7 @@ win_strncat_from_utf16(struct archive_string *as, const void *_p, size_t bytes,
 
 	if (sc->to_cp == CP_C_LOCALE) {
 		/*
-		 * "C" locale special process.
+		 * "C" locale special processing.
 		 */
 		u16 = _p;
 		ll = 0;
@@ -3690,7 +3690,7 @@ win_strncat_to_utf16(struct archive_string *as16, const void *_p,
 	avail = as16->buffer_length - 2;
 	if (sc->from_cp == CP_C_LOCALE) {
 		/*
-		 * "C" locale special process.
+		 * "C" locale special processing.
 		 */
 		count = 0;
 		while (count < length && *s) {
diff --git a/contrib/libarchive/libarchive/archive_util.c b/contrib/libarchive/libarchive/archive_util.c
index d048bbc94650..0d1de1ef2091 100644
--- a/contrib/libarchive/libarchive/archive_util.c
+++ b/contrib/libarchive/libarchive/archive_util.c
@@ -456,7 +456,7 @@ __archive_issetugid(void)
 		return (-1);
 	if (ruid != euid || ruid != suid)
 		return (1);
-	if (getresgid(&ruid, &egid, &sgid) != 0)
+	if (getresgid(&rgid, &egid, &sgid) != 0)
 		return (-1);
 	if (rgid != egid || rgid != sgid)
 		return (1);
diff --git a/contrib/libarchive/libarchive/archive_write_open_fd.c b/contrib/libarchive/libarchive/archive_write_open_fd.c
index ba034ed92f8a..a795552020df 100644
--- a/contrib/libarchive/libarchive/archive_write_open_fd.c
+++ b/contrib/libarchive/libarchive/archive_write_open_fd.c
@@ -135,11 +135,7 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
 static int
 file_free(struct archive *a, void *client_data)
 {
-	struct write_fd_data	*mine = (struct write_fd_data *)client_data;
-
 	(void)a; /* UNUSED */
-	if (mine == NULL)
-		return (ARCHIVE_OK);
-	free(mine);
+	free(client_data);
 	return (ARCHIVE_OK);
 }
diff --git a/contrib/libarchive/libarchive/archive_write_open_file.c b/contrib/libarchive/libarchive/archive_write_open_file.c
index 0b310f3da83b..6271b368d07f 100644
--- a/contrib/libarchive/libarchive/archive_write_open_file.c
+++ b/contrib/libarchive/libarchive/archive_write_open_file.c
@@ -96,11 +96,7 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
 static int
 file_free(struct archive *a, void *client_data)
 {
-	struct write_FILE_data	*mine = client_data;
-
 	(void)a; /* UNUSED */
-	if (mine == NULL)
-		return (ARCHIVE_OK);
-	free(mine);
+	free(client_data);
 	return (ARCHIVE_OK);
 }
diff --git a/contrib/libarchive/libarchive/archive_write_open_memory.c b/contrib/libarchive/libarchive/archive_write_open_memory.c
index e31650447279..3b929ac7f60d 100644
--- a/contrib/libarchive/libarchive/archive_write_open_memory.c
+++ b/contrib/libarchive/libarchive/archive_write_open_memory.c
@@ -104,11 +104,7 @@ memory_write(struct archive *a, void *client_data, const void *buff, size_t leng
 static int
 memory_write_free(struct archive *a, void *client_data)
 {
-	struct write_memory_data *mine;
 	(void)a; /* UNUSED */
-	mine = client_data;
-	if (mine == NULL)
-		return (ARCHIVE_OK);
-	free(mine);
+	free(client_data);
 	return (ARCHIVE_OK);
 }
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_shar.c b/contrib/libarchive/libarchive/archive_write_set_format_shar.c
index be9f78ce96cd..f6f28debdfa9 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_shar.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_shar.c
@@ -144,7 +144,9 @@ archive_write_set_format_shar_dump(struct archive *_a)
 	struct archive_write *a = (struct archive_write *)_a;
 	struct shar *shar;
 
-	archive_write_set_format_shar(&a->archive);
+	int ret = archive_write_set_format_shar(&a->archive);
+	if (ret != ARCHIVE_OK)
+		return ret;
 	shar = (struct shar *)a->format_data;
 	shar->dump = 1;
 	a->format_write_data = archive_write_shar_data_uuencode;
@@ -240,6 +242,7 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
 				shar_quote(&shar->work, p, 1);
 				archive_strcat(&shar->work,
 				    " > /dev/null 2>&1\n");
+				free(shar->last_dir);
 				shar->last_dir = p;
 			}
 		} else {
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_ustar.c b/contrib/libarchive/libarchive/archive_write_set_format_ustar.c
index 09b71fe6672a..4084eb455968 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_ustar.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_ustar.c
@@ -539,7 +539,7 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
 		ret = ARCHIVE_WARN;
 	}
 	if (copy_length > 0) {
-		if (strlen(p) > USTAR_gname_size) {
+		if (copy_length > USTAR_gname_size) {
 			if (tartype != 'x') {
 				archive_set_error(&a->archive,
 				    ARCHIVE_ERRNO_MISC, "Group name too long");
diff --git a/contrib/libarchive/libarchive/test/test_compat_lzip.c b/contrib/libarchive/libarchive/test/test_compat_lzip.c
index 50920eefb1cf..cd246b943b22 100644
--- a/contrib/libarchive/libarchive/test/test_compat_lzip.c
+++ b/contrib/libarchive/libarchive/test/test_compat_lzip.c
@@ -47,7 +47,7 @@ echo "f3" > $dir/d1/f3
 rm -r $dir
 }
 #
-# Make a lzip file from split tar file.
+# Make a lzip file from the split tar file.
 #
 name=test_compat_lzip_1
 dir="$name`date +%Y%m%d%H%M%S`.$USER"
@@ -75,7 +75,7 @@ exit 0
 */
 
 /*
- * Verify our ability to read sample files compatibly with lzip.
+ * Verify our ability to read the sample files compatibly with lzip.
  *
  * In particular:
  *  * lzip will read multiple lzip streams, concatenating the output
diff --git a/contrib/libarchive/libarchive_fe/line_reader.c b/contrib/libarchive/libarchive_fe/line_reader.c
index 0af9db53c0a2..a4bc84b7f233 100644
--- a/contrib/libarchive/libarchive_fe/line_reader.c
+++ b/contrib/libarchive/libarchive_fe/line_reader.c
@@ -64,6 +64,8 @@ lafe_line_reader(const char *pathname, int nullSeparator)
 
 	lr->nullSeparator = nullSeparator;
 	lr->pathname = strdup(pathname);
+	if (lr->pathname == NULL)
+		lafe_errc(1, ENOMEM, "Can't open %s", pathname);
 
 	if (strcmp(pathname, "-") == 0)
 		lr->f = stdin;
diff --git a/contrib/libarchive/tar/subst.c b/contrib/libarchive/tar/subst.c
index a466f65358a5..53497ad0d1a3 100644
--- a/contrib/libarchive/tar/subst.c
+++ b/contrib/libarchive/tar/subst.c
@@ -237,7 +237,7 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result,
 
 		char isEnd = 0;
 		do {
-            isEnd = *name == '\0';
+			isEnd = *name == '\0';
 			if (regexec(&rule->re, name, 10, matches, 0))
 				break;
 
@@ -293,13 +293,13 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result,
 
 			realloc_strcat(result, rule->result + j);
 			if (matches[0].rm_eo > 0) {
-                name += matches[0].rm_eo;
-            } else {
-                // We skip a character because the match is 0-length
-                // so we need to add it to the output
-                realloc_strncat(result, name, 1);
-                name += 1;
-            }
+				name += matches[0].rm_eo;
+			} else if (!isEnd) {
+				// We skip a character because the match is 0-length
+				// so we need to add it to the output
+				realloc_strncat(result, name, 1);
+				name += 1;
+			}
 		} while (rule->global && !isEnd); // Testing one step after because sed et al. run 0-length patterns a last time on the empty string at the end
 	}
 
diff --git a/contrib/libarchive/tar/write.c b/contrib/libarchive/tar/write.c
index 9e6c97b580b7..b39a397707ba 100644
--- a/contrib/libarchive/tar/write.c
+++ b/contrib/libarchive/tar/write.c
@@ -163,7 +163,7 @@ set_writer_options(struct bsdtar *bsdtar, struct archive *a)
 		 * a format or filters which are not added to
 		 * the archive write object. */
 		memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len);
-		memcpy(p, writer_options, opt_len);
+		memcpy(p + module_len, writer_options, opt_len);
 		r = archive_write_set_options(a, p);
 		free(p);
 		if (r < ARCHIVE_WARN)
@@ -190,13 +190,12 @@ set_reader_options(struct bsdtar *bsdtar, struct archive *a)
 		char *p;
 		/* Set default write options. */
 		if ((p = malloc(module_len + opt_len)) == NULL)
-		if (p == NULL)
 			lafe_errc(1, errno, "Out of memory");
 		/* Prepend magic code to ignore options for
 		 * a format or filters which are not added to
 		 * the archive write object. */
 		memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len);
-		memcpy(p, reader_options, opt_len);
+		memcpy(p + module_len, reader_options, opt_len);
 		r = archive_read_set_options(a, p);
 		free(p);
 		if (r < ARCHIVE_WARN)
diff --git a/contrib/libarchive/test_utils/test_main.c b/contrib/libarchive/test_utils/test_main.c
index f31678166ad0..dbd3fcf60e9a 100644
--- a/contrib/libarchive/test_utils/test_main.c
+++ b/contrib/libarchive/test_utils/test_main.c
@@ -3681,11 +3681,19 @@ test_run(int i, const char *tmpdir)
  */
 
 static void
-usage(const char *program)
+list_tests(void)
 {
 	static const int limit = nitems(tests);
 	int i;
 
+	for (i = 0; i < limit; i++)
+		printf("  %d: %s\n", i, tests[i].name);
+}
+
+static void
+usage(const char *program)
+{
+
 	printf("Usage: %s [options] <test> <test> ...\n", program);
 	printf("Default is to run all tests.\n");
 	printf("Otherwise, specify the numbers of the tests you wish to run.\n");
@@ -3693,6 +3701,8 @@ usage(const char *program)
 	printf("  -d  Dump core after any failure, for debugging.\n");
 	printf("  -k  Keep all temp files.\n");
 	printf("      Default: temp files for successful tests deleted.\n");
+	printf("  -l  List available tests and exit, ignoring all other.\n");
+	printf("      options and arguments.\n");
 #ifdef PROGRAM
 	printf("  -p <path>  Path to executable to be tested.\n");
 	printf("      Default: path taken from " ENVBASE " environment variable.\n");
@@ -3704,8 +3714,7 @@ usage(const char *program)
 	printf("  -u  Keep running specified tests until one fails.\n");
 	printf("  -v  Verbose.\n");
 	printf("Available tests:\n");
-	for (i = 0; i < limit; i++)
-		printf("  %d: %s\n", i, tests[i].name);
+	list_tests();
 	exit(1);
 }
 
@@ -4079,6 +4088,10 @@ main(int argc, char **argv)
 			case 'k':
 				keep_temp_files = 1;
 				break;
+			case 'l':
+				list_tests();
+				exit(0);
+				break;
 			case 'p':
 #ifdef PROGRAM
 				testprogfile = option_arg;
diff --git a/contrib/libarchive/unzip/bsdunzip.c b/contrib/libarchive/unzip/bsdunzip.c
index 1b520e841690..14bd418f169c 100644
--- a/contrib/libarchive/unzip/bsdunzip.c
+++ b/contrib/libarchive/unzip/bsdunzip.c
@@ -654,11 +654,11 @@ recheck:
 #elif HAVE_STRUCT_STAT_ST_MTIME_N
 			    sb.st_mtime > mtime.tv_sec ||
 			    (sb.st_mtime == mtime.tv_sec &&
-			    sb.st_mtime_n => mtime.tv_nsec)
+			    sb.st_mtime_n >= mtime.tv_nsec)
 #elif HAVE_STRUCT_STAT_ST_MTIME_USEC
 			    sb.st_mtime > mtime.tv_sec ||
 			    (sb.st_mtime == mtime.tv_sec &&
-			    sb.st_mtime_usec => mtime.tv_nsec / 1000)
+			    sb.st_mtime_usec >= mtime.tv_nsec / 1000)
 #else
 			    sb.st_mtime > mtime.tv_sec
 #endif
diff --git a/contrib/libarchive/unzip/la_queue.h b/contrib/libarchive/unzip/la_queue.h
index 917526531b2a..bb305f5bd8ce 100644
--- a/contrib/libarchive/unzip/la_queue.h
+++ b/contrib/libarchive/unzip/la_queue.h
@@ -85,7 +85,7 @@
  * _SWAP			+	+	+	+
  */
 #ifdef QUEUE_MACRO_DEBUG
-#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH
+#warning Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH
 #define	QUEUE_MACRO_DEBUG_TRACE
 #define	QUEUE_MACRO_DEBUG_TRASH
 #endif