summaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty
diff options
context:
space:
mode:
authorArttu Tarkiainen <arttu.tarkiainen@qt.io>2022-01-20 16:16:46 +0200
committerArttu Tarkiainen <arttu.tarkiainen@qt.io>2022-01-21 09:18:24 +0200
commit6233bf7d5645f9b8b4dcd99b1d3691ed15f9829c (patch)
tree10ec66220a2ad72bdc85866b2ffcab1c82fda5d4 /src/libs/3rdparty
parentadd344ee43670a87212639f979ad9a672291076e (diff)
Update libarchive sources to 3.5.2 release
Upstream details: https://github.com/libarchive/libarchive/releases/tag/v3.5.2 Change-Id: I92bc5911bde854c30d0b6515c49b5d512210401f Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src/libs/3rdparty')
-rw-r--r--src/libs/3rdparty/libarchive/archive.h8
-rw-r--r--src/libs/3rdparty/libarchive/archive_disk_acl_freebsd.c20
-rw-r--r--src/libs/3rdparty/libarchive/archive_disk_acl_linux.c23
-rw-r--r--src/libs/3rdparty/libarchive/archive_disk_acl_sunos.c13
-rw-r--r--src/libs/3rdparty/libarchive/archive_entry.h2
-rw-r--r--src/libs/3rdparty/libarchive/archive_pathmatch.c4
-rw-r--r--src/libs/3rdparty/libarchive/archive_private.h7
-rw-r--r--src/libs/3rdparty/libarchive/archive_random.c8
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_disk_posix.c66
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_disk_windows.c2
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_filter_rpm.c2
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_filter_uu.c2
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_format_7zip.c14
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_format_cab.c1
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_format_cpio.c18
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_format_mtree.c8
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_format_rar.c14
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_format_rar5.c1
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_format_tar.c6
-rw-r--r--src/libs/3rdparty/libarchive/archive_read_support_format_zip.c154
-rw-r--r--src/libs/3rdparty/libarchive/archive_write.c23
-rw-r--r--src/libs/3rdparty/libarchive/archive_write_disk_posix.c63
-rw-r--r--src/libs/3rdparty/libarchive/archive_write_set_format.c4
-rw-r--r--src/libs/3rdparty/libarchive/archive_write_set_format_7zip.c7
-rw-r--r--src/libs/3rdparty/libarchive/archive_write_set_format_by_name.c4
-rw-r--r--src/libs/3rdparty/libarchive/archive_write_set_format_cpio.c494
-rw-r--r--src/libs/3rdparty/libarchive/archive_write_set_format_cpio_binary.c610
-rw-r--r--src/libs/3rdparty/libarchive/archive_write_set_format_cpio_odc.c500
-rw-r--r--src/libs/3rdparty/libarchive/config_freebsd.h1
-rw-r--r--src/libs/3rdparty/libarchive/libarchive.pro2
-rw-r--r--src/libs/3rdparty/libarchive/qt_attribution.json2
-rw-r--r--src/libs/3rdparty/libarchive/xxhash.c6
32 files changed, 1412 insertions, 677 deletions
diff --git a/src/libs/3rdparty/libarchive/archive.h b/src/libs/3rdparty/libarchive/archive.h
index 52f4d7829..ca83cbd09 100644
--- a/src/libs/3rdparty/libarchive/archive.h
+++ b/src/libs/3rdparty/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 3005002
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.5.1"
+#define ARCHIVE_VERSION_ONLY_STRING "3.5.2"
#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 *);
diff --git a/src/libs/3rdparty/libarchive/archive_disk_acl_freebsd.c b/src/libs/3rdparty/libarchive/archive_disk_acl_freebsd.c
index aba41e5da..ed4e7a789 100644
--- a/src/libs/3rdparty/libarchive/archive_disk_acl_freebsd.c
+++ b/src/libs/3rdparty/libarchive/archive_disk_acl_freebsd.c
@@ -319,7 +319,7 @@ translate_acl(struct archive_read_disk *a,
static int
set_acl(struct archive *a, int fd, const char *name,
- struct archive_acl *abstract_acl,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode,
int ae_requested_type, const char *tname)
{
int acl_type = 0;
@@ -364,6 +364,13 @@ set_acl(struct archive *a, int fd, const char *name,
return (ARCHIVE_FAILED);
}
+ if (acl_type == ACL_TYPE_DEFAULT && !S_ISDIR(mode)) {
+ errno = EINVAL;
+ archive_set_error(a, errno,
+ "Cannot set default ACL on non-directory");
+ return (ARCHIVE_WARN);
+ }
+
acl = acl_init(entries);
if (acl == (acl_t)NULL) {
archive_set_error(a, errno,
@@ -542,7 +549,10 @@ set_acl(struct archive *a, int fd, const char *name,
else if (acl_set_link_np(name, acl_type, acl) != 0)
#else
/* FreeBSD older than 8.0 */
- else if (acl_set_file(name, acl_type, acl) != 0)
+ else if (S_ISLNK(mode)) {
+ /* acl_set_file() follows symbolic links, skip */
+ ret = ARCHIVE_OK;
+ } else if (acl_set_file(name, acl_type, acl) != 0)
#endif
{
if (errno == EOPNOTSUPP) {
@@ -677,14 +687,14 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
if ((archive_acl_types(abstract_acl)
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- ret = set_acl(a, fd, name, abstract_acl,
+ ret = set_acl(a, fd, name, abstract_acl, mode,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
if (ret != ARCHIVE_OK)
return (ret);
}
if ((archive_acl_types(abstract_acl)
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
- ret = set_acl(a, fd, name, abstract_acl,
+ ret = set_acl(a, fd, name, abstract_acl, mode,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
/* Simultaneous POSIX.1e and NFSv4 is not supported */
@@ -693,7 +703,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
#if ARCHIVE_ACL_FREEBSD_NFS4
else if ((archive_acl_types(abstract_acl) &
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- ret = set_acl(a, fd, name, abstract_acl,
+ ret = set_acl(a, fd, name, abstract_acl, mode,
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
}
#endif
diff --git a/src/libs/3rdparty/libarchive/archive_disk_acl_linux.c b/src/libs/3rdparty/libarchive/archive_disk_acl_linux.c
index 3928f3d6f..31d270535 100644
--- a/src/libs/3rdparty/libarchive/archive_disk_acl_linux.c
+++ b/src/libs/3rdparty/libarchive/archive_disk_acl_linux.c
@@ -343,6 +343,11 @@ set_richacl(struct archive *a, int fd, const char *name,
return (ARCHIVE_FAILED);
}
+ if (S_ISLNK(mode)) {
+ /* Linux does not support RichACLs on symbolic links */
+ return (ARCHIVE_OK);
+ }
+
richacl = richacl_alloc(entries);
if (richacl == NULL) {
archive_set_error(a, errno,
@@ -455,7 +460,7 @@ exit_free:
#if ARCHIVE_ACL_LIBACL
static int
set_acl(struct archive *a, int fd, const char *name,
- struct archive_acl *abstract_acl,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode,
int ae_requested_type, const char *tname)
{
int acl_type = 0;
@@ -488,6 +493,18 @@ set_acl(struct archive *a, int fd, const char *name,
return (ARCHIVE_FAILED);
}
+ if (S_ISLNK(mode)) {
+ /* Linux does not support ACLs on symbolic links */
+ return (ARCHIVE_OK);
+ }
+
+ if (acl_type == ACL_TYPE_DEFAULT && !S_ISDIR(mode)) {
+ errno = EINVAL;
+ archive_set_error(a, errno,
+ "Cannot set default ACL on non-directory");
+ return (ARCHIVE_WARN);
+ }
+
acl = acl_init(entries);
if (acl == (acl_t)NULL) {
archive_set_error(a, errno,
@@ -727,14 +744,14 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
if ((archive_acl_types(abstract_acl)
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- ret = set_acl(a, fd, name, abstract_acl,
+ ret = set_acl(a, fd, name, abstract_acl, mode,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
if (ret != ARCHIVE_OK)
return (ret);
}
if ((archive_acl_types(abstract_acl)
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
- ret = set_acl(a, fd, name, abstract_acl,
+ ret = set_acl(a, fd, name, abstract_acl, mode,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
}
#endif /* ARCHIVE_ACL_LIBACL */
diff --git a/src/libs/3rdparty/libarchive/archive_disk_acl_sunos.c b/src/libs/3rdparty/libarchive/archive_disk_acl_sunos.c
index b0f5dfad9..0ef3ad52e 100644
--- a/src/libs/3rdparty/libarchive/archive_disk_acl_sunos.c
+++ b/src/libs/3rdparty/libarchive/archive_disk_acl_sunos.c
@@ -443,7 +443,7 @@ translate_acl(struct archive_read_disk *a,
static int
set_acl(struct archive *a, int fd, const char *name,
- struct archive_acl *abstract_acl,
+ struct archive_acl *abstract_acl, __LA_MODE_T mode,
int ae_requested_type, const char *tname)
{
aclent_t *aclent;
@@ -467,7 +467,6 @@ set_acl(struct archive *a, int fd, const char *name,
if (entries == 0)
return (ARCHIVE_OK);
-
switch (ae_requested_type) {
case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
cmd = SETACL;
@@ -492,6 +491,12 @@ set_acl(struct archive *a, int fd, const char *name,
return (ARCHIVE_FAILED);
}
+ if (S_ISLNK(mode)) {
+ /* Skip ACLs on symbolic links */
+ ret = ARCHIVE_OK;
+ goto exit_free;
+ }
+
e = 0;
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
@@ -801,7 +806,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
if ((archive_acl_types(abstract_acl)
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
/* Solaris writes POSIX.1e access and default ACLs together */
- ret = set_acl(a, fd, name, abstract_acl,
+ ret = set_acl(a, fd, name, abstract_acl, mode,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
/* Simultaneous POSIX.1e and NFSv4 is not supported */
@@ -810,7 +815,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
#if ARCHIVE_ACL_SUNOS_NFS4
else if ((archive_acl_types(abstract_acl) &
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
- ret = set_acl(a, fd, name, abstract_acl,
+ ret = set_acl(a, fd, name, abstract_acl, mode,
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
}
#endif
diff --git a/src/libs/3rdparty/libarchive/archive_entry.h b/src/libs/3rdparty/libarchive/archive_entry.h
index c0e75bf9f..bfba54f71 100644
--- a/src/libs/3rdparty/libarchive/archive_entry.h
+++ b/src/libs/3rdparty/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 3005002
/*
* Note: archive_entry.h is for use outside of libarchive; the
diff --git a/src/libs/3rdparty/libarchive/archive_pathmatch.c b/src/libs/3rdparty/libarchive/archive_pathmatch.c
index 619e2b622..0867a268e 100644
--- a/src/libs/3rdparty/libarchive/archive_pathmatch.c
+++ b/src/libs/3rdparty/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/libs/3rdparty/libarchive/archive_private.h b/src/libs/3rdparty/libarchive/archive_private.h
index 937a87bb1..55a8da18e 100644
--- a/src/libs/3rdparty/libarchive/archive_private.h
+++ b/src/libs/3rdparty/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)
diff --git a/src/libs/3rdparty/libarchive/archive_random.c b/src/libs/3rdparty/libarchive/archive_random.c
index 65ea69157..9d1aa493f 100644
--- a/src/libs/3rdparty/libarchive/archive_random.c
+++ b/src/libs/3rdparty/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/libs/3rdparty/libarchive/archive_read_disk_posix.c b/src/libs/3rdparty/libarchive/archive_read_disk_posix.c
index 289820695..3ee6269ff 100644
--- a/src/libs/3rdparty/libarchive/archive_read_disk_posix.c
+++ b/src/libs/3rdparty/libarchive/archive_read_disk_posix.c
@@ -1522,8 +1522,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 +1625,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 +1717,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 +1824,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 +1933,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)
diff --git a/src/libs/3rdparty/libarchive/archive_read_disk_windows.c b/src/libs/3rdparty/libarchive/archive_read_disk_windows.c
index fdd376f9b..877bc449a 100644
--- a/src/libs/3rdparty/libarchive/archive_read_disk_windows.c
+++ b/src/libs/3rdparty/libarchive/archive_read_disk_windows.c
@@ -1844,7 +1844,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;
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_filter_rpm.c b/src/libs/3rdparty/libarchive/archive_read_support_filter_rpm.c
index e7e58e51f..ddd68392f 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_filter_rpm.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_filter_rpm.c
@@ -216,7 +216,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
archive_set_error(
&self->archive->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
- "Unrecoginized rpm header");
+ "Unrecognized rpm header");
return (ARCHIVE_FATAL);
}
rpm->state = ST_ARCHIVE;
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_filter_uu.c b/src/libs/3rdparty/libarchive/archive_read_support_filter_uu.c
index 67ddffb06..689c18ce4 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_filter_uu.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_filter_uu.c
@@ -248,7 +248,7 @@ bid_get_line(struct archive_read_filter *filter,
*ravail = *avail;
*b += diff;
*avail -= diff;
- tested = len;/* Skip some bytes we already determinated. */
+ tested = len;/* Skip some bytes we already determined. */
len = get_line(*b + tested, *avail - tested, nl);
if (len >= 0)
len += tested;
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_format_7zip.c b/src/libs/3rdparty/libarchive/archive_read_support_format_7zip.c
index 6ce9d1a0e..63cbb7df3 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_format_7zip.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_format_7zip.c
@@ -808,8 +808,12 @@ archive_read_format_7zip_read_data(struct archive_read *a,
if (zip->end_of_entry)
return (ARCHIVE_EOF);
- bytes = read_stream(a, buff,
- (size_t)zip->entry_bytes_remaining, 0);
+ const uint64_t max_read_size = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time
+ size_t bytes_to_read = max_read_size;
+ if ((uint64_t)bytes_to_read > zip->entry_bytes_remaining) {
+ bytes_to_read = zip->entry_bytes_remaining;
+ }
+ bytes = read_stream(a, buff, bytes_to_read, 0);
if (bytes < 0)
return ((int)bytes);
if (bytes == 0) {
@@ -1493,7 +1497,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
zip->ppmd7_stat = -1;
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
- "Failed to initialize PPMd range decorder");
+ "Failed to initialize PPMd range decoder");
return (ARCHIVE_FAILED);
}
if (zip->ppstream.overconsumed) {
@@ -3031,10 +3035,10 @@ extract_pack_stream(struct archive_read *a, size_t minimum)
"Truncated 7-Zip file body");
return (ARCHIVE_FATAL);
}
- if (bytes_avail > (ssize_t)zip->pack_stream_inbytes_remaining)
+ if ((uint64_t)bytes_avail > zip->pack_stream_inbytes_remaining)
bytes_avail = (ssize_t)zip->pack_stream_inbytes_remaining;
zip->pack_stream_inbytes_remaining -= bytes_avail;
- if (bytes_avail > (ssize_t)zip->folder_outbytes_remaining)
+ if ((uint64_t)bytes_avail > zip->folder_outbytes_remaining)
bytes_avail = (ssize_t)zip->folder_outbytes_remaining;
zip->folder_outbytes_remaining -= bytes_avail;
zip->uncompressed_buffer_bytes_remaining = bytes_avail;
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_format_cab.c b/src/libs/3rdparty/libarchive/archive_read_support_format_cab.c
index 43738b537..950f3d254 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_format_cab.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_format_cab.c
@@ -2110,7 +2110,6 @@ lzx_decode_init(struct lzx_stream *strm, int w_bits)
ds->pos_tbl = malloc(sizeof(ds->pos_tbl[0]) * w_slot);
if (ds->pos_tbl == NULL)
return (ARCHIVE_FATAL);
- lzx_huffman_free(&(ds->mt));
}
for (footer = 0; footer < 18; footer++)
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_format_cpio.c b/src/libs/3rdparty/libarchive/archive_read_support_format_cpio.c
index 1c96e6ac1..6b8ae33a4 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_format_cpio.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_format_cpio.c
@@ -185,6 +185,8 @@ struct cpio {
struct archive_string_conv *opt_sconv;
struct archive_string_conv *sconv_default;
int init_default_conversion;
+
+ int option_pwb;
};
static int64_t atol16(const char *, unsigned);
@@ -343,6 +345,10 @@ archive_read_format_cpio_options(struct archive_read *a,
ret = ARCHIVE_FATAL;
}
return (ret);
+ } else if (strcmp(key, "pwb") == 0) {
+ if (val != NULL && val[0] != 0)
+ cpio->option_pwb = 1;
+ return (ARCHIVE_OK);
}
/* Note: The "warn" return is just to inform the options
@@ -891,6 +897,12 @@ header_bin_le(struct archive_read *a, struct cpio *cpio,
archive_entry_set_dev(entry, header[bin_dev_offset] + header[bin_dev_offset + 1] * 256);
archive_entry_set_ino(entry, header[bin_ino_offset] + header[bin_ino_offset + 1] * 256);
archive_entry_set_mode(entry, header[bin_mode_offset] + header[bin_mode_offset + 1] * 256);
+ if (cpio->option_pwb) {
+ /* turn off random bits left over from V6 inode */
+ archive_entry_set_mode(entry, archive_entry_mode(entry) & 067777);
+ if ((archive_entry_mode(entry) & AE_IFMT) == 0)
+ archive_entry_set_mode(entry, archive_entry_mode(entry) | AE_IFREG);
+ }
archive_entry_set_uid(entry, header[bin_uid_offset] + header[bin_uid_offset + 1] * 256);
archive_entry_set_gid(entry, header[bin_gid_offset] + header[bin_gid_offset + 1] * 256);
archive_entry_set_nlink(entry, header[bin_nlink_offset] + header[bin_nlink_offset + 1] * 256);
@@ -930,6 +942,12 @@ header_bin_be(struct archive_read *a, struct cpio *cpio,
archive_entry_set_dev(entry, header[bin_dev_offset] * 256 + header[bin_dev_offset + 1]);
archive_entry_set_ino(entry, header[bin_ino_offset] * 256 + header[bin_ino_offset + 1]);
archive_entry_set_mode(entry, header[bin_mode_offset] * 256 + header[bin_mode_offset + 1]);
+ if (cpio->option_pwb) {
+ /* turn off random bits left over from V6 inode */
+ archive_entry_set_mode(entry, archive_entry_mode(entry) & 067777);
+ if ((archive_entry_mode(entry) & AE_IFMT) == 0)
+ archive_entry_set_mode(entry, archive_entry_mode(entry) | AE_IFREG);
+ }
archive_entry_set_uid(entry, header[bin_uid_offset] * 256 + header[bin_uid_offset + 1]);
archive_entry_set_gid(entry, header[bin_gid_offset] * 256 + header[bin_gid_offset + 1]);
archive_entry_set_nlink(entry, header[bin_nlink_offset] * 256 + header[bin_nlink_offset + 1]);
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_format_mtree.c b/src/libs/3rdparty/libarchive/archive_read_support_format_mtree.c
index 93ba2959a..c87a15442 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_format_mtree.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_format_mtree.c
@@ -408,7 +408,7 @@ next_line(struct archive_read *a,
*ravail = *avail;
*b += diff;
*avail -= diff;
- tested = len;/* Skip some bytes we already determinated. */
+ tested = len;/* Skip some bytes we already determined. */
len = get_line_size(*b + len, *avail - len, nl);
if (len >= 0)
len += tested;
@@ -1074,7 +1074,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
continue;
/* Non-printable characters are not allowed */
for (s = p;s < p + len - 1; s++) {
- if (!isprint(*s)) {
+ if (!isprint((unsigned char)*s)) {
r = ARCHIVE_FATAL;
break;
}
@@ -2035,13 +2035,13 @@ mtree_atol(char **p, int base)
if (**p == '-') {
limit = INT64_MIN / base;
- last_digit_limit = INT64_MIN % base;
+ last_digit_limit = -(INT64_MIN % base);
++(*p);
l = 0;
digit = parsedigit(**p);
while (digit >= 0 && digit < base) {
- if (l < limit || (l == limit && digit > last_digit_limit))
+ if (l < limit || (l == limit && digit >= last_digit_limit))
return INT64_MIN;
l = (l * base) - digit;
digit = parsedigit(*++(*p));
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_format_rar.c b/src/libs/3rdparty/libarchive/archive_read_support_format_rar.c
index 283a96044..c2666b2f4 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_format_rar.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_format_rar.c
@@ -958,17 +958,17 @@ archive_read_format_rar_read_header(struct archive_read *a,
crc32_val = 0;
while (skip > 0) {
size_t to_read = skip;
- ssize_t did_read;
- if (to_read > 32 * 1024) {
+ if (to_read > 32 * 1024)
to_read = 32 * 1024;
- }
- if ((h = __archive_read_ahead(a, to_read, &did_read)) == NULL) {
+ if ((h = __archive_read_ahead(a, to_read, NULL)) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file");
return (ARCHIVE_FATAL);
}
p = h;
- crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned)did_read);
- __archive_read_consume(a, did_read);
- skip -= did_read;
+ crc32_val = crc32(crc32_val, (const unsigned char *)p, to_read);
+ __archive_read_consume(a, to_read);
+ skip -= to_read;
}
if ((crc32_val & 0xffff) != crc32_expected) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_format_rar5.c b/src/libs/3rdparty/libarchive/archive_read_support_format_rar5.c
index 58a61d1bc..5d62d16ee 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_format_rar5.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_format_rar5.c
@@ -4076,6 +4076,7 @@ int archive_read_support_format_rar5(struct archive *_a) {
if(ARCHIVE_OK != rar5_init(rar)) {
archive_set_error(&ar->archive, ENOMEM,
"Can't allocate rar5 filter buffer");
+ free(rar);
return ARCHIVE_FATAL;
}
diff --git a/src/libs/3rdparty/libarchive/archive_read_support_format_tar.c b/src/libs/3rdparty/libarchive/archive_read_support_format_tar.c
index 96d810184..7e8febacf 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_format_tar.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_format_tar.c
@@ -1906,7 +1906,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 +2643,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/libs/3rdparty/libarchive/archive_read_support_format_zip.c b/src/libs/3rdparty/libarchive/archive_read_support_format_zip.c
index a64332c28..21d41cc0f 100644
--- a/src/libs/3rdparty/libarchive/archive_read_support_format_zip.c
+++ b/src/libs/3rdparty/libarchive/archive_read_support_format_zip.c
@@ -142,6 +142,7 @@ struct zip {
/* Structural information about the archive. */
struct archive_string format_name;
int64_t central_directory_offset;
+ int64_t central_directory_offset_adjusted;
size_t central_directory_entries_total;
size_t central_directory_entries_on_this_disk;
int has_encrypted_entries;
@@ -246,6 +247,17 @@ struct zip {
/* Many systems define min or MIN, but not all. */
#define zipmin(a,b) ((a) < (b) ? (a) : (b))
+#ifdef HAVE_ZLIB_H
+static int
+zip_read_data_deflate(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset);
+#endif
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+static int
+zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset);
+#endif
+
/* This function is used by Ppmd8_DecodeSymbol during decompression of Ppmd8
* streams inside ZIP files. It has 2 purposes: one is to fetch the next
* compressed byte from the stream, second one is to increase the counter how
@@ -899,81 +911,6 @@ process_extra(struct archive_read *a, struct archive_entry *entry,
return ARCHIVE_OK;
}
-#if HAVE_LZMA_H && HAVE_LIBLZMA
-/*
- * Auxiliary function to uncompress data chunk from zipx archive
- * (zip with lzma compression).
- */
-static int
-zipx_lzma_uncompress_buffer(const char *compressed_buffer,
- size_t compressed_buffer_size,
- char *uncompressed_buffer,
- size_t uncompressed_buffer_size)
-{
- int status = ARCHIVE_FATAL;
- // length of 'lzma properties data' in lzma compressed
- // data segment (stream) inside zip archive
- const size_t lzma_params_length = 5;
- // offset of 'lzma properties data' from the beginning of lzma stream
- const size_t lzma_params_offset = 4;
- // end position of 'lzma properties data' in lzma stream
- const size_t lzma_params_end = lzma_params_offset + lzma_params_length;
- if (compressed_buffer == NULL ||
- compressed_buffer_size < lzma_params_end ||
- uncompressed_buffer == NULL)
- return status;
-
- // prepare header for lzma_alone_decoder to replace zipx header
- // (see comments in 'zipx_lzma_alone_init' for justification)
-#pragma pack(push)
-#pragma pack(1)
- struct _alone_header
- {
- uint8_t bytes[5]; // lzma_params_length
- uint64_t uncompressed_size;
- } alone_header;
-#pragma pack(pop)
- // copy 'lzma properties data' blob
- memcpy(&alone_header.bytes[0], compressed_buffer + lzma_params_offset,
- lzma_params_length);
- alone_header.uncompressed_size = UINT64_MAX;
-
- // prepare new compressed buffer, see 'zipx_lzma_alone_init' for details
- const size_t lzma_alone_buffer_size =
- compressed_buffer_size - lzma_params_end + sizeof(alone_header);
- unsigned char *lzma_alone_compressed_buffer =
- (unsigned char*) malloc(lzma_alone_buffer_size);
- if (lzma_alone_compressed_buffer == NULL)
- return status;
- // copy lzma_alone header into new buffer
- memcpy(lzma_alone_compressed_buffer, (void*) &alone_header,
- sizeof(alone_header));
- // copy compressed data into new buffer
- memcpy(lzma_alone_compressed_buffer + sizeof(alone_header),
- compressed_buffer + lzma_params_end,
- compressed_buffer_size - lzma_params_end);
-
- // create and fill in lzma_alone_decoder stream
- lzma_stream stream = LZMA_STREAM_INIT;
- lzma_ret ret = lzma_alone_decoder(&stream, UINT64_MAX);
- if (ret == LZMA_OK)
- {
- stream.next_in = lzma_alone_compressed_buffer;
- stream.avail_in = lzma_alone_buffer_size;
- stream.total_in = 0;
- stream.next_out = (unsigned char*)uncompressed_buffer;
- stream.avail_out = uncompressed_buffer_size;
- stream.total_out = 0;
- ret = lzma_code(&stream, LZMA_RUN);
- if (ret == LZMA_OK || ret == LZMA_STREAM_END)
- status = ARCHIVE_OK;
- }
- lzma_end(&stream);
- free(lzma_alone_compressed_buffer);
- return status;
-}
-#endif
-
/*
* Assumes file pointer is at beginning of local file header.
*/
@@ -1242,36 +1179,30 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
linkname_length = (size_t)zip_entry->compressed_size;
archive_entry_set_size(entry, 0);
- p = __archive_read_ahead(a, linkname_length, NULL);
- if (p == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated Zip file");
- return ARCHIVE_FATAL;
- }
+
// take into account link compression if any
size_t linkname_full_length = linkname_length;
if (zip->entry->compression != 0)
{
// symlink target string appeared to be compressed
int status = ARCHIVE_FATAL;
- char *uncompressed_buffer =
- (char*) malloc(zip_entry->uncompressed_size);
- if (uncompressed_buffer == NULL)
- {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for lzma decompression");
- return status;
- }
+ const void *uncompressed_buffer;
switch (zip->entry->compression)
{
+#if HAVE_ZLIB_H
+ case 8: /* Deflate compression. */
+ zip->entry_bytes_remaining = zip_entry->compressed_size;
+ status = zip_read_data_deflate(a, &uncompressed_buffer,
+ &linkname_full_length, NULL);
+ break;
+#endif
#if HAVE_LZMA_H && HAVE_LIBLZMA
case 14: /* ZIPx LZMA compression. */
/*(see zip file format specification, section 4.4.5)*/
- status = zipx_lzma_uncompress_buffer(p,
- linkname_length,
- uncompressed_buffer,
- (size_t)zip_entry->uncompressed_size);
+ zip->entry_bytes_remaining = zip_entry->compressed_size;
+ status = zip_read_data_zipx_lzma_alone(a, &uncompressed_buffer,
+ &linkname_full_length, NULL);
break;
#endif
default: /* Unsupported compression. */
@@ -1280,8 +1211,6 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
if (status == ARCHIVE_OK)
{
p = uncompressed_buffer;
- linkname_full_length =
- (size_t)zip_entry->uncompressed_size;
}
else
{
@@ -1294,6 +1223,16 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
return ARCHIVE_FAILED;
}
}
+ else
+ {
+ p = __archive_read_ahead(a, linkname_length, NULL);
+ }
+
+ if (p == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated Zip file");
+ return ARCHIVE_FATAL;
+ }
sconv = zip->sconv;
if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
@@ -1663,7 +1602,8 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
/* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma
* that is a part of XZ Utils. The stream format stored inside ZIPX
* file is a modified "lzma alone" file format, that was used by the
- * `lzma` utility which was later deprecated in favour of `xz` utility. * Since those formats are nearly the same, we can use a standard
+ * `lzma` utility which was later deprecated in favour of `xz` utility.
+ * Since those formats are nearly the same, we can use a standard
* "lzma alone" decoder from XZ Utils. */
memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
@@ -3415,24 +3355,31 @@ archive_read_support_format_zip_capabilities_seekable(struct archive_read * a)
static int
read_eocd(struct zip *zip, const char *p, int64_t current_offset)
{
+ uint16_t disk_num;
+ uint32_t cd_size, cd_offset;
+
+ disk_num = archive_le16dec(p + 4);
+ cd_size = archive_le32dec(p + 12);
+ cd_offset = archive_le32dec(p + 16);
+
/* Sanity-check the EOCD we've found. */
/* This must be the first volume. */
- if (archive_le16dec(p + 4) != 0)
+ if (disk_num != 0)
return 0;
/* Central directory must be on this volume. */
- if (archive_le16dec(p + 4) != archive_le16dec(p + 6))
+ if (disk_num != archive_le16dec(p + 6))
return 0;
/* All central directory entries must be on this volume. */
if (archive_le16dec(p + 10) != archive_le16dec(p + 8))
return 0;
/* Central directory can't extend beyond start of EOCD record. */
- if (archive_le32dec(p + 16) + archive_le32dec(p + 12)
- > current_offset)
+ if (cd_offset + cd_size > current_offset)
return 0;
/* Save the central directory location for later use. */
- zip->central_directory_offset = archive_le32dec(p + 16);
+ zip->central_directory_offset = cd_offset;
+ zip->central_directory_offset_adjusted = current_offset - cd_size;
/* This is just a tiny bit higher than the maximum
returned by the streaming Zip bidder. This ensures
@@ -3484,6 +3431,8 @@ read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
/* Save the central directory offset for later use. */
zip->central_directory_offset = archive_le64dec(p + 48);
+ /* TODO: Needs scanning backwards to find the eocd64 instead of assuming */
+ zip->central_directory_offset_adjusted = zip->central_directory_offset;
return 32;
}
@@ -3655,7 +3604,8 @@ slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
* know the correction we need to apply to account for leading
* padding.
*/
- if (__archive_read_seek(a, zip->central_directory_offset, SEEK_SET) < 0)
+ if (__archive_read_seek(a, zip->central_directory_offset_adjusted, SEEK_SET)
+ < 0)
return ARCHIVE_FATAL;
found = 0;
diff --git a/src/libs/3rdparty/libarchive/archive_write.c b/src/libs/3rdparty/libarchive/archive_write.c
index 8d70f51a6..38c14cba7 100644
--- a/src/libs/3rdparty/libarchive/archive_write.c
+++ b/src/libs/3rdparty/libarchive/archive_write.c
@@ -482,6 +482,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 +506,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/libs/3rdparty/libarchive/archive_write_disk_posix.c b/src/libs/3rdparty/libarchive/archive_write_disk_posix.c
index 7e32fca92..fcd733aff 100644
--- a/src/libs/3rdparty/libarchive/archive_write_disk_posix.c
+++ b/src/libs/3rdparty/libarchive/archive_write_disk_posix.c
@@ -360,7 +360,7 @@ static int la_mktemp(struct archive_write_disk *);
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 *,
@@ -2263,7 +2263,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 +2284,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,6 +2461,7 @@ _archive_write_disk_close(struct archive *_a)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct fixup_entry *next, *p;
+ struct stat st;
int fd, ret;
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
@@ -2473,6 +2479,20 @@ _archive_write_disk_close(struct archive *_a)
(TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) {
fd = open(p->name,
O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC);
+ if (fd == -1) {
+ /* If we cannot lstat, skip entry */
+ if (lstat(p->name, &st) != 0)
+ goto skip_fixup_entry;
+ /*
+ * If we deal with a symbolic link, mark
+ * it in the fixup mode to ensure no
+ * modifications are made to its target.
+ */
+ if (S_ISLNK(st.st_mode)) {
+ p->mode &= ~S_IFMT;
+ p->mode |= S_IFLNK;
+ }
+ }
}
if (p->fixup & TODO_TIMES) {
set_times(a, fd, p->mode, p->name,
@@ -2487,7 +2507,12 @@ _archive_write_disk_close(struct archive *_a)
fchmod(fd, p->mode);
else
#endif
- chmod(p->name, p->mode);
+#ifdef HAVE_LCHMOD
+ lchmod(p->name, p->mode);
+#else
+ if (!S_ISLNK(p->mode))
+ chmod(p->name, p->mode);
+#endif
}
if (p->fixup & TODO_ACLS)
archive_write_disk_set_acls(&a->archive, fd,
@@ -2498,6 +2523,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 +2664,7 @@ new_fixup(struct archive_write_disk *a, const char *pathname)
fe->next = a->fixup_list;
a->fixup_list = fe;
fe->fixup = 0;
+ fe->mode = 0;
fe->name = strdup(pathname);
return (fe);
}
@@ -2675,7 +2702,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 +2711,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 +2833,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 +3021,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);
@@ -3899,7 +3949,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/libs/3rdparty/libarchive/archive_write_set_format.c b/src/libs/3rdparty/libarchive/archive_write_set_format.c
index 7dbe7b9a2..1f65fa4a7 100644
--- a/src/libs/3rdparty/libarchive/archive_write_set_format.c
+++ b/src/libs/3rdparty/libarchive/archive_write_set_format.c
@@ -44,7 +44,9 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
{
{ ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip },
{ ARCHIVE_FORMAT_CPIO, archive_write_set_format_cpio },
- { ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio },
+ { ARCHIVE_FORMAT_CPIO_BIN_LE, archive_write_set_format_cpio_bin },
+ { ARCHIVE_FORMAT_CPIO_PWB, archive_write_set_format_cpio_pwb },
+ { ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio_odc },
{ ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc },
{ ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 },
{ ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree },
diff --git a/src/libs/3rdparty/libarchive/archive_write_set_format_7zip.c b/src/libs/3rdparty/libarchive/archive_write_set_format_7zip.c
index f3a7446a0..d5ca9a665 100644
--- a/src/libs/3rdparty/libarchive/archive_write_set_format_7zip.c
+++ b/src/libs/3rdparty/libarchive/archive_write_set_format_7zip.c
@@ -755,6 +755,10 @@ _7z_close(struct archive_write *a)
*/
#if HAVE_LZMA_H
header_compression = _7Z_LZMA1;
+ if(zip->opt_compression == _7Z_LZMA2 ||
+ zip->opt_compression == _7Z_COPY)
+ header_compression = zip->opt_compression;
+
/* If the stored file is only one, do not encode the header.
* This is the same way 7z command does. */
if (zip->total_number_entry == 1)
@@ -762,7 +766,8 @@ _7z_close(struct archive_write *a)
#else
header_compression = _7Z_COPY;
#endif
- r = _7z_compression_init_encoder(a, header_compression, 6);
+ r = _7z_compression_init_encoder(a, header_compression,
+ zip->opt_compression_level);
if (r < 0)
return (r);
zip->crc32flg = PRECODE_CRC32;
diff --git a/src/libs/3rdparty/libarchive/archive_write_set_format_by_name.c b/src/libs/3rdparty/libarchive/archive_write_set_format_by_name.c
index 86e8621ef..bfb4b3545 100644
--- a/src/libs/3rdparty/libarchive/archive_write_set_format_by_name.c
+++ b/src/libs/3rdparty/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/libs/3rdparty/libarchive/archive_write_set_format_cpio.c b/src/libs/3rdparty/libarchive/archive_write_set_format_cpio.c
index e06673352..29a7cada1 100644
--- a/src/libs/3rdparty/libarchive/archive_write_set_format_cpio.c
+++ b/src/libs/3rdparty/libarchive/archive_write_set_format_cpio.c
@@ -1,500 +1,10 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
- * All rights reserved.
- *
- * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
#include "archive.h"
-#include "archive_entry.h"
-#include "archive_entry_locale.h"
-#include "archive_private.h"
-#include "archive_write_private.h"
-#include "archive_write_set_format_private.h"
-
-static ssize_t archive_write_cpio_data(struct archive_write *,
- const void *buff, size_t s);
-static int archive_write_cpio_close(struct archive_write *);
-static int archive_write_cpio_free(struct archive_write *);
-static int archive_write_cpio_finish_entry(struct archive_write *);
-static int archive_write_cpio_header(struct archive_write *,
- struct archive_entry *);
-static int archive_write_cpio_options(struct archive_write *,
- const char *, const char *);
-static int format_octal(int64_t, void *, int);
-static int64_t format_octal_recursive(int64_t, char *, int);
-static int write_header(struct archive_write *, struct archive_entry *);
-
-struct cpio {
- uint64_t entry_bytes_remaining;
-
- int64_t ino_next;
-
- struct { int64_t old; int new;} *ino_list;
- size_t ino_list_size;
- size_t ino_list_next;
-
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
-};
-
-#define c_magic_offset 0
-#define c_magic_size 6
-#define c_dev_offset 6
-#define c_dev_size 6
-#define c_ino_offset 12
-#define c_ino_size 6
-#define c_mode_offset 18
-#define c_mode_size 6
-#define c_uid_offset 24
-#define c_uid_size 6
-#define c_gid_offset 30
-#define c_gid_size 6
-#define c_nlink_offset 36
-#define c_nlink_size 6
-#define c_rdev_offset 42
-#define c_rdev_size 6
-#define c_mtime_offset 48
-#define c_mtime_size 11
-#define c_namesize_offset 59
-#define c_namesize_size 6
-#define c_filesize_offset 65
-#define c_filesize_size 11
/*
- * Set output format to 'cpio' format.
+ * Set output format to the default 'cpio' format.
*/
int
archive_write_set_format_cpio(struct archive *_a)
{
- struct archive_write *a = (struct archive_write *)_a;
- struct cpio *cpio;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_format_cpio");
-
- /* If someone else was already registered, unregister them. */
- if (a->format_free != NULL)
- (a->format_free)(a);
-
- cpio = (struct cpio *)calloc(1, sizeof(*cpio));
- if (cpio == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
- return (ARCHIVE_FATAL);
- }
- a->format_data = cpio;
- a->format_name = "cpio";
- a->format_options = archive_write_cpio_options;
- a->format_write_header = archive_write_cpio_header;
- a->format_write_data = archive_write_cpio_data;
- a->format_finish_entry = archive_write_cpio_finish_entry;
- a->format_close = archive_write_cpio_close;
- a->format_free = archive_write_cpio_free;
- a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
- a->archive.archive_format_name = "POSIX cpio";
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_cpio_options(struct archive_write *a, const char *key,
- const char *val)
-{
- struct cpio *cpio = (struct cpio *)a->format_data;
- int ret = ARCHIVE_FAILED;
-
- if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s: hdrcharset option needs a character-set name",
- a->format_name);
- else {
- cpio->opt_sconv = archive_string_conversion_to_charset(
- &a->archive, val, 0);
- if (cpio->opt_sconv != NULL)
- ret = ARCHIVE_OK;
- else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-/*
- * Ino values are as long as 64 bits on some systems; cpio format
- * only allows 18 bits and relies on the ino values to identify hardlinked
- * files. So, we can't merely "hash" the ino numbers since collisions
- * would corrupt the archive. Instead, we generate synthetic ino values
- * to store in the archive and maintain a map of original ino values to
- * synthetic ones so we can preserve hardlink information.
- *
- * TODO: Make this more efficient. It's not as bad as it looks (most
- * files don't have any hardlinks and we don't do any work here for those),
- * but it wouldn't be hard to do better.
- *
- * TODO: Work with dev/ino pairs here instead of just ino values.
- */
-static int
-synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
-{
- int64_t ino = archive_entry_ino64(entry);
- int ino_new;
- size_t i;
-
- /*
- * If no index number was given, don't assign one. In
- * particular, this handles the end-of-archive marker
- * correctly by giving it a zero index value. (This is also
- * why we start our synthetic index numbers with one below.)
- */
- if (ino == 0)
- return (0);
-
- /* Don't store a mapping if we don't need to. */
- if (archive_entry_nlink(entry) < 2) {
- return (int)(++cpio->ino_next);
- }
-
- /* Look up old ino; if we have it, this is a hardlink
- * and we reuse the same value. */
- for (i = 0; i < cpio->ino_list_next; ++i) {
- if (cpio->ino_list[i].old == ino)
- return (cpio->ino_list[i].new);
- }
-
- /* Assign a new index number. */
- ino_new = (int)(++cpio->ino_next);
-
- /* Ensure space for the new mapping. */
- if (cpio->ino_list_size <= cpio->ino_list_next) {
- size_t newsize = cpio->ino_list_size < 512
- ? 512 : cpio->ino_list_size * 2;
- void *newlist = realloc(cpio->ino_list,
- sizeof(cpio->ino_list[0]) * newsize);
- if (newlist == NULL)
- return (-1);
-
- cpio->ino_list_size = newsize;
- cpio->ino_list = newlist;
- }
-
- /* Record and return the new value. */
- cpio->ino_list[cpio->ino_list_next].old = ino;
- cpio->ino_list[cpio->ino_list_next].new = ino_new;
- ++cpio->ino_list_next;
- return (ino_new);
-}
-
-
-static struct archive_string_conv *
-get_sconv(struct archive_write *a)
-{
- struct cpio *cpio;
- struct archive_string_conv *sconv;
-
- cpio = (struct cpio *)a->format_data;
- sconv = cpio->opt_sconv;
- if (sconv == NULL) {
- if (!cpio->init_default_conversion) {
- cpio->sconv_default =
- archive_string_default_conversion_for_write(
- &(a->archive));
- cpio->init_default_conversion = 1;
- }
- sconv = cpio->sconv_default;
- }
- return (sconv);
-}
-
-static int
-archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
-{
- const char *path;
- size_t len;
-
- if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
- archive_set_error(&a->archive, -1, "Filetype required");
- return (ARCHIVE_FAILED);
- }
-
- if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
- && errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- if (len == 0 || path == NULL || path[0] == '\0') {
- archive_set_error(&a->archive, -1, "Pathname required");
- return (ARCHIVE_FAILED);
- }
-
- if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
- archive_set_error(&a->archive, -1, "Size required");
- return (ARCHIVE_FAILED);
- }
- return write_header(a, entry);
-}
-
-static int
-write_header(struct archive_write *a, struct archive_entry *entry)
-{
- struct cpio *cpio;
- const char *p, *path;
- int pathlength, ret, ret_final;
- int64_t ino;
- char h[76];
- struct archive_string_conv *sconv;
- struct archive_entry *entry_main;
- size_t len;
-
- cpio = (struct cpio *)a->format_data;
- ret_final = ARCHIVE_OK;
- sconv = get_sconv(a);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Make sure the path separators in pathname, hardlink and symlink
- * are all slash '/', not the Windows path separator '\'. */
- entry_main = __la_win_entry_in_posix_pathseparator(entry);
- if (entry_main == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate ustar data");
- return(ARCHIVE_FATAL);
- }
- if (entry != entry_main)
- entry = entry_main;
- else
- entry_main = NULL;
-#else
- entry_main = NULL;
-#endif
-
- ret = archive_entry_pathname_l(entry, &path, &len, sconv);
- if (ret != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate pathname '%s' to %s",
- archive_entry_pathname(entry),
- archive_string_conversion_charset_name(sconv));
- ret_final = ARCHIVE_WARN;
- }
- /* Include trailing null. */
- pathlength = (int)len + 1;
-
- memset(h, 0, sizeof(h));
- format_octal(070707, h + c_magic_offset, c_magic_size);
- format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size);
-
- ino = synthesize_ino_value(cpio, entry);
- if (ino < 0) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for ino translation table");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- } else if (ino > 0777777) {
- archive_set_error(&a->archive, ERANGE,
- "Too many files for this cpio format");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- format_octal(ino & 0777777, h + c_ino_offset, c_ino_size);
-
- /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
- format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
- format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
- format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
- format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
- if (archive_entry_filetype(entry) == AE_IFBLK
- || archive_entry_filetype(entry) == AE_IFCHR)
- format_octal(archive_entry_rdev(entry), h + c_rdev_offset, c_rdev_size);
- else
- format_octal(0, h + c_rdev_offset, c_rdev_size);
- format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
- format_octal(pathlength, h + c_namesize_offset, c_namesize_size);
-
- /* Non-regular files don't store bodies. */
- if (archive_entry_filetype(entry) != AE_IFREG)
- archive_entry_set_size(entry, 0);
-
- /* Symlinks get the link written as the body of the entry. */
- ret = archive_entry_symlink_l(entry, &p, &len, sconv);
- if (ret != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate linkname '%s' to %s",
- archive_entry_symlink(entry),
- archive_string_conversion_charset_name(sconv));
- ret_final = ARCHIVE_WARN;
- }
- if (len > 0 && p != NULL && *p != '\0')
- ret = format_octal(strlen(p), h + c_filesize_offset,
- c_filesize_size);
- else
- ret = format_octal(archive_entry_size(entry),
- h + c_filesize_offset, c_filesize_size);
- if (ret) {
- archive_set_error(&a->archive, ERANGE,
- "File is too large for cpio format.");
- ret_final = ARCHIVE_FAILED;
- goto exit_write_header;
- }
-
- ret = __archive_write_output(a, h, sizeof(h));
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
-
- ret = __archive_write_output(a, path, pathlength);
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
-
- cpio->entry_bytes_remaining = archive_entry_size(entry);
-
- /* Write the symlink now. */
- if (p != NULL && *p != '\0') {
- ret = __archive_write_output(a, p, strlen(p));
- if (ret != ARCHIVE_OK) {
- ret_final = ARCHIVE_FATAL;
- goto exit_write_header;
- }
- }
-exit_write_header:
- archive_entry_free(entry_main);
- return (ret_final);
-}
-
-static ssize_t
-archive_write_cpio_data(struct archive_write *a, const void *buff, size_t s)
-{
- struct cpio *cpio;
- int ret;
-
- cpio = (struct cpio *)a->format_data;
- if (s > cpio->entry_bytes_remaining)
- s = (size_t)cpio->entry_bytes_remaining;
-
- ret = __archive_write_output(a, buff, s);
- cpio->entry_bytes_remaining -= s;
- if (ret >= 0)
- return (s);
- else
- return (ret);
-}
-
-/*
- * Format a number into the specified field.
- */
-static int
-format_octal(int64_t v, void *p, int digits)
-{
- int64_t max;
- int ret;
-
- max = (((int64_t)1) << (digits * 3)) - 1;
- if (v >= 0 && v <= max) {
- format_octal_recursive(v, (char *)p, digits);
- ret = 0;
- } else {
- format_octal_recursive(max, (char *)p, digits);
- ret = -1;
- }
- return (ret);
-}
-
-static int64_t
-format_octal_recursive(int64_t v, char *p, int s)
-{
- if (s == 0)
- return (v);
- v = format_octal_recursive(v, p+1, s-1);
- *p = '0' + ((char)v & 7);
- return (v >> 3);
-}
-
-static int
-archive_write_cpio_close(struct archive_write *a)
-{
- int er;
- struct archive_entry *trailer;
-
- trailer = archive_entry_new2(NULL);
- /* nlink = 1 here for GNU cpio compat. */
- archive_entry_set_nlink(trailer, 1);
- archive_entry_set_size(trailer, 0);
- archive_entry_set_pathname(trailer, "TRAILER!!!");
- er = write_header(a, trailer);
- archive_entry_free(trailer);
- return (er);
-}
-
-static int
-archive_write_cpio_free(struct archive_write *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)a->format_data;
- free(cpio->ino_list);
- free(cpio);
- a->format_data = NULL;
- return (ARCHIVE_OK);
-}
-
-static int
-archive_write_cpio_finish_entry(struct archive_write *a)
-{
- struct cpio *cpio;
-
- cpio = (struct cpio *)a->format_data;
- return (__archive_write_nulls(a,
- (size_t)cpio->entry_bytes_remaining));
+ return archive_write_set_format_cpio_odc(_a);
}
diff --git a/src/libs/3rdparty/libarchive/archive_write_set_format_cpio_binary.c b/src/libs/3rdparty/libarchive/archive_write_set_format_cpio_binary.c
new file mode 100644
index 000000000..c1e2f65aa
--- /dev/null
+++ b/src/libs/3rdparty/libarchive/archive_write_set_format_cpio_binary.c
@@ -0,0 +1,610 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
+
+static ssize_t archive_write_binary_data(struct archive_write *,
+ const void *buff, size_t s);
+static int archive_write_binary_close(struct archive_write *);
+static int archive_write_binary_free(struct archive_write *);
+static int archive_write_binary_finish_entry(struct archive_write *);
+static int archive_write_binary_header(struct archive_write *,
+ struct archive_entry *);
+static int archive_write_binary_options(struct archive_write *,
+ const char *, const char *);
+static int write_header(struct archive_write *, struct archive_entry *);
+
+struct cpio {
+ uint64_t entry_bytes_remaining;
+
+ int64_t ino_next;
+
+ struct { int64_t old; int new;} *ino_list;
+ size_t ino_list_size;
+ size_t ino_list_next;
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
+
+/* This struct needs to be packed to get the header right */
+
+#if defined(__GNUC__)
+#define PACKED(x) x __attribute__((packed))
+#elif defined(_MSC_VER)
+#define PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
+#else
+#define PACKED(x) x
+#endif
+
+#define HSIZE 26
+
+PACKED(struct cpio_binary_header {
+ uint16_t h_magic;
+ uint16_t h_dev;
+ uint16_t h_ino;
+ uint16_t h_mode;
+ uint16_t h_uid;
+ uint16_t h_gid;
+ uint16_t h_nlink;
+ uint16_t h_majmin;
+ uint32_t h_mtime;
+ uint16_t h_namesize;
+ uint32_t h_filesize;
+});
+
+/* Back in the day, the 7th Edition cpio.c had this, to
+ * adapt to, as the comment said, "VAX, Interdata, ...":
+ *
+ * union { long l; short s[2]; char c[4]; } U;
+ * #define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];}
+ * long mklong(v)
+ * short v[];
+ * {
+ * U.l = 1;
+ * if(U.c[0])
+ * U.s[0] = v[1], U.s[1] = v[0];
+ * else
+ * U.s[0] = v[0], U.s[1] = v[1];
+ * return U.l;
+ * }
+ *
+ * Of course, that assumes that all machines have little-endian shorts,
+ * and just adapts the others to the special endianness of the PDP-11.
+ *
+ * Now, we could do this:
+ *
+ * union { uint32_t l; uint16_t s[2]; uint8_t c[4]; } U;
+ * #define PUTI16(v,sv) {U.s[0]=1;if(U.c[0]) v=sv; else U.s[0]=sv,U.c[2]=U.c[1],U.c[3]=U.c[0],v=U.s[1];}
+ * #define PUTI32(v,lv) {char_t Ut;U.l=1;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,Ut=U.c[0],U.c[0]=U.c[1],U.c[1]=Ut,Ut=U.c[2],U.c[2]=U.c[3],U.c[3]=Ut,v[0]=U.s[0],v[1]=U.s[1];}
+ *
+ * ...but it feels a little better to do it like this:
+ */
+
+static uint16_t swap16(uint16_t in) {
+ union {
+ uint16_t s[2];
+ uint8_t c[4];
+ } U;
+ U.s[0] = 1;
+ if (U.c[0])
+ return in;
+ else {
+ U.s[0] = in;
+ U.c[2] = U.c[1];
+ U.c[3] = U.c[0];
+ return U.s[1];
+ }
+ /* NOTREACHED */
+}
+
+static uint32_t swap32(uint32_t in) {
+ union {
+ uint32_t l;
+ uint16_t s[2];
+ uint8_t c[4];
+ } U;
+ U.l = 1;
+ if (U.c[0]) { /* Little-endian */
+ uint16_t t;
+ U.l = in;
+ t = U.s[0];
+ U.s[0] = U.s[1];
+ U.s[1] = t;
+ } else if (U.c[3]) { /* Big-endian */
+ U.l = in;
+ U.s[0] = swap16(U.s[0]);
+ U.s[1] = swap16(U.s[1]);
+ } else { /* PDP-endian */
+ U.l = in;
+ }
+ return U.l;
+}
+
+/*
+ * Set output format to the selected binary variant
+ */
+static int
+archive_write_set_format_cpio_binary(struct archive *_a, int format)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct cpio *cpio;
+
+ if (sizeof(struct cpio_binary_header) != HSIZE) {
+ archive_set_error(&a->archive, EINVAL,
+ "Binary cpio format not supported on this platform");
+ return (ARCHIVE_FATAL);
+ }
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_binary");
+
+ /* If someone else was already registered, unregister them. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ cpio = (struct cpio *)calloc(1, sizeof(*cpio));
+ if (cpio == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
+ return (ARCHIVE_FATAL);
+ }
+ a->format_data = cpio;
+ a->format_name = "cpio";
+ a->format_options = archive_write_binary_options;
+ a->format_write_header = archive_write_binary_header;
+ a->format_write_data = archive_write_binary_data;
+ a->format_finish_entry = archive_write_binary_finish_entry;
+ a->format_close = archive_write_binary_close;
+ a->format_free = archive_write_binary_free;
+ a->archive.archive_format = format;
+ switch (format) {
+ case ARCHIVE_FORMAT_CPIO_PWB:
+ a->archive.archive_format_name = "PWB cpio";
+ break;
+ case ARCHIVE_FORMAT_CPIO_BIN_LE:
+ a->archive.archive_format_name = "7th Edition cpio";
+ break;
+ default:
+ archive_set_error(&a->archive, EINVAL, "binary format must be 'pwb' or 'bin'");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Set output format to PWB (6th Edition) binary format
+ */
+int
+archive_write_set_format_cpio_pwb(struct archive *_a)
+{
+ return archive_write_set_format_cpio_binary(_a, ARCHIVE_FORMAT_CPIO_PWB);
+}
+
+/*
+ * Set output format to 7th Edition binary format
+ */
+int
+archive_write_set_format_cpio_bin(struct archive *_a)
+{
+ return archive_write_set_format_cpio_binary(_a, ARCHIVE_FORMAT_CPIO_BIN_LE);
+}
+
+static int
+archive_write_binary_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct cpio *cpio = (struct cpio *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ cpio->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (cpio->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ return (ret);
+ }
+
+ /* Note: The "warn" return is just to inform the options
+ * supervisor that we didn't handle it. It will generate
+ * a suitable error if no one used this option. */
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Ino values are as long as 64 bits on some systems; cpio format
+ * only allows 16 bits and relies on the ino values to identify hardlinked
+ * files. So, we can't merely "hash" the ino numbers since collisions
+ * would corrupt the archive. Instead, we generate synthetic ino values
+ * to store in the archive and maintain a map of original ino values to
+ * synthetic ones so we can preserve hardlink information.
+ *
+ * TODO: Make this more efficient. It's not as bad as it looks (most
+ * files don't have any hardlinks and we don't do any work here for those),
+ * but it wouldn't be hard to do better.
+ *
+ * TODO: Work with dev/ino pairs here instead of just ino values.
+ */
+static int
+synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
+{
+ int64_t ino = archive_entry_ino64(entry);
+ int ino_new;
+ size_t i;
+
+ /*
+ * If no index number was given, don't assign one. In
+ * particular, this handles the end-of-archive marker
+ * correctly by giving it a zero index value. (This is also
+ * why we start our synthetic index numbers with one below.)
+ */
+ if (ino == 0)
+ return (0);
+
+ /* Don't store a mapping if we don't need to. */
+ if (archive_entry_nlink(entry) < 2) {
+ return (int)(++cpio->ino_next);
+ }
+
+ /* Look up old ino; if we have it, this is a hardlink
+ * and we reuse the same value. */
+ for (i = 0; i < cpio->ino_list_next; ++i) {
+ if (cpio->ino_list[i].old == ino)
+ return (cpio->ino_list[i].new);
+ }
+
+ /* Assign a new index number. */
+ ino_new = (int)(++cpio->ino_next);
+
+ /* Ensure space for the new mapping. */
+ if (cpio->ino_list_size <= cpio->ino_list_next) {
+ size_t newsize = cpio->ino_list_size < 512
+ ? 512 : cpio->ino_list_size * 2;
+ void *newlist = realloc(cpio->ino_list,
+ sizeof(cpio->ino_list[0]) * newsize);
+ if (newlist == NULL)
+ return (-1);
+
+ cpio->ino_list_size = newsize;
+ cpio->ino_list = newlist;
+ }
+
+ /* Record and return the new value. */
+ cpio->ino_list[cpio->ino_list_next].old = ino;
+ cpio->ino_list[cpio->ino_list_next].new = ino_new;
+ ++cpio->ino_list_next;
+ return (ino_new);
+}
+
+
+static struct archive_string_conv *
+get_sconv(struct archive_write *a)
+{
+ struct cpio *cpio;
+ struct archive_string_conv *sconv;
+
+ cpio = (struct cpio *)a->format_data;
+ sconv = cpio->opt_sconv;
+ if (sconv == NULL) {
+ if (!cpio->init_default_conversion) {
+ cpio->sconv_default =
+ archive_string_default_conversion_for_write(
+ &(a->archive));
+ cpio->init_default_conversion = 1;
+ }
+ sconv = cpio->sconv_default;
+ }
+ return (sconv);
+}
+
+static int
+archive_write_binary_header(struct archive_write *a, struct archive_entry *entry)
+{
+ const char *path;
+ size_t len;
+
+ if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
+ archive_set_error(&a->archive, -1, "Filetype required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
+ && errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ if (len == 0 || path == NULL || path[0] == '\0') {
+ archive_set_error(&a->archive, -1, "Pathname required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
+ archive_set_error(&a->archive, -1, "Size required");
+ return (ARCHIVE_FAILED);
+ }
+ return write_header(a, entry);
+}
+
+static int
+write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct cpio *cpio;
+ const char *p, *path;
+ int pathlength, ret, ret_final;
+ int64_t ino;
+ struct cpio_binary_header h;
+ struct archive_string_conv *sconv;
+ struct archive_entry *entry_main;
+ size_t len;
+
+ cpio = (struct cpio *)a->format_data;
+ ret_final = ARCHIVE_OK;
+ sconv = get_sconv(a);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Make sure the path separators in pathname, hardlink and symlink
+ * are all slash '/', not the Windows path separator '\'. */
+ entry_main = __la_win_entry_in_posix_pathseparator(entry);
+ if (entry_main == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate ustar data");
+ return(ARCHIVE_FATAL);
+ }
+ if (entry != entry_main)
+ entry = entry_main;
+ else
+ entry_main = NULL;
+#else
+ entry_main = NULL;
+#endif
+
+ ret = archive_entry_pathname_l(entry, &path, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ /* Include trailing null */
+ pathlength = (int)len + 1;
+
+ h.h_magic = swap16(070707);
+ h.h_dev = swap16(archive_entry_dev(entry));
+
+ ino = synthesize_ino_value(cpio, entry);
+ if (ino < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for ino translation table");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ } else if (ino > 077777) {
+ archive_set_error(&a->archive, ERANGE,
+ "Too many files for this cpio format");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ h.h_ino = swap16(ino);
+
+ h.h_mode = archive_entry_mode(entry);
+ if (((h.h_mode & AE_IFMT) == AE_IFSOCK) || ((h.h_mode & AE_IFMT) == AE_IFIFO)) {
+ archive_set_error(&a->archive, EINVAL,
+ "sockets and fifos cannot be represented in the binary cpio formats");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) {
+ if ((h.h_mode & AE_IFMT) == AE_IFLNK) {
+ archive_set_error(&a->archive, EINVAL,
+ "symbolic links cannot be represented in the PWB cpio format");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ /* we could turn off AE_IFREG here, but it does no harm, */
+ /* and allows v7 cpio to read the entry without confusion */
+ }
+ h.h_mode = swap16(h.h_mode);
+
+ h.h_uid = swap16(archive_entry_uid(entry));
+ h.h_gid = swap16(archive_entry_gid(entry));
+ h.h_nlink = swap16(archive_entry_nlink(entry));
+
+ if (archive_entry_filetype(entry) == AE_IFBLK
+ || archive_entry_filetype(entry) == AE_IFCHR)
+ h.h_majmin = swap16(archive_entry_rdev(entry));
+ else
+ h.h_majmin = 0;
+
+ h.h_mtime = swap32(archive_entry_mtime(entry));
+ h.h_namesize = swap16(pathlength);
+
+ /* Non-regular files don't store bodies. */
+ if (archive_entry_filetype(entry) != AE_IFREG)
+ archive_entry_set_size(entry, 0);
+
+ /* Symlinks get the link written as the body of the entry. */
+ ret = archive_entry_symlink_l(entry, &p, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_symlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+
+ if (len > 0 && p != NULL && *p != '\0') {
+ if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) {
+ archive_set_error(&a->archive, EINVAL,
+ "symlinks are not supported by UNIX V6 or by PWB cpio");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ h.h_filesize = swap32(strlen(p)); /* symlink */
+ } else {
+ if ((a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) &&
+ (archive_entry_size(entry) > 256*256*256-1)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File is too large for PWB binary cpio format.");
+ ret_final = ARCHIVE_FAILED;
+ goto exit_write_header;
+ } else if (archive_entry_size(entry) > INT32_MAX) {
+ archive_set_error(&a->archive, ERANGE,
+ "File is too large for binary cpio format.");
+ ret_final = ARCHIVE_FAILED;
+ goto exit_write_header;
+ }
+ h.h_filesize = swap32(archive_entry_size(entry)); /* file */
+ }
+
+ ret = __archive_write_output(a, &h, HSIZE);
+ if (ret != ARCHIVE_OK) {
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+
+ ret = __archive_write_output(a, path, pathlength);
+ if ((ret == ARCHIVE_OK) && ((pathlength % 2) != 0))
+ ret = __archive_write_nulls(a, 1);
+ if (ret != ARCHIVE_OK) {
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+
+ cpio->entry_bytes_remaining = archive_entry_size(entry);
+ if ((cpio->entry_bytes_remaining % 2) != 0)
+ cpio->entry_bytes_remaining++;
+
+ /* Write the symlink now. */
+ if (p != NULL && *p != '\0') {
+ ret = __archive_write_output(a, p, strlen(p));
+ if ((ret == ARCHIVE_OK) && ((strlen(p) % 2) != 0))
+ ret = __archive_write_nulls(a, 1);
+ if (ret != ARCHIVE_OK) {
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ }
+
+exit_write_header:
+ archive_entry_free(entry_main);
+ return (ret_final);
+}
+
+static ssize_t
+archive_write_binary_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct cpio *cpio;
+ int ret;
+
+ cpio = (struct cpio *)a->format_data;
+ if (s > cpio->entry_bytes_remaining)
+ s = (size_t)cpio->entry_bytes_remaining;
+
+ ret = __archive_write_output(a, buff, s);
+ cpio->entry_bytes_remaining -= s;
+ if (ret >= 0)
+ return (s);
+ else
+ return (ret);
+}
+
+static int
+archive_write_binary_close(struct archive_write *a)
+{
+ int er;
+ struct archive_entry *trailer;
+
+ trailer = archive_entry_new2(NULL);
+ /* nlink = 1 here for GNU cpio compat. */
+ archive_entry_set_nlink(trailer, 1);
+ archive_entry_set_size(trailer, 0);
+ archive_entry_set_pathname(trailer, "TRAILER!!!");
+ er = write_header(a, trailer);
+ archive_entry_free(trailer);
+ return (er);
+}
+
+static int
+archive_write_binary_free(struct archive_write *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)a->format_data;
+ free(cpio->ino_list);
+ free(cpio);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_binary_finish_entry(struct archive_write *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)a->format_data;
+ return (__archive_write_nulls(a,
+ (size_t)cpio->entry_bytes_remaining));
+}
diff --git a/src/libs/3rdparty/libarchive/archive_write_set_format_cpio_odc.c b/src/libs/3rdparty/libarchive/archive_write_set_format_cpio_odc.c
new file mode 100644
index 000000000..091925a2f
--- /dev/null
+++ b/src/libs/3rdparty/libarchive/archive_write_set_format_cpio_odc.c
@@ -0,0 +1,500 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
+
+static ssize_t archive_write_odc_data(struct archive_write *,
+ const void *buff, size_t s);
+static int archive_write_odc_close(struct archive_write *);
+static int archive_write_odc_free(struct archive_write *);
+static int archive_write_odc_finish_entry(struct archive_write *);
+static int archive_write_odc_header(struct archive_write *,
+ struct archive_entry *);
+static int archive_write_odc_options(struct archive_write *,
+ const char *, const char *);
+static int format_octal(int64_t, void *, int);
+static int64_t format_octal_recursive(int64_t, char *, int);
+static int write_header(struct archive_write *, struct archive_entry *);
+
+struct cpio {
+ uint64_t entry_bytes_remaining;
+
+ int64_t ino_next;
+
+ struct { int64_t old; int new;} *ino_list;
+ size_t ino_list_size;
+ size_t ino_list_next;
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
+
+#define c_magic_offset 0
+#define c_magic_size 6
+#define c_dev_offset 6
+#define c_dev_size 6
+#define c_ino_offset 12
+#define c_ino_size 6
+#define c_mode_offset 18
+#define c_mode_size 6
+#define c_uid_offset 24
+#define c_uid_size 6
+#define c_gid_offset 30
+#define c_gid_size 6
+#define c_nlink_offset 36
+#define c_nlink_size 6
+#define c_rdev_offset 42
+#define c_rdev_size 6
+#define c_mtime_offset 48
+#define c_mtime_size 11
+#define c_namesize_offset 59
+#define c_namesize_size 6
+#define c_filesize_offset 65
+#define c_filesize_size 11
+
+/*
+ * Set output format to 'cpio' format.
+ */
+int
+archive_write_set_format_cpio_odc(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct cpio *cpio;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_odc");
+
+ /* If someone else was already registered, unregister them. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ cpio = (struct cpio *)calloc(1, sizeof(*cpio));
+ if (cpio == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
+ return (ARCHIVE_FATAL);
+ }
+ a->format_data = cpio;
+ a->format_name = "cpio";
+ a->format_options = archive_write_odc_options;
+ a->format_write_header = archive_write_odc_header;
+ a->format_write_data = archive_write_odc_data;
+ a->format_finish_entry = archive_write_odc_finish_entry;
+ a->format_close = archive_write_odc_close;
+ a->format_free = archive_write_odc_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
+ a->archive.archive_format_name = "POSIX cpio";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_odc_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct cpio *cpio = (struct cpio *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ cpio->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (cpio->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ return (ret);
+ }
+
+ /* Note: The "warn" return is just to inform the options
+ * supervisor that we didn't handle it. It will generate
+ * a suitable error if no one used this option. */
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Ino values are as long as 64 bits on some systems; cpio format
+ * only allows 18 bits and relies on the ino values to identify hardlinked
+ * files. So, we can't merely "hash" the ino numbers since collisions
+ * would corrupt the archive. Instead, we generate synthetic ino values
+ * to store in the archive and maintain a map of original ino values to
+ * synthetic ones so we can preserve hardlink information.
+ *
+ * TODO: Make this more efficient. It's not as bad as it looks (most
+ * files don't have any hardlinks and we don't do any work here for those),
+ * but it wouldn't be hard to do better.
+ *
+ * TODO: Work with dev/ino pairs here instead of just ino values.
+ */
+static int
+synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
+{
+ int64_t ino = archive_entry_ino64(entry);
+ int ino_new;
+ size_t i;
+
+ /*
+ * If no index number was given, don't assign one. In
+ * particular, this handles the end-of-archive marker
+ * correctly by giving it a zero index value. (This is also
+ * why we start our synthetic index numbers with one below.)
+ */
+ if (ino == 0)
+ return (0);
+
+ /* Don't store a mapping if we don't need to. */
+ if (archive_entry_nlink(entry) < 2) {
+ return (int)(++cpio->ino_next);
+ }
+
+ /* Look up old ino; if we have it, this is a hardlink
+ * and we reuse the same value. */
+ for (i = 0; i < cpio->ino_list_next; ++i) {
+ if (cpio->ino_list[i].old == ino)
+ return (cpio->ino_list[i].new);
+ }
+
+ /* Assign a new index number. */
+ ino_new = (int)(++cpio->ino_next);
+
+ /* Ensure space for the new mapping. */
+ if (cpio->ino_list_size <= cpio->ino_list_next) {
+ size_t newsize = cpio->ino_list_size < 512
+ ? 512 : cpio->ino_list_size * 2;
+ void *newlist = realloc(cpio->ino_list,
+ sizeof(cpio->ino_list[0]) * newsize);
+ if (newlist == NULL)
+ return (-1);
+
+ cpio->ino_list_size = newsize;
+ cpio->ino_list = newlist;
+ }
+
+ /* Record and return the new value. */
+ cpio->ino_list[cpio->ino_list_next].old = ino;
+ cpio->ino_list[cpio->ino_list_next].new = ino_new;
+ ++cpio->ino_list_next;
+ return (ino_new);
+}
+
+
+static struct archive_string_conv *
+get_sconv(struct archive_write *a)
+{
+ struct cpio *cpio;
+ struct archive_string_conv *sconv;
+
+ cpio = (struct cpio *)a->format_data;
+ sconv = cpio->opt_sconv;
+ if (sconv == NULL) {
+ if (!cpio->init_default_conversion) {
+ cpio->sconv_default =
+ archive_string_default_conversion_for_write(
+ &(a->archive));
+ cpio->init_default_conversion = 1;
+ }
+ sconv = cpio->sconv_default;
+ }
+ return (sconv);
+}
+
+static int
+archive_write_odc_header(struct archive_write *a, struct archive_entry *entry)
+{
+ const char *path;
+ size_t len;
+
+ if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
+ archive_set_error(&a->archive, -1, "Filetype required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
+ && errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ if (len == 0 || path == NULL || path[0] == '\0') {
+ archive_set_error(&a->archive, -1, "Pathname required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
+ archive_set_error(&a->archive, -1, "Size required");
+ return (ARCHIVE_FAILED);
+ }
+ return write_header(a, entry);
+}
+
+static int
+write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct cpio *cpio;
+ const char *p, *path;
+ int pathlength, ret, ret_final;
+ int64_t ino;
+ char h[76];
+ struct archive_string_conv *sconv;
+ struct archive_entry *entry_main;
+ size_t len;
+
+ cpio = (struct cpio *)a->format_data;
+ ret_final = ARCHIVE_OK;
+ sconv = get_sconv(a);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Make sure the path separators in pathname, hardlink and symlink
+ * are all slash '/', not the Windows path separator '\'. */
+ entry_main = __la_win_entry_in_posix_pathseparator(entry);
+ if (entry_main == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate ustar data");
+ return(ARCHIVE_FATAL);
+ }
+ if (entry != entry_main)
+ entry = entry_main;
+ else
+ entry_main = NULL;
+#else
+ entry_main = NULL;
+#endif
+
+ ret = archive_entry_pathname_l(entry, &path, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ /* Include trailing null. */
+ pathlength = (int)len + 1;
+
+ memset(h, 0, sizeof(h));
+ format_octal(070707, h + c_magic_offset, c_magic_size);
+ format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size);
+
+ ino = synthesize_ino_value(cpio, entry);
+ if (ino < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for ino translation table");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ } else if (ino > 0777777) {
+ archive_set_error(&a->archive, ERANGE,
+ "Too many files for this cpio format");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ format_octal(ino & 0777777, h + c_ino_offset, c_ino_size);
+
+ /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
+ format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
+ format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
+ format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
+ format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
+ if (archive_entry_filetype(entry) == AE_IFBLK
+ || archive_entry_filetype(entry) == AE_IFCHR)
+ format_octal(archive_entry_rdev(entry), h + c_rdev_offset, c_rdev_size);
+ else
+ format_octal(0, h + c_rdev_offset, c_rdev_size);
+ format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
+ format_octal(pathlength, h + c_namesize_offset, c_namesize_size);
+
+ /* Non-regular files don't store bodies. */
+ if (archive_entry_filetype(entry) != AE_IFREG)
+ archive_entry_set_size(entry, 0);
+
+ /* Symlinks get the link written as the body of the entry. */
+ ret = archive_entry_symlink_l(entry, &p, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_symlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ if (len > 0 && p != NULL && *p != '\0')
+ ret = format_octal(strlen(p), h + c_filesize_offset,
+ c_filesize_size);
+ else
+ ret = format_octal(archive_entry_size(entry),
+ h + c_filesize_offset, c_filesize_size);
+ if (ret) {
+ archive_set_error(&a->archive, ERANGE,
+ "File is too large for cpio format.");
+ ret_final = ARCHIVE_FAILED;
+ goto exit_write_header;
+ }
+
+ ret = __archive_write_output(a, h, sizeof(h));
+ if (ret != ARCHIVE_OK) {
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+
+ ret = __archive_write_output(a, path, pathlength);
+ if (ret != ARCHIVE_OK) {
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+
+ cpio->entry_bytes_remaining = archive_entry_size(entry);
+
+ /* Write the symlink now. */
+ if (p != NULL && *p != '\0') {
+ ret = __archive_write_output(a, p, strlen(p));
+ if (ret != ARCHIVE_OK) {
+ ret_final = ARCHIVE_FATAL;
+ goto exit_write_header;
+ }
+ }
+exit_write_header:
+ archive_entry_free(entry_main);
+ return (ret_final);
+}
+
+static ssize_t
+archive_write_odc_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct cpio *cpio;
+ int ret;
+
+ cpio = (struct cpio *)a->format_data;
+ if (s > cpio->entry_bytes_remaining)
+ s = (size_t)cpio->entry_bytes_remaining;
+
+ ret = __archive_write_output(a, buff, s);
+ cpio->entry_bytes_remaining -= s;
+ if (ret >= 0)
+ return (s);
+ else
+ return (ret);
+}
+
+/*
+ * Format a number into the specified field.
+ */
+static int
+format_octal(int64_t v, void *p, int digits)
+{
+ int64_t max;
+ int ret;
+
+ max = (((int64_t)1) << (digits * 3)) - 1;
+ if (v >= 0 && v <= max) {
+ format_octal_recursive(v, (char *)p, digits);
+ ret = 0;
+ } else {
+ format_octal_recursive(max, (char *)p, digits);
+ ret = -1;
+ }
+ return (ret);
+}
+
+static int64_t
+format_octal_recursive(int64_t v, char *p, int s)
+{
+ if (s == 0)
+ return (v);
+ v = format_octal_recursive(v, p+1, s-1);
+ *p = '0' + ((char)v & 7);
+ return (v >> 3);
+}
+
+static int
+archive_write_odc_close(struct archive_write *a)
+{
+ int er;
+ struct archive_entry *trailer;
+
+ trailer = archive_entry_new2(NULL);
+ /* nlink = 1 here for GNU cpio compat. */
+ archive_entry_set_nlink(trailer, 1);
+ archive_entry_set_size(trailer, 0);
+ archive_entry_set_pathname(trailer, "TRAILER!!!");
+ er = write_header(a, trailer);
+ archive_entry_free(trailer);
+ return (er);
+}
+
+static int
+archive_write_odc_free(struct archive_write *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)a->format_data;
+ free(cpio->ino_list);
+ free(cpio);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_odc_finish_entry(struct archive_write *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)a->format_data;
+ return (__archive_write_nulls(a,
+ (size_t)cpio->entry_bytes_remaining));
+}
diff --git a/src/libs/3rdparty/libarchive/config_freebsd.h b/src/libs/3rdparty/libarchive/config_freebsd.h
index a484618b4..ac651f00e 100644
--- a/src/libs/3rdparty/libarchive/config_freebsd.h
+++ b/src/libs/3rdparty/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
diff --git a/src/libs/3rdparty/libarchive/libarchive.pro b/src/libs/3rdparty/libarchive/libarchive.pro
index accaf3af7..a647d6572 100644
--- a/src/libs/3rdparty/libarchive/libarchive.pro
+++ b/src/libs/3rdparty/libarchive/libarchive.pro
@@ -146,7 +146,9 @@ SOURCES += $$PWD/archive_acl.c \
$$PWD/archive_write_set_format_ar.c \
$$PWD/archive_write_set_format_by_name.c \
$$PWD/archive_write_set_format_cpio.c \
+ $$PWD/archive_write_set_format_cpio_binary.c \
$$PWD/archive_write_set_format_cpio_newc.c \
+ $$PWD/archive_write_set_format_cpio_odc.c \
$$PWD/archive_write_set_format_filter_by_ext.c \
$$PWD/archive_write_set_format_gnutar.c \
$$PWD/archive_write_set_format_iso9660.c \
diff --git a/src/libs/3rdparty/libarchive/qt_attribution.json b/src/libs/3rdparty/libarchive/qt_attribution.json
index 86beb162c..b5d97b74c 100644
--- a/src/libs/3rdparty/libarchive/qt_attribution.json
+++ b/src/libs/3rdparty/libarchive/qt_attribution.json
@@ -5,7 +5,7 @@
"Description": "Multi-format archive and compression library.",
"QtUsage": "Used for reading and writing archive files in Qt Installer Framework",
"Homepage": "https://www.libarchive.org",
- "Version": "3.5.1",
+ "Version": "3.5.2",
"License": "BSD 2-clause \"Simplified\" License",
"LicenseId": "BSD-2-Clause",
"LicenseFile": "COPYING",
diff --git a/src/libs/3rdparty/libarchive/xxhash.c b/src/libs/3rdparty/libarchive/xxhash.c
index 70750bae0..f96e9d934 100644
--- a/src/libs/3rdparty/libarchive/xxhash.c
+++ b/src/libs/3rdparty/libarchive/xxhash.c
@@ -150,7 +150,11 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
#if GCC_VERSION >= 409
__attribute__((__no_sanitize_undefined__))
#endif
-static inline U32 A32(const void * x)
+#if defined(_MSC_VER)
+static __inline U32 A32(const void * x)
+#else
+static inline U32 A32(const void* x)
+#endif
{
return (((const U32_S *)(x))->v);
}