diff options
author | Robert Griebl <robert.griebl@qt.io> | 2022-08-18 16:40:41 +0200 |
---|---|---|
committer | Robert Griebl <robert.griebl@qt.io> | 2022-09-16 13:15:13 +0200 |
commit | 5de64c095e2b5a230ec53dc77fbb213cb9b87093 (patch) | |
tree | c5def4b70e22ca1adbad446f33f023827995227a | |
parent | ff7a6b71093d5b7c007eee0af998daffcc0504e1 (diff) | |
download | qtapplicationmanager-5de64c095e2b5a230ec53dc77fbb213cb9b87093.tar.gz |
3rdparty update: libarchive from 3.5.1 to 3.6.1
Change-Id: I1e31754344e4880cb493b5f118e98be2ae725960
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Dominik Holland <dominik.holland@qt.io>
30 files changed, 668 insertions, 455 deletions
diff --git a/src/3rdparty/libarchive/config-windows.h b/src/3rdparty/libarchive/config-windows.h index 6019e58c..65023918 100644 --- a/src/3rdparty/libarchive/config-windows.h +++ b/src/3rdparty/libarchive/config-windows.h @@ -22,14 +22,14 @@ #define HAVE_UNSIGNED___INT64 /* The sizes of various standard integer types. */ -#define SIZE_OF_SHORT 2 -#define SIZE_OF_INT 4 -#define SIZE_OF_LONG 4 -#define SIZE_OF_LONG_LONG 8 -#define SIZE_OF_UNSIGNED_SHORT 2 -#define SIZE_OF_UNSIGNED 4 -#define SIZE_OF_UNSIGNED_LONG 4 -#define SIZE_OF_UNSIGNED_LONG_LONG 8 +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 +#define SIZEOF_LONG_LONG 8 +#define SIZEOF_UNSIGNED_SHORT 2 +#define SIZEOF_UNSIGNED 4 +#define SIZEOF_UNSIGNED_LONG 4 +#define SIZEOF_UNSIGNED_LONG_LONG 8 /* * If we lack int64_t, define it to the first of __int64, int, long, and long long @@ -40,17 +40,17 @@ typedef __int64 int64_t; #define HAVE_INT64_T #endif -#if !defined(HAVE_INT64_T) && SIZE_OF_INT == 8 +#if !defined(HAVE_INT64_T) && SIZEOF_INT == 8 typedef int int64_t; #define HAVE_INT64_T #endif -#if !defined(HAVE_INT64_T) && SIZE_OF_LONG == 8 +#if !defined(HAVE_INT64_T) && SIZEOF_LONG == 8 typedef long int64_t; #define HAVE_INT64_T #endif -#if !defined(HAVE_INT64_T) && SIZE_OF_LONG_LONG == 8 +#if !defined(HAVE_INT64_T) && SIZEOF_LONG_LONG == 8 typedef long long int64_t; #define HAVE_INT64_T #endif @@ -62,12 +62,12 @@ typedef long long int64_t; /* * Similarly for int32_t */ -#if !defined(HAVE_INT32_T) && SIZE_OF_INT == 4 +#if !defined(HAVE_INT32_T) && SIZEOF_INT == 4 typedef long int32_t; #define HAVE_INT32_T #endif -#if !defined(HAVE_INT32_T) && SIZE_OF_LONG == 4 +#if !defined(HAVE_INT32_T) && SIZEOF_LONG == 4 typedef long int32_t; #define HAVE_INT32_T #endif @@ -79,12 +79,12 @@ typedef long int32_t; /* * Similarly for int16_t */ -#if !defined(HAVE_INT16_T) && SIZE_OF_INT == 2 +#if !defined(HAVE_INT16_T) && SIZEOF_INT == 2 typedef int int16_t; #define HAVE_INT16_T #endif -#if !defined(HAVE_INT16_T) && SIZE_OF_SHORT == 2 +#if !defined(HAVE_INT16_T) && SIZEOF_SHORT == 2 typedef short int16_t; #define HAVE_INT16_T #endif @@ -101,17 +101,17 @@ typedef unsigned __int64 uint64_t; #define HAVE_UINT64_T #endif -#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED == 8 +#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED == 8 typedef unsigned uint64_t; #define HAVE_UINT64_T #endif -#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG == 8 +#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED_LONG == 8 typedef unsigned long uint64_t; #define HAVE_UINT64_T #endif -#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG_LONG == 8 +#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED_LONG_LONG == 8 typedef unsigned long long uint64_t; #define HAVE_UINT64_T #endif @@ -124,12 +124,12 @@ typedef unsigned long long uint64_t; /* * Similarly for uint32_t */ -#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED == 4 +#if !defined(HAVE_UINT32_T) && SIZEOF_UNSIGNED == 4 typedef unsigned uint32_t; #define HAVE_UINT32_T #endif -#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED_LONG == 4 +#if !defined(HAVE_UINT32_T) && SIZEOF_UNSIGNED_LONG == 4 typedef unsigned long uint32_t; #define HAVE_UINT32_T #endif @@ -141,12 +141,12 @@ typedef unsigned long uint32_t; /* * Similarly for uint16_t */ -#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED == 2 +#if !defined(HAVE_UINT16_T) && SIZEOF_UNSIGNED == 2 typedef unsigned uint16_t; #define HAVE_UINT16_T #endif -#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED_SHORT == 2 +#if !defined(HAVE_UINT16_T) && SIZEOF_UNSIGNED_SHORT == 2 typedef unsigned short uint16_t; #define HAVE_UINT16_T #endif diff --git a/src/3rdparty/libarchive/libarchive/archive.h b/src/3rdparty/libarchive/libarchive/archive.h index 52f4d782..46041eb0 100644 --- a/src/3rdparty/libarchive/libarchive/archive.h +++ b/src/3rdparty/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 3005001 +#define ARCHIVE_VERSION_NUMBER 3006001 #include <sys/stat.h> #include <stddef.h> /* for wchar_t */ @@ -97,7 +97,7 @@ typedef ssize_t la_ssize_t; #endif /* Large file support for Android */ -#ifdef __ANDROID__ +#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__) #include "android_lf.h" #endif @@ -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.5.1" +#define ARCHIVE_VERSION_ONLY_STRING "3.6.1" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); @@ -319,6 +319,7 @@ typedef const char *archive_passphrase_callback(struct archive *, #define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4) #define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5) #define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6) +#define ARCHIVE_FORMAT_CPIO_PWB (ARCHIVE_FORMAT_CPIO | 7) #define ARCHIVE_FORMAT_SHAR 0x20000 #define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1) #define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2) @@ -800,7 +801,10 @@ __LA_DECL int archive_write_set_format_7zip(struct archive *); __LA_DECL int archive_write_set_format_ar_bsd(struct archive *); __LA_DECL int archive_write_set_format_ar_svr4(struct archive *); __LA_DECL int archive_write_set_format_cpio(struct archive *); +__LA_DECL int archive_write_set_format_cpio_bin(struct archive *); __LA_DECL int archive_write_set_format_cpio_newc(struct archive *); +__LA_DECL int archive_write_set_format_cpio_odc(struct archive *); +__LA_DECL int archive_write_set_format_cpio_pwb(struct archive *); __LA_DECL int archive_write_set_format_gnutar(struct archive *); __LA_DECL int archive_write_set_format_iso9660(struct archive *); __LA_DECL int archive_write_set_format_mtree(struct archive *); @@ -1020,6 +1024,8 @@ __LA_DECL int archive_read_disk_set_atime_restored(struct archive *); #define ARCHIVE_READDISK_NO_ACL (0x0020) /* Default: File flags are read from disk. */ #define ARCHIVE_READDISK_NO_FFLAGS (0x0040) +/* Default: Sparse file information is read from disk. */ +#define ARCHIVE_READDISK_NO_SPARSE (0x0080) __LA_DECL int archive_read_disk_set_behavior(struct archive *, int flags); diff --git a/src/3rdparty/libarchive/libarchive/archive_entry.h b/src/3rdparty/libarchive/libarchive/archive_entry.h index c0e75bf9..d5cb30de 100644 --- a/src/3rdparty/libarchive/libarchive/archive_entry.h +++ b/src/3rdparty/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 3005001 +#define ARCHIVE_VERSION_NUMBER 3006001 /* * Note: archive_entry.h is for use outside of libarchive; the @@ -99,7 +99,7 @@ typedef ssize_t la_ssize_t; #endif /* Large file support for Android */ -#ifdef __ANDROID__ +#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__) #include "android_lf.h" #endif diff --git a/src/3rdparty/libarchive/libarchive/archive_getdate.c b/src/3rdparty/libarchive/libarchive/archive_getdate.c index 3ec5bba8..39e224cb 100644 --- a/src/3rdparty/libarchive/libarchive/archive_getdate.c +++ b/src/3rdparty/libarchive/libarchive/archive_getdate.c @@ -714,7 +714,7 @@ Convert(time_t Month, time_t Day, time_t Year, ? 29 : 28; /* Checking for 2038 bogusly assumes that time_t is 32 bits. But I'm too lazy to try to check for time_t overflow in another way. */ - if (Year < EPOCH || Year > 2038 + if (Year < EPOCH || Year >= 2038 || Month < 1 || Month > 12 /* Lint fluff: "conversion from long may lose accuracy" */ || Day < 1 || Day > DaysInMonth[(int)--Month] diff --git a/src/3rdparty/libarchive/libarchive/archive_pathmatch.c b/src/3rdparty/libarchive/libarchive/archive_pathmatch.c index 619e2b62..0867a268 100644 --- a/src/3rdparty/libarchive/libarchive/archive_pathmatch.c +++ b/src/3rdparty/libarchive/libarchive/archive_pathmatch.c @@ -384,6 +384,8 @@ __archive_pathmatch(const char *p, const char *s, int flags) /* Empty pattern only matches the empty string. */ if (p == NULL || *p == '\0') return (s == NULL || *s == '\0'); + else if (s == NULL) + return (0); /* Leading '^' anchors the start of the pattern. */ if (*p == '^') { @@ -424,6 +426,8 @@ __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags) /* Empty pattern only matches the empty string. */ if (p == NULL || *p == L'\0') return (s == NULL || *s == L'\0'); + else if (s == NULL) + return (0); /* Leading '^' anchors the start of the pattern. */ if (*p == L'^') { diff --git a/src/3rdparty/libarchive/libarchive/archive_platform.h b/src/3rdparty/libarchive/libarchive/archive_platform.h index b8bcb52b..3426975d 100644 --- a/src/3rdparty/libarchive/libarchive/archive_platform.h +++ b/src/3rdparty/libarchive/libarchive/archive_platform.h @@ -69,8 +69,16 @@ * either Windows or Posix APIs. */ #if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__) #include "archive_windows.h" +/* The C library on Windows specifies a calling convention for callback + * functions and exports; when we interact with them (capture pointers, + * call and pass function pointers) we need to match their calling + * convention. + * This only matters when libarchive is built with /Gr, /Gz or /Gv + * (which change the default calling convention.) */ +#define __LA_LIBC_CC __cdecl #else #define la_stat(path,stref) stat(path,stref) +#define __LA_LIBC_CC #endif /* @@ -155,6 +163,28 @@ #define INTMAX_MIN ((intmax_t)(~INTMAX_MAX)) #endif +/* Some platforms lack the standard PRIxN/PRIdN definitions. */ +#if !HAVE_INTTYPES_H || !defined(PRIx32) || !defined(PRId32) +#ifndef PRIx32 +#if SIZEOF_INT == 4 +#define PRIx32 "x" +#elif SIZEOF_LONG == 4 +#define PRIx32 "lx" +#else +#error No suitable 32-bit unsigned integer type found for this platform +#endif +#endif // PRIx32 +#ifndef PRId32 +#if SIZEOF_INT == 4 +#define PRId32 "d" +#elif SIZEOF_LONG == 4 +#define PRId32 "ld" +#else +#error No suitable 32-bit signed integer type found for this platform +#endif +#endif // PRId32 +#endif // !HAVE_INTTYPES_H || !defined(PRIx32) || !defined(PRId32) + /* * If we can't restore metadata using a file descriptor, then * for compatibility's sake, close files before trying to restore metadata. diff --git a/src/3rdparty/libarchive/libarchive/archive_private.h b/src/3rdparty/libarchive/libarchive/archive_private.h index 937a87bb..b2a2cda2 100644 --- a/src/3rdparty/libarchive/libarchive/archive_private.h +++ b/src/3rdparty/libarchive/libarchive/archive_private.h @@ -46,6 +46,13 @@ #define __LA_DEAD #endif +#if defined(__GNUC__) && (__GNUC__ > 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) +#define __LA_UNUSED __attribute__((__unused__)) +#else +#define __LA_UNUSED +#endif + #define ARCHIVE_WRITE_MAGIC (0xb0c5c0deU) #define ARCHIVE_READ_MAGIC (0xdeb0c5U) #define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U) @@ -100,14 +107,11 @@ struct archive { * Some public API functions depend on the "real" type of the * archive object. */ - struct archive_vtable *vtable; + const struct archive_vtable *vtable; int archive_format; const char *archive_format_name; - int compression_code; /* Currently active compression. */ - const char *compression_name; - /* Number of file entries processed. */ int file_count; diff --git a/src/3rdparty/libarchive/libarchive/archive_random.c b/src/3rdparty/libarchive/libarchive/archive_random.c index 65ea6915..9d1aa493 100644 --- a/src/3rdparty/libarchive/libarchive/archive_random.c +++ b/src/3rdparty/libarchive/libarchive/archive_random.c @@ -173,7 +173,7 @@ arc4_init(void) } static inline void -arc4_addrandom(u_char *dat, int datlen) +arc4_addrandom(uint8_t *dat, int datlen) { int n; uint8_t si; @@ -196,7 +196,7 @@ arc4_stir(void) struct { struct timeval tv; pid_t pid; - u_char rnd[KEYSIZE]; + uint8_t rnd[KEYSIZE]; } rdat; if (!rs_initialized) { @@ -216,7 +216,7 @@ arc4_stir(void) /* We'll just take whatever was on the stack too... */ } - arc4_addrandom((u_char *)&rdat, KEYSIZE); + arc4_addrandom((uint8_t *)&rdat, KEYSIZE); /* * Discard early keystream, as per recommendations in: @@ -258,7 +258,7 @@ arc4_getbyte(void) static void arc4random_buf(void *_buf, size_t n) { - u_char *buf = (u_char *)_buf; + uint8_t *buf = (uint8_t *)_buf; _ARC4_LOCK(); arc4_stir_if_needed(); while (n--) { diff --git a/src/3rdparty/libarchive/libarchive/archive_read.c b/src/3rdparty/libarchive/libarchive/archive_read.c index c59f0515..45a38aed 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read.c +++ b/src/3rdparty/libarchive/libarchive/archive_read.c @@ -58,7 +58,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read.c 201157 2009-12-29 05:30:2 static int choose_filters(struct archive_read *); static int choose_format(struct archive_read *); static int close_filters(struct archive_read *); -static struct archive_vtable *archive_read_vtable(void); static int64_t _archive_filter_bytes(struct archive *, int); static int _archive_filter_code(struct archive *, int); static const char *_archive_filter_name(struct archive *, int); @@ -73,26 +72,18 @@ static int _archive_read_next_header2(struct archive *, struct archive_entry *); static int64_t advance_file_pointer(struct archive_read_filter *, int64_t); -static struct archive_vtable * -archive_read_vtable(void) -{ - static struct archive_vtable av; - static int inited = 0; - - if (!inited) { - av.archive_filter_bytes = _archive_filter_bytes; - av.archive_filter_code = _archive_filter_code; - av.archive_filter_name = _archive_filter_name; - av.archive_filter_count = _archive_filter_count; - av.archive_read_data_block = _archive_read_data_block; - av.archive_read_next_header = _archive_read_next_header; - av.archive_read_next_header2 = _archive_read_next_header2; - av.archive_free = _archive_read_free; - av.archive_close = _archive_read_close; - inited = 1; - } - return (&av); -} +static const struct archive_vtable +archive_read_vtable = { + .archive_filter_bytes = _archive_filter_bytes, + .archive_filter_code = _archive_filter_code, + .archive_filter_name = _archive_filter_name, + .archive_filter_count = _archive_filter_count, + .archive_read_data_block = _archive_read_data_block, + .archive_read_next_header = _archive_read_next_header, + .archive_read_next_header2 = _archive_read_next_header2, + .archive_free = _archive_read_free, + .archive_close = _archive_read_close, +}; /* * Allocate, initialize and return a struct archive object. @@ -109,7 +100,7 @@ archive_read_new(void) a->archive.state = ARCHIVE_STATE_NEW; a->entry = archive_entry_new2(&a->archive); - a->archive.vtable = archive_read_vtable(); + a->archive.vtable = &archive_read_vtable; a->passphrases.last = &a->passphrases.first; @@ -245,18 +236,17 @@ client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence) } static int -client_close_proxy(struct archive_read_filter *self) +read_client_close_proxy(struct archive_read *a) { int r = ARCHIVE_OK, r2; unsigned int i; - if (self->archive->client.closer == NULL) + if (a->client.closer == NULL) return (r); - for (i = 0; i < self->archive->client.nodes; i++) + for (i = 0; i < a->client.nodes; i++) { - r2 = (self->archive->client.closer) - ((struct archive *)self->archive, - self->archive->client.dataset[i].data); + r2 = (a->client.closer) + ((struct archive *)a, a->client.dataset[i].data); if (r > r2) r = r2; } @@ -264,6 +254,12 @@ client_close_proxy(struct archive_read_filter *self) } static int +client_close_proxy(struct archive_read_filter *self) +{ + return read_client_close_proxy(self->archive); +} + +static int client_open_proxy(struct archive_read_filter *self) { int r = ARCHIVE_OK; @@ -298,9 +294,7 @@ client_switch_proxy(struct archive_read_filter *self, unsigned int iindex) r1 = (self->archive->client.closer) ((struct archive *)self->archive, self->data); self->data = data2; - if (self->archive->client.opener != NULL) - r2 = (self->archive->client.opener) - ((struct archive *)self->archive, self->data); + r2 = client_open_proxy(self); } return (r1 < r2) ? r1 : r2; } @@ -457,13 +451,18 @@ archive_read_prepend_callback_data(struct archive *_a, void *client_data) return archive_read_add_callback_data(_a, client_data, 0); } +static const struct archive_read_filter_vtable +none_reader_vtable = { + .read = client_read_proxy, + .close = client_close_proxy, +}; + int archive_read_open1(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; struct archive_read_filter *filter, *tmp; int slot, e = ARCHIVE_OK; - unsigned int i; archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, "archive_read_open"); @@ -481,11 +480,7 @@ archive_read_open1(struct archive *_a) e = (a->client.opener)(&a->archive, a->client.dataset[0].data); if (e != 0) { /* If the open failed, call the closer to clean up. */ - if (a->client.closer) { - for (i = 0; i < a->client.nodes; i++) - (a->client.closer)(&a->archive, - a->client.dataset[i].data); - } + read_client_close_proxy(a); return (e); } } @@ -497,14 +492,11 @@ archive_read_open1(struct archive *_a) filter->upstream = NULL; filter->archive = a; filter->data = a->client.dataset[0].data; - filter->open = client_open_proxy; - filter->read = client_read_proxy; - filter->skip = client_skip_proxy; - filter->seek = client_seek_proxy; - filter->close = client_close_proxy; - filter->sswitch = client_switch_proxy; + filter->vtable = &none_reader_vtable; filter->name = "none"; filter->code = ARCHIVE_FILTER_NONE; + filter->can_skip = 1; + filter->can_seek = 1; a->client.dataset[0].begin_position = 0; if (!a->filter || !a->bypass_filter_bidding) @@ -570,12 +562,12 @@ choose_filters(struct archive_read *a) bidder = a->bidders; for (i = 0; i < number_bidders; i++, bidder++) { - if (bidder->bid != NULL) { - bid = (bidder->bid)(bidder, a->filter); - if (bid > best_bid) { - best_bid = bid; - best_bidder = bidder; - } + if (bidder->vtable == NULL) + continue; + bid = (bidder->vtable->bid)(bidder, a->filter); + if (bid > best_bid) { + best_bid = bid; + best_bidder = bidder; } } @@ -587,8 +579,6 @@ choose_filters(struct archive_read *a) __archive_read_free_filters(a); return (ARCHIVE_FATAL); } - a->archive.compression_name = a->filter->name; - a->archive.compression_code = a->filter->code; return (ARCHIVE_OK); } @@ -600,7 +590,7 @@ choose_filters(struct archive_read *a) filter->archive = a; filter->upstream = a->filter; a->filter = filter; - r = (best_bidder->init)(a->filter); + r = (best_bidder->vtable->init)(a->filter); if (r != ARCHIVE_OK) { __archive_read_free_filters(a); return (ARCHIVE_FATAL); @@ -614,10 +604,9 @@ choose_filters(struct archive_read *a) int __archive_read_header(struct archive_read *a, struct archive_entry *entry) { - if (a->filter->read_header) - return a->filter->read_header(a->filter, entry); - else + if (!a->filter->vtable->read_header) return (ARCHIVE_OK); + return a->filter->vtable->read_header(a->filter, entry); } /* @@ -1006,8 +995,8 @@ close_filters(struct archive_read *a) /* Close each filter in the pipeline. */ while (f != NULL) { struct archive_read_filter *t = f->upstream; - if (!f->closed && f->close != NULL) { - int r1 = (f->close)(f); + if (!f->closed && f->vtable != NULL) { + int r1 = (f->vtable->close)(f); f->closed = 1; if (r1 < r) r = r1; @@ -1112,11 +1101,10 @@ _archive_read_free(struct archive *_a) /* Release the bidder objects. */ n = sizeof(a->bidders)/sizeof(a->bidders[0]); for (i = 0; i < n; i++) { - if (a->bidders[i].free != NULL) { - int r1 = (a->bidders[i].free)(&a->bidders[i]); - if (r1 < r) - r = r1; - } + if (a->bidders[i].vtable == NULL || + a->bidders[i].vtable->free == NULL) + continue; + (a->bidders[i].vtable->free)(&a->bidders[i]); } /* Release passphrase list. */ @@ -1241,19 +1229,35 @@ __archive_read_register_format(struct archive_read *a, * initialization functions. */ int -__archive_read_get_bidder(struct archive_read *a, - struct archive_read_filter_bidder **bidder) +__archive_read_register_bidder(struct archive_read *a, + void *bidder_data, + const char *name, + const struct archive_read_filter_bidder_vtable *vtable) { + struct archive_read_filter_bidder *bidder; int i, number_slots; + archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC, + ARCHIVE_STATE_NEW, "__archive_read_register_bidder"); + number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]); for (i = 0; i < number_slots; i++) { - if (a->bidders[i].bid == NULL) { - memset(a->bidders + i, 0, sizeof(a->bidders[0])); - *bidder = (a->bidders + i); - return (ARCHIVE_OK); + if (a->bidders[i].vtable != NULL) + continue; + memset(a->bidders + i, 0, sizeof(a->bidders[0])); + bidder = (a->bidders + i); + bidder->data = bidder_data; + bidder->name = name; + bidder->vtable = vtable; + if (bidder->vtable->bid == NULL || bidder->vtable->init == NULL) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, + "Internal error: " + "no bid/init for filter bidder"); + return (ARCHIVE_FATAL); } + + return (ARCHIVE_OK); } archive_set_error(&a->archive, ENOMEM, @@ -1382,7 +1386,7 @@ __archive_read_filter_ahead(struct archive_read_filter *filter, *avail = 0; return (NULL); } - bytes_read = (filter->read)(filter, + bytes_read = (filter->vtable->read)(filter, &filter->client_buff); if (bytes_read < 0) { /* Read error. */ filter->client_total = filter->client_avail = 0; @@ -1561,8 +1565,8 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request) return (total_bytes_skipped); /* If there's an optimized skip function, use it. */ - if (filter->skip != NULL) { - bytes_skipped = (filter->skip)(filter, request); + if (filter->can_skip != 0) { + bytes_skipped = client_skip_proxy(filter, request); if (bytes_skipped < 0) { /* error */ filter->fatal = 1; return (bytes_skipped); @@ -1576,7 +1580,7 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request) /* Use ordinary reads as necessary to complete the request. */ for (;;) { - bytes_read = (filter->read)(filter, &filter->client_buff); + bytes_read = (filter->vtable->read)(filter, &filter->client_buff); if (bytes_read < 0) { filter->client_buff = NULL; filter->fatal = 1; @@ -1631,7 +1635,7 @@ __archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset, if (filter->closed || filter->fatal) return (ARCHIVE_FATAL); - if (filter->seek == NULL) + if (filter->can_seek == 0) return (ARCHIVE_FAILED); client = &(filter->archive->client); diff --git a/src/3rdparty/libarchive/libarchive/archive_read_append_filter.c b/src/3rdparty/libarchive/libarchive/archive_read_append_filter.c index da7c55b9..25dc4b2a 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_append_filter.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_append_filter.c @@ -135,7 +135,7 @@ archive_read_append_filter(struct archive *_a, int code) filter->archive = a; filter->upstream = a->filter; a->filter = filter; - r2 = (bidder->init)(a->filter); + r2 = (bidder->vtable->init)(a->filter); if (r2 != ARCHIVE_OK) { __archive_read_free_filters(a); return (ARCHIVE_FATAL); @@ -192,7 +192,7 @@ archive_read_append_filter_program_signature(struct archive *_a, filter->archive = a; filter->upstream = a->filter; a->filter = filter; - r = (bidder->init)(a->filter); + r = (bidder->vtable->init)(a->filter); if (r != ARCHIVE_OK) { __archive_read_free_filters(a); return (ARCHIVE_FATAL); diff --git a/src/3rdparty/libarchive/libarchive/archive_read_disk_entry_from_file.c b/src/3rdparty/libarchive/libarchive/archive_read_disk_entry_from_file.c index 9c9cf38e..ab0270bc 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_disk_entry_from_file.c @@ -303,9 +303,11 @@ archive_read_disk_entry_from_file(struct archive *_a, if (r1 < r) r = r1; } - r1 = setup_sparse(a, entry, &fd); - if (r1 < r) - r = r1; + if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) { + r1 = setup_sparse(a, entry, &fd); + if (r1 < r) + r = r1; + } /* If we opened the file earlier in this function, close it. */ if (initial_fd != fd) diff --git a/src/3rdparty/libarchive/libarchive/archive_read_disk_posix.c b/src/3rdparty/libarchive/libarchive/archive_read_disk_posix.c index 28982069..2b39e672 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_disk_posix.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_disk_posix.c @@ -109,6 +109,11 @@ __FBSDID("$FreeBSD$"); #define O_CLOEXEC 0 #endif +#if defined(__hpux) && !defined(HAVE_DIRFD) +#define dirfd(x) ((x)->__dd_fd) +#define HAVE_DIRFD +#endif + /*- * This is a new directory-walking system that addresses a number * of problems I've had with fts(3). In particular, it has no @@ -369,22 +374,14 @@ static int open_on_current_dir(struct tree *, const char *, int); static int tree_dup(int); -static struct archive_vtable * -archive_read_disk_vtable(void) -{ - static struct archive_vtable av; - static int inited = 0; - - if (!inited) { - av.archive_free = _archive_read_free; - av.archive_close = _archive_read_close; - av.archive_read_data_block = _archive_read_data_block; - av.archive_read_next_header = _archive_read_next_header; - av.archive_read_next_header2 = _archive_read_next_header2; - inited = 1; - } - return (&av); -} +static const struct archive_vtable +archive_read_disk_vtable = { + .archive_free = _archive_read_free, + .archive_close = _archive_read_close, + .archive_read_data_block = _archive_read_data_block, + .archive_read_next_header = _archive_read_next_header, + .archive_read_next_header2 = _archive_read_next_header2, +}; const char * archive_read_disk_gname(struct archive *_a, la_int64_t gid) @@ -461,7 +458,7 @@ archive_read_disk_new(void) return (NULL); a->archive.magic = ARCHIVE_READ_DISK_MAGIC; a->archive.state = ARCHIVE_STATE_NEW; - a->archive.vtable = archive_read_disk_vtable(); + a->archive.vtable = &archive_read_disk_vtable; a->entry = archive_entry_new2(&a->archive); a->lookup_uname = trivial_lookup_uname; a->lookup_gname = trivial_lookup_gname; @@ -1290,7 +1287,7 @@ archive_read_disk_descend(struct archive *_a) ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, "archive_read_disk_descend"); - if (t->visit_type != TREE_REGULAR || !t->descend) + if (!archive_read_disk_can_descend(_a)) return (ARCHIVE_OK); /* @@ -1522,8 +1519,40 @@ get_xfer_size(struct tree *t, int fd, const char *path) } #endif -#if defined(HAVE_STATFS) && defined(HAVE_FSTATFS) && defined(MNT_LOCAL) \ - && !defined(ST_LOCAL) +#if defined(HAVE_STATVFS) +static inline __LA_UNUSED void +set_statvfs_transfer_size(struct filesystem *fs, const struct statvfs *sfs) +{ + fs->xfer_align = sfs->f_frsize > 0 ? (long)sfs->f_frsize : -1; + fs->max_xfer_size = -1; +#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE) + fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; + fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; +#else + fs->min_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; + fs->incr_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; +#endif +} +#endif + +#if defined(HAVE_STRUCT_STATFS) +static inline __LA_UNUSED void +set_statfs_transfer_size(struct filesystem *fs, const struct statfs *sfs) +{ + fs->xfer_align = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; + fs->max_xfer_size = -1; +#if defined(HAVE_STRUCT_STATFS_F_IOSIZE) + fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; + fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; +#else + fs->min_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; + fs->incr_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; +#endif +} +#endif + +#if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) && \ + defined(HAVE_FSTATFS) && defined(MNT_LOCAL) && !defined(ST_LOCAL) /* * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X. @@ -1593,10 +1622,7 @@ setup_current_filesystem(struct archive_read_disk *a) return (ARCHIVE_FAILED); } else if (xr == 1) { /* pathconf(_PC_REX_*) operations are not supported. */ - t->current_filesystem->xfer_align = sfs.f_bsize; - t->current_filesystem->max_xfer_size = -1; - t->current_filesystem->min_xfer_size = sfs.f_iosize; - t->current_filesystem->incr_xfer_size = sfs.f_iosize; + set_statfs_transfer_size(t->current_filesystem, &sfs); } if (sfs.f_flags & MNT_LOCAL) t->current_filesystem->remote = 0; @@ -1688,15 +1714,7 @@ setup_current_filesystem(struct archive_read_disk *a) } else if (xr == 1) { /* Usually come here unless NetBSD supports _PC_REC_XFER_ALIGN * for pathconf() function. */ - t->current_filesystem->xfer_align = svfs.f_frsize; - t->current_filesystem->max_xfer_size = -1; -#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE) - t->current_filesystem->min_xfer_size = svfs.f_iosize; - t->current_filesystem->incr_xfer_size = svfs.f_iosize; -#else - t->current_filesystem->min_xfer_size = svfs.f_bsize; - t->current_filesystem->incr_xfer_size = svfs.f_bsize; -#endif + set_statvfs_transfer_size(t->current_filesystem, &svfs); } if (svfs.f_flag & ST_LOCAL) t->current_filesystem->remote = 0; @@ -1803,15 +1821,9 @@ setup_current_filesystem(struct archive_read_disk *a) } else if (xr == 1) { /* pathconf(_PC_REX_*) operations are not supported. */ #if defined(HAVE_STATVFS) - t->current_filesystem->xfer_align = svfs.f_frsize; - t->current_filesystem->max_xfer_size = -1; - t->current_filesystem->min_xfer_size = svfs.f_bsize; - t->current_filesystem->incr_xfer_size = svfs.f_bsize; + set_statvfs_transfer_size(t->current_filesystem, &svfs); #else - t->current_filesystem->xfer_align = sfs.f_frsize; - t->current_filesystem->max_xfer_size = -1; - t->current_filesystem->min_xfer_size = sfs.f_bsize; - t->current_filesystem->incr_xfer_size = sfs.f_bsize; + set_statfs_transfer_size(t->current_filesystem, &sfs); #endif } switch (sfs.f_type) { @@ -1918,10 +1930,7 @@ setup_current_filesystem(struct archive_read_disk *a) return (ARCHIVE_FAILED); } else if (xr == 1) { /* pathconf(_PC_REX_*) operations are not supported. */ - t->current_filesystem->xfer_align = svfs.f_frsize; - t->current_filesystem->max_xfer_size = -1; - t->current_filesystem->min_xfer_size = svfs.f_bsize; - t->current_filesystem->incr_xfer_size = svfs.f_bsize; + set_statvfs_transfer_size(t->current_filesystem, &svfs); } #if defined(ST_NOATIME) @@ -2424,7 +2433,7 @@ tree_dir_next_posix(struct tree *t) #else /* HAVE_FDOPENDIR */ if (tree_enter_working_dir(t) == 0) { t->d = opendir("."); -#if HAVE_DIRFD || defined(dirfd) +#ifdef HAVE_DIRFD __archive_ensure_cloexec_flag(dirfd(t->d)); #endif } diff --git a/src/3rdparty/libarchive/libarchive/archive_read_disk_windows.c b/src/3rdparty/libarchive/libarchive/archive_read_disk_windows.c index fdd376f9..ea32e2aa 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_disk_windows.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_disk_windows.c @@ -449,22 +449,14 @@ entry_symlink_from_pathw(struct archive_entry *entry, const wchar_t *path) return; } -static struct archive_vtable * -archive_read_disk_vtable(void) -{ - static struct archive_vtable av; - static int inited = 0; - - if (!inited) { - av.archive_free = _archive_read_free; - av.archive_close = _archive_read_close; - av.archive_read_data_block = _archive_read_data_block; - av.archive_read_next_header = _archive_read_next_header; - av.archive_read_next_header2 = _archive_read_next_header2; - inited = 1; - } - return (&av); -} +static const struct archive_vtable +archive_read_disk_vtable = { + .archive_free = _archive_read_free, + .archive_close = _archive_read_close, + .archive_read_data_block = _archive_read_data_block, + .archive_read_next_header = _archive_read_next_header, + .archive_read_next_header2 = _archive_read_next_header2, +}; const char * archive_read_disk_gname(struct archive *_a, la_int64_t gid) @@ -541,7 +533,7 @@ archive_read_disk_new(void) return (NULL); a->archive.magic = ARCHIVE_READ_DISK_MAGIC; a->archive.state = ARCHIVE_STATE_NEW; - a->archive.vtable = archive_read_disk_vtable(); + a->archive.vtable = &archive_read_disk_vtable; a->entry = archive_entry_new2(&a->archive); a->lookup_uname = trivial_lookup_uname; a->lookup_gname = trivial_lookup_gname; @@ -1090,9 +1082,11 @@ next_entry(struct archive_read_disk *a, struct tree *t, } /* Find sparse data from the disk. */ - if (archive_entry_hardlink(entry) == NULL && - (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0) - r = setup_sparse_from_disk(a, entry, t->entry_fh); + if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) { + if (archive_entry_hardlink(entry) == NULL && + (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0) + r = setup_sparse_from_disk(a, entry, t->entry_fh); + } } return (r); } @@ -1300,7 +1294,7 @@ archive_read_disk_descend(struct archive *_a) ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, "archive_read_disk_descend"); - if (t->visit_type != TREE_REGULAR || !t->descend) + if (!archive_read_disk_can_descend(_a)) return (ARCHIVE_OK); if (tree_current_is_physical_dir(t)) { @@ -1844,7 +1838,7 @@ tree_next(struct tree *t) continue; return (r); } else { - HANDLE h = FindFirstFileW(d, &t->_findData); + HANDLE h = FindFirstFileW(t->stack->full_path.s, &t->_findData); if (h == INVALID_HANDLE_VALUE) { la_dosmaperr(GetLastError()); t->tree_errno = errno; @@ -2371,9 +2365,11 @@ archive_read_disk_entry_from_file(struct archive *_a, return (ARCHIVE_OK); } - r = setup_sparse_from_disk(a, entry, h); - if (fd < 0) - CloseHandle(h); + if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) { + r = setup_sparse_from_disk(a, entry, h); + if (fd < 0) + CloseHandle(h); + } return (r); } diff --git a/src/3rdparty/libarchive/libarchive/archive_read_private.h b/src/3rdparty/libarchive/libarchive/archive_read_private.h index c842e6f0..383405d5 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_private.h +++ b/src/3rdparty/libarchive/libarchive/archive_read_private.h @@ -42,6 +42,16 @@ struct archive_read; struct archive_read_filter_bidder; struct archive_read_filter; +struct archive_read_filter_bidder_vtable { + /* Taste the upstream filter to see if we handle this. */ + int (*bid)(struct archive_read_filter_bidder *, + struct archive_read_filter *); + /* Initialize a newly-created filter. */ + int (*init)(struct archive_read_filter *); + /* Release the bidder's configuration data. */ + void (*free)(struct archive_read_filter_bidder *); +}; + /* * How bidding works for filters: * * The bid manager initializes the client-provided reader as the @@ -62,16 +72,16 @@ struct archive_read_filter_bidder { void *data; /* Name of the filter */ const char *name; - /* Taste the upstream filter to see if we handle this. */ - int (*bid)(struct archive_read_filter_bidder *, - struct archive_read_filter *); - /* Initialize a newly-created filter. */ - int (*init)(struct archive_read_filter *); - /* Set an option for the filter bidder. */ - int (*options)(struct archive_read_filter_bidder *, - const char *key, const char *value); - /* Release the bidder's configuration data. */ - int (*free)(struct archive_read_filter_bidder *); + const struct archive_read_filter_bidder_vtable *vtable; +}; + +struct archive_read_filter_vtable { + /* Return next block. */ + ssize_t (*read)(struct archive_read_filter *, const void **); + /* Close (just this filter) and free(self). */ + int (*close)(struct archive_read_filter *self); + /* Read any header metadata if available. */ + int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry); }; /* @@ -86,25 +96,14 @@ struct archive_read_filter { struct archive_read_filter_bidder *bidder; /* My bidder. */ struct archive_read_filter *upstream; /* Who I read from. */ struct archive_read *archive; /* Associated archive. */ - /* Open a block for reading */ - int (*open)(struct archive_read_filter *self); - /* Return next block. */ - ssize_t (*read)(struct archive_read_filter *, const void **); - /* Skip forward this many bytes. */ - int64_t (*skip)(struct archive_read_filter *self, int64_t request); - /* Seek to an absolute location. */ - int64_t (*seek)(struct archive_read_filter *self, int64_t offset, int whence); - /* Close (just this filter) and free(self). */ - int (*close)(struct archive_read_filter *self); - /* Function that handles switching from reading one block to the next/prev */ - int (*sswitch)(struct archive_read_filter *self, unsigned int iindex); - /* Read any header metadata if available. */ - int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry); + const struct archive_read_filter_vtable *vtable; /* My private data. */ void *data; const char *name; int code; + int can_skip; + int can_seek; /* Used by reblocking logic. */ char *buffer; @@ -242,8 +241,10 @@ int __archive_read_register_format(struct archive_read *a, int (*format_capabilities)(struct archive_read *), int (*has_encrypted_entries)(struct archive_read *)); -int __archive_read_get_bidder(struct archive_read *a, - struct archive_read_filter_bidder **bidder); +int __archive_read_register_bidder(struct archive_read *a, + void *bidder_data, + const char *name, + const struct archive_read_filter_bidder_vtable *vtable); const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *); const void *__archive_read_filter_ahead(struct archive_read_filter *, diff --git a/src/3rdparty/libarchive/libarchive/archive_read_set_options.c b/src/3rdparty/libarchive/libarchive/archive_read_set_options.c index 2e2eea69..2bd9b811 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_set_options.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_set_options.c @@ -112,37 +112,15 @@ static int archive_set_filter_option(struct archive *_a, const char *m, const char *o, const char *v) { - struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter *filter; - struct archive_read_filter_bidder *bidder; - int r, rv = ARCHIVE_WARN, matched_modules = 0; - - for (filter = a->filter; filter != NULL; filter = filter->upstream) { - bidder = filter->bidder; - if (bidder == NULL) - continue; - if (bidder->options == NULL) - /* This bidder does not support option */ - continue; - if (m != NULL) { - if (strcmp(filter->name, m) != 0) - continue; - ++matched_modules; - } + (void)_a; /* UNUSED */ + (void)o; /* UNUSED */ + (void)v; /* UNUSED */ - r = bidder->options(bidder, o, v); - - if (r == ARCHIVE_FATAL) - return (ARCHIVE_FATAL); - - if (r == ARCHIVE_OK) - rv = ARCHIVE_OK; - } /* If the filter name didn't match, return a special code for * _archive_set_option[s]. */ - if (m != NULL && matched_modules == 0) + if (m != NULL) return ARCHIVE_WARN - 1; - return (rv); + return ARCHIVE_WARN; } static int diff --git a/src/3rdparty/libarchive/libarchive/archive_read_support_filter_bzip2.c b/src/3rdparty/libarchive/libarchive/archive_read_support_filter_bzip2.c index 3885a7cf..793d605c 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_support_filter_bzip2.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_support_filter_bzip2.c @@ -70,7 +70,6 @@ static int bzip2_filter_close(struct archive_read_filter *); */ static int bzip2_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *); static int bzip2_reader_init(struct archive_read_filter *); -static int bzip2_reader_free(struct archive_read_filter_bidder *); #if ARCHIVE_VERSION_NUMBER < 4000000 /* Deprecated; remove in libarchive 4.0 */ @@ -81,24 +80,21 @@ archive_read_support_compression_bzip2(struct archive *a) } #endif +static const struct archive_read_filter_bidder_vtable +bzip2_bidder_vtable = { + .bid = bzip2_reader_bid, + .init = bzip2_reader_init, +}; + int archive_read_support_filter_bzip2(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *reader; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_bzip2"); - if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "bzip2", + &bzip2_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - reader->data = NULL; - reader->name = "bzip2"; - reader->bid = bzip2_reader_bid; - reader->init = bzip2_reader_init; - reader->options = NULL; - reader->free = bzip2_reader_free; #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) return (ARCHIVE_OK); #else @@ -108,12 +104,6 @@ archive_read_support_filter_bzip2(struct archive *_a) #endif } -static int -bzip2_reader_free(struct archive_read_filter_bidder *self){ - (void)self; /* UNUSED */ - return (ARCHIVE_OK); -} - /* * Test whether we can handle this data. * @@ -183,6 +173,12 @@ bzip2_reader_init(struct archive_read_filter *self) #else +static const struct archive_read_filter_vtable +bzip2_reader_vtable = { + .read = bzip2_filter_read, + .close = bzip2_filter_close, +}; + /* * Setup the callbacks. */ @@ -209,9 +205,7 @@ bzip2_reader_init(struct archive_read_filter *self) self->data = state; state->out_block_size = out_block_size; state->out_block = out_block; - self->read = bzip2_filter_read; - self->skip = NULL; /* not supported */ - self->close = bzip2_filter_close; + self->vtable = &bzip2_reader_vtable; return (ARCHIVE_OK); } diff --git a/src/3rdparty/libarchive/libarchive/archive_read_support_filter_gzip.c b/src/3rdparty/libarchive/libarchive/archive_read_support_filter_gzip.c index 9fa9e2b0..4135a636 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_support_filter_gzip.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_support_filter_gzip.c @@ -94,24 +94,21 @@ archive_read_support_compression_gzip(struct archive *a) } #endif +static const struct archive_read_filter_bidder_vtable +gzip_bidder_vtable = { + .bid = gzip_bidder_bid, + .init = gzip_bidder_init, +}; + int archive_read_support_filter_gzip(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_gzip"); - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "gzip", + &gzip_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "gzip"; - bidder->bid = gzip_bidder_bid; - bidder->init = gzip_bidder_init; - bidder->options = NULL; - bidder->free = NULL; /* No data, so no cleanup necessary. */ /* Signal the extent of gzip support with the return value here. */ #if HAVE_ZLIB_H return (ARCHIVE_OK); @@ -291,6 +288,15 @@ gzip_read_header(struct archive_read_filter *self, struct archive_entry *entry) return (ARCHIVE_OK); } +static const struct archive_read_filter_vtable +gzip_reader_vtable = { + .read = gzip_filter_read, + .close = gzip_filter_close, +#ifdef HAVE_ZLIB_H + .read_header = gzip_read_header, +#endif +}; + /* * Initialize the filter object. */ @@ -317,12 +323,7 @@ gzip_bidder_init(struct archive_read_filter *self) self->data = state; state->out_block_size = out_block_size; state->out_block = out_block; - self->read = gzip_filter_read; - self->skip = NULL; /* not supported */ - self->close = gzip_filter_close; -#ifdef HAVE_ZLIB_H - self->read_header = gzip_read_header; -#endif + self->vtable = &gzip_reader_vtable; state->in_stream = 0; /* We're not actually within a stream yet. */ diff --git a/src/3rdparty/libarchive/libarchive/archive_read_support_filter_program.c b/src/3rdparty/libarchive/libarchive/archive_read_support_filter_program.c index bf5b6f2b..885b2c20 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_support_filter_program.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_support_filter_program.c @@ -98,7 +98,7 @@ struct program_bidder { static int program_bidder_bid(struct archive_read_filter_bidder *, struct archive_read_filter *upstream); static int program_bidder_init(struct archive_read_filter *); -static int program_bidder_free(struct archive_read_filter_bidder *); +static void program_bidder_free(struct archive_read_filter_bidder *); /* * The actual filter needs to track input and output data. @@ -123,43 +123,21 @@ static ssize_t program_filter_read(struct archive_read_filter *, static int program_filter_close(struct archive_read_filter *); static void free_state(struct program_bidder *); -static int -set_bidder_signature(struct archive_read_filter_bidder *bidder, - struct program_bidder *state, const void *signature, size_t signature_len) -{ - - if (signature != NULL && signature_len > 0) { - state->signature_len = signature_len; - state->signature = malloc(signature_len); - memcpy(state->signature, signature, signature_len); - } - - /* - * Fill in the bidder object. - */ - bidder->data = state; - bidder->bid = program_bidder_bid; - bidder->init = program_bidder_init; - bidder->options = NULL; - bidder->free = program_bidder_free; - return (ARCHIVE_OK); -} +static const struct archive_read_filter_bidder_vtable +program_bidder_vtable = { + .bid = program_bidder_bid, + .init = program_bidder_init, + .free = program_bidder_free, +}; int archive_read_support_filter_program_signature(struct archive *_a, const char *cmd, const void *signature, size_t signature_len) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; struct program_bidder *state; /* - * Get a bidder object from the read core. - */ - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* * Allocate our private state. */ state = (struct program_bidder *)calloc(1, sizeof (*state)); @@ -169,20 +147,31 @@ archive_read_support_filter_program_signature(struct archive *_a, if (state->cmd == NULL) goto memerr; - return set_bidder_signature(bidder, state, signature, signature_len); + if (signature != NULL && signature_len > 0) { + state->signature_len = signature_len; + state->signature = malloc(signature_len); + memcpy(state->signature, signature, signature_len); + } + + if (__archive_read_register_bidder(a, state, NULL, + &program_bidder_vtable) != ARCHIVE_OK) { + free_state(state); + return (ARCHIVE_FATAL); + } + return (ARCHIVE_OK); + memerr: free_state(state); archive_set_error(_a, ENOMEM, "Can't allocate memory"); return (ARCHIVE_FATAL); } -static int +static void program_bidder_free(struct archive_read_filter_bidder *self) { struct program_bidder *state = (struct program_bidder *)self->data; free_state(state); - return (ARCHIVE_OK); } static void @@ -393,6 +382,12 @@ child_read(struct archive_read_filter *self, char *buf, size_t buf_len) } } +static const struct archive_read_filter_vtable +program_reader_vtable = { + .read = program_filter_read, + .close = program_filter_close, +}; + int __archive_read_program(struct archive_read_filter *self, const char *cmd) { @@ -439,9 +434,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd) } self->data = state; - self->read = program_filter_read; - self->skip = NULL; - self->close = program_filter_close; + self->vtable = &program_reader_vtable; /* XXX Check that we can read at least one byte? */ return (ARCHIVE_OK); diff --git a/src/3rdparty/libarchive/libarchive/archive_read_support_filter_xz.c b/src/3rdparty/libarchive/libarchive/archive_read_support_filter_xz.c index 11807cf6..32ae0be9 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_support_filter_xz.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_support_filter_xz.c @@ -108,24 +108,21 @@ archive_read_support_compression_xz(struct archive *a) } #endif +static const struct archive_read_filter_bidder_vtable +xz_bidder_vtable = { + .bid = xz_bidder_bid, + .init = xz_bidder_init, +}; + int archive_read_support_filter_xz(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_xz"); - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "xz", + &xz_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "xz"; - bidder->bid = xz_bidder_bid; - bidder->init = xz_bidder_init; - bidder->options = NULL; - bidder->free = NULL; #if HAVE_LZMA_H && HAVE_LIBLZMA return (ARCHIVE_OK); #else @@ -143,24 +140,21 @@ archive_read_support_compression_lzma(struct archive *a) } #endif +static const struct archive_read_filter_bidder_vtable +lzma_bidder_vtable = { + .bid = lzma_bidder_bid, + .init = lzma_bidder_init, +}; + int archive_read_support_filter_lzma(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_lzma"); - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "lzma", + &lzma_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "lzma"; - bidder->bid = lzma_bidder_bid; - bidder->init = lzma_bidder_init; - bidder->options = NULL; - bidder->free = NULL; #if HAVE_LZMA_H && HAVE_LIBLZMA return (ARCHIVE_OK); #else @@ -179,24 +173,21 @@ archive_read_support_compression_lzip(struct archive *a) } #endif +static const struct archive_read_filter_bidder_vtable +lzip_bidder_vtable = { + .bid = lzip_bidder_bid, + .init = lzip_bidder_init, +}; + int archive_read_support_filter_lzip(struct archive *_a) { struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_lzip"); - if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK) + if (__archive_read_register_bidder(a, NULL, "lzip", + &lzip_bidder_vtable) != ARCHIVE_OK) return (ARCHIVE_FATAL); - bidder->data = NULL; - bidder->name = "lzip"; - bidder->bid = lzip_bidder_bid; - bidder->init = lzip_bidder_init; - bidder->options = NULL; - bidder->free = NULL; #if HAVE_LZMA_H && HAVE_LIBLZMA return (ARCHIVE_OK); #else @@ -293,8 +284,8 @@ lzma_bidder_bid(struct archive_read_filter_bidder *self, /* Second through fifth bytes are dictionary size, stored in * little-endian order. The minimum dictionary size is * 1 << 12(4KiB) which the lzma of LZMA SDK uses with option - * -d12 and the maximum dictionary size is 1 << 27(128MiB) - * which the one uses with option -d27. + * -d12 and the maximum dictionary size is 1 << 29(512MiB) + * which the one uses with option -d29. * NOTE: A comment of LZMA SDK source code says this dictionary * range is from 1 << 12 to 1 << 30. */ dicsize = archive_le32dec(buffer+1); @@ -377,7 +368,7 @@ lzip_has_member(struct archive_read_filter *filter) /* Dictionary size. */ log2dic = buffer[5] & 0x1f; - if (log2dic < 12 || log2dic > 27) + if (log2dic < 12 || log2dic > 29) return (0); bits_checked += 8; @@ -470,6 +461,12 @@ set_error(struct archive_read_filter *self, int ret) } } +static const struct archive_read_filter_vtable +xz_lzma_reader_vtable = { + .read = xz_filter_read, + .close = xz_filter_close, +}; + /* * Setup the callbacks. */ @@ -494,9 +491,7 @@ xz_lzma_bidder_init(struct archive_read_filter *self) self->data = state; state->out_block_size = out_block_size; state->out_block = out_block; - self->read = xz_filter_read; - self->skip = NULL; /* not supported */ - self->close = xz_filter_close; + self->vtable = &xz_lzma_reader_vtable; state->stream.avail_in = 0; @@ -562,7 +557,7 @@ lzip_init(struct archive_read_filter *self) /* Get dictionary size. */ log2dic = h[5] & 0x1f; - if (log2dic < 12 || log2dic > 27) + if (log2dic < 12 || log2dic > 29) return (ARCHIVE_FATAL); dicsize = 1U << log2dic; if (log2dic > 12) diff --git a/src/3rdparty/libarchive/libarchive/archive_read_support_format_tar.c b/src/3rdparty/libarchive/libarchive/archive_read_support_format_tar.c index 96d81018..bfdad7f8 100644 --- a/src/3rdparty/libarchive/libarchive/archive_read_support_format_tar.c +++ b/src/3rdparty/libarchive/libarchive/archive_read_support_format_tar.c @@ -573,11 +573,15 @@ archive_read_format_tar_read_header(struct archive_read *a, l = wcslen(wp); if (l > 0 && wp[l - 1] == L'/') { archive_entry_set_filetype(entry, AE_IFDIR); + tar->entry_bytes_remaining = 0; + tar->entry_padding = 0; } } else if ((p = archive_entry_pathname(entry)) != NULL) { l = strlen(p); if (l > 0 && p[l - 1] == '/') { archive_entry_set_filetype(entry, AE_IFDIR); + tar->entry_bytes_remaining = 0; + tar->entry_padding = 0; } } } @@ -1396,6 +1400,7 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar, struct archive_entry *entry, const void *h, size_t *unconsumed) { int64_t size; + size_t msize; const void *data; const char *p, *name; const wchar_t *wp, *wname; @@ -1434,6 +1439,11 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar, /* Read the body as a Mac OS metadata blob. */ size = archive_entry_size(entry); + msize = (size_t)size; + if (size < 0 || (uintmax_t)msize != (uintmax_t)size) { + *unconsumed = 0; + return (ARCHIVE_FATAL); + } /* * TODO: Look beyond the body here to peek at the next header. @@ -1447,13 +1457,13 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar, * Q: Is the above idea really possible? Even * when there are GNU or pax extension entries? */ - data = __archive_read_ahead(a, (size_t)size, NULL); + data = __archive_read_ahead(a, msize, NULL); if (data == NULL) { *unconsumed = 0; return (ARCHIVE_FATAL); } - archive_entry_copy_mac_metadata(entry, data, (size_t)size); - *unconsumed = (size_t)((size + 511) & ~ 511); + archive_entry_copy_mac_metadata(entry, data, msize); + *unconsumed = (msize + 511) & ~ 511; tar_flush_unconsumed(a, unconsumed); return (tar_read_header(a, tar, entry, unconsumed)); } @@ -1906,7 +1916,7 @@ pax_attribute(struct archive_read *a, struct tar *tar, } if (strcmp(key, "GNU.sparse.numbytes") == 0) { tar->sparse_numbytes = tar_atol10(value, strlen(value)); - if (tar->sparse_numbytes != -1) { + if (tar->sparse_offset != -1) { if (gnu_add_sparse_entry(a, tar, tar->sparse_offset, tar->sparse_numbytes) != ARCHIVE_OK) @@ -2643,14 +2653,14 @@ tar_atol_base_n(const char *p, size_t char_cnt, int base) maxval = INT64_MIN; limit = -(INT64_MIN / base); - last_digit_limit = INT64_MIN % base; + last_digit_limit = -(INT64_MIN % base); } l = 0; if (char_cnt != 0) { digit = *p - '0'; while (digit >= 0 && digit < base && char_cnt != 0) { - if (l>limit || (l == limit && digit > last_digit_limit)) { + if (l>limit || (l == limit && digit >= last_digit_limit)) { return maxval; /* Truncate on overflow. */ } l = (l * base) + digit; diff --git a/src/3rdparty/libarchive/libarchive/archive_string.c b/src/3rdparty/libarchive/libarchive/archive_string.c index 7460ded0..d7f2c46b 100644 --- a/src/3rdparty/libarchive/libarchive/archive_string.c +++ b/src/3rdparty/libarchive/libarchive/archive_string.c @@ -745,7 +745,7 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as, dp = &defchar_used; count = WideCharToMultiByte(to_cp, 0, ws, wslen, as->s + as->length, - (int)as->buffer_length - as->length - 1, NULL, dp); + (int)as->buffer_length - (int)as->length - 1, NULL, dp); if (count == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { /* Expand the MBS buffer and retry. */ diff --git a/src/3rdparty/libarchive/libarchive/archive_write.c b/src/3rdparty/libarchive/libarchive/archive_write.c index 8d70f51a..66592e82 100644 --- a/src/3rdparty/libarchive/libarchive/archive_write.c +++ b/src/3rdparty/libarchive/libarchive/archive_write.c @@ -60,8 +60,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03: #include "archive_private.h" #include "archive_write_private.h" -static struct archive_vtable *archive_write_vtable(void); - static int _archive_filter_code(struct archive *, int); static const char *_archive_filter_name(struct archive *, int); static int64_t _archive_filter_bytes(struct archive *, int); @@ -79,26 +77,18 @@ struct archive_none { char *next; }; -static struct archive_vtable * -archive_write_vtable(void) -{ - static struct archive_vtable av; - static int inited = 0; - - if (!inited) { - av.archive_close = _archive_write_close; - av.archive_filter_bytes = _archive_filter_bytes; - av.archive_filter_code = _archive_filter_code; - av.archive_filter_name = _archive_filter_name; - av.archive_filter_count = _archive_write_filter_count; - av.archive_free = _archive_write_free; - av.archive_write_header = _archive_write_header; - av.archive_write_finish_entry = _archive_write_finish_entry; - av.archive_write_data = _archive_write_data; - inited = 1; - } - return (&av); -} +static const struct archive_vtable +archive_write_vtable = { + .archive_close = _archive_write_close, + .archive_filter_bytes = _archive_filter_bytes, + .archive_filter_code = _archive_filter_code, + .archive_filter_name = _archive_filter_name, + .archive_filter_count = _archive_write_filter_count, + .archive_free = _archive_write_free, + .archive_write_header = _archive_write_header, + .archive_write_finish_entry = _archive_write_finish_entry, + .archive_write_data = _archive_write_data, +}; /* * Allocate, initialize and return an archive object. @@ -114,7 +104,7 @@ archive_write_new(void) return (NULL); a->archive.magic = ARCHIVE_WRITE_MAGIC; a->archive.state = ARCHIVE_STATE_NEW; - a->archive.vtable = archive_write_vtable(); + a->archive.vtable = &archive_write_vtable; /* * The value 10240 here matches the traditional tar default, * but is otherwise arbitrary. @@ -482,6 +472,8 @@ archive_write_client_close(struct archive_write_filter *f) ssize_t block_length; ssize_t target_block_length; ssize_t bytes_written; + size_t to_write; + char *p; int ret = ARCHIVE_OK; /* If there's pending data, pad and write the last block */ @@ -504,9 +496,24 @@ archive_write_client_close(struct archive_write_filter *f) target_block_length - block_length); block_length = target_block_length; } - bytes_written = (a->client_writer)(&a->archive, - a->client_data, state->buffer, block_length); - ret = bytes_written <= 0 ? ARCHIVE_FATAL : ARCHIVE_OK; + p = state->buffer; + to_write = block_length; + while (to_write > 0) { + bytes_written = (a->client_writer)(&a->archive, + a->client_data, p, to_write); + if (bytes_written <= 0) { + ret = ARCHIVE_FATAL; + break; + } + if ((size_t)bytes_written > to_write) { + archive_set_error(&(a->archive), + -1, "write overrun"); + ret = ARCHIVE_FATAL; + break; + } + p += bytes_written; + to_write -= bytes_written; + } } if (a->client_closer) (*a->client_closer)(&a->archive, a->client_data); diff --git a/src/3rdparty/libarchive/libarchive/archive_write_add_filter_xz.c b/src/3rdparty/libarchive/libarchive/archive_write_add_filter_xz.c index 9dd2c30e..04bee90e 100644 --- a/src/3rdparty/libarchive/libarchive/archive_write_add_filter_xz.c +++ b/src/3rdparty/libarchive/libarchive/archive_write_add_filter_xz.c @@ -251,13 +251,13 @@ archive_compressor_xz_init_stream(struct archive_write_filter *f, int ds, log2dic, wedges; /* Calculate a coded dictionary size */ - if (dict_size < (1 << 12) || dict_size > (1 << 27)) { + if (dict_size < (1 << 12) || dict_size > (1 << 29)) { archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, "Unacceptable dictionary size for lzip: %d", dict_size); return (ARCHIVE_FATAL); } - for (log2dic = 27; log2dic >= 12; log2dic--) { + for (log2dic = 29; log2dic >= 12; log2dic--) { if (dict_size & (1 << log2dic)) break; } diff --git a/src/3rdparty/libarchive/libarchive/archive_write_disk_posix.c b/src/3rdparty/libarchive/libarchive/archive_write_disk_posix.c index 7e32fca9..dd7eb9a5 100644 --- a/src/3rdparty/libarchive/libarchive/archive_write_disk_posix.c +++ b/src/3rdparty/libarchive/libarchive/archive_write_disk_posix.c @@ -173,6 +173,7 @@ struct fixup_entry { struct fixup_entry *next; struct archive_acl acl; mode_t mode; + __LA_MODE_T filetype; int64_t atime; int64_t birthtime; int64_t mtime; @@ -357,10 +358,11 @@ struct archive_write_disk { static int la_opendirat(int, const char *); static int la_mktemp(struct archive_write_disk *); +static int la_verify_filetype(mode_t, __LA_MODE_T); static void fsobj_error(int *, struct archive_string *, int, const char *, const char *); static int check_symlinks_fsobj(char *, int *, struct archive_string *, - int); + int, int); static int check_symlinks(struct archive_write_disk *); static int create_filesystem_object(struct archive_write_disk *); static struct fixup_entry *current_fixup(struct archive_write_disk *, @@ -396,8 +398,6 @@ static struct fixup_entry *sort_dir_list(struct fixup_entry *p); static ssize_t write_data_block(struct archive_write_disk *, const char *, size_t); -static struct archive_vtable *archive_write_disk_vtable(void); - static int _archive_write_disk_close(struct archive *); static int _archive_write_disk_free(struct archive *); static int _archive_write_disk_header(struct archive *, @@ -465,6 +465,39 @@ la_opendirat(int fd, const char *path) { } static int +la_verify_filetype(mode_t mode, __LA_MODE_T filetype) { + int ret = 0; + + switch (filetype) { + case AE_IFREG: + ret = (S_ISREG(mode)); + break; + case AE_IFDIR: + ret = (S_ISDIR(mode)); + break; + case AE_IFLNK: + ret = (S_ISLNK(mode)); + break; + case AE_IFSOCK: + ret = (S_ISSOCK(mode)); + break; + case AE_IFCHR: + ret = (S_ISCHR(mode)); + break; + case AE_IFBLK: + ret = (S_ISBLK(mode)); + break; + case AE_IFIFO: + ret = (S_ISFIFO(mode)); + break; + default: + break; + } + + return (ret); +} + +static int lazy_stat(struct archive_write_disk *a) { if (a->pst != NULL) { @@ -489,25 +522,16 @@ lazy_stat(struct archive_write_disk *a) return (ARCHIVE_WARN); } -static struct archive_vtable * -archive_write_disk_vtable(void) -{ - static struct archive_vtable av; - static int inited = 0; - - if (!inited) { - av.archive_close = _archive_write_disk_close; - av.archive_filter_bytes = _archive_write_disk_filter_bytes; - av.archive_free = _archive_write_disk_free; - av.archive_write_header = _archive_write_disk_header; - av.archive_write_finish_entry - = _archive_write_disk_finish_entry; - av.archive_write_data = _archive_write_disk_data; - av.archive_write_data_block = _archive_write_disk_data_block; - inited = 1; - } - return (&av); -} +static const struct archive_vtable +archive_write_disk_vtable = { + .archive_close = _archive_write_disk_close, + .archive_filter_bytes = _archive_write_disk_filter_bytes, + .archive_free = _archive_write_disk_free, + .archive_write_header = _archive_write_disk_header, + .archive_write_finish_entry = _archive_write_disk_finish_entry, + .archive_write_data = _archive_write_disk_data, + .archive_write_data_block = _archive_write_disk_data_block, +}; static int64_t _archive_write_disk_filter_bytes(struct archive *_a, int n) @@ -822,6 +846,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL); + fe->filetype = archive_entry_filetype(entry); fe->fixup |= TODO_MODE_BASE; fe->mode = a->mode; } @@ -832,6 +857,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL); + fe->filetype = archive_entry_filetype(entry); fe->mode = a->mode; fe->fixup |= TODO_TIMES; if (archive_entry_atime_is_set(entry)) { @@ -865,6 +891,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL); + fe->filetype = archive_entry_filetype(entry); fe->fixup |= TODO_ACLS; archive_acl_copy(&fe->acl, archive_entry_acl(entry)); } @@ -877,6 +904,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL); + fe->filetype = archive_entry_filetype(entry); fe->mac_metadata = malloc(metadata_size); if (fe->mac_metadata != NULL) { memcpy(fe->mac_metadata, metadata, @@ -891,6 +919,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL); + fe->filetype = archive_entry_filetype(entry); fe->fixup |= TODO_FFLAGS; /* TODO: Complete this.. defer fflags from below. */ } @@ -1956,7 +1985,7 @@ archive_write_disk_new(void) a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC; /* We're ready to write a header immediately. */ a->archive.state = ARCHIVE_STATE_HEADER; - a->archive.vtable = archive_write_disk_vtable(); + a->archive.vtable = &archive_write_disk_vtable; a->start_time = time(NULL); /* Query and restore the umask. */ umask(a->user_umask = umask(0)); @@ -2263,7 +2292,7 @@ create_filesystem_object(struct archive_write_disk *a) return (EPERM); } r = check_symlinks_fsobj(linkname_copy, &error_number, - &error_string, a->flags); + &error_string, a->flags, 1); if (r != ARCHIVE_OK) { archive_set_error(&a->archive, error_number, "%s", error_string.s); @@ -2284,7 +2313,12 @@ create_filesystem_object(struct archive_write_disk *a) */ if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) unlink(a->name); +#ifdef HAVE_LINKAT + r = linkat(AT_FDCWD, linkname, AT_FDCWD, a->name, + 0) ? errno : 0; +#else r = link(linkname, a->name) ? errno : 0; +#endif /* * New cpio and pax formats allow hardlink entries * to carry data, so we may have to open the file @@ -2456,7 +2490,9 @@ _archive_write_disk_close(struct archive *_a) { struct archive_write_disk *a = (struct archive_write_disk *)_a; struct fixup_entry *next, *p; - int fd, ret; + struct stat st; + char *c; + int fd, ret, openflags; archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, @@ -2469,10 +2505,70 @@ _archive_write_disk_close(struct archive *_a) while (p != NULL) { fd = -1; a->pst = NULL; /* Mark stat cache as out-of-date. */ - if (p->fixup & - (TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) { - fd = open(p->name, - O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC); + + /* We must strip trailing slashes from the path to avoid + dereferencing symbolic links to directories */ + c = p->name; + while (*c != '\0') + c++; + while (c != p->name && *(c - 1) == '/') { + c--; + *c = '\0'; + } + + if (p->fixup == 0) + goto skip_fixup_entry; + else { + /* + * We need to verify if the type of the file + * we are going to open matches the file type + * of the fixup entry. + */ + openflags = O_BINARY | O_NOFOLLOW | O_RDONLY + | O_CLOEXEC; +#if defined(O_DIRECTORY) + if (p->filetype == AE_IFDIR) + openflags |= O_DIRECTORY; +#endif + fd = open(p->name, openflags); + +#if defined(O_DIRECTORY) + /* + * If we support O_DIRECTORY and open was + * successful we can skip the file type check + * for directories. For other file types + * we need to verify via fstat() or lstat() + */ + if (fd == -1 || p->filetype != AE_IFDIR) { +#if HAVE_FSTAT + if (fd > 0 && ( + fstat(fd, &st) != 0 || + la_verify_filetype(st.st_mode, + p->filetype) == 0)) { + goto skip_fixup_entry; + } else +#endif + if (lstat(p->name, &st) != 0 || + la_verify_filetype(st.st_mode, + p->filetype) == 0) { + goto skip_fixup_entry; + } + } +#else +#if HAVE_FSTAT + if (fd > 0 && ( + fstat(fd, &st) != 0 || + la_verify_filetype(st.st_mode, + p->filetype) == 0)) { + goto skip_fixup_entry; + } else +#endif + if (lstat(p->name, &st) != 0 || + la_verify_filetype(st.st_mode, + p->filetype) == 0) { + goto skip_fixup_entry; + } +#endif } if (p->fixup & TODO_TIMES) { set_times(a, fd, p->mode, p->name, @@ -2484,10 +2580,14 @@ _archive_write_disk_close(struct archive *_a) if (p->fixup & TODO_MODE_BASE) { #ifdef HAVE_FCHMOD if (fd >= 0) - fchmod(fd, p->mode); + fchmod(fd, p->mode & 07777); else #endif - chmod(p->name, p->mode); +#ifdef HAVE_LCHMOD + lchmod(p->name, p->mode & 07777); +#else + chmod(p->name, p->mode & 07777); +#endif } if (p->fixup & TODO_ACLS) archive_write_disk_set_acls(&a->archive, fd, @@ -2498,6 +2598,7 @@ _archive_write_disk_close(struct archive *_a) if (p->fixup & TODO_MAC_METADATA) set_mac_metadata(a, p->name, p->mac_metadata, p->mac_metadata_size); +skip_fixup_entry: next = p->next; archive_acl_clear(&p->acl); free(p->mac_metadata); @@ -2638,6 +2739,7 @@ new_fixup(struct archive_write_disk *a, const char *pathname) fe->next = a->fixup_list; a->fixup_list = fe; fe->fixup = 0; + fe->filetype = 0; fe->name = strdup(pathname); return (fe); } @@ -2675,7 +2777,7 @@ fsobj_error(int *a_eno, struct archive_string *a_estr, */ static int check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, - int flags) + int flags, int checking_linkname) { #if !defined(HAVE_LSTAT) && \ !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)) @@ -2684,6 +2786,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, (void)error_number; /* UNUSED */ (void)error_string; /* UNUSED */ (void)flags; /* UNUSED */ + (void)checking_linkname; /* UNUSED */ return (ARCHIVE_OK); #else int res = ARCHIVE_OK; @@ -2805,6 +2908,28 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, head = tail + 1; } } else if (S_ISLNK(st.st_mode)) { + if (last && checking_linkname) { +#ifdef HAVE_LINKAT + /* + * Hardlinks to symlinks are safe to write + * if linkat() is supported as it does not + * follow symlinks. + */ + res = ARCHIVE_OK; +#else + /* + * We return ARCHIVE_FAILED here as we are + * not able to safely write hardlinks + * to symlinks. + */ + tail[0] = c; + fsobj_error(a_eno, a_estr, errno, + "Cannot write hardlink to symlink ", + path); + res = ARCHIVE_FAILED; +#endif + break; + } else if (last) { /* * Last element is symlink; remove it @@ -2971,7 +3096,7 @@ check_symlinks(struct archive_write_disk *a) int rc; archive_string_init(&error_string); rc = check_symlinks_fsobj(a->name, &error_number, &error_string, - a->flags); + a->flags, 0); if (rc != ARCHIVE_OK) { archive_set_error(&a->archive, error_number, "%s", error_string.s); @@ -3737,6 +3862,7 @@ set_fflags(struct archive_write_disk *a) le = current_fixup(a, a->name); if (le == NULL) return (ARCHIVE_FATAL); + le->filetype = archive_entry_filetype(a->entry); le->fixup |= TODO_FFLAGS; le->fflags_set = set; /* Store the mode if it's not already there. */ @@ -3899,7 +4025,8 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name, /* If we weren't given an fd, open it ourselves. */ if (myfd < 0) { - myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY | O_CLOEXEC); + myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY | + O_CLOEXEC | O_NOFOLLOW); __archive_ensure_cloexec_flag(myfd); } if (myfd < 0) diff --git a/src/3rdparty/libarchive/libarchive/archive_write_disk_windows.c b/src/3rdparty/libarchive/libarchive/archive_write_disk_windows.c index 0c600176..1b12a299 100644 --- a/src/3rdparty/libarchive/libarchive/archive_write_disk_windows.c +++ b/src/3rdparty/libarchive/libarchive/archive_write_disk_windows.c @@ -213,7 +213,7 @@ static int check_symlinks(struct archive_write_disk *); static int create_filesystem_object(struct archive_write_disk *); static struct fixup_entry *current_fixup(struct archive_write_disk *, const wchar_t *pathname); -static int cleanup_pathname(struct archive_write_disk *); +static int cleanup_pathname(struct archive_write_disk *, wchar_t *); static int create_dir(struct archive_write_disk *, wchar_t *); static int create_parent_dir(struct archive_write_disk *, wchar_t *); static int la_chmod(const wchar_t *, mode_t); @@ -238,8 +238,6 @@ static struct fixup_entry *sort_dir_list(struct fixup_entry *p); static ssize_t write_data_block(struct archive_write_disk *, const char *, size_t); -static struct archive_vtable *archive_write_disk_vtable(void); - static int _archive_write_disk_close(struct archive *); static int _archive_write_disk_free(struct archive *); static int _archive_write_disk_header(struct archive *, @@ -628,7 +626,7 @@ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target, static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD); static int set; wchar_t *ttarget, *p; - int len; + size_t len; DWORD attrs = 0; DWORD flags = 0; DWORD newflags = 0; @@ -759,25 +757,16 @@ lazy_stat(struct archive_write_disk *a) return (ARCHIVE_WARN); } -static struct archive_vtable * -archive_write_disk_vtable(void) -{ - static struct archive_vtable av; - static int inited = 0; - - if (!inited) { - av.archive_close = _archive_write_disk_close; - av.archive_filter_bytes = _archive_write_disk_filter_bytes; - av.archive_free = _archive_write_disk_free; - av.archive_write_header = _archive_write_disk_header; - av.archive_write_finish_entry - = _archive_write_disk_finish_entry; - av.archive_write_data = _archive_write_disk_data; - av.archive_write_data_block = _archive_write_disk_data_block; - inited = 1; - } - return (&av); -} +static const struct archive_vtable +archive_write_disk_vtable = { + .archive_close = _archive_write_disk_close, + .archive_filter_bytes = _archive_write_disk_filter_bytes, + .archive_free = _archive_write_disk_free, + .archive_write_header = _archive_write_disk_header, + .archive_write_finish_entry = _archive_write_disk_finish_entry, + .archive_write_data = _archive_write_disk_data, + .archive_write_data_block = _archive_write_disk_data_block, +}; static int64_t _archive_write_disk_filter_bytes(struct archive *_a, int n) @@ -854,7 +843,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) * dir restores; the dir restore logic otherwise gets messed * up by nonsense like "dir/.". */ - ret = cleanup_pathname(a); + ret = cleanup_pathname(a, a->name); if (ret != ARCHIVE_OK) return (ret); @@ -1373,7 +1362,7 @@ archive_write_disk_new(void) a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC; /* We're ready to write a header immediately. */ a->archive.state = ARCHIVE_STATE_HEADER; - a->archive.vtable = archive_write_disk_vtable(); + a->archive.vtable = &archive_write_disk_vtable; a->start_time = time(NULL); /* Query and restore the umask. */ umask(a->user_umask = umask(0)); @@ -1671,9 +1660,22 @@ create_filesystem_object(struct archive_write_disk *a) /* Since link(2) and symlink(2) don't handle modes, we're done here. */ linkname = archive_entry_hardlink_w(a->entry); if (linkname != NULL) { - wchar_t *linkfull, *namefull; - - linkfull = __la_win_permissive_name_w(linkname); + wchar_t *linksanitized, *linkfull, *namefull; + size_t l = (wcslen(linkname) + 1) * sizeof(wchar_t); + linksanitized = malloc(l); + if (linksanitized == NULL) { + archive_set_error(&a->archive, ENOMEM, + "Can't allocate memory for hardlink target"); + return (-1); + } + memcpy(linksanitized, linkname, l); + r = cleanup_pathname(a, linksanitized); + if (r != ARCHIVE_OK) { + free(linksanitized); + return (r); + } + linkfull = __la_win_permissive_name_w(linksanitized); + free(linksanitized); namefull = __la_win_permissive_name_w(a->name); if (linkfull == NULL || namefull == NULL) { errno = EINVAL; @@ -2184,12 +2186,12 @@ guidword(wchar_t *p, int n) * set) any '..' in the path. */ static int -cleanup_pathname(struct archive_write_disk *a) +cleanup_pathname(struct archive_write_disk *a, wchar_t *name) { wchar_t *dest, *src, *p, *top; wchar_t separator = L'\0'; - p = a->name; + p = name; if (*p == L'\0') { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Invalid empty pathname"); @@ -2201,7 +2203,7 @@ cleanup_pathname(struct archive_write_disk *a) if (*p == L'/') *p = L'\\'; } - p = a->name; + p = name; /* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or * "\\?\Volume{GUID}\" diff --git a/src/3rdparty/libarchive/libarchive/archive_write_set_format.c b/src/3rdparty/libarchive/libarchive/archive_write_set_format.c index b4c6ef25..652fb4d6 100644 --- a/src/3rdparty/libarchive/libarchive/archive_write_set_format.c +++ b/src/3rdparty/libarchive/libarchive/archive_write_set_format.c @@ -44,7 +44,9 @@ struct { int code; int (*setter)(struct archive *); } codes[] = { //QT { ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip }, //QT { ARCHIVE_FORMAT_CPIO, archive_write_set_format_cpio }, -//QT { ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio }, +//QT { ARCHIVE_FORMAT_CPIO_BIN_LE, archive_write_set_format_cpio_bin }, +//QT { ARCHIVE_FORMAT_CPIO_PWB, archive_write_set_format_cpio_pwb }, +//QT { ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio_odc }, //QT { ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc }, //QT { ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 }, //QT { ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree }, diff --git a/src/3rdparty/libarchive/libarchive/archive_write_set_format_by_name.c b/src/3rdparty/libarchive/libarchive/archive_write_set_format_by_name.c index 86e8621e..bfb4b354 100644 --- a/src/3rdparty/libarchive/libarchive/archive_write_set_format_by_name.c +++ b/src/3rdparty/libarchive/libarchive/archive_write_set_format_by_name.c @@ -49,6 +49,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] = { "arbsd", archive_write_set_format_ar_bsd }, { "argnu", archive_write_set_format_ar_svr4 }, { "arsvr4", archive_write_set_format_ar_svr4 }, + { "bin", archive_write_set_format_cpio_bin }, { "bsdtar", archive_write_set_format_pax_restricted }, { "cd9660", archive_write_set_format_iso9660 }, { "cpio", archive_write_set_format_cpio }, @@ -58,11 +59,12 @@ struct { const char *name; int (*setter)(struct archive *); } names[] = { "mtree", archive_write_set_format_mtree }, { "mtree-classic", archive_write_set_format_mtree_classic }, { "newc", archive_write_set_format_cpio_newc }, - { "odc", archive_write_set_format_cpio }, + { "odc", archive_write_set_format_cpio_odc }, { "oldtar", archive_write_set_format_v7tar }, { "pax", archive_write_set_format_pax }, { "paxr", archive_write_set_format_pax_restricted }, { "posix", archive_write_set_format_pax }, + { "pwb", archive_write_set_format_cpio_pwb }, { "raw", archive_write_set_format_raw }, { "rpax", archive_write_set_format_pax_restricted }, { "shar", archive_write_set_format_shar }, diff --git a/src/3rdparty/libarchive/libarchive/config_freebsd.h b/src/3rdparty/libarchive/libarchive/config_freebsd.h index a484618b..758621c4 100644 --- a/src/3rdparty/libarchive/libarchive/config_freebsd.h +++ b/src/3rdparty/libarchive/libarchive/config_freebsd.h @@ -138,6 +138,7 @@ #define HAVE_LIBZ 1 #define HAVE_LIMITS_H 1 #define HAVE_LINK 1 +#define HAVE_LINKAT 1 #define HAVE_LOCALE_H 1 #define HAVE_LOCALTIME_R 1 #define HAVE_LONG_LONG_INT 1 @@ -235,6 +236,14 @@ #define HAVE_ZLIB_H 1 #define TIME_WITH_SYS_TIME 1 +#if __FreeBSD_version >= 800505 +#define HAVE_LIBLZMA 1 +#define HAVE_LZMA_H 1 +#if __FreeBSD_version >= 1002504 +#define HAVE_LZMA_STREAM_ENCODER_MT 1 +#endif +#endif + #if __FreeBSD_version >= 1100056 #define HAVE_FUTIMENS 1 #define HAVE_UTIMENSAT 1 diff --git a/src/3rdparty/libarchive/libarchive/filter_fork_windows.c b/src/3rdparty/libarchive/libarchive/filter_fork_windows.c index 8d11179f..0b963975 100644 --- a/src/3rdparty/libarchive/libarchive/filter_fork_windows.c +++ b/src/3rdparty/libarchive/libarchive/filter_fork_windows.c @@ -31,6 +31,43 @@ #include "filter_fork.h" +/* There are some editions of Windows ("nano server," for example) that + * do not host user32.dll. If we want to keep running on those editions, + * we need to delay-load WaitForInputIdle. */ +static void * +la_GetFunctionUser32(const char *name) +{ + static HINSTANCE lib; + static int set; + if (!set) { + set = 1; + lib = LoadLibrary(TEXT("user32.dll")); + } + if (lib == NULL) { + return NULL; + } + return (void *)GetProcAddress(lib, name); +} + +static int +la_WaitForInputIdle(HANDLE hProcess, DWORD dwMilliseconds) +{ + static DWORD (WINAPI *f)(HANDLE, DWORD); + static int set; + + if (!set) { + set = 1; + f = la_GetFunctionUser32("WaitForInputIdle"); + } + + if (!f) { + /* An inability to wait for input idle is + * not _good_, but it is not catastrophic. */ + return WAIT_FAILED; + } + return (*f)(hProcess, dwMilliseconds); +} + int __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child) @@ -149,7 +186,7 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, if (CreateProcessA(fullpath.s, cmdline.s, NULL, NULL, TRUE, 0, NULL, NULL, &staInfo, &childInfo) == 0) goto fail; - WaitForInputIdle(childInfo.hProcess, INFINITE); + la_WaitForInputIdle(childInfo.hProcess, INFINITE); CloseHandle(childInfo.hProcess); CloseHandle(childInfo.hThread); diff --git a/src/3rdparty/libarchive/qt_attribution.json b/src/3rdparty/libarchive/qt_attribution.json index cd3f417f..7da80900 100644 --- a/src/3rdparty/libarchive/qt_attribution.json +++ b/src/3rdparty/libarchive/qt_attribution.json @@ -6,7 +6,7 @@ "Description": "Multi-format archive and compression library.", "Homepage": "https://www.libarchive.org/", - "Version": "3.5.1", + "Version": "3.6.1", "License": "BSD 2-clause \"Simplified\" License", "LicenseId": "BSD-2-Clause", |