git: 2cb0ab6bc177 - stable/13 - libarchive: merge from vendor branch
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 04 May 2024 12:37:35 UTC
The branch stable/13 has been updated by mm: URL: https://cgit.FreeBSD.org/src/commit/?id=2cb0ab6bc1772f2bc0d296d45b49d89f256febee commit 2cb0ab6bc1772f2bc0d296d45b49d89f256febee Author: Martin Matuska <mm@FreeBSD.org> AuthorDate: 2023-07-29 20:43:36 +0000 Commit: Martin Matuska <mm@FreeBSD.org> CommitDate: 2024-05-04 11:53:07 +0000 libarchive: merge from vendor branch Libarchive 3.7.1 Important changes (relevant to FreeBSD): ISSUE #1934: stack buffer overflow in cpio verbose mode ISSUE #1935: SEGV in cpio verbose mode PR #1731 tar: respect --strip-components and -s patterns in cru modes (cherry picked from commit 64884e0d4ce7ed57c970e1b34f93e3754c656900) --- contrib/libarchive/NEWS | 2 + contrib/libarchive/cpio/cpio.c | 7 +- contrib/libarchive/libarchive/archive.h | 4 +- contrib/libarchive/libarchive/archive_entry.h | 2 +- .../libarchive/archive_read_disk_posix.c | 2 +- .../libarchive/archive_read_support_filter_bzip2.c | 4 +- .../libarchive/archive_read_support_filter_lz4.c | 2 +- .../libarchive/archive_read_support_format_7zip.c | 8 +- .../libarchive/archive_read_support_format_lha.c | 7 +- .../libarchive/archive_read_support_format_rar.c | 4 +- .../libarchive/archive_read_support_format_rar5.c | 2 +- .../libarchive/archive_read_support_format_zip.c | 4 +- .../libarchive/archive_write_add_filter_bzip2.c | 6 +- .../libarchive/archive_write_add_filter_lz4.c | 8 +- .../libarchive/archive_write_add_filter_zstd.c | 4 +- .../libarchive/archive_write_disk_posix.c | 7 +- .../libarchive/archive_write_set_format_7zip.c | 8 +- contrib/libarchive/tar/write.c | 2 + contrib/libarchive/unzip/CMakeLists.txt | 37 - contrib/libarchive/unzip/bsdunzip.1 | 8 +- contrib/libarchive/unzip/bsdunzip.c | 56 +- contrib/libarchive/unzip/bsdunzip_platform.h | 8 - contrib/libarchive/unzip/la_getline.c | 99 +++ contrib/libarchive/unzip/la_queue.h | 840 +++++++++++++++++++++ contrib/libarchive/unzip/test/CMakeLists.txt | 80 -- 25 files changed, 1044 insertions(+), 167 deletions(-) diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS index 61d1ca47340e..7509c9ce5fa1 100644 --- a/contrib/libarchive/NEWS +++ b/contrib/libarchive/NEWS @@ -1,3 +1,5 @@ +Jul 29, 2023: libarchive 3.7.1 released + Jul 18, 2023: libarchive 3.7.0 released Jul 14, 2023: bsdunzip port from FreeBSD diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c index fbeae4133091..7bd6a782b5b2 100644 --- a/contrib/libarchive/cpio/cpio.c +++ b/contrib/libarchive/cpio/cpio.c @@ -1146,7 +1146,7 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry) { char size[32]; char date[32]; - char uids[16], gids[16]; + char uids[22], gids[22]; const char *uname, *gname; FILE *out = stdout; const char *fmt; @@ -1210,7 +1210,10 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry) #else ltime = localtime(&mtime); #endif - strftime(date, sizeof(date), fmt, ltime); + if (ltime != NULL) + strftime(date, sizeof(date), fmt, ltime); + else + strcpy(date, "invalid mtime"); fprintf(out, "%s%3d %-8s %-8s %8s %12s %s", archive_entry_strmode(entry), diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h index 4182cc55d4a4..25e47e96c058 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 3007000 +#define ARCHIVE_VERSION_NUMBER 3007001 #include <sys/stat.h> #include <stddef.h> /* for wchar_t */ @@ -157,7 +157,7 @@ __LA_DECL int archive_version_number(void); /* * Textual name/version of the library, useful for version displays. */ -#define ARCHIVE_VERSION_ONLY_STRING "3.7.0" +#define ARCHIVE_VERSION_ONLY_STRING "3.7.1" #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 74033564396d..f6860ec9afcb 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 3007000 +#define ARCHIVE_VERSION_NUMBER 3007001 /* * Note: archive_entry.h is for use outside of libarchive; the diff --git a/contrib/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libarchive/libarchive/archive_read_disk_posix.c index e9657f6a72e8..8d5c32f0385e 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_read_disk_posix.c @@ -1866,7 +1866,7 @@ setup_current_filesystem(struct archive_read_disk *a) #if defined(USE_READDIR_R) /* Set maximum filename length. */ #if defined(HAVE_STATVFS) - t->current_filesystem->name_max = svfs.f_namelen; + t->current_filesystem->name_max = svfs.f_namemax; #else t->current_filesystem->name_max = sfs.f_namelen; #endif diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_bzip2.c b/contrib/libarchive/libarchive/archive_read_support_filter_bzip2.c index 793d605c8725..9158e668eb42 100644 --- a/contrib/libarchive/libarchive/archive_read_support_filter_bzip2.c +++ b/contrib/libarchive/libarchive/archive_read_support_filter_bzip2.c @@ -230,7 +230,7 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p) /* Empty our output buffer. */ state->stream.next_out = state->out_block; - state->stream.avail_out = state->out_block_size; + state->stream.avail_out = (uint32_t)state->out_block_size; /* Try to fill the output buffer. */ for (;;) { @@ -288,7 +288,7 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p) return (ARCHIVE_FATAL); } state->stream.next_in = (char *)(uintptr_t)read_buf; - state->stream.avail_in = ret; + state->stream.avail_in = (uint32_t)ret; /* There is no more data, return whatever we have. */ if (ret == 0) { state->eof = 1; diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c b/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c index 1e99542d7b7b..d0fc1a83e462 100644 --- a/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c +++ b/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c @@ -584,7 +584,7 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p) state->out_block + prefix64k, (int)compressed_size, state->flags.block_maximum_size, state->out_block, - prefix64k); + (int)prefix64k); #else uncompressed_size = LZ4_decompress_safe_withPrefix64k( read_buf + 4, diff --git a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c index bb595b3e4b07..b171bea01a2f 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_7zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_7zip.c @@ -1477,9 +1477,9 @@ decompress(struct archive_read *a, struct _7zip *zip, #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) case _7Z_BZ2: zip->bzstream.next_in = (char *)(uintptr_t)t_next_in; - zip->bzstream.avail_in = t_avail_in; + zip->bzstream.avail_in = (uint32_t)t_avail_in; zip->bzstream.next_out = (char *)(uintptr_t)t_next_out; - zip->bzstream.avail_out = t_avail_out; + zip->bzstream.avail_out = (uint32_t)t_avail_out; r = BZ2_bzDecompress(&(zip->bzstream)); switch (r) { case BZ_STREAM_END: /* Found end of stream. */ @@ -3833,7 +3833,7 @@ arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size) } } - zip->bcj_ip += i; + zip->bcj_ip += (uint32_t)i; return i; } @@ -3896,7 +3896,7 @@ arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size) } } - zip->bcj_ip += i; + zip->bcj_ip += (uint32_t)i; return i; } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_lha.c b/contrib/libarchive/libarchive/archive_read_support_format_lha.c index fa907a346408..1c64b2900b8e 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_lha.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_lha.c @@ -1818,13 +1818,16 @@ lha_crc16(uint16_t crc, const void *pp, size_t len) /* This if statement expects compiler optimization will * remove the statement which will not be executed. */ #undef bswap16 +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif #if defined(_MSC_VER) && _MSC_VER >= 1400 /* Visual Studio */ # define bswap16(x) _byteswap_ushort(x) #elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ > 4) /* GCC 4.8 and later has __builtin_bswap16() */ # define bswap16(x) __builtin_bswap16(x) -#elif defined(__clang__) -/* All clang versions have __builtin_bswap16() */ +#elif defined(__clang__) && __has_builtin(__builtin_bswap16) +/* Newer clang versions have __builtin_bswap16() */ # define bswap16(x) __builtin_bswap16(x) #else # define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8)) diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar.c b/contrib/libarchive/libarchive/archive_read_support_format_rar.c index 8f239da9b39d..16b6e6eed8df 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_rar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_rar.c @@ -1062,7 +1062,7 @@ archive_read_format_rar_read_header(struct archive_read *a, return (ARCHIVE_FATAL); } p = h; - crc32_val = crc32(crc32_val, (const unsigned char *)p, to_read); + crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned int)to_read); __archive_read_consume(a, to_read); skip -= to_read; } @@ -3437,7 +3437,7 @@ compile_program(const uint8_t *bytes, size_t length) prog = calloc(1, sizeof(*prog)); if (!prog) return NULL; - prog->fingerprint = crc32(0, bytes, length) | ((uint64_t)length << 32); + prog->fingerprint = crc32(0, bytes, (unsigned int)length) | ((uint64_t)length << 32); if (membr_bits(&br, 1)) { diff --git a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c index 38979cbe91a8..1f9099439412 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_rar5.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_rar5.c @@ -2475,7 +2475,7 @@ static void update_crc(struct rar5* rar, const uint8_t* p, size_t to_read) { * `stored_crc32` info filled in. */ if(rar->file.stored_crc32 > 0) { rar->file.calculated_crc32 = - crc32(rar->file.calculated_crc32, p, to_read); + crc32(rar->file.calculated_crc32, p, (unsigned int)to_read); } /* Check if the file uses an optional BLAKE2sp checksum diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c index 0e05ea59ce67..5ba1085857bb 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c @@ -2186,11 +2186,11 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff, /* Setup buffer boundaries. */ zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff; - zip->bzstream.avail_in = in_bytes; + zip->bzstream.avail_in = (uint32_t)in_bytes; zip->bzstream.total_in_hi32 = 0; zip->bzstream.total_in_lo32 = 0; zip->bzstream.next_out = (char*) zip->uncompressed_buffer; - zip->bzstream.avail_out = zip->uncompressed_buffer_size; + zip->bzstream.avail_out = (uint32_t)zip->uncompressed_buffer_size; zip->bzstream.total_out_hi32 = 0; zip->bzstream.total_out_lo32 = 0; diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c b/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c index 7001e9c6b309..3e5c0891ae85 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c @@ -190,7 +190,7 @@ archive_compressor_bzip2_open(struct archive_write_filter *f) memset(&data->stream, 0, sizeof(data->stream)); data->stream.next_out = data->compressed; - data->stream.avail_out = data->compressed_buffer_size; + data->stream.avail_out = (uint32_t)data->compressed_buffer_size; f->write = archive_compressor_bzip2_write; /* Initialize compression library */ @@ -244,7 +244,7 @@ archive_compressor_bzip2_write(struct archive_write_filter *f, /* Compress input data to output buffer */ SET_NEXT_IN(data, buff); - data->stream.avail_in = length; + data->stream.avail_in = (uint32_t)length; if (drive_compressor(f, data, 0)) return (ARCHIVE_FATAL); return (ARCHIVE_OK); @@ -313,7 +313,7 @@ drive_compressor(struct archive_write_filter *f, return (ARCHIVE_FATAL); } data->stream.next_out = data->compressed; - data->stream.avail_out = data->compressed_buffer_size; + data->stream.avail_out = (uint32_t)data->compressed_buffer_size; } /* If there's nothing to do, we're done. */ diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c b/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c index cf19fadd5633..6ac450357d28 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c @@ -518,10 +518,10 @@ drive_compressor_independence(struct archive_write_filter *f, const char *p, } else { /* The buffer is not compressed. The compressed size was * bigger than its uncompressed size. */ - archive_le32enc(data->out, length | 0x80000000); + archive_le32enc(data->out, (uint32_t)(length | 0x80000000)); data->out += 4; memcpy(data->out, p, length); - outsize = length; + outsize = (uint32_t)length; } data->out += outsize; if (data->block_checksum) { @@ -603,10 +603,10 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p, } else { /* The buffer is not compressed. The compressed size was * bigger than its uncompressed size. */ - archive_le32enc(data->out, length | 0x80000000); + archive_le32enc(data->out, (uint32_t)(length | 0x80000000)); data->out += 4; memcpy(data->out, p, length); - outsize = length; + outsize = (uint32_t)length; } data->out += outsize; if (data->block_checksum) { diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c index f32258b460eb..584cfb668f05 100644 --- a/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c +++ b/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c @@ -214,7 +214,7 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key, if (level < minimum || level > maximum) { return (ARCHIVE_WARN); } - data->compression_level = level; + data->compression_level = (int)level; return (ARCHIVE_OK); } else if (strcmp(key, "threads") == 0) { intmax_t threads; @@ -224,7 +224,7 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key, if (threads < 0) { return (ARCHIVE_WARN); } - data->threads = threads; + data->threads = (int)threads; return (ARCHIVE_OK); #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR } else if (strcmp(key, "frame-per-file") == 0) { diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c index 9d52dbfb3941..aeefe93b38ef 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c @@ -1611,12 +1611,12 @@ hfs_write_data_block(struct archive_write_disk *a, const char *buff, "Seek failed"); return (ARCHIVE_FATAL); } else if (a->offset > a->fd_offset) { - int64_t skip = a->offset - a->fd_offset; + uint64_t skip = a->offset - a->fd_offset; char nullblock[1024]; memset(nullblock, 0, sizeof(nullblock)); while (skip > 0) { - if (skip > (int64_t)sizeof(nullblock)) + if (skip > sizeof(nullblock)) bytes_written = hfs_write_decmpfs_block( a, nullblock, sizeof(nullblock)); else @@ -1731,9 +1731,10 @@ _archive_write_disk_finish_entry(struct archive *_a) else r = hfs_write_data_block( a, null_d, a->file_remaining_bytes); - if (r < 0) + if (r < 0) { close_file_descriptor(a); return ((int)r); + } } #endif } else { diff --git a/contrib/libarchive/libarchive/archive_write_set_format_7zip.c b/contrib/libarchive/libarchive/archive_write_set_format_7zip.c index f4b34685d3d0..a5919061673d 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_7zip.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_7zip.c @@ -1809,11 +1809,11 @@ compression_init_encoder_bzip2(struct archive *a, * of ugly hackery to convert a const * pointer to * a non-const pointer. */ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = lastrm->avail_in; + strm->avail_in = (uint32_t)lastrm->avail_in; strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); strm->next_out = (char *)lastrm->next_out; - strm->avail_out = lastrm->avail_out; + strm->avail_out = (uint32_t)lastrm->avail_out; strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) { @@ -1842,11 +1842,11 @@ compression_code_bzip2(struct archive *a, * of ugly hackery to convert a const * pointer to * a non-const pointer. */ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = lastrm->avail_in; + strm->avail_in = (uint32_t)lastrm->avail_in; strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); strm->next_out = (char *)lastrm->next_out; - strm->avail_out = lastrm->avail_out; + strm->avail_out = (uint32_t)lastrm->avail_out; strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); r = BZ2_bzCompress(strm, diff --git a/contrib/libarchive/tar/write.c b/contrib/libarchive/tar/write.c index b1ec470e8a30..ac35c6f7c60e 100644 --- a/contrib/libarchive/tar/write.c +++ b/contrib/libarchive/tar/write.c @@ -694,6 +694,8 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) { if (archive_match_excluded(bsdtar->matching, in_entry)) continue; + if(edit_pathname(bsdtar, in_entry)) + continue; if ((bsdtar->flags & OPTFLAG_INTERACTIVE) && !yes("copy '%s'", archive_entry_pathname(in_entry))) continue; diff --git a/contrib/libarchive/unzip/CMakeLists.txt b/contrib/libarchive/unzip/CMakeLists.txt deleted file mode 100644 index 13b983d89db7..000000000000 --- a/contrib/libarchive/unzip/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -############################################ -# -# How to build bsdunzip -# -############################################ -IF(ENABLE_UNZIP) - - SET(bsdunzip_SOURCES - bsdunzip.c - bsdunzip_platform.h - ../libarchive_fe/err.c - ../libarchive_fe/err.h - ../libarchive_fe/lafe_platform.h - ../libarchive_fe/passphrase.c - ../libarchive_fe/passphrase.h - ) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe) - - # bsdunzip documentation - SET(bsdunzip_MANS bsdunzip.1) - - # How to build bsdunzip - ADD_EXECUTABLE(bsdunzip ${bsdunzip_SOURCES}) - IF(ENABLE_UNZIP_SHARED) - TARGET_LINK_LIBRARIES(bsdunzip archive ${ADDITIONAL_LIBS}) - ELSE(ENABLE_UNZIP_SHARED) - TARGET_LINK_LIBRARIES(bsdunzip archive_static ${ADDITIONAL_LIBS}) - SET_TARGET_PROPERTIES(bsdunzip PROPERTIES COMPILE_DEFINITIONS - LIBARCHIVE_STATIC) - ENDIF(ENABLE_UNZIP_SHARED) - - # Installation rules - INSTALL(TARGETS bsdunzip RUNTIME DESTINATION bin) - INSTALL_MAN(${bsdunzip_MANS}) -ENDIF(ENABLE_UNZIP) - -add_subdirectory(test) diff --git a/contrib/libarchive/unzip/bsdunzip.1 b/contrib/libarchive/unzip/bsdunzip.1 index 3c656ebc46e2..dda01e7b84d7 100644 --- a/contrib/libarchive/unzip/bsdunzip.1 +++ b/contrib/libarchive/unzip/bsdunzip.1 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 2, 2023 +.Dd June 27, 2023 .Dt BSDUNZIP 1 .Os .Sh NAME @@ -34,6 +34,7 @@ .Sh SYNOPSIS .Nm .Op Fl aCcfjLlnopqtuvy +.Op { Fl O | Fl I No } Ar encoding .Op Fl d Ar dir .Op Fl x Ar pattern .Op Fl P Ar password @@ -62,6 +63,9 @@ Update existing. Extract only files from the zipfile if a file with the same name already exists on disk and is older than the former. Otherwise, the file is silently skipped. +.It Fl I Ar encoding +.It Fl O Ar encoding +Convert filenames from the specified encoding. .It Fl j Ignore directories stored in the zipfile; instead, extract all files directly into the extraction directory. @@ -123,7 +127,7 @@ Currently only mode 1 is supported, which lists the file names one per line. .It Ar [member ...] Optional list of members to extract from the zipfile. -Can include patterns, e.g. +Can include patterns, e.g., .Ar 'memberdir/*' will extract all files and dirs below memberdir. .El diff --git a/contrib/libarchive/unzip/bsdunzip.c b/contrib/libarchive/unzip/bsdunzip.c index 469c69fd6efb..0b6506a18adc 100644 --- a/contrib/libarchive/unzip/bsdunzip.c +++ b/contrib/libarchive/unzip/bsdunzip.c @@ -40,6 +40,8 @@ #ifdef HAVE_SYS_QUEUE_H #include <sys/queue.h> +#else +#include "la_queue.h" #endif #ifdef HAVE_SYS_STAT_H #include <sys/stat.h> @@ -70,6 +72,12 @@ #ifdef HAVE_UNISTD_H #include <unistd.h> #endif +#if ((!defined(HAVE_UTIMENSAT) && defined(HAVE_LUTIMES)) || \ + (!defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES))) +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#endif #include <archive.h> #include <archive_entry.h> @@ -82,6 +90,7 @@ static int C_opt; /* match case-insensitively */ static int c_opt; /* extract to stdout */ static const char *d_arg; /* directory */ static int f_opt; /* update existing files only */ +static char *O_arg; /* encoding */ static int j_opt; /* junk directories */ static int L_opt; /* lowercase names */ static int n_opt; /* never overwrite */ @@ -628,9 +637,15 @@ extract_file(struct archive *a, struct archive_entry *e, char **path) int mode; struct timespec mtime; struct stat sb; - struct timespec ts[2]; int fd, check, text; const char *linkname; +#if defined(HAVE_UTIMENSAT) || defined(HAVE_FUTIMENS) + struct timespec ts[2]; +#endif +#if ((!defined(HAVE_UTIMENSAT) && defined(HAVE_LUTIMES)) || \ + (!defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES))) + struct timeval times[2]; +#endif mode = archive_entry_mode(e) & 0777; if (mode == 0) @@ -684,9 +699,18 @@ recheck: return; } +#if defined(HAVE_UTIMENSAT) || defined(HAVE_FUTIMENS) ts[0].tv_sec = 0; ts[0].tv_nsec = UTIME_NOW; ts[1] = mtime; +#endif +#if ((!defined(HAVE_UTIMENSAT) && defined(HAVE_LUTIMES)) || \ + (!defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES))) + times[0].tv_sec = 0; + times[0].tv_usec = -1; + times[1].tv_sec = mtime.tv_sec; + times[1].tv_usec = mtime.tv_nsec / 1000; +#endif /* process symlinks */ linkname = archive_entry_symlink(e); @@ -694,11 +718,19 @@ recheck: if (symlink(linkname, *path) != 0) error("symlink('%s')", *path); info(" extracting: %s -> %s\n", *path, linkname); +#ifdef HAVE_LCHMOD if (lchmod(*path, mode) != 0) warning("Cannot set mode for '%s'", *path); +#endif /* set access and modification time */ +#if defined(HAVE_UTIMENSAT) if (utimensat(AT_FDCWD, *path, ts, AT_SYMLINK_NOFOLLOW) != 0) warning("utimensat('%s')", *path); +#elif defined(HAVE_LUTIMES) + gettimeofday(×[0], NULL); + if (lutimes(*path, times) != 0) + warning("lutimes('%s')", *path); +#endif return; } @@ -716,8 +748,14 @@ recheck: info("\n"); /* set access and modification time */ +#if defined(HAVE_FUTIMENS) if (futimens(fd, ts) != 0) error("futimens('%s')", *path); +#elif defined(HAVE_FUTIMES) + gettimeofday(×[0], NULL); + if (futimes(fd, times) != 0) + error("futimes('%s')", *path); +#endif if (close(fd) != 0) error("close('%s')", *path); } @@ -961,6 +999,9 @@ unzip(const char *fn) ac(archive_read_support_format_zip(a)); + if (O_arg) + ac(archive_read_set_format_option(a, "zip", "hdrcharset", O_arg)); + if (P_arg) archive_read_add_passphrase(a, P_arg); else @@ -1043,7 +1084,7 @@ usage(void) { fprintf(stderr, -"Usage: unzip [-aCcfjLlnopqtuvyZ1] [-d dir] [-x pattern] [-P password] zipfile\n" +"Usage: unzip [-aCcfjLlnopqtuvyZ1] [{-O|-I} encoding] [-d dir] [-x pattern] [-P password] zipfile\n" " [member ...]\n"); exit(EXIT_FAILURE); } @@ -1053,8 +1094,11 @@ getopts(int argc, char *argv[]) { int opt; - optreset = optind = 1; - while ((opt = getopt(argc, argv, "aCcd:fjLlnopP:qtuvx:yZ1")) != -1) + optind = 1; +#ifdef HAVE_GETOPT_OPTRESET + optreset = 1; +#endif + while ((opt = getopt(argc, argv, "aCcd:fI:jLlnO:opP:qtuvx:yZ1")) != -1) switch (opt) { case '1': Z1_opt = 1; @@ -1074,6 +1118,10 @@ getopts(int argc, char *argv[]) case 'f': f_opt = 1; break; + case 'I': + case 'O': + O_arg = optarg; + break; case 'j': j_opt = 1; break; diff --git a/contrib/libarchive/unzip/bsdunzip_platform.h b/contrib/libarchive/unzip/bsdunzip_platform.h index 5aff5f208eab..76eca4f90902 100644 --- a/contrib/libarchive/unzip/bsdunzip_platform.h +++ b/contrib/libarchive/unzip/bsdunzip_platform.h @@ -62,14 +62,6 @@ #include "archive_entry.h" #endif -#ifndef HAVE_GETOPT_OPTRESET -/* - * If platform doesn't use optreset for resetting getopt, declare it so - * C source doesn't have to know this platform-specific difference - */ -int optreset; -#endif - /* How to mark functions that don't return. */ /* This facilitates use of some newer static code analysis tools. */ #undef __LA_DEAD diff --git a/contrib/libarchive/unzip/la_getline.c b/contrib/libarchive/unzip/la_getline.c new file mode 100644 index 000000000000..79a6bc010214 --- /dev/null +++ b/contrib/libarchive/unzip/la_getline.c @@ -0,0 +1,99 @@ +/* $NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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 "bsdunzip_platform.h" +#ifndef HAVE_GETLINE + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_STDIO_H +#include <stdio.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +static ssize_t +la_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) +{ + char *ptr, *eptr; + + + if (*buf == NULL || *bufsiz == 0) { + *bufsiz = BUFSIZ; + if ((*buf = malloc(*bufsiz)) == NULL) + return -1; + } + + for (ptr = *buf, eptr = *buf + *bufsiz;;) { + int c = fgetc(fp); + if (c == -1) { + if (feof(fp)) { + ssize_t diff = (ssize_t)(ptr - *buf); + if (diff != 0) { + *ptr = '\0'; + return diff; + } + } + return -1; + } + *ptr++ = c; + if (c == delimiter) { + *ptr = '\0'; + return ptr - *buf; + } + if (ptr + 2 >= eptr) { + char *nbuf; + size_t nbufsiz = *bufsiz * 2; + ssize_t d = ptr - *buf; + if ((nbuf = realloc(*buf, nbufsiz)) == NULL) + return -1; + *buf = nbuf; + *bufsiz = nbufsiz; + eptr = nbuf + nbufsiz; + ptr = nbuf + d; + } + } +} + +ssize_t +getline(char **buf, size_t *bufsiz, FILE *fp) +{ + return la_getdelim(buf, bufsiz, '\n', fp); +} +#endif diff --git a/contrib/libarchive/unzip/la_queue.h b/contrib/libarchive/unzip/la_queue.h new file mode 100644 index 000000000000..917526531b2a --- /dev/null +++ b/contrib/libarchive/unzip/la_queue.h @@ -0,0 +1,840 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * This file defines four types of data structures: singly-linked lists, + * singly-linked tail queues, lists and tail queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may be traversed in either direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * Below is a summary of implemented functions where: + * + means the macro is available + * - means the macro is not available + * s means the macro is available but is slow (runs in O(n) time) + * + * SLIST LIST STAILQ TAILQ + * _HEAD + + + + + * _CLASS_HEAD + + + + + * _HEAD_INITIALIZER + + + + + * _ENTRY + + + + + * _CLASS_ENTRY + + + + + * _INIT + + + + + * _EMPTY + + + + + * _FIRST + + + + + * _NEXT + + + + + * _PREV - + - + + * _LAST - - + + + * _LAST_FAST - - - + + * _FOREACH + + + + + * _FOREACH_FROM + + + + + * _FOREACH_SAFE + + + + + * _FOREACH_FROM_SAFE + + + + + * _FOREACH_REVERSE - - - + + * _FOREACH_REVERSE_FROM - - - + + * _FOREACH_REVERSE_SAFE - - - + + * _FOREACH_REVERSE_FROM_SAFE - - - + + * _INSERT_HEAD + + + + + * _INSERT_BEFORE - + - + + * _INSERT_AFTER + + + + + * _INSERT_TAIL - - + + + * _CONCAT s s + + + * _REMOVE_AFTER + - + - + * _REMOVE_HEAD + - + - + * _REMOVE s + s + + * _SWAP + + + + + */ +#ifdef QUEUE_MACRO_DEBUG +#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH +#define QUEUE_MACRO_DEBUG_TRACE +#define QUEUE_MACRO_DEBUG_TRASH +#endif + +#ifdef QUEUE_MACRO_DEBUG_TRACE +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + unsigned long lastline; + unsigned long prevline; + const char *lastfile; + const char *prevfile; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } , + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (0) + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (0) + +#else /* !QUEUE_MACRO_DEBUG_TRACE */ +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define TRACEBUF +#define TRACEBUF_INITIALIZER +#endif /* QUEUE_MACRO_DEBUG_TRACE */ + +#ifdef QUEUE_MACRO_DEBUG_TRASH +#define QMD_SAVELINK(name, link) void **name = (void *)&(link) +#define TRASHIT(x) do {(x) = (void *)-1;} while (0) +#define QMD_IS_TRASHED(x) ((x) == (void *)(intptr_t)-1) +#else /* !QUEUE_MACRO_DEBUG_TRASH */ +#define QMD_SAVELINK(name, link) +#define TRASHIT(x) +#define QMD_IS_TRASHED(x) 0 +#endif /* QUEUE_MACRO_DEBUG_TRASH */ + +#ifdef __cplusplus +/* + * In C++ there can be structure lists and class lists: + */ +#define QUEUE_TYPEOF(type) type +#else +#define QUEUE_TYPEOF(type) struct type +#endif + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_CLASS_HEAD(name, type) \ +struct name { \ + class type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +#define SLIST_CLASS_ENTRY(type) \ +struct { \ + class type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#if (defined(_KERNEL) && defined(INVARIANTS)) +#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) do { \ + if (*(prevp) != (elm)) \ + panic("Bad prevptr *(%p) == %p != %p", \ + (prevp), *(prevp), (elm)); \ +} while (0) +#else +#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) +#endif + +#define SLIST_CONCAT(head1, head2, type, field) do { \ + QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \ + if (curelm == NULL) { \ + if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \ + SLIST_INIT(head2); \ + } else if (SLIST_FIRST(head2) != NULL) { \ *** 737 LINES SKIPPED ***