diff options
| author | Martin Matuska <mm@FreeBSD.org> | 2025-12-01 14:05:35 +0100 |
|---|---|---|
| committer | Martin Matuska <mm@FreeBSD.org> | 2026-01-15 21:03:15 +0100 |
| commit | b9bf082d1f4816642ebc977d2769ca3f4069cb42 (patch) | |
| tree | 473f8dddf93a0b9976a3f56cc49442e4e469afbd | |
| parent | ca5d4e7f63d0c30ea829dd68930431693e8253cd (diff) | |
libarchive: merge from vendor branch
libarchive 3.8.4
Important bugfixes:
#2787 bsdtar: Fix zero-length pattern issue
#2797 lib: Fix regression introduced in libarchive 3.8.2
when walking enterable but unreadable directories
Obtained from: libarchive
Vendor commit: d114ceee6de08a7a60ff1209492ba38bf9436f79
MFC after: 1 week
(cherry picked from commit c1e033c33e8b290cd40f4069249c879efcbae6a6)
17 files changed, 63 insertions, 53 deletions
diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS index 971ae8e441e1..fbbb65440b39 100644 --- a/contrib/libarchive/NEWS +++ b/contrib/libarchive/NEWS @@ -1,8 +1,10 @@ -Nov 17, 2026: libarchive 3.8.3 released +Dec 01, 2025: libarchive 3.8.4 released -Oct 15, 2026: libarchive 3.8.2 released +Nov 17, 2025: libarchive 3.8.3 released -Jun 01, 2026: libarchive 3.8.1 released +Oct 15, 2025: libarchive 3.8.2 released + +Jun 01, 2025: libarchive 3.8.1 released May 20, 2025: libarchive 3.8.0 released diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h index 9794dced6ca9..0eda822ae6bf 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 3008003 +#define ARCHIVE_VERSION_NUMBER 3008004 #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.3" +#define ARCHIVE_VERSION_ONLY_STRING "3.8.4" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); diff --git a/contrib/libarchive/libarchive/archive_cryptor.c b/contrib/libarchive/libarchive/archive_cryptor.c index 9f03f9ca6dd0..b6a02fd1e7cb 100644 --- a/contrib/libarchive/libarchive/archive_cryptor.c +++ b/contrib/libarchive/libarchive/archive_cryptor.c @@ -490,9 +490,9 @@ aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in, size_t in_len, uint8_t * const out, size_t *out_len) { uint8_t *const ebuf = ctx->encr_buf; - unsigned pos = ctx->encr_pos; - unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len); - unsigned i; + size_t pos = ctx->encr_pos; + size_t max = (in_len < *out_len)? in_len: *out_len; + size_t i; for (i = 0; i < max; ) { if (pos == AES_BLOCK_SIZE) { diff --git a/contrib/libarchive/libarchive/archive_cryptor_private.h b/contrib/libarchive/libarchive/archive_cryptor_private.h index 1dbc5c17a01a..272f2f84b9c9 100644 --- a/contrib/libarchive/libarchive/archive_cryptor_private.h +++ b/contrib/libarchive/libarchive/archive_cryptor_private.h @@ -56,10 +56,10 @@ int __libarchive_cryptor_build_hack(void); typedef struct { CCCryptorRef ctx; uint8_t key[AES_MAX_KEY_SIZE]; - unsigned key_len; + size_t key_len; uint8_t nonce[AES_BLOCK_SIZE]; uint8_t encr_buf[AES_BLOCK_SIZE]; - unsigned encr_pos; + size_t encr_pos; } archive_crypto_ctx; #elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h index 924b67a301cf..74466f394c4a 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 3008003 +#define ARCHIVE_VERSION_NUMBER 3008004 /* * Note: archive_entry.h is for use outside of libarchive; the 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 121af19872e9..6e6bae6a4e06 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c @@ -254,7 +254,7 @@ archive_read_disk_entry_from_file(struct archive *_a, if (S_ISLNK(st->st_mode)) { size_t linkbuffer_len = st->st_size; char *linkbuffer; - int lnklen; + ssize_t lnklen; linkbuffer = malloc(linkbuffer_len + 1); if (linkbuffer == NULL) { @@ -892,7 +892,7 @@ setup_sparse_fiemap(struct archive_read_disk *a, for (iters = 0; ; ++iters) { int i, r; - r = ioctl(*fd, FS_IOC_FIEMAP, fm); + r = ioctl(*fd, FS_IOC_FIEMAP, fm); if (r < 0) { /* When something error happens, it is better we * should return ARCHIVE_OK because an earlier @@ -1079,4 +1079,3 @@ setup_sparse(struct archive_read_disk *a, #endif #endif /* !defined(_WIN32) || defined(__CYGWIN__) */ - diff --git a/contrib/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libarchive/libarchive/archive_read_disk_posix.c index 7cd292f259ff..94fa8fef963f 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_read_disk_posix.c @@ -2018,11 +2018,8 @@ tree_dup(int fd) } #endif /* F_DUPFD_CLOEXEC */ new_fd = dup(fd); - if (new_fd != -1) { - __archive_ensure_cloexec_flag(new_fd); - return (new_fd); - } - return (-1); + __archive_ensure_cloexec_flag(new_fd); + return (new_fd); } /* @@ -2144,16 +2141,11 @@ tree_reopen(struct tree *t, const char *path, int restore_time) * so try again for execute. The consequences of not opening this are * unhelpful and unnecessary errors later. */ - if (t->initial_dir_fd < 0) { + if (t->initial_dir_fd < 0) t->initial_dir_fd = open(".", o_flag | O_CLOEXEC); - if (t->initial_dir_fd < 0) - return NULL; - } #endif __archive_ensure_cloexec_flag(t->initial_dir_fd); t->working_dir_fd = tree_dup(t->initial_dir_fd); - if (t->working_dir_fd < 0) - return NULL; return (t); } @@ -2359,15 +2351,20 @@ static int tree_dir_next_posix(struct tree *t) { int r; +#if defined(HAVE_FDOPENDIR) + int fd; +#endif const char *name; size_t namelen; if (t->d == NULL) { #if defined(HAVE_FDOPENDIR) - int fd = tree_dup(t->working_dir_fd); - if (fd != -1) - t->d = fdopendir(fd); + if (t->working_dir_fd >= 0) { + fd = tree_dup(t->working_dir_fd); + if (fd != -1) + t->d = fdopendir(fd); + } #else /* HAVE_FDOPENDIR */ if (tree_enter_working_dir(t) == 0) { t->d = opendir("."); diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c index ded13bee79a3..96d2c71f4c4f 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c @@ -1254,7 +1254,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, archive_entry_filetype(entry) == AE_IFDIR) { mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC); __archive_ensure_cloexec_flag(mtree->fd); - if (mtree->fd < 0 && ( + if (mtree->fd == -1 && ( #if defined(_WIN32) && !defined(__CYGWIN__) /* * On Windows, attempting to open a file with an diff --git a/contrib/libarchive/libarchive/archive_version_details.c b/contrib/libarchive/libarchive/archive_version_details.c index 0cf92db73194..9063faa79426 100644 --- a/contrib/libarchive/libarchive/archive_version_details.c +++ b/contrib/libarchive/libarchive/archive_version_details.c @@ -333,7 +333,7 @@ archive_libbsdxml_version(void) const char * archive_libxml2_version(void) { -#if HAVE_LIBXML_XMLREADER_H && HAVE_LIBXML2 +#if HAVE_LIBXML_XMLVERSION_H && HAVE_LIBXML2 return LIBXML_DOTTED_VERSION; #else return NULL; diff --git a/contrib/libarchive/libarchive/archive_write.c b/contrib/libarchive/libarchive/archive_write.c index 9b9cb196f0f9..e1ce5d57288d 100644 --- a/contrib/libarchive/libarchive/archive_write.c +++ b/contrib/libarchive/libarchive/archive_write.c @@ -821,7 +821,7 @@ _archive_write_data(struct archive *_a, const void *buff, size_t s) { struct archive_write *a = (struct archive_write *)_a; const size_t max_write = INT_MAX; - int ret; + ssize_t ret; archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_DATA, "archive_write_data"); diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c index d69f041dde7e..cc59e58e4df6 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c @@ -2561,9 +2561,9 @@ _archive_write_disk_close(struct archive *_a) * for directories. For other file types * we need to verify via fstat() or lstat() */ - if (fd < 0 || p->filetype != AE_IFDIR) { + if (fd == -1 || p->filetype != AE_IFDIR) { #if HAVE_FSTAT - if (fd >= 0 && ( + if (fd > 0 && ( fstat(fd, &st) != 0 || la_verify_filetype(st.st_mode, p->filetype) == 0)) { @@ -4447,7 +4447,7 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname) */ fd = open(pathname, O_RDONLY | O_BINARY | O_CLOEXEC); __archive_ensure_cloexec_flag(fd); - if (fd < 0) { + if (fd == -1) { archive_set_error(&a->archive, errno, "Failed to open a restoring file"); ret = ARCHIVE_WARN; diff --git a/contrib/libarchive/libarchive/archive_write_set_format_xar.c b/contrib/libarchive/libarchive/archive_write_set_format_xar.c index 9921f1032be5..ec3219057e4e 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_xar.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_xar.c @@ -1000,13 +1000,13 @@ xmlwrite_heap(struct archive_write *a, struct xml_writer *writer, const char *encname; int r; - r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length); + r = xmlwrite_fstring(a, writer, "length", "%ju", (uintmax_t)heap->length); if (r < 0) return (ARCHIVE_FATAL); - r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset); + r = xmlwrite_fstring(a, writer, "offset", "%ju", (uintmax_t)heap->temp_offset); if (r < 0) return (ARCHIVE_FATAL); - r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size); + r = xmlwrite_fstring(a, writer, "size", "%ju", (uintmax_t)heap->size); if (r < 0) return (ARCHIVE_FATAL); switch (heap->compression) { @@ -1356,7 +1356,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer, * Make a inode entry, "<inode>". */ r = xmlwrite_fstring(a, writer, "inode", - "%jd", archive_entry_ino64(file->entry)); + "%jd", (intmax_t)archive_entry_ino64(file->entry)); if (r < 0) return (ARCHIVE_FATAL); if (archive_entry_dev(file->entry) != 0) { @@ -1378,7 +1378,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer, * Make a user entry, "<uid>" and "<user>. */ r = xmlwrite_fstring(a, writer, "uid", - "%d", archive_entry_uid(file->entry)); + "%jd", (intmax_t)archive_entry_uid(file->entry)); if (r < 0) return (ARCHIVE_FATAL); r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv); @@ -1404,7 +1404,7 @@ make_file_entry(struct archive_write *a, struct xml_writer *writer, * Make a group entry, "<gid>" and "<group>. */ r = xmlwrite_fstring(a, writer, "gid", - "%d", archive_entry_gid(file->entry)); + "%jd", (intmax_t)archive_entry_gid(file->entry)); if (r < 0) return (ARCHIVE_FATAL); r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv); diff --git a/contrib/libarchive/libarchive/test/test_archive_read_multiple_data_objects.c b/contrib/libarchive/libarchive/test/test_archive_read_multiple_data_objects.c index f9f75d96fa6b..791c7ad01121 100644 --- a/contrib/libarchive/libarchive/test/test_archive_read_multiple_data_objects.c +++ b/contrib/libarchive/libarchive/test/test_archive_read_multiple_data_objects.c @@ -202,7 +202,7 @@ static int64_t file_skip(struct archive *a, void *data, int64_t request) { struct mydata *mydata = (struct mydata *)data; - int64_t result = lseek(mydata->fd, SEEK_CUR, request); + int64_t result = lseek(mydata->fd, request, SEEK_CUR); if (result >= 0) return result; archive_set_error(a, errno, "Error seeking in '%s'", mydata->filename); diff --git a/contrib/libarchive/libarchive/test/test_write_disk_perms.c b/contrib/libarchive/libarchive/test/test_write_disk_perms.c index 77a15d1a3e42..72b55179d86e 100644 --- a/contrib/libarchive/libarchive/test/test_write_disk_perms.c +++ b/contrib/libarchive/libarchive/test/test_write_disk_perms.c @@ -94,21 +94,21 @@ searchgid(void) close(fd); } -static int +static long altgid(void) { searchgid(); return (_alt_gid); } -static int +static long invalidgid(void) { searchgid(); return (_invalid_gid); } -static int +static long defaultgid(void) { searchgid(); diff --git a/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c b/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c index 7b2e4f857a75..d7ed95e2c7ff 100644 --- a/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c +++ b/contrib/libarchive/libarchive/test/test_write_filter_bzip2.c @@ -40,7 +40,8 @@ DEFINE_TEST(test_write_filter_bzip2) size_t buffsize, datasize; char path[16]; size_t used1, used2; - int i, r, use_prog; + ssize_t r; + int i, use_prog; buffsize = 2000000; assert(NULL != (buff = malloc(buffsize))); diff --git a/contrib/libarchive/tar/subst.c b/contrib/libarchive/tar/subst.c index a5d644dc5a70..a466f65358a5 100644 --- a/contrib/libarchive/tar/subst.c +++ b/contrib/libarchive/tar/subst.c @@ -235,7 +235,9 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, (*result)[0] = 0; } - while (1) { + char isEnd = 0; + do { + isEnd = *name == '\0'; if (regexec(&rule->re, name, 10, matches, 0)) break; @@ -290,12 +292,15 @@ apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, } realloc_strcat(result, rule->result + j); - - name += matches[0].rm_eo; - - if (!rule->global) - break; - } + 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; + } + } 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 } if (got_match) diff --git a/contrib/libarchive/tar/test/test_option_s.c b/contrib/libarchive/tar/test/test_option_s.c index 125e971d3304..00753b99be3c 100644 --- a/contrib/libarchive/tar/test/test_option_s.c +++ b/contrib/libarchive/tar/test/test_option_s.c @@ -42,7 +42,13 @@ DEFINE_TEST(test_option_s) systemf("%s -cf test1_2.tar -s /d1/d2/ in/d1/foo", testprog); systemf("%s -xf test1_2.tar -C test1", testprog); assertFileContents("foo", 3, "test1/in/d2/foo"); - + systemf("%s -cf test1_3.tar -s /o/#/g in/d1/foo", testprog); + systemf("%s -xf test1_3.tar -C test1", testprog); + assertFileContents("foo", 3, "test1/in/d1/f##"); + // For the 0-length pattern check, remember that "test1/" isn't part of the string affected by the regexp + systemf("%s -cf test1_4.tar -s /f*/\\<~\\>/g in/d1/foo", testprog); + systemf("%s -xf test1_4.tar -C test1", testprog); + assertFileContents("foo", 3, "test1/<>i<>n<>/<>d<>1<>/<f><>o<>o<>"); /* * Test 2: Basic substitution when extracting archive. */ |
