mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-29 04:09:35 +03:00
libarchive 3.0.2-r4051 (reduced)
Extract upstream libarchive using the following shell code. url=https://libarchive.googlecode.com/svn/release/3.0 v=3.0.2 r=4051 paths=" CMakeLists.txt COPYING CTestConfig.cmake build/cmake build/pkgconfig build/utils build/version libarchive/*.* " date=$(svn log -q -c$r $url | sed -n "/^r/ {s/[^|]*|[^|]*|//;p;}") svn export -r$r $url libarchive-$v-r$r && mkdir libarchive-$v-r$r-reduced && (cd libarchive-$v-r$r && tar c $paths) | (cd libarchive-$v-r$r-reduced && tar x) echo "r$r date: $date"
This commit is contained in:
committed by
Brad King
parent
2f4a3792bb
commit
4f4fe6e50b
+8
-11
@@ -2,12 +2,12 @@
|
||||
#
|
||||
PROJECT(libarchive C)
|
||||
#
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
|
||||
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
|
||||
endif()
|
||||
SET(CMAKE_BUILD_TYPE "Debug")
|
||||
SET(CMAKE_BUILD_TYPE "Release")
|
||||
|
||||
# On MacOS, prefer MacPorts libraries to system libraries.
|
||||
# I haven't come up with a compelling argument for this to be conditional.
|
||||
@@ -38,9 +38,10 @@ SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
|
||||
# INTERFACE_VERSION increments with every release
|
||||
# libarchive 2.7 == interface version 9 = 2 + 7
|
||||
# libarchive 2.8 == interface version 10 = 2 + 8
|
||||
# libarchive 3.0 == interface version 11
|
||||
# libarchive 3.x == interface version 11 + x
|
||||
math(EXPR INTERFACE_VERSION "11 + ${_minor}")
|
||||
# libarchive 2.9 == interface version 11 = 2 + 9
|
||||
# libarchive 3.0 == interface version 12
|
||||
# libarchive 3.x == interface version 12 + x
|
||||
math(EXPR INTERFACE_VERSION "12 + ${_minor}")
|
||||
|
||||
# Set SOVERSION == Interface version
|
||||
# ?? Should there be more here ??
|
||||
@@ -50,17 +51,13 @@ SET(SOVERSION "${INTERFACE_VERSION}")
|
||||
# aggressive about diagnosing build problems; this can get
|
||||
# relaxed somewhat in final shipping versions.
|
||||
IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
|
||||
ADD_DEFINITIONS(-Wall -Werror)
|
||||
SET(CMAKE_REQUIRED_FLAGS "-Wall -Werror")
|
||||
ADD_DEFINITIONS(-Wall)
|
||||
SET(CMAKE_REQUIRED_FLAGS "-Wall")
|
||||
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
|
||||
|
||||
# Enable CTest/CDash support
|
||||
include(CTest)
|
||||
|
||||
# Provide ADD_TEST_28 macro to approximate CMake 2.8 ADD_TEST(NAME).
|
||||
# TODO: Require CMake 2.8 and drop this workaround (perhaps late 2010).
|
||||
INCLUDE(AddTest28)
|
||||
|
||||
OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
|
||||
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
|
||||
OPTION(ENABLE_TAR "Enable tar building" ON)
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
# - Macro approximating the CMake 2.8 ADD_TEST(NAME) signature.
|
||||
# ADD_TEST_28(NAME <name> COMMAND <command> [arg1 [arg2 ...]])
|
||||
# <name> - The name of the test
|
||||
# <command> - The test executable
|
||||
# [argN...] - Arguments to the test executable
|
||||
# This macro approximates the ADD_TEST(NAME) signature provided in
|
||||
# CMake 2.8 but works with CMake 2.6 too. See CMake 2.8 documentation
|
||||
# of ADD_TEST()for details.
|
||||
#
|
||||
# This macro automatically replaces a <command> that names an
|
||||
# executable target with the target location. A generator expression
|
||||
# of the form "$<TARGET_FILE:tgt>" is supported in both the command
|
||||
# and arguments of the test. Howerver, this macro only works for
|
||||
# targets without per-config output name properties set.
|
||||
#
|
||||
# Example usage:
|
||||
# add_test(NAME mytest COMMAND testDriver --exe $<TARGET_FILE:myexe>)
|
||||
# This creates a test "mytest" whose command runs a testDriver tool
|
||||
# passing the full path to the executable file produced by target
|
||||
# "myexe".
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer
|
||||
# in this position and unchanged.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#=============================================================================
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3)
|
||||
|
||||
# CMake 2.8 supports ADD_TEST(NAME) natively.
|
||||
IF(NOT "${CMAKE_VERSION}" VERSION_LESS "2.8")
|
||||
MACRO(ADD_TEST_28)
|
||||
ADD_TEST(${ARGV})
|
||||
ENDMACRO()
|
||||
RETURN()
|
||||
ENDIF()
|
||||
|
||||
# Simulate ADD_TEST(NAME) signature from CMake 2.8.
|
||||
MACRO(ADD_TEST_28 NAME name COMMAND command)
|
||||
# Enforce the signature.
|
||||
IF(NOT "x${NAME}" STREQUAL "xNAME")
|
||||
MESSAGE(FATAL_ERROR "First ADD_TEST_28 argument must be \"NAME\"")
|
||||
ENDIF()
|
||||
IF(NOT "x${COMMAND}" STREQUAL "xCOMMAND")
|
||||
MESSAGE(FATAL_ERROR "Third ADD_TEST_28 argument must be \"COMMAND\"")
|
||||
ENDIF()
|
||||
|
||||
# Perform "COMMAND myexe ..." substitution.
|
||||
SET(cmd "${command}")
|
||||
IF(TARGET "${cmd}")
|
||||
_ADD_TEST_28_GET_EXE(${cmd} cmd)
|
||||
ENDIF()
|
||||
|
||||
# Perform "COMMAND ... $<TARGET_FILE:myexe> ..." substitution.
|
||||
SET(target_file "\\$<TARGET_FILE:(.+)>")
|
||||
SET(args)
|
||||
FOREACH(ARG ${cmd} ${ARGN})
|
||||
SET(arg "${ARG}")
|
||||
IF("${arg}" MATCHES "${target_file}")
|
||||
STRING(REGEX REPLACE "${target_file}" "\\1" tgt "${arg}")
|
||||
IF(TARGET "${tgt}")
|
||||
_ADD_TEST_28_GET_EXE(${tgt} exe)
|
||||
STRING(REGEX REPLACE "${target_file}" "${exe}" arg "${arg}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
LIST(APPEND args "${arg}")
|
||||
ENDFOREACH()
|
||||
|
||||
# Invoke old ADD_TEST() signature with transformed arguments.
|
||||
ADD_TEST(${name} ${args})
|
||||
ENDMACRO()
|
||||
|
||||
# Get the test-time location of an executable target.
|
||||
MACRO(_ADD_TEST_28_GET_EXE tgt exe_var)
|
||||
# The LOCATION property gives a build-time location.
|
||||
GET_TARGET_PROPERTY(${exe_var} ${tgt} LOCATION)
|
||||
|
||||
# In single-configuration generatrs the build-time and test-time
|
||||
# locations are the same because there is no per-config variable
|
||||
# reference. In multi-configuration generators the following
|
||||
# substitution converts the build-time configuration variable
|
||||
# reference to a test-time configuration variable reference.
|
||||
IF(CMAKE_CONFIGURATION_TYPES)
|
||||
STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CTEST_CONFIGURATION_TYPE}"
|
||||
${exe_var} "${${exe_var}}")
|
||||
ENDIF(CMAKE_CONFIGURATION_TYPES)
|
||||
ENDMACRO()
|
||||
+1
-1
@@ -1 +1 @@
|
||||
3000001b
|
||||
3000002
|
||||
|
||||
+3
-16
@@ -124,27 +124,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. */
|
||||
@@ -447,8 +436,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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -246,7 +246,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
return (r);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) && defined(HAVE_COPYFILE_H)
|
||||
/*
|
||||
* The Mac OS "copyfile()" API copies the extended metadata for a
|
||||
* file into a separate file in AppleDouble format (see RFC 1740).
|
||||
|
||||
@@ -1321,9 +1321,11 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
t->current_filesystem->synthetic = 0;
|
||||
#endif
|
||||
|
||||
#if defined(MNT_NOATIME)
|
||||
if (sfs.f_flags & MNT_NOATIME)
|
||||
t->current_filesystem->noatime = 1;
|
||||
else
|
||||
#endif
|
||||
t->current_filesystem->noatime = 0;
|
||||
|
||||
#if defined(HAVE_READDIR_R)
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 *,
|
||||
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_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 *,
|
||||
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);
|
||||
return (p - _p);
|
||||
if (*p != kEnd)
|
||||
return (-1);
|
||||
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);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/* Get an uncompressed header size. */
|
||||
vsize = (size_t)zip->folder_outbytes_remaining;
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
if (zip->header_bytes_remaining < rbytes)
|
||||
return (NULL);
|
||||
if (zip->pack_stream_bytes_unconsumed)
|
||||
read_consume(a);
|
||||
|
||||
/* Get the bytes we can read to decode the header. */
|
||||
zip->pack_stream_inbytes_remaining = si->pi.sizes[0];
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+30
-21
@@ -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) {
|
||||
/*
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -135,6 +135,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);
|
||||
@@ -229,27 +234,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);
|
||||
}
|
||||
|
||||
/* This can exceed MAX_PATH limitation. */
|
||||
int
|
||||
__la_open(const char *path, int flags, ...)
|
||||
@@ -368,22 +352,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) {
|
||||
|
||||
@@ -90,7 +90,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
|
||||
@@ -243,7 +243,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);
|
||||
extern int __la_open(const char *path, int flags, ...);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ,
|
||||
|
||||
+25
-25
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user