summaryrefslogtreecommitdiffstats
path: root/Utilities/cmlibarchive/libarchive
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2012-01-05 14:02:58 (GMT)
committerBrad King <brad.king@kitware.com>2012-01-05 14:02:58 (GMT)
commit156cb3bbf257f747672eac945fa2e19d33fc3a63 (patch)
treea411d9b89fb1ad0960b5baf76ca0ff752acf6fa9 /Utilities/cmlibarchive/libarchive
parentfd42bf1bdcb95615dd725ae588db02b22a3aebaa (diff)
parent4f4fe6e50bb3dbe59f9bc3cc848cbd07dead324d (diff)
downloadCMake-156cb3bbf257f747672eac945fa2e19d33fc3a63.zip
CMake-156cb3bbf257f747672eac945fa2e19d33fc3a63.tar.gz
CMake-156cb3bbf257f747672eac945fa2e19d33fc3a63.tar.bz2
Merge branch 'libarchive-upstream' into update-libarchive
Conflicts: Utilities/cmlibarchive/CMakeLists.txt Utilities/cmlibarchive/libarchive/archive_windows.c
Diffstat (limited to 'Utilities/cmlibarchive/libarchive')
-rw-r--r--Utilities/cmlibarchive/libarchive/archive.h19
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_acl.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_linkify.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_paths.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_perms.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_stat.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_time.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.c16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_data.316
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_filter.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_format.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_free.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_header.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_new.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_options.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c1009
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c35
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.c51
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.c42
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.h3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_blocksize.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_data.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c28
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_filter.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_finish_entry.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_format.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_free.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_header.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_new.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c40
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c17
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c84
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_options.32
-rw-r--r--Utilities/cmlibarchive/libarchive/cpio.550
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork_windows.c46
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive-formats.52
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_changes.32
-rw-r--r--Utilities/cmlibarchive/libarchive/tar.52
50 files changed, 808 insertions, 726 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index a815e49..9b6b1b0 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -131,27 +131,16 @@ extern "C" {
* easy to compare versions at build time: for version a.b.c, the
* version number is printf("%d%03d%03d",a,b,c). For example, if you
* know your application requires version 2.12.108 or later, you can
- * assert that ARCHIVE_VERSION >= 2012108.
- *
- * This single-number format was introduced with libarchive 1.9.0 in
- * the libarchive 1.x family and libarchive 2.2.4 in the libarchive
- * 2.x family. The following may be useful if you really want to do
- * feature detection for earlier libarchive versions (which defined
- * ARCHIVE_API_VERSION and ARCHIVE_API_FEATURE instead):
- *
- * #ifndef ARCHIVE_VERSION_NUMBER
- * #define ARCHIVE_VERSION_NUMBER \
- * (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000)
- * #endif
+ * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3000001
+#define ARCHIVE_VERSION_NUMBER 3000002
__LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_STRING "libarchive 3.0.1b"
+#define ARCHIVE_VERSION_STRING "libarchive 3.0.2"
__LA_DECL const char * archive_version_string(void);
/* Declare our basic types. */
@@ -454,8 +443,6 @@ __LA_DECL int archive_read_data_block(struct archive *a,
* 'into_fd': writes data to specified filedes
*/
__LA_DECL int archive_read_data_skip(struct archive *);
-__LA_DECL int archive_read_data_into_buffer(struct archive *,
- void *buffer, __LA_SSIZE_T len);
__LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.3 b/Utilities/cmlibarchive/libarchive/archive_entry.3
index 1bd7cfb..10e3c34 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.3
@@ -26,7 +26,7 @@
.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
.\"
.Dd Feburary 22, 2010
-.Dt archive_entry 3
+.Dt ARCHIVE_ENTRY 3
.Os
.Sh NAME
.Nm archive_entry_clear ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index c85cf44..9c44e25 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -29,7 +29,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3000001
+#define ARCHIVE_VERSION_NUMBER 3000002
/*
* Note: archive_entry.h is for use outside of libarchive; the
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3 b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
index 896b35a..93906e7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.Dd February 21, 2010
-.Dt archive_entry_acl 3
+.Dt ARCHIVE_ENTRY_ACL 3
.Os
.Sh NAME
.Nm archive_entry_acl_add_entry ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_linkify.3 b/Utilities/cmlibarchive/libarchive/archive_entry_linkify.3
index 6b1b9a5..a34b095 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_linkify.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_linkify.3
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.Dd February 20, 2010
-.Dt archive_entry_linkify 3
+.Dt ARCHIVE_ENTRY_LINKIFY 3
.Os
.Sh NAME
.Nm archive_entry_linkresolver ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3 b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
index 05243c0..621f655 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.Dd February 22, 2010
-.Dt archive_entry_paths 3
+.Dt ARCHIVE_ENTRY_PATHS 3
.Os
.Sh NAME
.Nm archive_entry_hardlink ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3 b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
index 452a19f..164af97 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
@@ -24,7 +24,7 @@
.\" SUCH DAMAGE.
.\"
.Dd February 22, 2010
-.Dt archive_entry_perms 3
+.Dt ARCHIVE_ENTRY_PERMS 3
.Os
.Sh NAME
.Nm archive_entry_gid ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3 b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
index a988ecf..36a7efb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.Dd May 12, 2008
-.Dt archive_entry 3
+.Dt ARCHIVE_ENTRY 3
.Os
.Sh NAME
.Nm archive_entry_stat ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_time.3 b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
index 7787ca5..85a8209 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_time.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
@@ -26,7 +26,7 @@
.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
.\"
.Dd February 21, 2010
-.Dt archive_entry_time 3
+.Dt ARCHIVE_ENTRY_TIME 3
.Os
.Sh NAME
.Nm archive_entry_atime ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.3 b/Utilities/cmlibarchive/libarchive/archive_read.3
index 70527fb..5285192 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
.\"
.Dd March 23, 2011
-.Dt archive_read 3
+.Dt ARCHIVE_READ 3
.Os
.Sh NAME
.Nm archive_read
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.c b/Utilities/cmlibarchive/libarchive/archive_read.c
index 6d7f263..baf9dc4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read.c
@@ -668,22 +668,6 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
return (bytes_read);
}
-#if ARCHIVE_API_VERSION < 3
-/*
- * Obsolete function provided for compatibility only. Note that the API
- * of this function doesn't allow the caller to detect if the remaining
- * data from the archive entry is shorter than the buffer provided, or
- * even if an error occurred while reading data.
- */
-int
-archive_read_data_into_buffer(struct archive *a, void *d, ssize_t len)
-{
-
- archive_read_data(a, d, len);
- return (ARCHIVE_OK);
-}
-#endif
-
/*
* Skip over all remaining data in this entry.
*/
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data.3 b/Utilities/cmlibarchive/libarchive/archive_read_data.3
index a5898e7..78d0497 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data.3
@@ -25,15 +25,12 @@
.\" $FreeBSD$
.\"
.Dd March 22, 2011
-.Dt archive_read_data 3
+.Dt ARCHIVE_READ_DATA 3
.Os
.Sh NAME
.Nm archive_read_data
.Nm archive_read_data_block ,
.Nm archive_read_data_skip ,
-.\" #if ARCHIVE_API_VERSION < 3
-.Nm archive_read_data_into_buffer ,
-.\" #endif
.Nm archive_read_data_into_fd
.Nd functions for reading streaming archives
.Sh SYNOPSIS
@@ -49,10 +46,6 @@
.Fc
.Ft int
.Fn archive_read_data_skip "struct archive *"
-.\" #if ARCHIVE_API_VERSION < 3
-.Ft int
-.Fn archive_read_data_into_buffer "struct archive *" "void *" "ssize_t len"
-.\" #endif
.Ft int
.Fn archive_read_data_into_fd "struct archive *" "int fd"
.\"
@@ -84,13 +77,6 @@ to skip all of the data for this archive entry.
Note that this function is invoked automatically by
.Fn archive_read_next_header2
if the previous entry was not completely consumed.
-.\" #if ARCHIVE_API_VERSION < 3
-.It Fn archive_read_data_into_buffer
-This function is deprecated and will be removed.
-Use
-.Fn archive_read_data
-instead.
-.\" #endif
.It Fn archive_read_data_into_fd
A convenience function that repeatedly calls
.Fn archive_read_data_block
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c b/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
index 04d3ab0..14f9410 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
@@ -45,7 +45,7 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/0
/*
* This implementation minimizes copying of data and is sparse-file aware.
*/
-int
+static int
pad_to(struct archive *a, int fd, int can_lseek,
size_t nulls_size, const char *nulls,
int64_t target_offset, int64_t actual_offset)
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk.3 b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
index d3b6101..3c49bff 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_read_disk.3 190957 2009-04-12 05:04:02Z kientzle $
.\"
.Dd March 10, 2009
-.Dt archive_read_disk 3
+.Dt ARCHIVE_READ_DISK 3
.Os
.Sh NAME
.Nm archive_read_disk_new ,
@@ -283,7 +283,7 @@ and first appeared in
The
.Nm libarchive
library was written by
-.An Tim Kientzle Aq kientzle@freebsd.org .
+.An Tim Kientzle Aq kientzle@FreeBSD.org .
.Sh BUGS
The
.Dq standard
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract.3 b/Utilities/cmlibarchive/libarchive/archive_read_extract.3
index 950248e..882c6e1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_extract.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 22, 2011
-.Dt archive_read_extract 3
+.Dt ARCHIVE_READ_EXTRACT 3
.Os
.Sh NAME
.Nm archive_read_extract ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_filter.3 b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
index 7b506cc..1cfa215 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 19, 2011
-.Dt archive_read_filter 3
+.Dt ARCHIVE_READ_FILTER 3
.Os
.Sh NAME
.Nm archive_read_support_filter_all ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_format.3 b/Utilities/cmlibarchive/libarchive/archive_read_format.3
index 3b5abf3..e707e05 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_format.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
.\"
.Dd March 19, 2011
-.Dt archive_read_format 3
+.Dt ARCHIVE_READ_FORMAT 3
.Os
.Sh NAME
.Nm archive_read_support_format_7zip ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_free.3 b/Utilities/cmlibarchive/libarchive/archive_read_free.3
index 5838e20..f5f2515 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_free.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_free.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
.\"
.Dd March 20, 2011
-.Dt archive_read_free 3
+.Dt ARCHIVE_READ_FREE 3
.Os
.Sh NAME
.Nm archive_read_close ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_header.3 b/Utilities/cmlibarchive/libarchive/archive_read_header.3
index f8543f7..999e963 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_header.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_header.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 22, 2011
-.Dt archive_read_header 3
+.Dt ARCHIVE_READ_HEADER 3
.Os
.Sh NAME
.Nm archive_read_next_header ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_new.3 b/Utilities/cmlibarchive/libarchive/archive_read_new.3
index d2d9862..e04406a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_new.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_new.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
.\"
.Dd March 20, 2011
-.Dt archive_read_new 3
+.Dt ARCHIVE_READ_NEW 3
.Os
.Sh NAME
.Nm archive_read_new
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open.3 b/Utilities/cmlibarchive/libarchive/archive_read_open.3
index ff15641..09c0575 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
.\"
.Dd March 19, 2011
-.Dt archive_read_open 3
+.Dt ARCHIVE_READ_OPEN 3
.Os
.Sh NAME
.Nm archive_read_open ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
index 2079d2e..81efb08 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd April 13, 2009
-.Dt archive_read_options 3
+.Dt ARCHIVE_READ_OPTIONS 3
.Os
.Sh NAME
.Nm archive_read_set_filter_option ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
index 3a12405..1580c92 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -204,6 +204,10 @@ struct _7zip {
/* Structural information about the archive. */
struct _7z_stream_info si;
+ int header_is_being_read;
+ int header_is_encoded;
+ uint64_t header_bytes_remaining;
+ unsigned long header_crc32;
/* Header offset to check that reading pointes of the file contens
* will not exceed the header. */
uint64_t header_offset;
@@ -228,6 +232,7 @@ struct _7zip {
char end_of_entry;
/* Uncompressed buffer control. */
+#define UBUFF_SIZE (64 * 1024)
unsigned char *uncompressed_buffer;
unsigned char *uncompressed_buffer_pointer;
size_t uncompressed_buffer_size;
@@ -288,6 +293,10 @@ struct _7zip {
uint32_t bcj_state;
size_t odd_bcj_size;
unsigned char odd_bcj[4];
+ /* Decoding BCJ data. */
+ size_t bcj_prevPosT;
+ uint32_t bcj_prevMask;
+ uint32_t bcj_ip;
/* Decoding BCJ2 data. */
size_t main_stream_bytes_remaining;
@@ -324,12 +333,11 @@ static int archive_read_format_7zip_read_header(struct archive_read *,
struct archive_entry *);
static int check_7zip_header_in_sfx(const char *);
static unsigned long decode_codec_id(const unsigned char *, size_t);
-static ssize_t decode_header_image(struct archive_read *, struct _7zip *,
- struct _7z_stream_info *, const unsigned char *, uint64_t,
- const void **);
+static int decode_encoded_header_info(struct archive_read *,
+ struct _7z_stream_info *);
static int decompress(struct archive_read *, struct _7zip *,
void *, size_t *, const void *, size_t *);
-static ssize_t extract_pack_stream(struct archive_read *);
+static ssize_t extract_pack_stream(struct archive_read *, size_t);
static void fileTimeToUtc(uint64_t, time_t *, long *);
static uint64_t folder_uncompressed_size(struct _7z_folder *);
static void free_CodersInfo(struct _7z_coders_info *);
@@ -341,39 +349,39 @@ static void free_StreamsInfo(struct _7z_stream_info *);
static void free_SubStreamsInfo(struct _7z_substream_info *);
static int free_decompression(struct archive_read *, struct _7zip *);
static ssize_t get_uncompressed_data(struct archive_read *, const void **,
- size_t);
+ size_t, size_t);
+static const unsigned char * header_bytes(struct archive_read *, size_t);
static int init_decompression(struct archive_read *, struct _7zip *,
const struct _7z_coder *, const struct _7z_coder *);
-static int parse_7zip_uint64(const unsigned char *, size_t, uint64_t *);
-static int read_Bools(unsigned char *, size_t, const unsigned char *,
- size_t);
-static int read_CodersInfo(struct _7z_coders_info *,
- const unsigned char *, size_t);
-static int read_Digests(struct _7z_digests *, size_t,
- const unsigned char *, size_t);
-static int read_Folder(struct _7z_folder *, const unsigned char *,
- size_t);
-static int read_Header(struct _7zip *, struct _7z_header_info *,
- const unsigned char *, size_t);
-static int read_PackInfo(struct _7z_pack_info *, const unsigned char *,
+static int parse_7zip_uint64(struct archive_read *, uint64_t *);
+static int read_Bools(struct archive_read *, unsigned char *, size_t);
+static int read_CodersInfo(struct archive_read *,
+ struct _7z_coders_info *);
+static int read_Digests(struct archive_read *, struct _7z_digests *,
size_t);
-static int read_StreamsInfo(struct _7zip *, struct _7z_stream_info *,
- const unsigned char *, size_t);
-static int read_SubStreamsInfo(struct _7z_substream_info *,
- struct _7z_folder *, size_t, const unsigned char *,
- size_t);
-static int read_Times(struct _7zip *, struct _7z_header_info *, int,
- const unsigned char *, size_t);
+static int read_Folder(struct archive_read *, struct _7z_folder *);
+static int read_Header(struct archive_read *, struct _7z_header_info *,
+ int);
+static int read_PackInfo(struct archive_read *, struct _7z_pack_info *);
+static int read_StreamsInfo(struct archive_read *,
+ struct _7z_stream_info *);
+static int read_SubStreamsInfo(struct archive_read *,
+ struct _7z_substream_info *, struct _7z_folder *, size_t);
+static int read_Times(struct archive_read *, struct _7z_header_info *,
+ int);
static void read_consume(struct archive_read *);
-static ssize_t read_stream(struct archive_read *, const void **, size_t);
+static ssize_t read_stream(struct archive_read *, const void **, size_t,
+ size_t);
+static int seek_pack(struct archive_read *);
static int64_t skip_stream(struct archive_read *, size_t);
static int skip_sfx(struct archive_read *, ssize_t);
static int slurp_central_directory(struct archive_read *, struct _7zip *,
struct _7z_header_info *);
static int setup_decode_folder(struct archive_read *, struct _7z_folder *,
int);
-static size_t x86_Convert(uint8_t *, size_t, uint32_t, uint32_t *);
-ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
+static void x86_Init(struct _7zip *);
+static size_t x86_Convert(struct _7zip *, uint8_t *, size_t);
+static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
int
@@ -641,16 +649,16 @@ archive_read_format_7zip_read_header(struct archive_read *a,
int r;
/*
- * Symbolic-name is recorded as its contents. We have to read the
- * contents at this time.
+ * Symbolic-name is recorded as its contents. We have to
+ * read the contents at this time.
*/
while (zip->entry_bytes_remaining > 0) {
const void *buff;
size_t size;
int64_t offset;
- r = archive_read_format_7zip_read_data(a, &buff, &size,
- &offset);
+ r = archive_read_format_7zip_read_data(a, &buff,
+ &size, &offset);
if (r < ARCHIVE_WARN)
return (r);
symname = realloc(symname, symsize + size + 1);
@@ -663,13 +671,15 @@ archive_read_format_7zip_read_header(struct archive_read *a,
symsize += size;
}
if (symsize == 0) {
- /* If there is no synname, handle it as a regular file. */
+ /* If there is no synname, handle it as a regular
+ * file. */
zip_entry->mode &= ~AE_IFMT;
zip_entry->mode |= AE_IFREG;
archive_entry_set_mode(entry, zip_entry->mode);
} else {
symname[symsize] = '\0';
- archive_entry_copy_symlink(entry, (const char *)symname);
+ archive_entry_copy_symlink(entry,
+ (const char *)symname);
free(symname);
}
archive_entry_set_size(entry, 0);
@@ -706,7 +716,7 @@ archive_read_format_7zip_read_data(struct archive_read *a,
return (ARCHIVE_EOF);
}
- bytes = read_stream(a, buff, zip->entry_bytes_remaining);
+ bytes = read_stream(a, buff, zip->entry_bytes_remaining, 0);
if (bytes < 0)
return ((int)bytes);
if (bytes == 0) {
@@ -929,6 +939,8 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
}
zip->codec2 = coder2->codec;
zip->bcj_state = 0;
+ if (coder2->codec == _7Z_X86)
+ x86_Init(zip);
}
break;
default:
@@ -990,7 +1002,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
fi++;
} else
/* Use our filter. */
- zip->bcj_state = 0;
+ x86_Init(zip);
break;
case _7Z_X86_BCJ2:
/* Use our filter. */
@@ -1213,6 +1225,14 @@ decompress(struct archive_read *a, struct _7zip *zip,
if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
int i;
+
+ /* Do not copy out the BCJ remaining bytes when the output
+ * buffer size is less than five bytes. */
+ if (o_avail_in != 0 && t_avail_out < 5 && zip->odd_bcj_size) {
+ *used = 0;
+ *outbytes = 0;
+ return (ret);
+ }
for (i = 0; zip->odd_bcj_size > 0 && t_avail_out; i++) {
*t_next_out++ = zip->odd_bcj[i];
t_avail_out--;
@@ -1233,7 +1253,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
/*
* Decord a remaining decompressed main stream for BCJ2.
*/
- if (zip->tmp_stream_bytes_remaining > 0) {
+ if (zip->tmp_stream_bytes_remaining) {
ssize_t bytes;
size_t remaining = zip->tmp_stream_bytes_remaining;
bytes = Bcj2_Decode(zip, t_next_out, t_avail_out);
@@ -1249,7 +1269,8 @@ decompress(struct archive_read *a, struct _7zip *zip,
if (o_avail_in == 0 || t_avail_out == 0) {
*used = 0;
*outbytes = o_avail_out - t_avail_out;
- if (o_avail_in == 0)
+ if (o_avail_in == 0 &&
+ zip->tmp_stream_bytes_remaining)
ret = ARCHIVE_EOF;
return (ret);
}
@@ -1440,7 +1461,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
* Decord BCJ.
*/
if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
- size_t l = x86_Convert(buff, *outbytes, 0, &(zip->bcj_state));
+ size_t l = x86_Convert(zip, buff, *outbytes);
zip->odd_bcj_size = *outbytes - l;
if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
o_avail_in && ret != ARCHIVE_EOF) {
@@ -1520,49 +1541,48 @@ free_decompression(struct archive_read *a, struct _7zip *zip)
}
static int
-parse_7zip_uint64(const unsigned char *p, size_t len, uint64_t *val)
+parse_7zip_uint64(struct archive_read *a, uint64_t *val)
{
- const unsigned char *_p = p;
+ const unsigned char *p;
unsigned char avail, mask;
int i;
- if (len-- == 0)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- avail = *p++;
+ avail = *p;
mask = 0x80;
*val = 0;
for (i = 0; i < 8; i++) {
if (avail & mask) {
- if (len-- == 0)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- *val |= ((uint64_t)*p++) << (8 * i);
+ *val |= ((uint64_t)*p) << (8 * i);
mask >>= 1;
continue;
}
*val += (avail & (mask -1)) << (8 * i);
break;
}
- return (p - _p);
+ return (0);
}
static int
-read_Bools(unsigned char *data, size_t num, const unsigned char *p, size_t len)
+read_Bools(struct archive_read *a, unsigned char *data, size_t num)
{
- const unsigned char *_p = p;
- unsigned i, mask = 0, avail;
+ const unsigned char *p;
+ unsigned i, mask = 0, avail = 0;
for (i = 0; i < num; i++) {
if (mask == 0) {
- if (len == 0)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- avail = *p++;
- len--;
+ avail = *p;
mask = 0x80;
}
data[i] = (avail & mask)?1:0;
mask >>= 1;
}
- return (p - _p);
+ return (0);
}
static void
@@ -1573,16 +1593,13 @@ free_Digest(struct _7z_digests *d)
}
static int
-read_Digests(struct _7z_digests *d, size_t num, const unsigned char *p,
- size_t len)
+read_Digests(struct archive_read *a, struct _7z_digests *d, size_t num)
{
- const unsigned char *_p = p;
+ const unsigned char *p;
unsigned i;
memset(d, 0, sizeof(*d));
- if (len == 0)
- return (-1);
d->defineds = malloc(num);
if (d->defineds == NULL)
@@ -1590,13 +1607,11 @@ read_Digests(struct _7z_digests *d, size_t num, const unsigned char *p,
/*
* Read Bools.
*/
- len--;
- if (*p++ == 0) {
- int r = read_Bools(d->defineds, num, p, len);
- if (r < 0)
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == 0) {
+ if (read_Bools(a, d->defineds, num) < 0)
return (-1);
- p += r;
- len -= r;
} else
/* All are defined */
memset(d->defineds, 1, num);
@@ -1604,17 +1619,15 @@ read_Digests(struct _7z_digests *d, size_t num, const unsigned char *p,
d->digests = calloc(num, sizeof(*d->digests));
if (d->digests == NULL)
return (-1);
- if (len < 4 * num)
- return (-1);
for (i = 0; i < num; i++) {
if (d->defineds[i]) {
+ if ((p = header_bytes(a, 4)) == NULL)
+ return (-1);
d->digests[i] = archive_le32dec(p);
- p += 4;
- len -= 4;
}
}
- return (p - _p);
+ return (0);
}
static void
@@ -1626,62 +1639,55 @@ free_PackInfo(struct _7z_pack_info *pi)
}
static int
-read_PackInfo(struct _7z_pack_info *pi, const unsigned char *p, size_t len)
+read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
{
- const unsigned char *_p = p;
+ const unsigned char *p;
unsigned i;
- int r;
memset(pi, 0, sizeof(*pi));
- if (len < 3 || *p++ != kPackInfo)
- return (-1);
- --len;
-
/*
* Read PackPos.
*/
- r = parse_7zip_uint64(p, len, &(pi->pos));
- if (r < 0)
- return (r);
- p += r;
- len -= r;
+ if (parse_7zip_uint64(a, &(pi->pos)) < 0)
+ return (-1);
/*
* Read NumPackStreams.
*/
- r = parse_7zip_uint64(p, len, &(pi->numPackStreams));
- if (r < 0 || pi->numPackStreams == 0)
- return (r);
- p += r;
- len -= r;
+ if (parse_7zip_uint64(a, &(pi->numPackStreams)) < 0)
+ return (-1);
+ if (pi->numPackStreams == 0)
+ return (-1);
+ if (1000000 < pi->numPackStreams)
+ return (-1);
/*
* Read PackSizes[num]
*/
- if (len >= 1 && *p == kEnd)
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kEnd)
/* PackSizes[num] are not present. */
- return (p - _p + 1);
- if (len < 1 + pi->numPackStreams || *p++ != kSize)
+ return (0);
+ if (*p != kSize)
return (-1);
- --len;
pi->sizes = calloc(pi->numPackStreams, sizeof(uint64_t));
pi->positions = calloc(pi->numPackStreams, sizeof(uint64_t));
if (pi->sizes == NULL || pi->positions == NULL)
return (-1);
for (i = 0; i < pi->numPackStreams; i++) {
- r = parse_7zip_uint64(p, len, &(pi->sizes[i]));
- if (r < 0)
+ if (parse_7zip_uint64(a, &(pi->sizes[i])) < 0)
return (-1);
- p += r;
- len -= r;
}
/*
* Read PackStreamDigests[num]
*/
- if (len >= 1 && *p == kEnd) {
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kEnd) {
/* PackStreamDigests[num] are not present. */
pi->digest.defineds =
calloc(pi->numPackStreams, sizeof(*pi->digest.defineds));
@@ -1689,25 +1695,23 @@ read_PackInfo(struct _7z_pack_info *pi, const unsigned char *p, size_t len)
calloc(pi->numPackStreams, sizeof(*pi->digest.digests));
if (pi->digest.defineds == NULL || pi->digest.digests == NULL)
return (-1);
- return (p - _p + 1);
+ return (0);
}
- if (len < 1 + pi->numPackStreams || *p++ != kSize)
+ if (*p != kSize)
return (-1);
- --len;
- r = read_Digests(&(pi->digest), pi->numPackStreams, p, len);
- if (r < 0)
+ if (read_Digests(a, &(pi->digest), pi->numPackStreams) < 0)
return (-1);
- p += r;
- len -= r;
/*
* Must be marked by kEnd.
*/
- if (len == 0 || *p++ != kEnd)
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p != kEnd)
return (-1);
- return (p - _p);
+ return (0);
}
static void
@@ -1727,12 +1731,12 @@ free_Folder(struct _7z_folder *f)
}
static int
-read_Folder(struct _7z_folder *f, const unsigned char *p, size_t len)
+read_Folder(struct archive_read *a, struct _7z_folder *f)
{
- const unsigned char *_p = p;
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
uint64_t numInStreamsTotal = 0;
uint64_t numOutStreamsTotal = 0;
- int r;
unsigned i;
memset(f, 0, sizeof(*f));
@@ -1740,11 +1744,11 @@ read_Folder(struct _7z_folder *f, const unsigned char *p, size_t len)
/*
* Read NumCoders.
*/
- r = parse_7zip_uint64(p, len, &(f->numCoders));
- if (r < 0)
+ if (parse_7zip_uint64(a, &(f->numCoders)) < 0)
+ return (-1);
+ if (f->numCoders > 4)
+ /* Too many coders. */
return (-1);
- p += r;
- len -= r;
f->coders = calloc(f->numCoders, sizeof(*f->coders));
if (f->coders == NULL)
@@ -1753,7 +1757,7 @@ read_Folder(struct _7z_folder *f, const unsigned char *p, size_t len)
size_t codec_size;
int simple, attr;
- if (len == 0)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
/*
* 0:3 CodecIdSize
@@ -1768,46 +1772,37 @@ read_Folder(struct _7z_folder *f, const unsigned char *p, size_t len)
attr = *p & 0x20;
if (*p & 0x80)
return (-1);/* Not supported. */
- p++;
- len--;
/*
* Read Decompression Method IDs.
*/
- if (len < codec_size)
+ if ((p = header_bytes(a, codec_size)) == NULL)
return (-1);
f->coders[i].codec = decode_codec_id(p, codec_size);
- p += codec_size;
- len -= codec_size;
if (simple) {
f->coders[i].numInStreams = 1;
f->coders[i].numOutStreams = 1;
} else {
- r = parse_7zip_uint64(p, len,
- &(f->coders[i].numInStreams));
- if (r < 0)
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].numInStreams)) < 0)
return (-1);
- p += r;
- len -= r;
- r = parse_7zip_uint64(p, len,
- &(f->coders[i].numOutStreams));
- if (r < 0)
+ if (1000000 < f->coders[i].numInStreams)
+ return (-1);
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].numOutStreams)) < 0)
+ return (-1);
+ if (1000000 < f->coders[i].numOutStreams)
return (-1);
- p += r;
- len -= r;
}
if (attr) {
- r = parse_7zip_uint64(p, len,
- &(f->coders[i].propertiesSize));
- if (r < 0)
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].propertiesSize)) < 0)
return (-1);
- p += r;
- len -= r;
-
- if (len < f->coders[i].propertiesSize)
+ if ((p = header_bytes(
+ a, f->coders[i].propertiesSize)) == NULL)
return (-1);
f->coders[i].properties =
malloc(f->coders[i].propertiesSize);
@@ -1815,8 +1810,6 @@ read_Folder(struct _7z_folder *f, const unsigned char *p, size_t len)
return (-1);
memcpy(f->coders[i].properties, p,
f->coders[i].propertiesSize);
- p += f->coders[i].propertiesSize;
- len -= f->coders[i].propertiesSize;
}
numInStreamsTotal += f->coders[i].numInStreams;
@@ -1828,20 +1821,20 @@ read_Folder(struct _7z_folder *f, const unsigned char *p, size_t len)
return (-1);
f->numBindPairs = numOutStreamsTotal - 1;
+ if (zip->header_bytes_remaining < f->numBindPairs)
+ return (-1);
f->bindPairs = calloc(f->numBindPairs, sizeof(*f->bindPairs));
if (f->bindPairs == NULL)
return (-1);
for (i = 0; i < f->numBindPairs; i++) {
- r = parse_7zip_uint64(p, len, &(f->bindPairs[i].inIndex));
- if (r < 0)
+ if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0)
return (-1);
- p += r;
- len -= r;
- r = parse_7zip_uint64(p, len, &(f->bindPairs[i].outIndex));
- if (r < 0)
+ if (1000000 < f->bindPairs[i].inIndex)
+ return (-1);
+ if (parse_7zip_uint64(a, &(f->bindPairs[i].outIndex)) < 0)
+ return (-1);
+ if (1000000 < f->bindPairs[i].outIndex)
return (-1);
- p += r;
- len -= r;
}
f->numPackedStreams = numInStreamsTotal - f->numBindPairs;
@@ -1864,17 +1857,16 @@ read_Folder(struct _7z_folder *f, const unsigned char *p, size_t len)
f->packedStreams[0] = i;
} else {
for (i = 0; i < f->numPackedStreams; i++) {
- r = parse_7zip_uint64(p, len, &(f->packedStreams[i]));
- if (r < 0)
+ if (parse_7zip_uint64(a, &(f->packedStreams[i])) < 0)
+ return (-1);
+ if (1000000 < f->packedStreams[i])
return (-1);
- p += r;
- len -= r;
}
}
f->numInStreams = numInStreamsTotal;
f->numOutStreams = numOutStreamsTotal;
- return (p - _p);
+ return (0);
}
static void
@@ -1890,65 +1882,55 @@ free_CodersInfo(struct _7z_coders_info *ci)
}
static int
-read_CodersInfo(struct _7z_coders_info *ci, const unsigned char *p, size_t len)
+read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
{
- const unsigned char *_p = p;
+ const unsigned char *p;
struct _7z_digests digest;
- unsigned i, external;
- int r;
+ unsigned i;
memset(ci, 0, sizeof(*ci));
memset(&digest, 0, sizeof(digest));
- if (len < 3 || *p++ != kUnPackInfo)
+ if ((p = header_bytes(a, 1)) == NULL)
goto failed;
- --len;
-
- if (len < 3 || *p++ != kFolder)
+ if (*p != kFolder)
goto failed;
- --len;
/*
* Read NumFolders.
*/
- r = parse_7zip_uint64(p, len, &(ci->numFolders));
- if (r < 0)
+ if (parse_7zip_uint64(a, &(ci->numFolders)) < 0)
goto failed;
- p += r;
- len -= r;
+ if (1000000 < ci->numFolders)
+ return (-1);
/*
* Read External.
*/
- if (len == 0)
+ if ((p = header_bytes(a, 1)) == NULL)
goto failed;
- external = *p++;
- len --;
- switch (external) {
+ switch (*p) {
case 0:
ci->folders = calloc(ci->numFolders, sizeof(*ci->folders));
if (ci->folders == NULL)
return (-1);
for (i = 0; i < ci->numFolders; i++) {
- r = read_Folder(&(ci->folders[i]), p, len);
- if (r < 0)
+ if (read_Folder(a, &(ci->folders[i])) < 0)
goto failed;
- p += r;
- len -= r;
}
break;
case 1:
- r = parse_7zip_uint64(p, len, &(ci->dataStreamIndex));
- if (r < 0)
- return (r);
- p += r;
- len -= r;
+ if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0)
+ return (-1);
+ if (1000000 < ci->dataStreamIndex)
+ return (-1);
break;
}
- if (len < 1 + ci->numFolders || *p++ != kCodersUnPackSize)
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p != kCodersUnPackSize)
goto failed;
- --len;
for (i = 0; i < ci->numFolders; i++) {
struct _7z_folder *folder = &(ci->folders[i]);
@@ -1959,30 +1941,22 @@ read_CodersInfo(struct _7z_coders_info *ci, const unsigned char *p, size_t len)
if (folder->unPackSize == NULL)
goto failed;
for (j = 0; j < folder->numOutStreams; j++) {
- r = parse_7zip_uint64(p, len,
- &(folder->unPackSize[j]));
- if (r < 0)
+ if (parse_7zip_uint64(a, &(folder->unPackSize[j])) < 0)
goto failed;
- p += r;
- len -= r;
}
}
/*
* Read CRCs.
*/
- if (len == 0)
+ if ((p = header_bytes(a, 1)) == NULL)
goto failed;
if (*p == kEnd)
- return (p - _p + 1);
- if (len < 1 + ci->numFolders || *p++ != kCRC)
+ return (0);
+ if (*p != kCRC)
goto failed;
- --len;
- r = read_Digests(&digest, ci->numFolders, p, len);
- if (r < 0)
+ if (read_Digests(a, &digest, ci->numFolders) < 0)
goto failed;
- p += r;
- len -= r;
for (i = 0; i < ci->numFolders; i++) {
ci->folders[i].digest_defined = digest.defineds[i];
ci->folders[i].digest = digest.digests[i];
@@ -1991,10 +1965,12 @@ read_CodersInfo(struct _7z_coders_info *ci, const unsigned char *p, size_t len)
/*
* Must be kEnd.
*/
- if (len == 0 || *p++ != kEnd)
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p != kEnd)
goto failed;
free_Digest(&digest);
- return (p - _p);
+ return (0);
failed:
free_Digest(&digest);
return (-1);
@@ -2027,44 +2003,37 @@ free_SubStreamsInfo(struct _7z_substream_info *ss)
}
static int
-read_SubStreamsInfo(struct _7z_substream_info *ss, struct _7z_folder *f,
- size_t numFolders, const unsigned char *p, size_t len)
+read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
+ struct _7z_folder *f, size_t numFolders)
{
- const unsigned char *_p = p;
+ const unsigned char *p;
uint64_t *usizes;
size_t unpack_streams;
- int r, type;
+ int type;
unsigned i;
uint32_t numDigests;
memset(ss, 0, sizeof(*ss));
- if (len < 2 || *p++ != kSubStreamsInfo)
- return (-1);
- --len;
-
for (i = 0; i < numFolders; i++)
f[i].numUnpackStreams = 1;
- if (len < 1)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- type = *p++;
- --len;
+ type = *p;
if (type == kNumUnPackStream) {
unpack_streams = 0;
for (i = 0; i < numFolders; i++) {
- r = parse_7zip_uint64(p, len, &(f[i].numUnpackStreams));
- if (r < 0)
+ if (parse_7zip_uint64(a, &(f[i].numUnpackStreams)) < 0)
+ return (-1);
+ if (1000000 < f[i].numUnpackStreams)
return (-1);
- p += r;
- len -= r;
unpack_streams += f[i].numUnpackStreams;
}
- if (len < 1)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- type = *p++;
- --len;
+ type = *p;
} else
unpack_streams = numFolders;
@@ -2092,11 +2061,8 @@ read_SubStreamsInfo(struct _7z_substream_info *ss, struct _7z_folder *f,
sum = 0;
if (type == kSize) {
for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
- r = parse_7zip_uint64(p, len, usizes);
- if (r < 0)
+ if (parse_7zip_uint64(a, usizes) < 0)
return (-1);
- p += r;
- len -= r;
sum += *usizes++;
}
}
@@ -2104,10 +2070,9 @@ read_SubStreamsInfo(struct _7z_substream_info *ss, struct _7z_folder *f,
}
if (type == kSize) {
- if (len < 1)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- type = *p++;
- --len;
+ type = *p;
}
for (i = 0; i < unpack_streams; i++) {
@@ -2117,8 +2082,7 @@ read_SubStreamsInfo(struct _7z_substream_info *ss, struct _7z_folder *f,
numDigests = 0;
for (i = 0; i < numFolders; i++) {
- if (f[i].numUnpackStreams != 1 ||
- !f[i].digest_defined)
+ if (f[i].numUnpackStreams != 1 || !f[i].digest_defined)
numDigests += f[i].numUnpackStreams;
}
@@ -2129,13 +2093,10 @@ read_SubStreamsInfo(struct _7z_substream_info *ss, struct _7z_folder *f,
int di = 0;
memset(&tmpDigests, 0, sizeof(tmpDigests));
- r = read_Digests(&(tmpDigests), numDigests, p, len);
- if (r < 0) {
+ if (read_Digests(a, &(tmpDigests), numDigests) < 0) {
free_Digest(&tmpDigests);
return (-1);
}
- p += r;
- len -= r;
for (i = 0; i < numFolders; i++) {
if (f[i].numUnpackStreams == 1 && f[i].digest_defined) {
*digestsDefined++ = 1;
@@ -2153,10 +2114,9 @@ read_SubStreamsInfo(struct _7z_substream_info *ss, struct _7z_folder *f,
}
}
free_Digest(&tmpDigests);
- if (len < 1)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- type = *p++;
- --len;
+ type = *p;
}
/*
@@ -2164,7 +2124,7 @@ read_SubStreamsInfo(struct _7z_substream_info *ss, struct _7z_folder *f,
*/
if (type != kEnd)
return (-1);
- return (p - _p);
+ return (0);
}
static void
@@ -2176,24 +2136,24 @@ free_StreamsInfo(struct _7z_stream_info *si)
}
static int
-read_StreamsInfo(struct _7zip *zip, struct _7z_stream_info *si,
- const unsigned char *p, size_t len)
+read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
{
- const unsigned char *_p = p;
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
unsigned i;
- int r;
memset(si, 0, sizeof(*si));
- if (len > 0 && *p == kPackInfo) {
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kPackInfo) {
uint64_t packPos;
- r = read_PackInfo(&(si->pi), p, len);
- if (r < 0)
+ if (read_PackInfo(a, &(si->pi)) < 0)
return (-1);
- p += r;
- len -= r;
+ if (si->pi.positions == NULL || si->pi.sizes == NULL)
+ return (-1);
/*
* Calculate packed stream positions.
*/
@@ -2204,16 +2164,15 @@ read_StreamsInfo(struct _7zip *zip, struct _7z_stream_info *si,
if (packPos > zip->header_offset)
return (-1);
}
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
}
- if (len > 0 && *p == kUnPackInfo) {
+ if (*p == kUnPackInfo) {
uint32_t packIndex;
struct _7z_folder *f;
- r = read_CodersInfo(&(si->ci), p, len);
- if (r < 0)
+ if (read_CodersInfo(a, &(si->ci)) < 0)
return (-1);
- p += r;
- len -= r;
/*
* Calculate packed stream indexes.
@@ -2226,22 +2185,24 @@ read_StreamsInfo(struct _7zip *zip, struct _7z_stream_info *si,
if (packIndex > si->pi.numPackStreams)
return (-1);
}
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
}
- if (len > 0 && *p == kSubStreamsInfo) {
- r = read_SubStreamsInfo(&(si->ss),
- si->ci.folders, si->ci.numFolders, p, len);
- if (r < 0)
+
+ if (*p == kSubStreamsInfo) {
+ if (read_SubStreamsInfo(a, &(si->ss),
+ si->ci.folders, si->ci.numFolders) < 0)
+ return (-1);
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- p += r;
- len -= r;
}
/*
* Must be kEnd.
*/
- if (len == 0 || *p++ != kEnd)
+ if (*p != kEnd)
return (-1);
- return (p - _p);
+ return (0);
}
static void
@@ -2254,71 +2215,69 @@ free_Header(struct _7z_header_info *h)
}
static int
-read_Header(struct _7zip *zip, struct _7z_header_info *h,
- const unsigned char *p, size_t len)
+read_Header(struct archive_read *a, struct _7z_header_info *h,
+ int check_header_id)
{
- const unsigned char *_p = p;
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
struct _7z_folder *folders;
struct _7z_stream_info *si = &(zip->si);
struct _7zip_entry *entries;
uint32_t folderIndex, indexInFolder;
unsigned i;
- int eindex, empty_streams, r, sindex;
+ int eindex, empty_streams, sindex;
- if (len < 2 || *p++ != kHeader)
- return (-1);
- len--;
+ if (check_header_id) {
+ /*
+ * Read Header.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p != kHeader)
+ return (-1);
+ }
/*
* Read ArchiveProperties.
*/
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
if (*p == kArchiveProperties) {
- p++;
- len--;
-
for (;;) {
uint64_t size;
- int atype = *p++;
- len--;
- if (atype == 0)
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == 0)
break;
- r = parse_7zip_uint64(p, len, &size);
- if (r < 0 || len < r + size)
+ if (parse_7zip_uint64(a, &size) < 0)
return (-1);
- p += r + size;
- len -= r + size;
}
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
}
/*
* Read MainStreamsInfo.
*/
if (*p == kMainStreamsInfo) {
- p++;
- len--;
- r = read_StreamsInfo(zip, &(zip->si), p, len);
- if (r < 0)
+ if (read_StreamsInfo(a, &(zip->si)) < 0)
+ return (-1);
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- p += r;
- len -= r;
}
- if (len == 0)
- return (-1);
if (*p == kEnd)
- return (p - _p + 1);
+ return (0);
/*
* Read FilesInfo.
*/
- if (len < 2 || *p++ != kFilesInfo)
+ if (*p != kFilesInfo)
return (-1);
- len--;
- r = parse_7zip_uint64(p, len, &(zip->numFiles));
- if (r < 0)
+ if (parse_7zip_uint64(a, &(zip->numFiles)) < 0)
return (-1);
- p += r;
- len -= r;
+ if (1000000 < zip->numFiles)
+ return (-1);
zip->entries = calloc(zip->numFiles, sizeof(*zip->entries));
if (zip->entries == NULL)
@@ -2331,20 +2290,17 @@ read_Header(struct _7zip *zip, struct _7z_header_info *h,
uint64_t size;
size_t ll;
- if (len < 1)
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- type = *p++;
- len--;
+ type = *p;
if (type == kEnd)
break;
- r = parse_7zip_uint64(p, len, &size);
- if (r < 0 || len < size)
+ if (parse_7zip_uint64(a, &size) < 0)
+ return (-1);
+ if (zip->header_bytes_remaining < size)
return (-1);
- p += r;
- len -= r;
ll = (size_t)size;
- len -= ll;
switch (type) {
case kEmptyStream:
@@ -2352,12 +2308,9 @@ read_Header(struct _7zip *zip, struct _7z_header_info *h,
sizeof(*h->emptyStreamBools));
if (h->emptyStreamBools == NULL)
return (-1);
- r = read_Bools(h->emptyStreamBools, zip->numFiles,
- p, ll);
- if (r < 0)
+ if (read_Bools(
+ a, h->emptyStreamBools, zip->numFiles) < 0)
return (-1);
- p += r;
- ll -= r;
empty_streams = 0;
for (i = 0; i < zip->numFiles; i++) {
if (h->emptyStreamBools[i])
@@ -2369,48 +2322,59 @@ read_Header(struct _7zip *zip, struct _7z_header_info *h,
sizeof(*h->emptyFileBools));
if (h->emptyFileBools == NULL)
return (-1);
- r = read_Bools(h->emptyFileBools, empty_streams,
- p, len);
- if (r < 0)
+ if (read_Bools(a, h->emptyFileBools, empty_streams) < 0)
return (-1);
- p += r;
- ll -= r;
break;
case kAnti:
h->antiBools = calloc(empty_streams,
sizeof(*h->antiBools));
if (h->antiBools == NULL)
return (-1);
- r = read_Bools(h->antiBools, empty_streams, p, len);
- if (r < 0)
+ if (read_Bools(a, h->antiBools, empty_streams) < 0)
return (-1);
- p += r;
- ll -= r;
break;
case kCTime:
case kATime:
case kMTime:
- r = read_Times(zip, h, type, p, ll);
- if (r < 0)
+ if (read_Times(a, h, type) < 0)
return (-1);
- p += r;
- ll -= r;
break;
case kName:
{
unsigned char *np;
- size_t nl;
+ size_t nl, nb;
- if (ll < 1)
+ /* Skip one byte. */
+ if ((p = header_bytes(a, 1)) == NULL)
return (-1);
- p++; ll--;/* Skip one byte. */
+ ll--;
+
if ((ll & 1) || ll < zip->numFiles * 4)
return (-1);
zip->entry_names = malloc(ll);
if (zip->entry_names == NULL)
return (-1);
- memcpy(zip->entry_names, p, ll);
+ np = zip->entry_names;
+ nb = ll;
+ /*
+ * Copy whole file names.
+ * NOTE: This loop prevents from expanding
+ * the uncompressed buffer in order not to
+ * use extra memory resource.
+ */
+ while (nb) {
+ size_t b;
+ if (nb > UBUFF_SIZE)
+ b = UBUFF_SIZE;
+ else
+ b = nb;
+ if ((p = header_bytes(a, b)) == NULL)
+ return (-1);
+ memcpy(np, p, b);
+ np += b;
+ nb -= b;
+ }
np = zip->entry_names;
nl = ll;
@@ -2437,11 +2401,9 @@ read_Header(struct _7zip *zip, struct _7z_header_info *h,
{
int allAreDefined;
- if (ll < 2)
+ if ((p = header_bytes(a, 2)) == NULL)
return (-1);
- allAreDefined = *p++;
- --ll;
- p++; --ll;/* Skip one byte. */
+ allAreDefined = *p;
h->attrBools = calloc(zip->numFiles,
sizeof(*h->attrBools));
if (h->attrBools == NULL)
@@ -2449,29 +2411,24 @@ read_Header(struct _7zip *zip, struct _7z_header_info *h,
if (allAreDefined)
memset(h->attrBools, 1, zip->numFiles);
else {
- r = read_Bools(h->attrBools,
- zip->numFiles, p, ll);
- if (r < 0)
+ if (read_Bools(a, h->attrBools,
+ zip->numFiles) < 0)
return (-1);
- p += r;
- ll -= r;
}
for (i = 0; i < zip->numFiles; i++) {
if (h->attrBools[i]) {
- if (ll < 4)
+ if ((p = header_bytes(a, 4)) == NULL)
return (-1);
entries[i].attr = archive_le32dec(p);
- p += 4;
- ll -= 4;
}
}
break;
}
default:
+ if (header_bytes(a, ll) == NULL)
+ return (-1);
break;
}
- /* Skip remaining data. */
- p += ll;
}
/*
@@ -2481,8 +2438,7 @@ read_Header(struct _7zip *zip, struct _7z_header_info *h,
eindex = sindex = 0;
folderIndex = indexInFolder = 0;
for (i = 0; i < zip->numFiles; i++) {
- if (h->emptyStreamBools == NULL ||
- h->emptyStreamBools[i] == 0)
+ if (h->emptyStreamBools == NULL || h->emptyStreamBools[i] == 0)
entries[i].flg |= HAS_STREAM;
/* The high 16 bits of attributes is a posix file mode. */
entries[i].mode = entries[i].attr >> 16;
@@ -2556,7 +2512,7 @@ read_Header(struct _7zip *zip, struct _7z_header_info *h,
}
}
- return (p - _p);
+ return (0);
}
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
@@ -2577,50 +2533,44 @@ fileTimeToUtc(uint64_t fileTime, time_t *time, long *ns)
}
static int
-read_Times(struct _7zip *zip, struct _7z_header_info *h, int type,
- const unsigned char *p, size_t len)
+read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
{
- const unsigned char *_p = p;
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
struct _7zip_entry *entries = zip->entries;
unsigned char *timeBools;
- int r;
- int allAreDefined, external;
+ int allAreDefined;
unsigned i;
timeBools = calloc(zip->numFiles, sizeof(*timeBools));
if (timeBools == NULL)
return (-1);
- if (len < 1)
+ /* Read allAreDefined. */
+ if ((p = header_bytes(a, 1)) == NULL)
goto failed;
- allAreDefined = *p++;
- len--;
+ allAreDefined = *p;
if (allAreDefined)
memset(timeBools, 1, zip->numFiles);
else {
- r = read_Bools(timeBools, zip->numFiles, p, len);
- if (r < 0)
+ if (read_Bools(a, timeBools, zip->numFiles) < 0)
goto failed;
- p += r;
- len -= r;
}
- if (len < 1)
+ /* Read external. */
+ if ((p = header_bytes(a, 1)) == NULL)
goto failed;
- external = *p++;
- len--;
- if (external) {
- r = parse_7zip_uint64(p, len, &(h->dataIndex));
- if (r < 0)
+ if (*p) {
+ if (parse_7zip_uint64(a, &(h->dataIndex)) < 0)
goto failed;
- p += r;
- len -= r;
+ if (1000000 < h->dataIndex)
+ return (-1);
}
for (i = 0; i < zip->numFiles; i++) {
if (!timeBools[i])
continue;
- if (len < 8)
+ if ((p = header_bytes(a, 8)) == NULL)
goto failed;
switch (type) {
case kCTime:
@@ -2642,29 +2592,22 @@ read_Times(struct _7zip *zip, struct _7z_header_info *h, int type,
entries[i].flg |= MTIME_IS_SET;
break;
}
- p += 8;
- len -= 8;
}
free(timeBools);
- return (p - _p);
+ return (0);
failed:
free(timeBools);
return (-1);
}
-static ssize_t
-decode_header_image(struct archive_read *a, struct _7zip *zip,
- struct _7z_stream_info *si, const unsigned char *p, uint64_t len,
- const void **image)
+static int
+decode_encoded_header_info(struct archive_read *a, struct _7z_stream_info *si)
{
- const unsigned char *v;
- size_t vsize;
- int r;
+ struct _7zip *zip = (struct _7zip *)a->format->data;
errno = 0;
- r = read_StreamsInfo(zip, si, p, len);
- if (r < 0) {
+ if (read_StreamsInfo(a, si) < 0) {
if (errno == ENOMEM)
archive_set_error(&a->archive, -1,
"Couldn't allocate memory");
@@ -2686,79 +2629,40 @@ decode_header_image(struct archive_read *a, struct _7zip *zip,
return (ARCHIVE_FATAL);
}
- r = setup_decode_folder(a, si->ci.folders, 1);
- if (r != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
-
- /* Get an uncompressed header size. */
- vsize = (size_t)zip->folder_outbytes_remaining;
-
- /*
- * Allocate an uncompressed buffer for the header image.
- */
- zip->uncompressed_buffer_size = 64 * 1024;
- if (vsize > zip->uncompressed_buffer_size)
- zip->uncompressed_buffer_size = vsize;
- zip->uncompressed_buffer = malloc(zip->uncompressed_buffer_size);
- if (zip->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for 7-Zip decompression");
- return (ARCHIVE_FATAL);
- }
+ return (ARCHIVE_OK);
+}
- /* Get the bytes we can read to decode the header. */
- zip->pack_stream_inbytes_remaining = si->pi.sizes[0];
+static const unsigned char *
+header_bytes(struct archive_read *a, size_t rbytes)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
- /* Seek the read point. */
- if (__archive_read_seek(a, si->pi.pos + zip->seek_base, SEEK_SET) < 0)
- return (ARCHIVE_FATAL);
- zip->header_offset = si->pi.pos;
+ if (zip->header_bytes_remaining < rbytes)
+ return (NULL);
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
- /* Extract a pack stream. */
- r = extract_pack_stream(a);
- if (r < 0)
- return (r);
- for (;;) {
+ if (zip->header_is_encoded == 0) {
+ p = __archive_read_ahead(a, rbytes, NULL);
+ if (p == NULL)
+ return (NULL);
+ zip->header_bytes_remaining -= rbytes;
+ zip->pack_stream_bytes_unconsumed = rbytes;
+ } else {
+ const void *buff;
ssize_t bytes;
-
- bytes = get_uncompressed_data(a, image, vsize);
- if (bytes < 0)
- return (r);
- if (bytes != vsize) {
- if (*image != zip->uncompressed_buffer) {
- /* This might happen if the coder was COPY.
- * We have to make sure we read a full plain
- * header image. */
- if (NULL==__archive_read_ahead(a, vsize, NULL))
- return (ARCHIVE_FATAL);
- continue;
- } else {
- archive_set_error(&a->archive, -1,
- "Malformed 7-Zip archive file");
- return (ARCHIVE_FATAL);
- }
- }
- break;
- }
- v = *image;
-
- /* Clean up variables which will not be used for decoding the
- * archive header */
- zip->pack_stream_remaining = 0;
- zip->pack_stream_index = 0;
- zip->folder_outbytes_remaining = 0;
- zip->uncompressed_buffer_bytes_remaining = 0;
- zip->pack_stream_bytes_unconsumed = 0;
- /* Check the header CRC. */
- if (si->ci.folders[0].digest_defined){
- uint32_t c = crc32(0, v, vsize);
- if (c != si->ci.folders[0].digest) {
- archive_set_error(&a->archive, -1, "Header CRC error");
- return (ARCHIVE_FATAL);
- }
+ bytes = read_stream(a, &buff, rbytes, rbytes);
+ if (bytes <= 0)
+ return (NULL);
+ zip->header_bytes_remaining -= bytes;
+ p = buff;
}
- return ((ssize_t)vsize);
+
+ /* Update checksum */
+ zip->header_crc32 = crc32(zip->header_crc32, p, rbytes);
+ return (p);
}
static int
@@ -2766,13 +2670,11 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
struct _7z_header_info *header)
{
const unsigned char *p;
- const void *image;
- uint64_t len;
uint64_t next_header_offset;
uint64_t next_header_size;
uint32_t next_header_crc;
- ssize_t bytes_avail, image_bytes;
- int r;
+ ssize_t bytes_avail;
+ int check_header_crc, r;
if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
return (ARCHIVE_FATAL);
@@ -2782,7 +2684,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
r = skip_sfx(a, bytes_avail);
if (r < ARCHIVE_WARN)
return (r);
- if ((p = __archive_read_ahead(a, 32, NULL)) == NULL)
+ if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
return (ARCHIVE_FATAL);
}
zip->seek_base += 32;
@@ -2810,45 +2712,71 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
return (ARCHIVE_FATAL);
}
- if (__archive_read_seek(a, next_header_offset + zip->seek_base,
- SEEK_SET) < 0)
- return (ARCHIVE_FATAL);
+ __archive_read_consume(a, 32);
+ if (next_header_offset != 0) {
+ if (bytes_avail >= next_header_offset)
+ __archive_read_consume(a, next_header_offset);
+ else if (__archive_read_seek(a,
+ next_header_offset + zip->seek_base, SEEK_SET) < 0)
+ return (ARCHIVE_FATAL);
+ }
+ zip->stream_offset = next_header_offset;
zip->header_offset = next_header_offset;
+ zip->header_bytes_remaining = next_header_size;
+ zip->header_crc32 = 0;
+ zip->header_is_encoded = 0;
+ zip->header_is_being_read = 1;
+ check_header_crc = 1;
- if ((p = __archive_read_ahead(a, next_header_size, NULL)) == NULL)
- return (ARCHIVE_FATAL);
-
- if (crc32(0, p, next_header_size) != next_header_crc) {
- archive_set_error(&a->archive, -1, "Damaged 7-Zip archive");
+ if ((p = header_bytes(a, 1)) == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
return (ARCHIVE_FATAL);
}
-
- len = next_header_size;
/* Parse ArchiveProperties. */
switch (p[0]) {
case kEncodedHeader:
- p++;
- len--;
-
/*
* The archive has an encoded header and we have to decode it
* in order to parse the header correctly.
*/
- image_bytes =
- decode_header_image(a, zip, &(zip->si), p, len, &image);
+ r = decode_encoded_header_info(a, &(zip->si));
+
+ /* Check the EncodedHeader CRC.*/
+ if (r == 0 && zip->header_crc32 != next_header_crc) {
+ archive_set_error(&a->archive, -1,
+ "Damaged 7-Zip archive");
+ r = -1;
+ }
+ if (r == 0) {
+ if (zip->si.ci.folders[0].digest_defined)
+ next_header_crc = zip->si.ci.folders[0].digest;
+ else
+ check_header_crc = 0;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ r = setup_decode_folder(a, zip->si.ci.folders, 1);
+ if (r == 0) {
+ zip->header_bytes_remaining =
+ zip->folder_outbytes_remaining;
+ r = seek_pack(a);
+ }
+ }
+ /* Clean up StreamsInfo. */
free_StreamsInfo(&(zip->si));
memset(&(zip->si), 0, sizeof(zip->si));
- if (image_bytes < 0)
+ if (r < 0)
return (ARCHIVE_FATAL);
- p = image;
- len = image_bytes;
+ zip->header_is_encoded = 1;
+ zip->header_crc32 = 0;
/* FALL THROUGH */
case kHeader:
/*
* Parse the header.
*/
errno = 0;
- r = read_Header(zip, header, p, len);
+ r = read_Header(a, header, zip->header_is_encoded);
if (r < 0) {
if (errno == ENOMEM)
archive_set_error(&a->archive, -1,
@@ -2858,7 +2786,18 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
"Damaged 7-Zip archive");
return (ARCHIVE_FATAL);
}
- if (len - r == 0 || p[r] != kEnd) {
+
+ /*
+ * Must be kEnd.
+ */
+ if ((p = header_bytes(a, 1)) == NULL ||*p != kEnd) {
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Check the Header CRC.*/
+ if (check_header_crc && zip->header_crc32 != next_header_crc) {
archive_set_error(&a->archive, -1,
"Malformed 7-Zip archive");
return (ARCHIVE_FATAL);
@@ -2869,24 +2808,21 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
"Unexpected Property ID = %X", p[0]);
return (ARCHIVE_FATAL);
}
- zip->stream_offset = -1;
- /*
- * If the uncompressed buffer was allocated more than 64K for
- * the header image, release it.
- */
- if (zip->uncompressed_buffer != NULL &&
- zip->uncompressed_buffer_size != 64 * 1024) {
- free(zip->uncompressed_buffer);
- zip->uncompressed_buffer = NULL;
- zip->uncompressed_buffer_size = 0;
- }
+ /* Clean up variables be used for decoding the archive header */
+ zip->pack_stream_remaining = 0;
+ zip->pack_stream_index = 0;
+ zip->folder_outbytes_remaining = 0;
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ zip->pack_stream_bytes_unconsumed = 0;
+ zip->header_is_being_read = 0;
return (ARCHIVE_OK);
}
static ssize_t
-get_uncompressed_data(struct archive_read *a, const void **buff, size_t size)
+get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
+ size_t minimum)
{
struct _7zip *zip = (struct _7zip *)a->format->data;
ssize_t bytes_avail;
@@ -2922,6 +2858,15 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size)
return (ARCHIVE_FATAL);
} else {
/* Packed mode. */
+ if (minimum > zip->uncompressed_buffer_bytes_remaining) {
+ /*
+ * If remaining uncompressed data size is less than
+ * the minimum size, fill the buffer up to the
+ * minimum size.
+ */
+ if (extract_pack_stream(a, minimum) < 0)
+ return (ARCHIVE_FATAL);
+ }
if (size > zip->uncompressed_buffer_bytes_remaining)
bytes_avail = (ssize_t)
zip->uncompressed_buffer_bytes_remaining;
@@ -2935,14 +2880,16 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size)
}
static ssize_t
-extract_pack_stream(struct archive_read *a)
+extract_pack_stream(struct archive_read *a, size_t minimum)
{
struct _7zip *zip = (struct _7zip *)a->format->data;
ssize_t bytes_avail;
int r;
if (zip->codec == _7Z_COPY && zip->codec2 == -1) {
- if (__archive_read_ahead(a, 1, &bytes_avail) == NULL
+ if (minimum == 0)
+ minimum = 1;
+ if (__archive_read_ahead(a, minimum, &bytes_avail) == NULL
|| bytes_avail <= 0) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
@@ -2961,7 +2908,11 @@ extract_pack_stream(struct archive_read *a)
/* If the buffer hasn't been allocated, allocate it now. */
if (zip->uncompressed_buffer == NULL) {
- zip->uncompressed_buffer_size = 64 * 1024;
+ zip->uncompressed_buffer_size = UBUFF_SIZE;
+ if (zip->uncompressed_buffer_size < minimum) {
+ zip->uncompressed_buffer_size = minimum + 1023;
+ zip->uncompressed_buffer_size &= ~0x3ff;
+ }
zip->uncompressed_buffer =
malloc(zip->uncompressed_buffer_size);
if (zip->uncompressed_buffer == NULL) {
@@ -2969,8 +2920,46 @@ extract_pack_stream(struct archive_read *a)
"No memory for 7-Zip decompression");
return (ARCHIVE_FATAL);
}
- }
- zip->uncompressed_buffer_bytes_remaining = 0;
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ } else if (zip->uncompressed_buffer_size < minimum ||
+ zip->uncompressed_buffer_bytes_remaining < minimum) {
+ /*
+ * Make sure the uncompressed buffer can have bytes
+ * at least `minimum' bytes.
+ * NOTE: This case happen when reading the header.
+ */
+ size_t used;
+ if (zip->uncompressed_buffer_pointer != 0)
+ used = zip->uncompressed_buffer_pointer -
+ zip->uncompressed_buffer;
+ else
+ used = 0;
+ if (zip->uncompressed_buffer_size < minimum) {
+ /*
+ * Expand the uncompressed buffer up to
+ * the minimum size.
+ */
+ zip->uncompressed_buffer_size = minimum + 1023;
+ zip->uncompressed_buffer_size &= ~0x3ff;
+ zip->uncompressed_buffer =
+ realloc(zip->uncompressed_buffer,
+ zip->uncompressed_buffer_size);
+ if (zip->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ /*
+ * Move unconsumed bytes to the head.
+ */
+ if (used) {
+ memmove(zip->uncompressed_buffer,
+ zip->uncompressed_buffer + used,
+ zip->uncompressed_buffer_bytes_remaining);
+ }
+ } else
+ zip->uncompressed_buffer_bytes_remaining = 0;
zip->uncompressed_buffer_pointer = NULL;
for (;;) {
size_t bytes_in, bytes_out;
@@ -3025,6 +3014,10 @@ extract_pack_stream(struct archive_read *a)
if (zip->uncompressed_buffer_bytes_remaining ==
zip->uncompressed_buffer_size)
break;
+ if (zip->codec2 == _7Z_X86 && zip->odd_bcj_size &&
+ zip->uncompressed_buffer_bytes_remaining + 5 >
+ zip->uncompressed_buffer_size)
+ break;
if (zip->pack_stream_inbytes_remaining == 0 &&
zip->folder_outbytes_remaining == 0)
break;
@@ -3035,6 +3028,11 @@ extract_pack_stream(struct archive_read *a)
}
read_consume(a);
}
+ if (zip->uncompressed_buffer_bytes_remaining < minimum) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
zip->uncompressed_buffer_pointer = zip->uncompressed_buffer;
return (ARCHIVE_OK);
}
@@ -3065,7 +3063,8 @@ seek_pack(struct archive_read *a)
}
static ssize_t
-read_stream(struct archive_read *a, const void **buff, size_t size)
+read_stream(struct archive_read *a, const void **buff, size_t size,
+ size_t minimum)
{
struct _7zip *zip = (struct _7zip *)a->format->data;
uint64_t skip_bytes = 0;
@@ -3073,29 +3072,36 @@ read_stream(struct archive_read *a, const void **buff, size_t size)
if (zip->uncompressed_buffer_bytes_remaining == 0) {
if (zip->pack_stream_inbytes_remaining > 0) {
- r = extract_pack_stream(a);
+ r = extract_pack_stream(a, 0);
if (r < 0)
return (r);
- return (get_uncompressed_data(a, buff, size));
+ return (get_uncompressed_data(a, buff, size, minimum));
} else if (zip->folder_outbytes_remaining > 0) {
/* Extract a remaining pack stream. */
- r = extract_pack_stream(a);
+ r = extract_pack_stream(a, 0);
if (r < 0)
return (r);
- return (get_uncompressed_data(a, buff, size));
+ return (get_uncompressed_data(a, buff, size, minimum));
}
} else
- return (get_uncompressed_data(a, buff, size));
+ return (get_uncompressed_data(a, buff, size, minimum));
/*
* Current pack stream has been consumed.
*/
if (zip->pack_stream_remaining == 0) {
+ if (zip->header_is_being_read) {
+ /* Invalid sequence. This might happen when
+ * reading a malformed archive. */
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
/*
* All current folder's pack streams have been
* consumed. Switch to next folder.
*/
-
if (zip->folder_index == 0 &&
(zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
|| zip->folder_index != zip->entry->folderIndex)) {
@@ -3127,7 +3133,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size)
return (r);
/* Extract a new pack stream. */
- r = extract_pack_stream(a);
+ r = extract_pack_stream(a, 0);
if (r < 0)
return (r);
@@ -3139,12 +3145,12 @@ read_stream(struct archive_read *a, const void **buff, size_t size)
if (zip->uncompressed_buffer_bytes_remaining == 0) {
if (zip->pack_stream_inbytes_remaining > 0) {
- r = extract_pack_stream(a);
+ r = extract_pack_stream(a, 0);
if (r < 0)
return (r);
} else if (zip->folder_outbytes_remaining > 0) {
/* Extract a remaining pack stream. */
- r = extract_pack_stream(a);
+ r = extract_pack_stream(a, 0);
if (r < 0)
return (r);
} else {
@@ -3154,7 +3160,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size)
return (ARCHIVE_FATAL);
}
}
- skipped = get_uncompressed_data(a, buff, skip_bytes);
+ skipped = get_uncompressed_data(a, buff, skip_bytes, 0);
if (skipped < 0)
return (skipped);
skip_bytes -= skipped;
@@ -3162,7 +3168,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size)
read_consume(a);
}
- return (get_uncompressed_data(a, buff, size));
+ return (get_uncompressed_data(a, buff, size, minimum));
}
static int
@@ -3336,11 +3342,12 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
/* Extract a sub stream. */
while (zip->pack_stream_inbytes_remaining > 0) {
- r = extract_pack_stream(a);
+ r = extract_pack_stream(a, 0);
if (r < 0)
return (r);
bytes = get_uncompressed_data(a, &buff,
- zip->uncompressed_buffer_bytes_remaining);
+ zip->uncompressed_buffer_bytes_remaining,
+ 0);
if (bytes < 0)
return ((int)bytes);
memcpy(b[i]+s[i], buff, bytes);
@@ -3412,7 +3419,7 @@ skip_stream(struct archive_read *a, size_t skip_bytes)
}
while (bytes) {
- skipped_bytes = read_stream(a, &p, bytes);
+ skipped_bytes = read_stream(a, &p, bytes, 0);
if (skipped_bytes < 0)
return (skipped_bytes);
if (skipped_bytes == 0) {
@@ -3438,18 +3445,30 @@ skip_stream(struct archive_read *a, size_t skip_bytes)
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
-static const unsigned char kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
-static const unsigned char kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+static void
+x86_Init(struct _7zip *zip)
+{
+ zip->bcj_state = 0;
+ zip->bcj_prevPosT = (size_t)0 - 1;
+ zip->bcj_prevMask = 0;
+ zip->bcj_ip = 5;
+}
static size_t
-x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state)
+x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
{
- size_t bufferPos = 0, prevPosT;
- uint32_t prevMask = *state & 0x7;
+ static const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+ static const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+ size_t bufferPos, prevPosT;
+ uint32_t ip, prevMask;
+
if (size < 5)
return 0;
- ip += 5;
- prevPosT = (size_t)0 - 1;
+
+ bufferPos = 0;
+ prevPosT = zip->bcj_prevPosT;
+ prevMask = zip->bcj_prevMask;
+ ip = zip->bcj_ip;
for (;;) {
uint8_t *p = data + bufferPos;
@@ -3508,9 +3527,9 @@ x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state)
bufferPos++;
}
}
- prevPosT = bufferPos - prevPosT;
- *state = ((prevPosT > 3) ?
- 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
+ zip->bcj_prevPosT = prevPosT;
+ zip->bcj_prevMask = prevMask;
+ zip->bcj_ip += bufferPos;
return (bufferPos);
}
@@ -3545,7 +3564,7 @@ x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state)
#define UPDATE_0(p) zip->bcj2_range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
#define UPDATE_1(p) zip->bcj2_range -= bound; zip->bcj2_code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
-ssize_t
+static ssize_t
Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize)
{
size_t inPos = 0, outPos = 0;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
index 8d2ba1d..db7aa9d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -1962,7 +1962,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
(parent->re || parent->re_descendant))
file->re_descendant = 1;
if (file->cl_offset) {
- struct file_info *p;
+ struct file_info *r;
if (parent == NULL || parent->parent == NULL) {
archive_set_error(&a->archive,
@@ -1990,8 +1990,8 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* Sanity check: cl_offset does not point at its
* the parents or itself.
*/
- for (p = parent; p; p = p->parent) {
- if (p->offset == file->cl_offset) {
+ for (r = parent; r; r = r->parent) {
+ if (r->offset == file->cl_offset) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Rockridge CL");
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index f751874..d150802 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -112,6 +112,8 @@ struct zip {
};
#define ZIP_LENGTH_AT_END 8
+#define ZIP_ENCRYPTED (1<<0)
+#define ZIP_STRONG_ENCRYPTED (1<<6)
#define ZIP_UTF8_NAME (1<<11)
static int archive_read_format_zip_streamable_bid(struct archive_read *, int);
@@ -356,7 +358,32 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a,
typically faster (easier for I/O layer to optimize). */
__archive_read_seek(a, zip->entry->local_header_offset, SEEK_SET);
zip->unconsumed = 0;
- return zip_read_local_file_header(a, entry, zip);
+ r = zip_read_local_file_header(a, entry, zip);
+ if (r != ARCHIVE_OK)
+ return r;
+ if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
+ const void *p;
+ size_t linkname_length = archive_entry_size(entry);
+
+ 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;
+ }
+
+ if (archive_entry_copy_symlink_l(entry, p, linkname_length,
+ NULL) != 0) {
+ /* NOTE: If the last argument is NULL, this will
+ * fail only by memeory allocation failure. */
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Symlink");
+ return (ARCHIVE_FATAL);
+ }
+ /* TODO: handle character-set issues? */
+ }
+ return ARCHIVE_OK;
}
static int
@@ -722,6 +749,12 @@ archive_read_format_zip_read_data(struct archive_read *a,
if (AE_IFREG != (zip->entry->mode & AE_IFMT))
return (ARCHIVE_EOF);
+ if (zip->entry->flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Encrypted file is unsupported");
+ return (ARCHIVE_FAILED);
+ }
+
__archive_read_consume(a, zip->unconsumed);
zip->unconsumed = 0;
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index 5bd09bd..cbfad2c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -212,7 +212,7 @@ static struct archive_string *
archive_string_append(struct archive_string *as, const char *p, size_t s)
{
if (archive_string_ensure(as, as->length + s + 1) == NULL)
- __archive_errx(1, "Out of memory");
+ return (NULL);
memcpy(as->s + as->length, p, s);
as->length += s;
as->s[as->length] = 0;
@@ -223,7 +223,7 @@ static struct archive_wstring *
archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s)
{
if (archive_wstring_ensure(as, as->length + s + 1) == NULL)
- __archive_errx(1, "Out of memory");
+ return (NULL);
wmemcpy(as->s + as->length, p, s);
as->length += s;
as->s[as->length] = 0;
@@ -233,13 +233,15 @@ archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s)
void
archive_string_concat(struct archive_string *dest, struct archive_string *src)
{
- archive_string_append(dest, src->s, src->length);
+ if (archive_string_append(dest, src->s, src->length) == NULL)
+ __archive_errx(1, "Out of memory");
}
void
archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src)
{
- archive_wstring_append(dest, src->s, src->length);
+ if (archive_wstring_append(dest, src->s, src->length) == NULL)
+ __archive_errx(1, "Out of memory");
}
void
@@ -346,7 +348,9 @@ archive_strncat(struct archive_string *as, const void *_p, size_t n)
pp++;
s++;
}
- return (archive_string_append(as, p, s));
+ if ((as = archive_string_append(as, p, s)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
}
struct archive_wstring *
@@ -362,7 +366,9 @@ archive_wstrncat(struct archive_wstring *as, const wchar_t *p, size_t n)
pp++;
s++;
}
- return (archive_wstring_append(as, p, s));
+ if ((as = archive_wstring_append(as, p, s)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
}
struct archive_string *
@@ -387,13 +393,17 @@ archive_wstrcat(struct archive_wstring *as, const wchar_t *p)
struct archive_string *
archive_strappend_char(struct archive_string *as, char c)
{
- return (archive_string_append(as, &c, 1));
+ if ((as = archive_string_append(as, &c, 1)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
}
struct archive_wstring *
archive_wstrappend_wchar(struct archive_wstring *as, wchar_t c)
{
- return (archive_wstring_append(as, &c, 1));
+ if ((as = archive_wstring_append(as, &c, 1)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
}
/*
@@ -2080,14 +2090,8 @@ archive_strncat_in_locale(struct archive_string *as, const void *_p, size_t n,
*/
if (sc == NULL) {
length = mbsnbytes(_p, n);
- /*
- * archive_string_append() will call archive_string_ensure()
- * but we cannot know if that call is failed or not. so
- * we call archive_string_ensure() here.
- */
- if (archive_string_ensure(as, as->length + length + 1) == NULL)
- return (-1);
- archive_string_append(as, _p, length);
+ if (archive_string_append(as, _p, length) == NULL)
+ return (-1);/* No memory */
return (0);
}
@@ -2338,7 +2342,8 @@ best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
* And then this checks all copied MBS can be WCS if so returns 0.
*/
if (sc->same) {
- archive_string_append(as, _p, length);
+ if (archive_string_append(as, _p, length) == NULL)
+ return (-1);/* No memory */
return (invalid_mbs(_p, length, sc));
}
@@ -4115,10 +4120,14 @@ archive_mstring_copy_mbs_len_l(struct archive_mstring *aes,
* characters because Windows platform cannot make locale UTF-8.
*/
if (sc == NULL) {
- archive_string_append(&(aes->aes_mbs),
- mbs, mbsnbytes(mbs, len));
- aes->aes_set = AES_SET_MBS;
- r = 0;
+ if (archive_string_append(&(aes->aes_mbs),
+ mbs, mbsnbytes(mbs, len)) == NULL) {
+ aes->aes_set = 0;
+ r = -1;
+ } else {
+ aes->aes_set = AES_SET_MBS;
+ r = 0;
+ }
#if defined(HAVE_ICONV)
} else if (sc != NULL && sc->cd_w != (iconv_t)-1) {
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.3 b/Utilities/cmlibarchive/libarchive/archive_util.3
index e07ac95..cd05d03 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.3
+++ b/Utilities/cmlibarchive/libarchive/archive_util.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_util.3 201098 2009-12-28 02:58:14Z kientzle $
.\"
.Dd January 8, 2005
-.Dt archive_util 3
+.Dt ARCHIVE_UTIL 3
.Os
.Sh NAME
.Nm archive_clear_error ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.c b/Utilities/cmlibarchive/libarchive/archive_windows.c
index 51860ac..8f5d566 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.c
@@ -152,6 +152,11 @@ __la_win_permissive_name_w(const wchar_t *wname)
l = GetFullPathNameW(wname, 0, NULL, NULL);
if (l == 0)
return (NULL);
+ /* NOTE: GetFullPathNameW has a bug that if the length of the file
+ * name is just one that return imcomplete buffer size. Thus, we
+ * have to add three to the size to allocate a sufficient buffer
+ * size for the full-pathname of the file name. */
+ l += 3;
wnp = malloc(l * sizeof(wchar_t));
if (wnp == NULL)
return (NULL);
@@ -246,27 +251,6 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
return (handle);
}
-/*
- * This fcntl is limited implementation.
- */
-int
-__la_fcntl(int fd, int cmd, int val)
-{
- HANDLE handle;
-
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) == FILE_TYPE_PIPE) {
- if (cmd == F_SETFL && val == 0) {
- DWORD mode = PIPE_WAIT;
- if (SetNamedPipeHandleState(
- handle, &mode, NULL, NULL) != 0)
- return (0);
- }
- }
- errno = EINVAL;
- return (-1);
-}
-
#if defined(__LA_LSEEK_NEEDED)
__int64
__la_lseek(int fd, __int64 offset, int whence)
@@ -419,22 +403,6 @@ __la_read(int fd, void *buf, size_t nbytes)
if (nbytes == 0)
return (0);
handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) == FILE_TYPE_PIPE) {
- DWORD sta;
- if (GetNamedPipeHandleState(
- handle, &sta, NULL, NULL, NULL, NULL, 0) != 0 &&
- (sta & PIPE_NOWAIT) == 0) {
- DWORD avail = -1;
- int cnt = 3;
-
- while (PeekNamedPipe(
- handle, NULL, 0, NULL, &avail, NULL) != 0 &&
- avail == 0 && --cnt)
- Sleep(100);
- if (avail == 0)
- return (0);
- }
- }
r = ReadFile(handle, buf, (uint32_t)nbytes,
&bytes_read, NULL);
if (r == 0) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.h b/Utilities/cmlibarchive/libarchive/archive_windows.h
index ac44192..c581af3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.h
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.h
@@ -91,7 +91,7 @@
/* Alias the Windows _function to the POSIX equivalent. */
#define close _close
-#define fcntl __la_fcntl
+#define fcntl(fd, cmd, flg) /* No operation. */
#ifndef fileno
#define fileno _fileno
#endif
@@ -249,7 +249,6 @@
/* Replacement POSIX function */
-extern int __la_fcntl(int fd, int cmd, int val);
extern int __la_fstat(int fd, struct stat *st);
extern int __la_lstat(const char *path, struct stat *st);
#if defined(__LA_LSEEK_NEEDED)
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.3 b/Utilities/cmlibarchive/libarchive/archive_write.3
index 1fa4245..f87386a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
.\"
.Dd March 23, 2011
-.Dt archive_write 3
+.Dt ARCHIVE_WRITE 3
.Os
.Sh NAME
.Nm archive_write
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3 b/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
index 239fa92..96c7538 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 23, 2011
-.Dt archive_write_blocksize 3
+.Dt ARCHIVE_WRITE_BLOCKSIZE 3
.Os
.Sh NAME
.Nm archive_write_get_bytes_per_block ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_data.3 b/Utilities/cmlibarchive/libarchive/archive_write_data.3
index 2c98b3e..fc399bc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_data.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
.\"
.Dd March 23, 2011
-.Dt archive_write 3
+.Dt ARCHIVE_WRITE 3
.Os
.Sh NAME
.Nm archive_write_data
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk.3 b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
index 90bbdcf..ffadb04 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: src/lib/libarchive/archive_write_disk.3,v 1.4 2008/09/04 05:22:00 kientzle Exp $
.\"
.Dd August 5, 2008
-.Dt archive_write_disk 3
+.Dt ARCHIVE_WRITE_DISK 3
.Os
.Sh NAME
.Nm archive_write_disk_new ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 9df9ddc..2dc2d92 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -542,11 +542,36 @@ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
{
static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
static int set;
+ BOOL ret;
+
if (!set) {
set = 1;
f = la_GetFunctionKernel32("CreateHardLinkW");
}
- return f == NULL ? 0 : (*f)(linkname, target, NULL);
+ if (!f)
+ return (0);
+ ret = (*f)(linkname, target, NULL);
+ if (!ret) {
+ /* Under windows 2000, it is necessary to remove
+ * the "\\?\" prefix. */
+#define IS_UNC(name) ((name[0] == L'U' || name[0] == L'u') && \
+ (name[1] == L'N' || name[1] == L'n') && \
+ (name[2] == L'C' || name[2] == L'c') && \
+ name[3] == L'\\')
+ if (!wcsncmp(linkname,L"\\\\?\\", 4)) {
+ linkname += 4;
+ if (IS_UNC(linkname))
+ linkname += 4;
+ }
+ if (!wcsncmp(target,L"\\\\?\\", 4)) {
+ target += 4;
+ if (IS_UNC(target))
+ target += 4;
+ }
+#undef IS_UNC
+ ret = (*f)(linkname, target, NULL);
+ }
+ return (ret);
}
static int
@@ -2207,6 +2232,7 @@ create_dir(struct archive_write_disk *a, wchar_t *path)
le->fixup |=TODO_MODE_BASE;
le->mode = mode_final;
}
+ free(full);
return (ARCHIVE_OK);
} else {
la_dosmaperr(GetLastError());
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_filter.3 b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
index f084a51..00438d4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 23, 2011
-.Dt archive_write_filter 3
+.Dt ARCHIVE_WRITE_FILTER 3
.Os
.Sh NAME
.Nm archive_write_add_filter_bzip2 ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3 b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
index 06c002e..3add601 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
.\"
.Dd March 23, 2011
-.Dt archive_write_finish_entry 3
+.Dt ARCHIVE_WRITE_FINISH_ENTRY 3
.Os
.Sh NAME
.Nm archive_write_finish_entry
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_format.3 b/Utilities/cmlibarchive/libarchive/archive_write_format.3
index b3e7e35..e12e7d8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_format.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 23, 2011
-.Dt archive_write_format 3
+.Dt ARCHIVE_WRITE_FORMAT 3
.Os
.Sh NAME
.Nm archive_write_set_format_cpio ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_free.3 b/Utilities/cmlibarchive/libarchive/archive_write_free.3
index d939780..27efe18 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_free.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_free.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 23, 2011
-.Dt archive_write_free 3
+.Dt ARCHIVE_WRITE_FREE 3
.Os
.Sh NAME
.Nm archive_write_close ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_header.3 b/Utilities/cmlibarchive/libarchive/archive_write_header.3
index f76175b..423b38e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_header.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_header.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 23, 2011
-.Dt archive_write_header 3
+.Dt ARCHIVE_WRITE_HEADER 3
.Os
.Sh NAME
.Nm archive_write_header
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_new.3 b/Utilities/cmlibarchive/libarchive/archive_write_new.3
index 76515bb..d626ccb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_new.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_new.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 23, 2011
-.Dt archive_write_new 3
+.Dt ARCHIVE_WRITE_NEW 3
.Os
.Sh NAME
.Nm archive_write_new
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open.3 b/Utilities/cmlibarchive/libarchive/archive_write_open.3
index ab2d484..0d12cb3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
.\"
.Dd March 23, 2011
-.Dt archive_write 3
+.Dt ARCHIVE_WRITE 3
.Os
.Sh NAME
.Nm archive_write_open ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
index 0e5f5ce..ce3298b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
@@ -96,7 +96,7 @@ enum la_zaction {
};
/*
- * Universal zstream.
+ * A stream object of universal compressor.
*/
struct la_zstream {
const uint8_t *next_in;
@@ -154,8 +154,8 @@ struct file {
#define HAS_STREAM (1<<4)
struct {
- time_t time;
- long time_ns;
+ time_t time;
+ long time_ns;
} times[3];
#define MTIME 0
#define ATIME 1
@@ -455,6 +455,7 @@ _7z_write_header(struct archive_write *a, struct archive_entry *entry)
zip->total_number_entry++;
zip->total_bytes_entry_name += file->name_len + 2;
if (file->size == 0) {
+ /* Count up the number of empty files. */
zip->total_number_empty_entry++;
if (file->dir)
zip->total_number_dir_entry++;
@@ -488,6 +489,9 @@ _7z_write_header(struct archive_write *a, struct archive_entry *entry)
zip->entry_bytes_remaining = file->size;
zip->entry_crc32 = 0;
+ /*
+ * Store a symbolic link name as file contents.
+ */
if (archive_entry_filetype(entry) == AE_IFLNK) {
ssize_t bytes;
const void *p = (const void *)archive_entry_symlink(entry);
@@ -501,6 +505,9 @@ _7z_write_header(struct archive_write *a, struct archive_entry *entry)
return (r);
}
+/*
+ * Write data to a temporary file.
+ */
static int
write_to_temp(struct archive_write *a, const void *buff, size_t s)
{
@@ -719,19 +726,22 @@ _7z_close(struct archive_write *a)
zip->total_number_nonempty_entry =
zip->total_number_entry - zip->total_number_empty_entry;
+ /* Connect an empty file list. */
*zip->file_list.last = zip->empty_list.first;
zip->file_list.last = zip->empty_list.last;
+ /* Connect a directory file list. */
ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) {
file_register(zip, (struct file *)n);
}
/*
* NOTE: 7z command supports just LZMA1, LZMA2 and COPY for
- * the header.
+ * the compression type for encoding the header.
*/
#if HAVE_LZMA_H
header_compression = _7Z_LZMA1;
- /* If the stored file is only one, do not encode the header. */
+ /* 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)
header_compression = _7Z_COPY;
#else
@@ -823,6 +833,9 @@ _7z_close(struct archive_write *a)
return (r);
}
+/*
+ * Encode 64 bits value into 7-Zip's encoded UINT64 value.
+ */
static int
enc_uint64(struct archive_write *a, uint64_t val)
{
@@ -1586,6 +1599,9 @@ compression_unsupported_encoder(struct archive *a,
}
#endif
+/*
+ * _7_COPY compressor.
+ */
static int
compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm)
{
@@ -1631,6 +1647,9 @@ compression_end_copy(struct archive *a, struct la_zstream *lastrm)
return (ARCHIVE_OK);
}
+/*
+ * _7_DEFLATE compressor.
+ */
#ifdef HAVE_ZLIB_H
static int
compression_init_encoder_deflate(struct archive *a,
@@ -1741,6 +1760,9 @@ compression_init_encoder_deflate(struct archive *a,
}
#endif
+/*
+ * _7_BZIP2 compressor.
+ */
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
static int
compression_init_encoder_bzip2(struct archive *a,
@@ -1860,6 +1882,9 @@ compression_init_encoder_bzip2(struct archive *a,
}
#endif
+/*
+ * _7_LZMA1, _7_LZMA2 compressor.
+ */
#if defined(HAVE_LZMA_H)
static int
compression_init_encoder_lzma(struct archive *a,
@@ -2047,7 +2072,7 @@ compression_init_encoder_lzma2(struct archive *a,
#endif
/*
- * PPMd compression.
+ * _7_PPMD compressor.
*/
static void *
ppmd_alloc(void *p, size_t size)
@@ -2201,6 +2226,9 @@ compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
return (ARCHIVE_OK);
}
+/*
+ * Universal compressor initializer.
+ */
static int
_7z_compression_init_encoder(struct archive_write *a, unsigned compression,
int compression_level)
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
index 6b8741f..0f003a8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
@@ -684,21 +684,24 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s)
archive_string_empty(&(xar->cur_file->script));
if (rsize > 2 && b[0] == '#' && b[1] == '!') {
- char path[PATH_MAX];
size_t i, end, off;
- end = sizeof(path);
- if (end > rsize)
- end = rsize;
off = 2;
if (b[off] == ' ')
off++;
+#ifdef PATH_MAX
+ if ((rsize - off) > PATH_MAX)
+ end = off + PATH_MAX;
+ else
+#endif
+ end = rsize;
+ /* Find the end of a script path. */
for (i = off; i < end && b[i] != '\0' &&
b[i] != '\n' && b[i] != '\r' &&
b[i] != ' ' && b[i] != '\t'; i++)
- path[i - off] = b[i];
- path[i - off] = '\0';
- archive_strcpy(&(xar->cur_file->script), path);
+ ;
+ archive_strncpy(&(xar->cur_file->script), b + off,
+ i - off);
}
}
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
index 3c925d8..11fbd45 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
@@ -96,11 +96,13 @@ enum compression {
#endif
};
-static ssize_t archive_write_zip_data(struct archive_write *, const void *buff, size_t s);
+static ssize_t archive_write_zip_data(struct archive_write *,
+ const void *buff, size_t s);
static int archive_write_zip_close(struct archive_write *);
static int archive_write_zip_free(struct archive_write *);
static int archive_write_zip_finish_entry(struct archive_write *);
-static int archive_write_zip_header(struct archive_write *, struct archive_entry *);
+static int archive_write_zip_header(struct archive_write *,
+ struct archive_entry *);
static int archive_write_zip_options(struct archive_write *,
const char *, const char *);
static unsigned int dos_time(const time_t);
@@ -270,7 +272,8 @@ archive_write_set_format_zip(struct archive *_a)
zip = (struct zip *) calloc(1, sizeof(*zip));
if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip data");
return (ARCHIVE_FATAL);
}
zip->central_directory = NULL;
@@ -284,7 +287,8 @@ archive_write_set_format_zip(struct archive *_a)
zip->len_buf = 65536;
zip->buf = malloc(zip->len_buf);
if (zip->buf == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't allocate compression buffer");
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate compression buffer");
return (ARCHIVE_FATAL);
}
#else
@@ -335,7 +339,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
/* Entries other than a regular file or a folder are skipped. */
type = archive_entry_filetype(entry);
- if ((type != AE_IFREG) & (type != AE_IFDIR)) {
+ if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Filetype not supported");
return ARCHIVE_FAILED;
@@ -410,8 +414,20 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
/* Initialize the CRC variable and potentially the local crc32(). */
l->crc32 = crc32(0, NULL, 0);
- l->compression = zip->compression;
- l->compressed_size = 0;
+ if (type == AE_IFLNK) {
+ const char *p = archive_entry_symlink(l->entry);
+ if (p != NULL)
+ size = strlen(p);
+ else
+ size = 0;
+ zip->remaining_data_bytes = 0;
+ archive_entry_set_size(l->entry, size);
+ l->compression = COMPRESSION_STORE;
+ l->compressed_size = size;
+ } else {
+ l->compression = zip->compression;
+ l->compressed_size = 0;
+ }
l->next = NULL;
if (zip->central_directory == NULL) {
zip->central_directory = l;
@@ -420,22 +436,24 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
}
zip->central_directory_end = l;
- /* Store the offset of this header for later use in central directory. */
+ /* Store the offset of this header for later use in central
+ * directory. */
l->offset = zip->written_bytes;
memset(&h, 0, sizeof(h));
archive_le32enc(&h.signature, ZIP_SIGNATURE_LOCAL_FILE_HEADER);
archive_le16enc(&h.version, ZIP_VERSION_EXTRACT);
archive_le16enc(&h.flags, l->flags);
- archive_le16enc(&h.compression, zip->compression);
+ archive_le16enc(&h.compression, l->compression);
archive_le32enc(&h.timedate, dos_time(archive_entry_mtime(entry)));
archive_le16enc(&h.filename_length, (uint16_t)path_length(l->entry));
- switch (zip->compression) {
+ switch (l->compression) {
case COMPRESSION_STORE:
- /* Setting compressed and uncompressed sizes even when specification says
- * to set to zero when using data descriptors. Otherwise the end of the
- * data for an entry is rather difficult to find. */
+ /* Setting compressed and uncompressed sizes even when
+ * specification says to set to zero when using data
+ * descriptors. Otherwise the end of the data for an
+ * entry is rather difficult to find. */
archive_le32enc(&h.compressed_size, size);
archive_le32enc(&h.uncompressed_size, size);
break;
@@ -448,8 +466,8 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
zip->stream.opaque = Z_NULL;
zip->stream.next_out = zip->buf;
zip->stream.avail_out = zip->len_buf;
- if (deflateInit2(&zip->stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
- -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ if (deflateInit2(&zip->stream, Z_DEFAULT_COMPRESSION,
+ Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
archive_set_error(&a->archive, ENOMEM,
"Can't init deflate compressor");
return (ARCHIVE_FATAL);
@@ -495,6 +513,17 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(e);
+ if (type == AE_IFLNK) {
+ const unsigned char *p;
+
+ p = (const unsigned char *)archive_entry_symlink(l->entry);
+ ret = __archive_write_output(a, p, size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += size;
+ l->crc32 = crc32(l->crc32, p, size);
+ }
+
if (ret2 != ARCHIVE_OK)
return (ret2);
return (ARCHIVE_OK);
@@ -512,7 +541,7 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
if (s == 0) return 0;
- switch (zip->compression) {
+ switch (l->compression) {
case COMPRESSION_STORE:
ret = __archive_write_output(a, buff, s);
if (ret != ARCHIVE_OK) return (ret);
@@ -530,7 +559,8 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
if (ret == Z_STREAM_ERROR)
return (ARCHIVE_FATAL);
if (zip->stream.avail_out == 0) {
- ret = __archive_write_output(a, zip->buf, zip->len_buf);
+ ret = __archive_write_output(a, zip->buf,
+ zip->len_buf);
if (ret != ARCHIVE_OK)
return (ret);
l->compressed_size += zip->len_buf;
@@ -564,7 +594,7 @@ archive_write_zip_finish_entry(struct archive_write *a)
size_t reminder;
#endif
- switch(zip->compression) {
+ switch(l->compression) {
case COMPRESSION_STORE:
break;
#if HAVE_ZLIB_H
@@ -614,7 +644,8 @@ archive_write_zip_close(struct archive_write *a)
l = zip->central_directory;
/*
- * Formatting central directory file header fields that are fixed for all entries.
+ * Formatting central directory file header fields that are
+ * fixed for all entries.
* Fields not used (and therefor 0) are:
*
* - comment_length
@@ -634,18 +665,23 @@ archive_write_zip_close(struct archive_write *a)
while (l != NULL) {
archive_le16enc(&h.flags, l->flags);
archive_le16enc(&h.compression, l->compression);
- archive_le32enc(&h.timedate, dos_time(archive_entry_mtime(l->entry)));
+ archive_le32enc(&h.timedate,
+ dos_time(archive_entry_mtime(l->entry)));
archive_le32enc(&h.crc32, l->crc32);
archive_le32enc(&h.compressed_size, l->compressed_size);
- archive_le32enc(&h.uncompressed_size, archive_entry_size(l->entry));
- archive_le16enc(&h.filename_length, (uint16_t)path_length(l->entry));
+ archive_le32enc(&h.uncompressed_size,
+ archive_entry_size(l->entry));
+ archive_le16enc(&h.filename_length,
+ (uint16_t)path_length(l->entry));
archive_le16enc(&h.extra_length, sizeof(e));
- archive_le16enc(&h.attributes_external[2], archive_entry_mode(l->entry));
+ archive_le16enc(&h.attributes_external[2],
+ archive_entry_mode(l->entry));
archive_le32enc(&h.offset, l->offset);
/* Formatting extra data. */
archive_le16enc(&e.time_id, ZIP_SIGNATURE_EXTRA_TIMESTAMP);
- archive_le16enc(&e.time_size, sizeof(e.mtime) + sizeof(e.time_flag));
+ archive_le16enc(&e.time_size,
+ sizeof(e.mtime) + sizeof(e.time_flag));
e.time_flag[0] = 0x07;
archive_le32enc(&e.mtime, archive_entry_mtime(l->entry));
archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_NEW_UNIX);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
index 7e5cf21..9a8ea3d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
.\"
.Dd Feb 27, 2010
-.Dt archive_write_options 3
+.Dt ARCHIVE_WRITE_OPTIONS 3
.Os
.Sh NAME
.Nm archive_write_set_filter_option ,
diff --git a/Utilities/cmlibarchive/libarchive/cpio.5 b/Utilities/cmlibarchive/libarchive/cpio.5
index f544628..13a4445 100644
--- a/Utilities/cmlibarchive/libarchive/cpio.5
+++ b/Utilities/cmlibarchive/libarchive/cpio.5
@@ -268,31 +268,6 @@ data, including ACLs and extended attributes, as special
entries in cpio archives.
.Pp
XXX Others? XXX
-.Sh BUGS
-The
-.Dq CRC
-format is mis-named, as it uses a simple checksum and
-not a cyclic redundancy check.
-.Pp
-The old binary format is limited to 16 bits for user id,
-group id, device, and inode numbers.
-It is limited to 4 gigabyte file sizes.
-.Pp
-The old ASCII format is limited to 18 bits for
-the user id, group id, device, and inode numbers.
-It is limited to 8 gigabyte file sizes.
-.Pp
-The new ASCII format is limited to 4 gigabyte file sizes.
-.Pp
-None of the cpio formats store user or group names,
-which are essential when moving files between systems with
-dissimilar user or group numbering.
-.Pp
-Especially when writing older cpio variants, it may be necessary
-to map actual device/inode values to synthesized values that
-fit the available fields.
-With very large filesystems, this may be necessary even for
-the newer formats.
.Sh SEE ALSO
.Xr cpio 1 ,
.Xr tar 5
@@ -323,3 +298,28 @@ license.
The character format was adopted as part of
.St -p1003.1-88 .
XXX when did "newc" appear? Who invented it? When did HP come out with their variant? When did Sun introduce ACLs and extended attributes? XXX
+.Sh BUGS
+The
+.Dq CRC
+format is mis-named, as it uses a simple checksum and
+not a cyclic redundancy check.
+.Pp
+The old binary format is limited to 16 bits for user id,
+group id, device, and inode numbers.
+It is limited to 4 gigabyte file sizes.
+.Pp
+The old ASCII format is limited to 18 bits for
+the user id, group id, device, and inode numbers.
+It is limited to 8 gigabyte file sizes.
+.Pp
+The new ASCII format is limited to 4 gigabyte file sizes.
+.Pp
+None of the cpio formats store user or group names,
+which are essential when moving files between systems with
+dissimilar user or group numbering.
+.Pp
+Especially when writing older cpio variants, it may be necessary
+to map actual device/inode values to synthesized values that
+fit the available fields.
+With very large filesystems, this may be necessary even for
+the newer formats.
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
index 38b7097..272e56c 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
@@ -32,69 +32,73 @@
pid_t
__archive_create_child(const char *path, int *child_stdin, int *child_stdout)
{
- HANDLE childStdout[2], childStdin[2], childStdinWr, childStdoutRd;
+ HANDLE childStdout[2], childStdin[2],childStderr;
SECURITY_ATTRIBUTES secAtts;
STARTUPINFO staInfo;
PROCESS_INFORMATION childInfo;
char cmd[MAX_PATH];
- DWORD mode;
secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
secAtts.bInheritHandle = TRUE;
secAtts.lpSecurityDescriptor = NULL;
if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0)
goto fail;
- if (DuplicateHandle(GetCurrentProcess(), childStdout[0],
- GetCurrentProcess(), &childStdoutRd, 0, FALSE,
- DUPLICATE_SAME_ACCESS) == 0) {
+ if (!SetHandleInformation(childStdout[0], HANDLE_FLAG_INHERIT, 0))
+ {
CloseHandle(childStdout[0]);
CloseHandle(childStdout[1]);
goto fail;
}
- CloseHandle(childStdout[0]);
-
if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0) {
- CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[0]);
CloseHandle(childStdout[1]);
goto fail;
}
-
- if (DuplicateHandle(GetCurrentProcess(), childStdin[1],
- GetCurrentProcess(), &childStdinWr, 0, FALSE,
+ if (!SetHandleInformation(childStdin[1], HANDLE_FLAG_INHERIT, 0))
+ {
+ CloseHandle(childStdout[0]);
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
+ CloseHandle(childStdin[1]);
+ goto fail;
+ }
+ if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
+ GetCurrentProcess(), &childStderr, 0, TRUE,
DUPLICATE_SAME_ACCESS) == 0) {
- CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[0]);
CloseHandle(childStdout[1]);
CloseHandle(childStdin[0]);
CloseHandle(childStdin[1]);
goto fail;
}
- CloseHandle(childStdin[1]);
memset(&staInfo, 0, sizeof(staInfo));
staInfo.cb = sizeof(staInfo);
+ staInfo.hStdError = childStderr;
staInfo.hStdOutput = childStdout[1];
staInfo.hStdInput = childStdin[0];
staInfo.wShowWindow = SW_HIDE;
- staInfo.dwFlags = STARTF_USEFILLATTRIBUTE | STARTF_USECOUNTCHARS |
- STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ staInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
strncpy(cmd, path, sizeof(cmd)-1);
cmd[sizeof(cmd)-1] = '\0';
if (CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL,
&staInfo, &childInfo) == 0) {
- CloseHandle(childStdoutRd);
+ CloseHandle(childStdout[0]);
CloseHandle(childStdout[1]);
CloseHandle(childStdin[0]);
- CloseHandle(childStdinWr);
+ CloseHandle(childStdin[1]);
+ CloseHandle(childStderr);
goto fail;
}
WaitForInputIdle(childInfo.hProcess, INFINITE);
CloseHandle(childInfo.hProcess);
CloseHandle(childInfo.hThread);
- mode = PIPE_NOWAIT;
- SetNamedPipeHandleState(childStdoutRd, &mode, NULL, NULL);
- *child_stdout = _open_osfhandle((intptr_t)childStdoutRd, _O_RDONLY);
- *child_stdin = _open_osfhandle((intptr_t)childStdinWr, _O_WRONLY);
+ *child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
+ *child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
+
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
return (childInfo.dwProcessId);
diff --git a/Utilities/cmlibarchive/libarchive/libarchive-formats.5 b/Utilities/cmlibarchive/libarchive/libarchive-formats.5
index bd6bfe7..d223bf8 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive-formats.5
+++ b/Utilities/cmlibarchive/libarchive/libarchive-formats.5
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/libarchive-formats.5 201077 2009-12-28 01:50:23Z kientzle $
.\"
.Dd December 27, 2009
-.Dt libarchive-formats 5
+.Dt LIBARCHIVE-FORMATS 5
.Os
.Sh NAME
.Nm libarchive-formats
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_changes.3 b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
index 349eab9..6ee6af2 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive_changes.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
@@ -25,7 +25,7 @@
.\" $FreeBSD$
.\"
.Dd March 27, 2011
-.Dt libarchive_changes 3
+.Dt LIBARCHIVE_CHANGES 3
.Os
.Sh NAME
.Nm changes in libarchive interface
diff --git a/Utilities/cmlibarchive/libarchive/tar.5 b/Utilities/cmlibarchive/libarchive/tar.5
index e55999b..65875bd 100644
--- a/Utilities/cmlibarchive/libarchive/tar.5
+++ b/Utilities/cmlibarchive/libarchive/tar.5
@@ -25,7 +25,7 @@
.\" $FreeBSD: head/lib/libarchive/tar.5 201077 2009-12-28 01:50:23Z kientzle $
.\"
.Dd December 27, 2009
-.Dt tar 5
+.Dt TAR 5
.Os
.Sh NAME
.Nm tar