svn commit: r356212 - in head: contrib/libarchive contrib/libarchive/libarchive contrib/libarchive/libarchive/test contrib/libarchive/test_utils lib/libarchive/tests usr.bin/bsdcat usr.bin/cpio usr...
Martin Matuska
mm at FreeBSD.org
Tue Dec 31 00:05:10 UTC 2019
Author: mm
Date: Tue Dec 31 00:05:06 2019
New Revision: 356212
URL: https://svnweb.freebsd.org/changeset/base/356212
Log:
MFV r356163,r356197:
Update libarchive to 3.4.1
Relevant vendor changes since last update:
Issue #351: Refactor and implement private state logic for write filters
PR #1252: RAR5 reader - verify window size for solid files (OSS-Fuzz 15482)
PR #1255: zip writer - don't append unused NUL for directories
PR #1260: Fix sparse file offset overflow on 32-bit systems
PR #1263: UNICODE filename support for reading lha/lzh format
Issue #1276: Bugfix and optimize archive_wstring_append_from_mbs()
PR #1288: Add the "xattrhdr" option to pax write options
PR #1295: 7z reader - fix reading archives with digests in PackInfo
PR #1296: RAR5 reader - verify window size for multivolume archives
PR #1297: ZIP reader - support LZMA_STREAM_END marker in 'lzma alone' files
Issue #1298: Fix a heap-buffer-overflow in archive_string_append_from_wcs()
OSS-Fuzz 19360, 19362: LHA reader - plug two memory leaks on error
Fix possible off-by-one when dealing with readlink(2)
MFC after: 2 weeks
Added:
head/contrib/libarchive/libarchive/test/test_pax_xattr_header.c
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_pax_xattr_header.c
head/contrib/libarchive/libarchive/test/test_pax_xattr_header_all.tar.uu
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_pax_xattr_header_all.tar.uu
head/contrib/libarchive/libarchive/test/test_pax_xattr_header_libarchive.tar.uu
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_pax_xattr_header_libarchive.tar.uu
head/contrib/libarchive/libarchive/test/test_pax_xattr_header_schily.tar.uu
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_pax_xattr_header_schily.tar.uu
head/contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu
head/contrib/libarchive/libarchive/test/test_read_format_7zip_packinfo_digests.c
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_7zip_packinfo_digests.c
head/contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.c
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_lha_filename_utf16.c
head/contrib/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu
head/contrib/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu
head/contrib/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu
- copied unchanged from r356163, vendor/libarchive/dist/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu
Modified:
head/contrib/libarchive/NEWS
head/contrib/libarchive/libarchive/archive.h
head/contrib/libarchive/libarchive/archive_entry.h
head/contrib/libarchive/libarchive/archive_entry_acl.3
head/contrib/libarchive/libarchive/archive_hmac.c
head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
head/contrib/libarchive/libarchive/archive_read_disk_posix.c
head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
head/contrib/libarchive/libarchive/archive_read_support_format_lha.c
head/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
head/contrib/libarchive/libarchive/archive_read_support_format_zip.c
head/contrib/libarchive/libarchive/archive_string.c
head/contrib/libarchive/libarchive/archive_write.c
head/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c
head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c
head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c
head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c
head/contrib/libarchive/libarchive/archive_write_add_filter_lz4.c
head/contrib/libarchive/libarchive/archive_write_add_filter_lzop.c
head/contrib/libarchive/libarchive/archive_write_add_filter_program.c
head/contrib/libarchive/libarchive/archive_write_add_filter_uuencode.c
head/contrib/libarchive/libarchive/archive_write_add_filter_xz.c
head/contrib/libarchive/libarchive/archive_write_add_filter_zstd.c
head/contrib/libarchive/libarchive/archive_write_disk_posix.c
head/contrib/libarchive/libarchive/archive_write_private.h
head/contrib/libarchive/libarchive/archive_write_set_format_pax.c
head/contrib/libarchive/libarchive/archive_write_set_format_zip.c
head/contrib/libarchive/libarchive/archive_write_set_options.3
head/contrib/libarchive/libarchive/test/test_open_failure.c
head/contrib/libarchive/libarchive/test/test_open_fd.c
head/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
head/contrib/libarchive/libarchive/test/test_read_format_rar5.c
head/contrib/libarchive/libarchive/test/test_sparse_basic.c
head/contrib/libarchive/test_utils/test_main.c
head/lib/libarchive/tests/Makefile
head/usr.bin/bsdcat/Makefile
head/usr.bin/cpio/Makefile
head/usr.bin/tar/Makefile
Directory Properties:
head/contrib/libarchive/ (props changed)
Modified: head/contrib/libarchive/NEWS
==============================================================================
--- head/contrib/libarchive/NEWS Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/NEWS Tue Dec 31 00:05:06 2019 (r356212)
@@ -1,3 +1,9 @@
+Dec 30, 2019: libarchive 3.4.1 released
+
+Dec 11, 2019: New pax write option "xattrhdr"
+
+Nov 17, 2019: Unicode filename support for reading lha/lzh archives
+
Jun 11, 2019: libarchive 3.4.0 released
May 18, 2019: Fixes for reading Android APK and JAR archives
Modified: head/contrib/libarchive/libarchive/archive.h
==============================================================================
--- head/contrib/libarchive/libarchive/archive.h Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive.h Tue Dec 31 00:05:06 2019 (r356212)
@@ -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 3004000
+#define ARCHIVE_VERSION_NUMBER 3004001
#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.4.0"
+#define ARCHIVE_VERSION_ONLY_STRING "3.4.1"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
Modified: head/contrib/libarchive/libarchive/archive_entry.h
==============================================================================
--- head/contrib/libarchive/libarchive/archive_entry.h Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_entry.h Tue Dec 31 00:05:06 2019 (r356212)
@@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3004000
+#define ARCHIVE_VERSION_NUMBER 3004001
/*
* Note: archive_entry.h is for use outside of libarchive; the
@@ -524,9 +524,6 @@ __LA_DECL int archive_entry_acl_reset(struct archive_
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
int * /* type */, int * /* permset */, int * /* tag */,
int * /* qual */, const char ** /* name */);
-__LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
- int * /* type */, int * /* permset */, int * /* tag */,
- int * /* qual */, const wchar_t ** /* name */);
/*
* Construct a text-format ACL. The flags argument is a bitmask that
Modified: head/contrib/libarchive/libarchive/archive_entry_acl.3
==============================================================================
--- head/contrib/libarchive/libarchive/archive_entry_acl.3 Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_entry_acl.3 Tue Dec 31 00:05:06 2019 (r356212)
@@ -34,7 +34,6 @@
.Nm archive_entry_acl_from_text ,
.Nm archive_entry_acl_from_text_w ,
.Nm archive_entry_acl_next ,
-.Nm archive_entry_acl_next_w ,
.Nm archive_entry_acl_reset ,
.Nm archive_entry_acl_to_text ,
.Nm archive_entry_acl_to_text_w ,
@@ -89,16 +88,6 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "const char **ret_name"
.Fc
.Ft int
-.Fo archive_entry_acl_next_w
-.Fa "struct archive_entry *a"
-.Fa "int type"
-.Fa "int *ret_type"
-.Fa "int *ret_permset"
-.Fa "int *ret_tag"
-.Fa "int *ret_qual"
-.Fa "const wchar_t **ret_name"
-.Fc
-.Ft int
.Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
.Ft char *
.Fo archive_entry_acl_to_text
@@ -349,8 +338,6 @@ character
are skipped.
.Pp
.Fn archive_entry_acl_next
-and
-.Fn archive_entry_acl_next_w
return the next entry of the ACL list.
This functions may only be called after
.Fn archive_entry_acl_reset
@@ -358,9 +345,7 @@ has indicated the presence of extended ACL entries.
.Pp
.Fn archive_entry_acl_reset
prepare reading the list of ACL entries with
-.Fn archive_entry_acl_next
-or
-.Fn archive_entry_acl_next_w .
+.Fn archive_entry_acl_next .
The function returns 0 if no non-extended ACLs are found.
In this case, the access permissions should be obtained by
.Xr archive_entry_mode 3
@@ -447,9 +432,7 @@ if all entries were successfully parsed and
if one or more entries were invalid or non-parseable.
.Pp
.Fn archive_entry_acl_next
-and
-.Fn archive_entry_acl_next_w
-return
+returns
.Dv ARCHIVE_OK
on success,
.Dv ARCHIVE_EOF
Modified: head/contrib/libarchive/libarchive/archive_hmac.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_hmac.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_hmac.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -83,7 +83,9 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
static int
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
{
+#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
DWORD hash_len;
Modified: head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -249,11 +249,11 @@ archive_read_disk_entry_from_file(struct archive *_a,
#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
if (S_ISLNK(st->st_mode)) {
- size_t linkbuffer_len = st->st_size + 1;
+ size_t linkbuffer_len = st->st_size;
char *linkbuffer;
int lnklen;
- linkbuffer = malloc(linkbuffer_len);
+ linkbuffer = malloc(linkbuffer_len + 1);
if (linkbuffer == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Couldn't read link data");
@@ -280,7 +280,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
free(linkbuffer);
return (ARCHIVE_FAILED);
}
- linkbuffer[lnklen] = 0;
+ linkbuffer[lnklen] = '\0';
archive_entry_set_symlink(entry, linkbuffer);
free(linkbuffer);
}
Modified: head/contrib/libarchive/libarchive/archive_read_disk_posix.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_disk_posix.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_read_disk_posix.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -694,6 +694,7 @@ _archive_read_data_block(struct archive *_a, const voi
struct tree *t = a->tree;
int r;
ssize_t bytes;
+ int64_t sparse_bytes;
size_t buffbytes;
int empty_sparse_region = 0;
@@ -792,9 +793,9 @@ _archive_read_data_block(struct archive *_a, const voi
a->archive.state = ARCHIVE_STATE_FATAL;
goto abort_read_data;
}
- bytes = t->current_sparse->offset - t->entry_total;
- t->entry_remaining_bytes -= bytes;
- t->entry_total += bytes;
+ sparse_bytes = t->current_sparse->offset - t->entry_total;
+ t->entry_remaining_bytes -= sparse_bytes;
+ t->entry_total += sparse_bytes;
}
/*
@@ -2172,7 +2173,7 @@ tree_reopen(struct tree *t, const char *path, int rest
#elif defined(O_SEARCH)
/* SunOS */
const int o_flag = O_SEARCH;
-#elif defined(O_EXEC)
+#elif defined(__FreeBSD__) && defined(O_EXEC)
/* FreeBSD */
const int o_flag = O_EXEC;
#endif
@@ -2198,7 +2199,8 @@ tree_reopen(struct tree *t, const char *path, int rest
t->stack->flags = needsFirstVisit;
t->maxOpenCount = t->openCount = 1;
t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
-#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC)
+#if defined(O_PATH) || defined(O_SEARCH) || \
+ (defined(__FreeBSD__) && defined(O_EXEC))
/*
* Most likely reason to fail opening "." is that it's not readable,
* so try again for execute. The consequences of not opening this are
Modified: head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_read_support_format_7zip.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -1787,7 +1787,7 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_
return (0);
}
- if (*p != kSize)
+ if (*p != kCRC)
return (-1);
if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)
Modified: head/contrib/libarchive/libarchive/archive_read_support_format_lha.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_support_format_lha.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_read_support_format_lha.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -175,7 +175,9 @@ struct lha {
struct archive_string gname;
uint16_t header_crc;
uint16_t crc;
- struct archive_string_conv *sconv;
+ /* dirname and filename could be in different codepages */
+ struct archive_string_conv *sconv_dir;
+ struct archive_string_conv *sconv_fname;
struct archive_string_conv *opt_sconv;
struct archive_string dirname;
@@ -232,8 +234,8 @@ static time_t lha_dos_time(const unsigned char *);
static time_t lha_win_time(uint64_t, long *);
static unsigned char lha_calcsum(unsigned char, const void *,
int, size_t);
-static int lha_parse_linkname(struct archive_string *,
- struct archive_string *);
+static int lha_parse_linkname(struct archive_wstring *,
+ struct archive_wstring *);
static int lha_read_data_none(struct archive_read *, const void **,
size_t *, int64_t *);
static int lha_read_data_lzh(struct archive_read *, const void **,
@@ -473,13 +475,15 @@ static int
archive_read_format_lha_read_header(struct archive_read *a,
struct archive_entry *entry)
{
- struct archive_string linkname;
- struct archive_string pathname;
+ struct archive_wstring linkname;
+ struct archive_wstring pathname;
struct lha *lha;
const unsigned char *p;
const char *signature;
int err;
-
+ struct archive_mstring conv_buffer;
+ const wchar_t *conv_buffer_p;
+
lha_crc16_init();
a->archive.archive_format = ARCHIVE_FORMAT_LHA;
@@ -561,10 +565,13 @@ archive_read_format_lha_read_header(struct archive_rea
archive_string_empty(&lha->dirname);
archive_string_empty(&lha->filename);
lha->dos_attr = 0;
- if (lha->opt_sconv != NULL)
- lha->sconv = lha->opt_sconv;
- else
- lha->sconv = NULL;
+ if (lha->opt_sconv != NULL) {
+ lha->sconv_dir = lha->opt_sconv;
+ lha->sconv_fname = lha->opt_sconv;
+ } else {
+ lha->sconv_dir = NULL;
+ lha->sconv_fname = NULL;
+ }
switch (p[H_LEVEL_OFFSET]) {
case 0:
@@ -594,13 +601,55 @@ archive_read_format_lha_read_header(struct archive_rea
return (truncated_error(a));
/*
- * Make a pathname from a dirname and a filename.
- */
- archive_string_concat(&lha->dirname, &lha->filename);
+ * Make a pathname from a dirname and a filename, after converting to Unicode.
+ * This is because codepages might differ between dirname and filename.
+ */
archive_string_init(&pathname);
archive_string_init(&linkname);
- archive_string_copy(&pathname, &lha->dirname);
+ archive_string_init(&conv_buffer.aes_mbs);
+ archive_string_init(&conv_buffer.aes_mbs_in_locale);
+ archive_string_init(&conv_buffer.aes_utf8);
+ archive_string_init(&conv_buffer.aes_wcs);
+ if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->dirname.s, lha->dirname.length, lha->sconv_dir)) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to Unicode.",
+ archive_string_conversion_charset_name(lha->sconv_dir));
+ err = ARCHIVE_FATAL;
+ } else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
+ err = ARCHIVE_FATAL;
+ if (err == ARCHIVE_FATAL) {
+ archive_mstring_clean(&conv_buffer);
+ archive_wstring_free(&pathname);
+ archive_wstring_free(&linkname);
+ return (err);
+ }
+ archive_wstring_copy(&pathname, &conv_buffer.aes_wcs);
+ archive_string_empty(&conv_buffer.aes_mbs);
+ archive_string_empty(&conv_buffer.aes_mbs_in_locale);
+ archive_string_empty(&conv_buffer.aes_utf8);
+ archive_wstring_empty(&conv_buffer.aes_wcs);
+ if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->filename.s, lha->filename.length, lha->sconv_fname)) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to Unicode.",
+ archive_string_conversion_charset_name(lha->sconv_fname));
+ err = ARCHIVE_FATAL;
+ }
+ else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
+ err = ARCHIVE_FATAL;
+ if (err == ARCHIVE_FATAL) {
+ archive_mstring_clean(&conv_buffer);
+ archive_wstring_free(&pathname);
+ archive_wstring_free(&linkname);
+ return (err);
+ }
+ archive_wstring_concat(&pathname, &conv_buffer.aes_wcs);
+ archive_mstring_clean(&conv_buffer);
+
if ((lha->mode & AE_IFMT) == AE_IFLNK) {
/*
* Extract the symlink-name if it's included in the pathname.
@@ -610,8 +659,8 @@ archive_read_format_lha_read_header(struct archive_rea
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Unknown symlink-name");
- archive_string_free(&pathname);
- archive_string_free(&linkname);
+ archive_wstring_free(&pathname);
+ archive_wstring_free(&linkname);
return (ARCHIVE_FAILED);
}
} else {
@@ -629,39 +678,13 @@ archive_read_format_lha_read_header(struct archive_rea
/*
* Set basic file parameters.
*/
- if (archive_entry_copy_pathname_l(entry, pathname.s,
- pathname.length, lha->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Pathname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(lha->sconv));
- err = ARCHIVE_WARN;
- }
- archive_string_free(&pathname);
+ archive_entry_copy_pathname_w(entry, pathname.s);
+ archive_wstring_free(&pathname);
if (archive_strlen(&linkname) > 0) {
- if (archive_entry_copy_symlink_l(entry, linkname.s,
- linkname.length, lha->sconv) != 0) {
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Linkname");
- return (ARCHIVE_FATAL);
- }
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Linkname cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(lha->sconv));
- err = ARCHIVE_WARN;
- }
+ archive_entry_copy_symlink_w(entry, linkname.s);
} else
archive_entry_set_symlink(entry, NULL);
- archive_string_free(&linkname);
+ archive_wstring_free(&linkname);
/*
* When a header level is 0, there is a possibility that
* a pathname and a symlink has '\' character, a directory
@@ -1208,6 +1231,26 @@ lha_read_file_extended_header(struct archive_read *a,
archive_strncpy(&lha->filename,
(const char *)extdheader, datasize);
break;
+ case EXT_UTF16_FILENAME:
+ if (datasize == 0) {
+ /* maybe directory header */
+ archive_string_empty(&lha->filename);
+ break;
+ } else if (datasize & 1) {
+ /* UTF-16 characters take always 2 or 4 bytes */
+ goto invalid;
+ }
+ if (extdheader[0] == '\0')
+ goto invalid;
+ archive_string_empty(&lha->filename);
+ archive_array_append(&lha->filename,
+ (const char *)extdheader, datasize);
+ /* Setup a string conversion for a filename. */
+ lha->sconv_fname = archive_string_conversion_from_charset(
+ &a->archive, "UTF-16LE", 1);
+ if (lha->sconv_fname == NULL)
+ return (ARCHIVE_FATAL);
+ break;
case EXT_DIRECTORY:
if (datasize == 0 || extdheader[0] == '\0')
/* no directory name data. exit this case. */
@@ -1228,6 +1271,36 @@ lha_read_file_extended_header(struct archive_read *a,
/* invalid directory data */
goto invalid;
break;
+ case EXT_UTF16_DIRECTORY:
+ /* UTF-16 characters take always 2 or 4 bytes */
+ if (datasize == 0 || (datasize & 1) || extdheader[0] == '\0')
+ /* no directory name data. exit this case. */
+ goto invalid;
+
+ archive_string_empty(&lha->dirname);
+ archive_array_append(&lha->dirname,
+ (const char *)extdheader, datasize);
+ lha->sconv_dir = archive_string_conversion_from_charset(
+ &a->archive, "UTF-16LE", 1);
+ if (lha->sconv_dir == NULL)
+ return (ARCHIVE_FATAL);
+ else {
+ /*
+ * Convert directory delimiter from 0xFF
+ * to '/' for local system.
+ */
+ /* UTF-16LE character */
+ uint16_t *utf16name = (uint16_t *)lha->dirname.s;
+ for (i = 0; i < lha->dirname.length / 2; i++) {
+ if (utf16name[i] == 0xFFFF)
+ utf16name[i] = L'/';
+ }
+ /* Is last character directory separator? */
+ if (utf16name[lha->dirname.length / 2 - 1] != L'/')
+ /* invalid directory data */
+ goto invalid;
+ }
+ break;
case EXT_DOS_ATTR:
if (datasize == 2)
lha->dos_attr = (unsigned char)
@@ -1276,12 +1349,17 @@ lha_read_file_extended_header(struct archive_read *a,
charset = cp.s;
break;
}
- lha->sconv =
+ lha->sconv_dir =
archive_string_conversion_from_charset(
&(a->archive), charset, 1);
+ lha->sconv_fname =
+ archive_string_conversion_from_charset(
+ &(a->archive), charset, 1);
archive_string_free(&cp);
- if (lha->sconv == NULL)
+ if (lha->sconv_dir == NULL)
return (ARCHIVE_FATAL);
+ if (lha->sconv_fname == NULL)
+ return (ARCHIVE_FATAL);
}
break;
case EXT_UNIX_MODE:
@@ -1336,8 +1414,7 @@ lha_read_file_extended_header(struct archive_read *a,
}
break;
case EXT_TIMEZONE: /* Not supported */
- case EXT_UTF16_FILENAME: /* Not supported */
- case EXT_UTF16_DIRECTORY: /* Not supported */
+ break;
default:
break;
}
@@ -1600,19 +1677,19 @@ archive_read_format_lha_cleanup(struct archive_read *a
* then a archived pathname is 'xxx/bbb|aaa/bb/cc'
*/
static int
-lha_parse_linkname(struct archive_string *linkname,
- struct archive_string *pathname)
+lha_parse_linkname(struct archive_wstring *linkname,
+ struct archive_wstring *pathname)
{
- char * linkptr;
+ wchar_t * linkptr;
size_t symlen;
- linkptr = strchr(pathname->s, '|');
+ linkptr = wcschr(pathname->s, L'|');
if (linkptr != NULL) {
- symlen = strlen(linkptr + 1);
- archive_strncpy(linkname, linkptr+1, symlen);
+ symlen = wcslen(linkptr + 1);
+ archive_wstrncpy(linkname, linkptr+1, symlen);
*linkptr = 0;
- pathname->length = strlen(pathname->s);
+ pathname->length = wcslen(pathname->s);
return (1);
}
Modified: head/contrib/libarchive/libarchive/archive_read_support_format_rar5.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_support_format_rar5.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_read_support_format_rar5.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -63,6 +63,7 @@
#if defined DEBUG
#define DEBUG_CODE if(1)
+#define LOG(...) do { printf("rar5: " __VA_ARGS__); puts(""); } while(0)
#else
#define DEBUG_CODE if(0)
#endif
@@ -115,6 +116,8 @@ struct file_header {
/* Optional redir fields */
uint64_t redir_type;
uint64_t redir_flags;
+
+ ssize_t solid_window_size; /* Used in file format check. */
};
enum EXTRA {
@@ -1177,7 +1180,7 @@ static int process_main_locator_extra_block(struct arc
static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
ssize_t* extra_data_size)
{
- size_t hash_type;
+ size_t hash_type = 0;
size_t value_len;
if(!read_var_sized(a, &hash_type, &value_len))
@@ -1303,7 +1306,7 @@ static int parse_file_extra_htime(struct archive_read*
struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
{
char unix_time = 0;
- size_t flags;
+ size_t flags = 0;
size_t value_len;
enum HTIME_FLAGS {
@@ -1665,7 +1668,18 @@ static int process_head_file(struct archive_read* a, s
g_unpack_window_size << ((compression_info >> 10) & 15);
rar->cstate.method = c_method;
rar->cstate.version = c_version + 50;
+ rar->file.solid = (compression_info & SOLID) > 0;
+ /* Archives which declare solid files without initializing the window
+ * buffer first are invalid. */
+
+ if(rar->file.solid > 0 && rar->cstate.window_buf == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Declared solid file, but no window buffer "
+ "initialized yet.");
+ return ARCHIVE_FATAL;
+ }
+
/* Check if window_size is a sane value. Also, if the file is not
* declared as a directory, disallow window_size == 0. */
if(window_size > (64 * 1024 * 1024) ||
@@ -1676,12 +1690,36 @@ static int process_head_file(struct archive_read* a, s
return ARCHIVE_FATAL;
}
- /* Values up to 64M should fit into ssize_t on every
- * architecture. */
- rar->cstate.window_size = (ssize_t) window_size;
+ if(rar->file.solid > 0) {
+ /* Re-check if current window size is the same as previous
+ * window size (for solid files only). */
+ if(rar->file.solid_window_size > 0 &&
+ rar->file.solid_window_size != (ssize_t) window_size)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Window size for this solid file doesn't match "
+ "the window size used in previous solid file. ");
+ return ARCHIVE_FATAL;
+ }
+ }
+
+ /* If we're currently switching volumes, ignore the new definition of
+ * window_size. */
+ if(rar->cstate.switch_multivolume == 0) {
+ /* Values up to 64M should fit into ssize_t on every
+ * architecture. */
+ rar->cstate.window_size = (ssize_t) window_size;
+ }
+
+ if(rar->file.solid > 0 && rar->file.solid_window_size == 0) {
+ /* Solid files have to have the same window_size across
+ whole archive. Remember the window_size parameter
+ for first solid file found. */
+ rar->file.solid_window_size = rar->cstate.window_size;
+ }
+
init_window_mask(rar);
- rar->file.solid = (compression_info & SOLID) > 0;
rar->file.service = 0;
if(!read_var_sized(a, &host_os, NULL))
Modified: head/contrib/libarchive/libarchive/archive_read_support_format_zip.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_support_format_zip.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_read_support_format_zip.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -1797,6 +1797,23 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a,
"lzma data error (error %d)", (int) lz_ret);
return (ARCHIVE_FATAL);
+ /* This case is optional in lzma alone format. It can happen,
+ * but most of the files don't have it. (GitHub #1257) */
+ case LZMA_STREAM_END:
+ lzma_end(&zip->zipx_lzma_stream);
+ zip->zipx_lzma_valid = 0;
+ if((int64_t) zip->zipx_lzma_stream.total_in !=
+ zip->entry_bytes_remaining)
+ {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "lzma alone premature end of stream");
+ return (ARCHIVE_FATAL);
+ }
+
+ zip->end_of_entry = 1;
+ break;
+
case LZMA_OK:
break;
Modified: head/contrib/libarchive/libarchive/archive_string.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_string.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_string.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -75,6 +75,9 @@ __FBSDID("$FreeBSD$");
#define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t))
#endif
+#undef max
+#define max(a, b) ((a)>(b)?(a):(b))
+
struct archive_string_conv {
struct archive_string_conv *next;
char *from_charset;
@@ -591,7 +594,7 @@ archive_wstring_append_from_mbs(struct archive_wstring
* No single byte will be more than one wide character,
* so this length estimate will always be big enough.
*/
- size_t wcs_length = len;
+ // size_t wcs_length = len;
size_t mbs_length = len;
const char *mbs = p;
wchar_t *wcs;
@@ -600,7 +603,11 @@ archive_wstring_append_from_mbs(struct archive_wstring
memset(&shift_state, 0, sizeof(shift_state));
#endif
- if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
+ /*
+ * As we decided to have wcs_length == mbs_length == len
+ * we can use len here instead of wcs_length
+ */
+ if (NULL == archive_wstring_ensure(dest, dest->length + len + 1))
return (-1);
wcs = dest->s + dest->length;
/*
@@ -609,6 +616,12 @@ archive_wstring_append_from_mbs(struct archive_wstring
* multi bytes.
*/
while (*mbs && mbs_length > 0) {
+ /*
+ * The buffer we allocated is always big enough.
+ * Keep this code path in a comment if we decide to choose
+ * smaller wcs_length in the future
+ */
+/*
if (wcs_length == 0) {
dest->length = wcs - dest->s;
dest->s[dest->length] = L'\0';
@@ -618,24 +631,20 @@ archive_wstring_append_from_mbs(struct archive_wstring
return (-1);
wcs = dest->s + dest->length;
}
+*/
#if HAVE_MBRTOWC
- r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
+ r = mbrtowc(wcs, mbs, mbs_length, &shift_state);
#else
- r = mbtowc(wcs, mbs, wcs_length);
+ r = mbtowc(wcs, mbs, mbs_length);
#endif
if (r == (size_t)-1 || r == (size_t)-2) {
ret_val = -1;
- if (errno == EILSEQ) {
- ++mbs;
- --mbs_length;
- continue;
- } else
- break;
+ break;
}
if (r == 0 || r > mbs_length)
break;
wcs++;
- wcs_length--;
+ // wcs_length--;
mbs += r;
mbs_length -= r;
}
@@ -798,7 +807,8 @@ archive_string_append_from_wcs(struct archive_string *
as->s[as->length] = '\0';
/* Re-allocate buffer for MBS. */
if (archive_string_ensure(as,
- as->length + len * 2 + 1) == NULL)
+ as->length + max(len * 2,
+ (size_t)MB_CUR_MAX) + 1) == NULL)
return (-1);
p = as->s + as->length;
end = as->s + as->buffer_length - MB_CUR_MAX -1;
@@ -3440,7 +3450,8 @@ strncat_from_utf8_libarchive2(struct archive_string *a
as->length = p - as->s;
/* Re-allocate buffer for MBS. */
if (archive_string_ensure(as,
- as->length + len * 2 + 1) == NULL)
+ as->length + max(len * 2,
+ (size_t)MB_CUR_MAX) + 1) == NULL)
return (-1);
p = as->s + as->length;
end = as->s + as->buffer_length - MB_CUR_MAX -1;
Modified: head/contrib/libarchive/libarchive/archive_write.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_write.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -212,6 +212,7 @@ __archive_write_allocate_filter(struct archive *_a)
f = calloc(1, sizeof(*f));
f->archive = _a;
+ f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
if (a->filter_first == NULL)
a->filter_first = f;
else
@@ -228,6 +229,9 @@ __archive_write_filter(struct archive_write_filter *f,
const void *buff, size_t length)
{
int r;
+ /* Never write to non-open filters */
+ if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN)
+ return(ARCHIVE_FATAL);
if (length == 0)
return(ARCHIVE_OK);
if (f->write == NULL)
@@ -240,29 +244,72 @@ __archive_write_filter(struct archive_write_filter *f,
}
/*
- * Open a filter.
+ * Recursive function for opening the filter chain
+ * Last filter is opened first
*/
-int
+static int
__archive_write_open_filter(struct archive_write_filter *f)
{
- if (f->open == NULL)
+ int ret;
+
+ ret = ARCHIVE_OK;
+ if (f->next_filter != NULL)
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW)
+ return (ARCHIVE_FATAL);
+ if (f->open == NULL) {
+ f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
return (ARCHIVE_OK);
- return (f->open)(f);
+ }
+ ret = (f->open)(f);
+ if (ret == ARCHIVE_OK)
+ f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
+ else
+ f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
+ return (ret);
}
/*
- * Close a filter.
+ * Open all filters
*/
-int
-__archive_write_close_filter(struct archive_write_filter *f)
+static int
+__archive_write_filters_open(struct archive_write *a)
{
- if (f->close != NULL)
- return (f->close)(f);
- if (f->next_filter != NULL)
- return (__archive_write_close_filter(f->next_filter));
- return (ARCHIVE_OK);
+ return (__archive_write_open_filter(a->filter_first));
}
+/*
+ * Close all filtes
+ */
+static int
+__archive_write_filters_close(struct archive_write *a)
+{
+ struct archive_write_filter *f;
+ int ret, ret1;
+ ret = ARCHIVE_OK;
+ for (f = a->filter_first; f != NULL; f = f->next_filter) {
+ /* Do not close filters that are not open */
+ if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) {
+ if (f->close != NULL) {
+ ret1 = (f->close)(f);
+ if (ret1 < ret)
+ ret = ret1;
+ if (ret1 == ARCHIVE_OK) {
+ f->state =
+ ARCHIVE_WRITE_FILTER_STATE_CLOSED;
+ } else {
+ f->state =
+ ARCHIVE_WRITE_FILTER_STATE_FATAL;
+ }
+ } else
+ f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
+ }
+ }
+ return (ret);
+}
+
int
__archive_write_output(struct archive_write *a, const void *buff, size_t length)
{
@@ -440,7 +487,7 @@ archive_write_client_close(struct archive_write_filter
free(state->buffer);
free(state);
/* Clear the close handler myself not to be called again. */
- f->close = NULL;
+ f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
a->client_data = NULL;
/* Clear passphrase. */
if (a->passphrase != NULL) {
@@ -477,9 +524,10 @@ archive_write_open(struct archive *_a, void *client_da
client_filter->write = archive_write_client_write;
client_filter->close = archive_write_client_close;
- ret = __archive_write_open_filter(a->filter_first);
+ ret = __archive_write_filters_open(a);
if (ret < ARCHIVE_WARN) {
- r1 = __archive_write_close_filter(a->filter_first);
+ r1 = __archive_write_filters_close(a);
+ __archive_write_filters_free(_a);
return (r1 < ret ? r1 : ret);
}
@@ -521,7 +569,7 @@ _archive_write_close(struct archive *_a)
}
/* Finish the compression and close the stream. */
- r1 = __archive_write_close_filter(a->filter_first);
+ r1 = __archive_write_filters_close(a);
if (r1 < r)
r = r1;
Modified: head/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_write_add_filter_b64encode.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -149,12 +149,7 @@ archive_filter_b64encode_open(struct archive_write_fil
{
struct private_b64encode *state = (struct private_b64encode *)f->data;
size_t bs = 65536, bpb;
- int ret;
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
-
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
* per block for performance. */
@@ -266,7 +261,6 @@ static int
archive_filter_b64encode_close(struct archive_write_filter *f)
{
struct private_b64encode *state = (struct private_b64encode *)f->data;
- int ret, ret2;
/* Flush remaining bytes. */
if (state->hold_len != 0)
@@ -274,12 +268,8 @@ archive_filter_b64encode_close(struct archive_write_fi
archive_string_sprintf(&state->encoded_buff, "====\n");
/* Write the last block */
archive_write_set_bytes_in_last_block(f->archive, 1);
- ret = __archive_write_filter(f->next_filter,
+ return __archive_write_filter(f->next_filter,
state->encoded_buff.s, archive_strlen(&state->encoded_buff));
- ret2 = __archive_write_close_filter(f->next_filter);
- if (ret > ret2)
- ret = ret2;
- return (ret);
}
static int
Modified: head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_write_add_filter_bzip2.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -167,10 +167,6 @@ archive_compressor_bzip2_open(struct archive_write_fil
struct private_data *data = (struct private_data *)f->data;
int ret;
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != 0)
- return (ret);
-
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
@@ -262,7 +258,7 @@ static int
archive_compressor_bzip2_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- int ret, r1;
+ int ret;
/* Finish compression cycle. */
ret = drive_compressor(f, data, 1);
@@ -281,9 +277,7 @@ archive_compressor_bzip2_close(struct archive_write_fi
"Failed to clean up compressor");
ret = ARCHIVE_FATAL;
}
-
- r1 = __archive_write_close_filter(f->next_filter);
- return (r1 < ret ? r1 : ret);
+ return ret;
}
static int
Modified: head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_write_add_filter_compress.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -146,17 +146,12 @@ archive_write_add_filter_compress(struct archive *_a)
static int
archive_compressor_compress_open(struct archive_write_filter *f)
{
- int ret;
struct private_data *state;
size_t bs = 65536, bpb;
f->code = ARCHIVE_FILTER_COMPRESS;
f->name = "compress";
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
-
state = (struct private_data *)calloc(1, sizeof(*state));
if (state == NULL) {
archive_set_error(f->archive, ENOMEM,
@@ -426,30 +421,27 @@ static int
archive_compressor_compress_close(struct archive_write_filter *f)
{
struct private_data *state = (struct private_data *)f->data;
- int ret, ret2;
+ int ret;
ret = output_code(f, state->cur_code);
if (ret != ARCHIVE_OK)
- goto cleanup;
+ return ret;
ret = output_flush(f);
if (ret != ARCHIVE_OK)
- goto cleanup;
+ return ret;
/* Write the last block */
ret = __archive_write_filter(f->next_filter,
state->compressed, state->compressed_offset);
-cleanup:
- ret2 = __archive_write_close_filter(f->next_filter);
- if (ret > ret2)
- ret = ret2;
- free(state->compressed);
- free(state);
return (ret);
}
static int
archive_compressor_compress_free(struct archive_write_filter *f)
{
- (void)f; /* UNUSED */
+ struct private_data *state = (struct private_data *)f->data;
+
+ free(state->compressed);
+ free(state);
return (ARCHIVE_OK);
}
Modified: head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c Mon Dec 30 23:20:46 2019 (r356211)
+++ head/contrib/libarchive/libarchive/archive_write_add_filter_gzip.c Tue Dec 31 00:05:06 2019 (r356212)
@@ -184,10 +184,6 @@ archive_compressor_gzip_open(struct archive_write_filt
struct private_data *data = (struct private_data *)f->data;
int ret;
- ret = __archive_write_open_filter(f->next_filter);
- if (ret != ARCHIVE_OK)
- return (ret);
-
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
@@ -307,7 +303,7 @@ archive_compressor_gzip_close(struct archive_write_fil
{
unsigned char trailer[8];
struct private_data *data = (struct private_data *)f->data;
- int ret, r1;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-head
mailing list