Merge topic 'update-libarchive'

d83c9ff24a Utilities: Update hard-coded try_compile results for libarchive 3.7.2
0ff572370f libarchive: Set build options the way we need for CMake
b281fd471a libarchive: Add cm3p prefixes on includes new to version 3.7.2
c4fec0edd6 Merge branch 'upstream-LibArchive' into update-libarchive
939e164ee5 LibArchive 2023-09-12 (6468cd1f)
1cc25f22ff libarchive: Update script to get 3.7.2

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !8890
This commit is contained in:
Brad King
2023-10-17 14:23:38 +00:00
committed by Kitware Robot
58 changed files with 1353 additions and 439 deletions
+2
View File
@@ -287,6 +287,8 @@ else()
set(ENABLE_CPIO_SHARED OFF)
set(ENABLE_CAT OFF)
set(ENABLE_CAT_SHARED OFF)
set(ENABLE_UNZIP OFF)
set(ENABLE_UNZIP_SHARED OFF)
set(ENABLE_XATTR OFF)
set(ENABLE_ACL OFF)
set(ENABLE_ICONV OFF)
+1 -1
View File
@@ -8,7 +8,7 @@ readonly name="LibArchive"
readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
readonly subtree="Utilities/cmlibarchive"
readonly repo="https://github.com/libarchive/libarchive.git"
readonly tag="v3.6.2"
readonly tag="v3.7.2"
readonly shortlog=false
readonly paths="
CMakeLists.txt
+8 -4
View File
@@ -43,8 +43,8 @@ if(WIN32)
set(HAVE_CHROOT 0)
set(HAVE_COPYFILE_H 0)
set(HAVE_CRYPTO_H 0)
set(HAVE__CTIME64_S 1)
set(HAVE_CTIME_R 0)
set(HAVE_CTIME_S 1)
set(HAVE_CYGWIN_CONV_PATH 0)
set(HAVE_DES_H 0)
set(HAVE_DIRECT_H 1)
@@ -64,6 +64,8 @@ if(WIN32)
set(HAVE_FCNTL_H 1)
set(HAVE_FCNTL_O_NONBLOCK 0)
set(HAVE_FDOPENDIR 0)
set(HAVE_FNMATCH 0)
set(HAVE_FNMATCH_H 0)
set(HAVE_FORK 0)
set(HAVE_FREEADDRINFO 1)
set(HAVE_FREEIFADDRS 0)
@@ -82,6 +84,7 @@ if(WIN32)
set(HAVE_GETGRGID_R 0)
set(HAVE_GETGRNAM_R 0)
set(HAVE_GETHOSTBYNAME 1)
set(HAVE_GETLINE 0)
set(HAVE_GETPAGESIZE 0)
set(HAVE_GETPEERNAME 1)
set(HAVE_GETPID 1)
@@ -94,8 +97,8 @@ if(WIN32)
set(HAVE_GETSOCKNAME 1)
set(HAVE_GETVFSBYNAME 0)
set(HAVE_GLIBC_STRERROR_R 0)
set(HAVE__GMTIME64_S 1)
set(HAVE_GMTIME_R 0)
set(HAVE_GMTIME_S 1)
set(HAVE_GRP_H 0)
set(HAVE_IDN2_H 0)
set(HAVE_IFADDRS_H 0)
@@ -126,8 +129,8 @@ if(WIN32)
set(HAVE_LINUX_FS_H 0)
set(HAVE_LINUX_MAGIC_H 0)
set(HAVE_LINUX_TYPES_H 0)
set(HAVE__LOCALTIME64_S 1)
set(HAVE_LOCALTIME_R 0)
set(HAVE_LOCALTIME_S 0)
set(HAVE_LSTAT 0)
set(HAVE_LUTIMES 0)
set(HAVE_MACH_ABSOLUTE_TIME 0)
@@ -136,7 +139,7 @@ if(WIN32)
set(HAVE_MEMORY_H 1)
set(HAVE_MKDIR 1)
set(HAVE_MKFIFO 0)
set(HAVE__MKGMTIME64 1)
set(HAVE__MKGMTIME 1)
set(HAVE_MKNOD 0)
set(HAVE_MMAP 0)
set(HAVE_MSG_NOSIGNAL 0)
@@ -216,6 +219,7 @@ if(WIN32)
set(HAVE_SYS_MKDEV_H 0)
set(HAVE_SYS_MOUNT_H 0)
set(HAVE_SYS_POLL_H 0)
set(HAVE_SYS_QUEUE_H 0)
set(HAVE_SYS_RESOURCE_H 0)
set(HAVE_SYS_RICHACL_H 0)
set(HAVE_SYS_SELECT_H 0)
+38 -24
View File
@@ -69,6 +69,7 @@ SET(VERSION "${_major}.${_trimmed_minor}.${_trimmed_revision}
SET(BSDCPIO_VERSION_STRING "${VERSION}")
SET(BSDTAR_VERSION_STRING "${VERSION}")
SET(BSDCAT_VERSION_STRING "${VERSION}")
SET(BSDUNZIP_VERSION_STRING "${VERSION}")
SET(LIBARCHIVE_VERSION_NUMBER "${_version_number}")
SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
@@ -224,6 +225,8 @@ ENDIF()
# Enable CTest/CDash support
include(CTest)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" OFF)
OPTION(ENABLE_NETTLE "Enable use of Nettle" OFF)
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
@@ -248,6 +251,13 @@ OPTION(ENABLE_CPIO "Enable cpio building" ON)
OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
OPTION(ENABLE_CAT "Enable cat building" ON)
OPTION(ENABLE_CAT_SHARED "Enable dynamic build of cat" FALSE)
IF(WIN32 AND NOT CYGWIN)
SET(ENABLE_UNZIP FALSE)
SET(ENABLE_UNZIP_SHARED FALSE)
ELSE()
OPTION(ENABLE_UNZIP "Enable unzip building" ON)
OPTION(ENABLE_UNZIP_SHARED "Enable dynamic build of unzip" FALSE)
ENDIF()
OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
OPTION(ENABLE_ACL "Enable ACL support" ON)
OPTION(ENABLE_ICONV "Enable iconv support" ON)
@@ -324,6 +334,7 @@ ENDIF()
IF(MINGW)
ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO)
ADD_DEFINITIONS(-D__MINGW_USE_VC2005_COMPAT)
ENDIF()
#
@@ -394,7 +405,11 @@ MACRO (TRY_MACRO_FOR_LIBRARY INCLUDES LIBRARIES
IF("${TRY_TYPE}" MATCHES "COMPILES")
CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
IF(CMAKE_CROSSCOMPILING)
MESSAGE(WARNING "Cannot test run \"${VAR}\" when cross-compiling")
ELSE(CMAKE_CROSSCOMPILING)
CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
ENDIF(CMAKE_CROSSCOMPILING)
ELSE("${TRY_TYPE}" MATCHES "COMPILES")
MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
@@ -533,15 +548,19 @@ IF(LIBLZMA_FOUND)
COMPILES
"#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
"WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
CHECK_C_SOURCE_COMPILES(
"#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
HAVE_LZMA_STREAM_ENCODER_MT)
IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
ADD_DEFINITIONS(-DLZMA_API_STATIC)
ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
ENDIF()
ELSE()
ADD_DEFINITIONS(-DLZMA_API_STATIC)
ENDIF()
CMAKE_POP_CHECK_STATE()
ELSE(LIBLZMA_FOUND)
# LZMA not found and will not be used.
SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
ENDIF(LIBLZMA_FOUND)
#
# Find LZO2
@@ -590,6 +609,7 @@ IF(LIBB2_FOUND)
SET(HAVE_BLAKE2_H 1)
SET(ARCHIVE_BLAKE2 FALSE)
LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY})
INCLUDE_DIRECTORIES(${LIBB2_INCLUDE_DIR})
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY})
SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR})
@@ -708,6 +728,7 @@ CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
LA_CHECK_INCLUDE_FILE("fnmatch.h" HAVE_FNMATCH_H)
LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
@@ -745,6 +766,7 @@ LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
LA_CHECK_INCLUDE_FILE("sys/queue.h" HAVE_SYS_QUEUE_H)
LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
@@ -764,9 +786,9 @@ LA_CHECK_INCLUDE_FILE("wchar.h" HAVE_WCHAR_H)
LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
IF(ENABLE_CNG)
LA_CHECK_INCLUDE_FILE("Bcrypt.h" HAVE_BCRYPT_H)
LA_CHECK_INCLUDE_FILE("bcrypt.h" HAVE_BCRYPT_H)
IF(HAVE_BCRYPT_H)
LIST(APPEND ADDITIONAL_LIBS "Bcrypt")
LIST(APPEND ADDITIONAL_LIBS "bcrypt")
ENDIF(HAVE_BCRYPT_H)
ELSE(ENABLE_CNG)
UNSET(HAVE_BCRYPT_H CACHE)
@@ -842,6 +864,10 @@ IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
IF(OPENSSL_FOUND)
SET(HAVE_LIBCRYPTO 1)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
LA_CHECK_INCLUDE_FILE("openssl/evp.h" HAVE_OPENSSL_EVP_H)
CHECK_FUNCTION_EXISTS(PKCS5_PBKDF2_HMAC_SHA1 HAVE_PKCS5_PBKDF2_HMAC_SHA1)
ENDIF(OPENSSL_FOUND)
ELSE()
SET(OPENSSL_FOUND FALSE) # Override cached value
@@ -1379,6 +1405,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD)
CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL)
CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR)
CHECK_FUNCTION_EXISTS_GLIBC(fnmatch HAVE_FNMATCH)
CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK)
CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT)
CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT)
@@ -1391,6 +1418,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE)
CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
@@ -1443,12 +1471,12 @@ CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
CHECK_FUNCTION_EXISTS_GLIBC(_gmtime64_s HAVE__GMTIME64_S)
CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
CHECK_SYMBOL_EXISTS(ctime_s "time.h" HAVE_CTIME_S)
CHECK_SYMBOL_EXISTS(gmtime_s "time.h" HAVE_GMTIME_S)
CHECK_SYMBOL_EXISTS(localtime_s "time.h" HAVE_LOCALTIME_S)
CHECK_SYMBOL_EXISTS(_mkgmtime "time.h" HAVE__MKGMTIME)
SET(CMAKE_REQUIRED_LIBRARIES "")
CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
@@ -1491,7 +1519,6 @@ CHECK_C_SOURCE_COMPILES(
"#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
HAVE_READLINKAT)
# To verify major(), we need to both include the header
# of interest and verify that the result can be linked.
# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
@@ -1503,20 +1530,6 @@ CHECK_C_SOURCE_COMPILES(
"#include <sys/sysmacros.h>\nint main() { return major(256); }"
MAJOR_IN_SYSMACROS)
IF(ENABLE_LZMA)
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
CHECK_C_SOURCE_COMPILES(
"#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
HAVE_LZMA_STREAM_ENCODER_MT)
CMAKE_POP_CHECK_STATE()
ELSE()
SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
ENDIF(ENABLE_LZMA)
IF(HAVE_STRERROR_R)
SET(HAVE_DECL_STRERROR_R 1)
ENDIF(HAVE_STRERROR_R)
@@ -1578,7 +1591,7 @@ ENDIF()
#
#
CHECK_STRUCT_HAS_MEMBER("struct tm" tm_sec
"sys/types.h;sys/time.h;time.h" TIME_WITH_SYS_TIME)
"sys/types.h;sys/time.h;time.h" HAVE_SYS_TIME_H)
CHECK_TYPE_SIZE(dev_t DEV_T)
IF(NOT HAVE_DEV_T)
@@ -2076,6 +2089,7 @@ IF(0) # CMake does not build libarchive's command-line tools.
add_subdirectory(cat)
add_subdirectory(tar)
add_subdirectory(cpio)
add_subdirectory(unzip)
ENDIF()
install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibarchive)
@@ -7,7 +7,7 @@ find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
find_package_handle_standard_args(MbedTLS DEFAULT_MSG
MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
+60 -9
View File
@@ -38,6 +38,9 @@
/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
/* MD5 via ARCHIVE_CRYPTO_MD5_MBEDTLS supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_MBEDTLS 1
/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1
@@ -53,6 +56,9 @@
/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1
/* RMD160 via ARCHIVE_CRYPTO_RMD160_MBEDTLS supported. */
#cmakedefine ARCHIVE_CRYPTO_RMD160_MBEDTLS 1
/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
#cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1
@@ -62,6 +68,9 @@
/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
/* SHA1 via ARCHIVE_CRYPTO_SHA1_MBEDTLS supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA1_MBEDTLS 1
/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1
@@ -83,6 +92,9 @@
/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
/* SHA256 via ARCHIVE_CRYPTO_SHA256_MBEDTLS supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_MBEDTLS 1
/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1
@@ -104,6 +116,9 @@
/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
/* SHA384 via ARCHIVE_CRYPTO_SHA384_MBEDTLS supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_MBEDTLS 1
/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1
@@ -125,6 +140,9 @@
/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
/* SHA512 via ARCHIVE_CRYPTO_SHA512_MBEDTLS supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_MBEDTLS 1
/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1
@@ -155,6 +173,9 @@
/* Version number of bsdcat */
#cmakedefine BSDCAT_VERSION_STRING "@BSDCAT_VERSION_STRING@"
/* Version number of bsdunzip */
#cmakedefine BSDUNZIP_VERSION_STRING "@BSDUNZIP_VERSION_STRING@"
/* Define to 1 if you have the `acl_create_entry' function. */
#cmakedefine HAVE_ACL_CREATE_ENTRY 1
@@ -197,7 +218,7 @@
/* Define to 1 if you have the <attr/xattr.h> header file. */
#cmakedefine HAVE_ATTR_XATTR_H 1
/* Define to 1 if you have the <Bcrypt.h> header file. */
/* Define to 1 if you have the <bcrypt.h> header file. */
#cmakedefine HAVE_BCRYPT_H 1
/* Define to 1 if you have the <bsdxml.h> header file. */
@@ -357,6 +378,12 @@
/* Define to 1 if you have the `flistxattr' function. */
#cmakedefine HAVE_FLISTXATTR 1
/* Define to 1 if you have the `fnmatch' function. */
#cmakedefine HAVE_FNMATCH 1
/* Define to 1 if you have the <fnmatch.h> header file. */
#cmakedefine HAVE_FNMATCH_H 1
/* Define to 1 if you have the `fork' function. */
#cmakedefine HAVE_FORK 1
@@ -405,6 +432,9 @@
/* Define to 1 if you have the `getgrnam_r' function. */
#cmakedefine HAVE_GETGRNAM_R 1
/* Define to 1 if you have the `getline' function. */
#cmakedefine HAVE_GETLINE 1
/* Define to 1 if you have the `getpid' function. */
#cmakedefine HAVE_GETPID 1
@@ -611,6 +641,15 @@
/* Define to 1 if you have the <lzo/lzoconf.h> header file. */
#cmakedefine HAVE_LZO_LZOCONF_H 1
/* Define to 1 if you have the <mbedtls/aes.h> header file. */
#cmakedefine HAVE_MBEDTLS_AES_H 1
/* Define to 1 if you have the <mbedtls/md.h> header file. */
#cmakedefine HAVE_MBEDTLS_MD_H 1
/* Define to 1 if you have the <mbedtls/pkcs5.h> header file. */
#cmakedefine HAVE_MBEDTLS_PKCS5_H 1
/* Define to 1 if you have the `mbrtowc' function. */
#cmakedefine HAVE_MBRTOWC 1
@@ -662,6 +701,9 @@
/* Define to 1 if you have the `openat' function. */
#cmakedefine HAVE_OPENAT 1
/* Define to 1 if you have the <openssl/evp.h> header file. */
#cmakedefine HAVE_OPENSSL_EVP_H 1
/* Define to 1 if you have the <paths.h> header file. */
#cmakedefine HAVE_PATHS_H 1
@@ -771,6 +813,12 @@
/* Define to 1 if you have the `strrchr' function. */
#cmakedefine HAVE_STRRCHR 1
/* Define to 1 if the system has the type `struct statfs'. */
#cmakedefine HAVE_STRUCT_STATFS 1
/* Define to 1 if `f_iosize' is a member of `struct statfs'. */
#cmakedefine HAVE_STRUCT_STATFS_F_IOSIZE 1
/* Define to 1 if `f_namemax' is a member of `struct statfs'. */
#cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
@@ -854,6 +902,9 @@
/* Define to 1 if you have the <sys/poll.h> header file. */
#cmakedefine HAVE_SYS_POLL_H 1
/* Define to 1 if you have the <sys/queue.h> header file. */
#cmakedefine HAVE_SYS_QUEUE_H 1
/* Define to 1 if you have the <sys/richacl.h> header file. */
#cmakedefine HAVE_SYS_RICHACL_H 1
@@ -993,8 +1044,8 @@
/* Define to 1 if you have the <zstd.h> header file. */
#cmakedefine HAVE_ZSTD_H 1
/* Define to 1 if you have the `_ctime64_s' function. */
#cmakedefine HAVE__CTIME64_S 1
/* Define to 1 if you have the `ctime_s' function. */
#cmakedefine HAVE_CTIME_S 1
/* Define to 1 if you have the `_fseeki64' function. */
#cmakedefine HAVE__FSEEKI64 1
@@ -1002,14 +1053,14 @@
/* Define to 1 if you have the `_get_timezone' function. */
#cmakedefine HAVE__GET_TIMEZONE 1
/* Define to 1 if you have the `_gmtime64_s' function. */
#cmakedefine HAVE__GMTIME64_S 1
/* Define to 1 if you have the `gmtime_s' function. */
#cmakedefine HAVE_GMTIME_S 1
/* Define to 1 if you have the `_localtime64_s' function. */
#cmakedefine HAVE__LOCALTIME64_S 1
/* Define to 1 if you have the `localtime_s' function. */
#cmakedefine HAVE_LOCALTIME_S 1
/* Define to 1 if you have the `_mkgmtime64' function. */
#cmakedefine HAVE__MKGMTIME64 1
/* Define to 1 if you have the `_mkgmtime' function. */
#cmakedefine HAVE__MKGMTIME 1
/* Define as const if the declaration of iconv() needs const. */
#define ICONV_CONST @ICONV_CONST@
+1 -1
View File
@@ -1 +1 @@
3006002
3007002
@@ -252,10 +252,12 @@ endif()
IF(0) # CMake does not build libarchive's full package.
# Libarchive is a shared library
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
IF(BUILD_SHARED_LIBS)
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
ENDIF(BUILD_SHARED_LIBS)
# archive_static is a static library
ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
@@ -263,13 +265,19 @@ TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
# On Posix systems, libarchive.so and libarchive.a can co-exist.
IF(NOT WIN32 OR CYGWIN)
IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
ENDIF(NOT WIN32 OR CYGWIN)
ENDIF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
IF(ENABLE_INSTALL)
# How to install the libraries
INSTALL(TARGETS archive archive_static
IF(BUILD_SHARED_LIBS)
INSTALL(TARGETS archive
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
ENDIF(BUILD_SHARED_LIBS)
INSTALL(TARGETS archive_static
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
+2 -2
View File
@@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3006002
#define ARCHIVE_VERSION_NUMBER 3007002
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -154,7 +154,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.6.2"
#define ARCHIVE_VERSION_ONLY_STRING "3.7.2"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@@ -36,6 +36,11 @@
#error Cannot use both OpenSSL and libmd.
#endif
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
/*
* Message digest functions for Windows platform.
*/
@@ -48,6 +53,26 @@
/*
* Initialize a Message digest.
*/
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
static int
win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
{
NTSTATUS status;
ctx->valid = 0;
status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0);
if (!BCRYPT_SUCCESS(status))
return (ARCHIVE_FAILED);
status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0);
if (!BCRYPT_SUCCESS(status)) {
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
return (ARCHIVE_FAILED);
}
ctx->valid = 1;
return (ARCHIVE_OK);
}
#else
static int
win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
{
@@ -70,6 +95,7 @@ win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
ctx->valid = 1;
return (ARCHIVE_OK);
}
#endif
/*
* Update a Message digest.
@@ -81,23 +107,37 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
if (!ctx->valid)
return (ARCHIVE_FAILED);
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCryptHashData(ctx->hHash,
(PUCHAR)(uintptr_t)buf,
(ULONG)len, 0);
#else
CryptHashData(ctx->hash,
(unsigned char *)(uintptr_t)buf,
(DWORD)len, 0);
#endif
return (ARCHIVE_OK);
}
static int
win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
{
#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
DWORD siglen = (DWORD)bufsize;
#endif
if (!ctx->valid)
return (ARCHIVE_FAILED);
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
BCryptDestroyHash(ctx->hHash);
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
#else
CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
CryptDestroyHash(ctx->hash);
CryptReleaseContext(ctx->cryptProv, 0);
#endif
ctx->valid = 0;
return (ARCHIVE_OK);
}
@@ -276,7 +316,11 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
static int
__archive_md5init(archive_md5_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
#endif
}
static int
@@ -659,7 +703,11 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
static int
__archive_sha1init(archive_sha1_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
#endif
}
static int
@@ -919,7 +967,11 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
static int
__archive_sha256init(archive_sha256_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
#endif
}
static int
@@ -1155,7 +1207,11 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
static int
__archive_sha384init(archive_sha384_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
#endif
}
static int
@@ -1415,7 +1471,11 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
static int
__archive_sha512init(archive_sha512_ctx *ctx)
{
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
#else
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
#endif
}
static int
@@ -164,6 +164,15 @@
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
/* don't use bcrypt when XP needs to be supported */
#include <bcrypt.h>
typedef struct {
int valid;
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
} Digest_CTX;
#else
#include <windows.h>
#include <wincrypt.h>
typedef struct {
@@ -172,6 +181,7 @@ typedef struct {
HCRYPTHASH hash;
} Digest_CTX;
#endif
#endif
/* typedefs */
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
@@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3006002
#define ARCHIVE_VERSION_NUMBER 3007002
/*
* Note: archive_entry.h is for use outside of libarchive; the
@@ -700,13 +700,9 @@ Convert(time_t Month, time_t Day, time_t Year,
time_t Julian;
int i;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (Year < 69)
Year += 2000;
@@ -733,15 +729,10 @@ Convert(time_t Month, time_t Day, time_t Year,
Julian *= DAY;
Julian += Timezone;
Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Julian, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Julian;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Julian);
#endif
@@ -757,36 +748,21 @@ DSTcorrect(time_t Start, time_t Future)
time_t StartDay;
time_t FutureDay;
struct tm *ltime;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Start, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Start;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Start);
#endif
StartDay = (ltime->tm_hour + 1) % 24;
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
ltime = localtime_r(&Future, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Future;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
ltime = NULL;
else
ltime = &tmbuf;
#else
ltime = localtime(&Future);
#endif
@@ -801,24 +777,15 @@ RelativeDate(time_t Start, time_t zone, int dstmode,
{
struct tm *tm;
time_t t, now;
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
t = Start - zone;
#if defined(HAVE_GMTIME_R)
#if defined(HAVE_GMTIME_S)
tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf;
#elif defined(HAVE_GMTIME_R)
tm = gmtime_r(&t, &tmbuf);
#elif defined(HAVE__GMTIME64_S)
tmptime = t;
terr = _gmtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = gmtime(&t);
#endif
@@ -837,25 +804,16 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
struct tm *tm;
time_t Month;
time_t Year;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (RelMonth == 0)
return 0;
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&Start, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = Start;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&Start);
#endif
@@ -995,10 +953,6 @@ __archive_get_date(time_t now, const char *p)
time_t Start;
time_t tod;
long tzone;
#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/* Clear out the parsed token array. */
memset(tokens, 0, sizeof(tokens));
@@ -1007,36 +961,26 @@ __archive_get_date(time_t now, const char *p)
gds = &_gds;
/* Look up the current time. */
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&local, &now) ? NULL : &local;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&now, &local);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = now;
terr = _localtime64_s(&local, &tmptime);
if (terr)
tm = NULL;
else
tm = &local;
#else
memset(&local, 0, sizeof(local));
tm = localtime(&now);
#endif
if (tm == NULL)
return -1;
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S)
local = *tm;
#endif
/* Look up UTC if we can and use that to determine the current
* timezone offset. */
#if defined(HAVE_GMTIME_R)
#if defined(HAVE_GMTIME_S)
gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
#elif defined(HAVE_GMTIME_R)
gmt_ptr = gmtime_r(&now, &gmt);
#elif defined(HAVE__GMTIME64_S)
tmptime = now;
terr = _gmtime64_s(&gmt, &tmptime);
if (terr)
gmt_ptr = NULL;
else
gmt_ptr = &gmt;
#else
memset(&gmt, 0, sizeof(gmt));
gmt_ptr = gmtime(&now);
@@ -1078,15 +1022,10 @@ __archive_get_date(time_t now, const char *p)
* time components instead of the local timezone. */
if (gds->HaveZone && gmt_ptr != NULL) {
now -= gds->Timezone;
#if defined(HAVE_GMTIME_R)
#if defined(HAVE_GMTIME_S)
gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
#elif defined(HAVE_GMTIME_R)
gmt_ptr = gmtime_r(&now, &gmt);
#elif defined(HAVE__GMTIME64_S)
tmptime = now;
terr = _gmtime64_s(&gmt, &tmptime);
if (terr)
gmt_ptr = NULL;
else
gmt_ptr = &gmt;
#else
gmt_ptr = gmtime(&now);
#endif
@@ -231,15 +231,20 @@ static int
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PARAM params[2];
EVP_MAC *mac;
EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
char sha1[] = "SHA1";
OSSL_PARAM params[] = {
OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
OSSL_PARAM_END
};
mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
*ctx = EVP_MAC_CTX_new(mac);
EVP_MAC_free(mac);
if (*ctx == NULL)
return -1;
EVP_MAC_free(mac);
params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
params[1] = OSSL_PARAM_construct_end();
EVP_MAC_init(*ctx, key, key_len, params);
#else
*ctx = HMAC_CTX_new();
@@ -77,6 +77,8 @@ typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
#include <openssl/opensslv.h>
#include <openssl/hmac.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/params.h>
typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
#else
@@ -33,7 +33,8 @@
#include <openssl/evp.h>
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
static inline EVP_MD_CTX *EVP_MD_CTX_new(void)
@@ -51,16 +51,27 @@ __FBSDID("$FreeBSD$");
#include <pthread.h>
#endif
static void arc4random_buf(void *, size_t);
static void la_arc4random_buf(void *, size_t);
#endif /* HAVE_ARC4RANDOM_BUF */
#include "archive.h"
#include "archive_random_private.h"
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
/* don't use bcrypt when XP needs to be supported */
#include <bcrypt.h>
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
#elif defined(HAVE_WINCRYPT_H)
#include <wincrypt.h>
#endif
#endif
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
@@ -75,6 +86,20 @@ int
archive_random(void *buf, size_t nbytes)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
NTSTATUS status;
BCRYPT_ALG_HANDLE hAlg;
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0);
if (!BCRYPT_SUCCESS(status))
return ARCHIVE_FAILED;
status = BCryptGenRandom(hAlg, buf, (ULONG)nbytes, 0);
BCryptCloseAlgorithmProvider(hAlg, 0);
if (!BCRYPT_SUCCESS(status))
return ARCHIVE_FAILED;
return ARCHIVE_OK;
# else
HCRYPTPROV hProv;
BOOL success;
@@ -92,6 +117,10 @@ archive_random(void *buf, size_t nbytes)
}
/* TODO: Does this case really happen? */
return ARCHIVE_FAILED;
# endif
#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
la_arc4random_buf(buf, nbytes);
return ARCHIVE_OK;
#else
arc4random_buf(buf, nbytes);
return ARCHIVE_OK;
@@ -256,7 +285,7 @@ arc4_getbyte(void)
}
static void
arc4random_buf(void *_buf, size_t n)
la_arc4random_buf(void *_buf, size_t n)
{
uint8_t *buf = (uint8_t *)_buf;
_ARC4_LOCK();
@@ -95,8 +95,13 @@ archive_read_data_into_fd(struct archive *a, int fd)
"archive_read_data_into_fd");
can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
if (!can_lseek)
if (!can_lseek) {
nulls = calloc(1, nulls_size);
if (!nulls) {
r = ARCHIVE_FATAL;
goto cleanup;
}
}
while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
ARCHIVE_OK) {
@@ -1678,6 +1678,11 @@ setup_current_filesystem(struct archive_read_disk *a)
else
t->current_filesystem->name_max = nm;
#endif
if (t->current_filesystem->name_max == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot determine name_max");
return (ARCHIVE_FAILED);
}
#endif /* USE_READDIR_R */
return (ARCHIVE_OK);
}
@@ -1868,7 +1873,16 @@ setup_current_filesystem(struct archive_read_disk *a)
#if defined(USE_READDIR_R)
/* Set maximum filename length. */
#if defined(HAVE_STATVFS)
t->current_filesystem->name_max = svfs.f_namemax;
#else
t->current_filesystem->name_max = sfs.f_namelen;
#endif
if (t->current_filesystem->name_max == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot determine name_max");
return (ARCHIVE_FAILED);
}
#endif
return (ARCHIVE_OK);
}
@@ -1950,6 +1964,11 @@ setup_current_filesystem(struct archive_read_disk *a)
#if defined(USE_READDIR_R)
/* Set maximum filename length. */
t->current_filesystem->name_max = svfs.f_namemax;
if (t->current_filesystem->name_max == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot determine name_max");
return (ARCHIVE_FAILED);
}
#endif
return (ARCHIVE_OK);
}
@@ -2004,6 +2023,11 @@ setup_current_filesystem(struct archive_read_disk *a)
else
t->current_filesystem->name_max = nm;
# endif /* _PC_NAME_MAX */
if (t->current_filesystem->name_max == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot determine name_max");
return (ARCHIVE_FAILED);
}
#endif /* USE_READDIR_R */
return (ARCHIVE_OK);
}
@@ -2554,7 +2578,11 @@ tree_current_lstat(struct tree *t)
#else
if (tree_enter_working_dir(t) != 0)
return NULL;
#ifdef HAVE_LSTAT
if (lstat(tree_current_access_path(t), &t->lst) != 0)
#else
if (la_stat(tree_current_access_path(t), &t->lst) != 0)
#endif
#endif
return NULL;
t->flags |= hasLstat;
@@ -418,9 +418,19 @@ la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
FILE_FLAG_OPEN_REPARSE_POINT;
int ret;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileFlags = flag;
h = CreateFile2(path, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
OPEN_EXISTING, &createExParams);
#else
h = CreateFileW(path, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, flag, NULL);
#endif
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
return (-1);
@@ -1067,16 +1077,29 @@ next_entry(struct archive_read_disk *a, struct tree *t,
if (archive_entry_filetype(entry) == AE_IFREG &&
archive_entry_size(entry) > 0) {
DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
if (t->async_io)
flags |= FILE_FLAG_OVERLAPPED;
if (t->direct_io)
flags |= FILE_FLAG_NO_BUFFERING;
else
flags |= FILE_FLAG_SEQUENTIAL_SCAN;
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileFlags = flags;
t->entry_fh = CreateFile2(tree_current_access_path(t),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
OPEN_EXISTING, &createExParams);
#else
t->entry_fh = CreateFileW(tree_current_access_path(t),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, flags, NULL);
#endif
if (t->entry_fh == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
archive_set_error(&a->archive, errno,
@@ -1547,6 +1570,9 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
{
HANDLE handle;
int r = 0;
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
return (0);
@@ -1560,8 +1586,16 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
if ((t->flags & needsRestoreTimes) == 0)
return (r);
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
handle = CreateFile2(rt->full_path, FILE_WRITE_ATTRIBUTES,
0, OPEN_EXISTING, &createExParams);
#else
handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
#endif
if (handle == INVALID_HANDLE_VALUE) {
errno = EINVAL;
return (-1);
@@ -2046,12 +2080,24 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
HANDLE h;
int r;
DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
if (sim_lstat && tree_current_is_physical_link(t))
flag |= FILE_FLAG_OPEN_REPARSE_POINT;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileFlags = flag;
h = CreateFile2(tree_current_access_path(t), 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
OPEN_EXISTING, &createExParams);
#else
h = CreateFileW(tree_current_access_path(t), 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, flag, NULL);
#endif
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
t->tree_errno = errno;
@@ -2257,7 +2303,10 @@ archive_read_disk_entry_from_file(struct archive *_a,
} else {
WIN32_FIND_DATAW findData;
DWORD flag, desiredAccess;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
h = FindFirstFileW(path, &findData);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
@@ -2279,9 +2328,18 @@ archive_read_disk_entry_from_file(struct archive *_a,
} else
desiredAccess = GENERIC_READ;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileFlags = flag;
h = CreateFile2(path, desiredAccess,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
OPEN_EXISTING, &createExParams);
#else
h = CreateFileW(path, desiredAccess,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, flag, NULL);
#endif
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
archive_set_error(&a->archive, errno,
@@ -2342,9 +2400,19 @@ archive_read_disk_entry_from_file(struct archive *_a,
if (fd >= 0) {
h = (HANDLE)_get_osfhandle(fd);
} else {
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
h = CreateFile2(path, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
OPEN_EXISTING, &createExParams);
#else
h = CreateFileW(path, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
#endif
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
archive_set_error(&a->archive, errno,
@@ -154,10 +154,10 @@ file_skip(struct archive *a, void *client_data, int64_t request)
#ifdef __ANDROID__
/* fileno() isn't safe on all platforms ... see above. */
if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
#elif HAVE_FSEEKO
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
#elif HAVE__FSEEKI64
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
#elif HAVE_FSEEKO
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
#else
if (fseek(mine->f, skip, SEEK_CUR) != 0)
#endif
@@ -255,6 +255,27 @@ have been concatenated together.
Without this option, only the contents of
the first concatenated archive would be read.
.El
.It Format zip
.Bl -tag -compact -width indent
.It Cm compat-2x
Libarchive 2.x incorrectly encoded Unicode filenames on
some platforms.
This option mimics the libarchive 2.x filename handling
so that such archives can be read correctly.
.It Cm hdrcharset
The value is used as a character set name that will be
used when translating file names.
.It Cm ignorecrc32
Skip the CRC32 check.
Mostly used for testing.
.It Cm mac-ext
Support Mac OS metadata extension that records data in special
files beginning with a period and underscore.
Defaults to enabled on Mac OS, disabled on other platforms.
Use
.Cm !mac-ext
to disable.
.El
.El
.\"
.Sh ERRORS
@@ -230,7 +230,7 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p)
/* Empty our output buffer. */
state->stream.next_out = state->out_block;
state->stream.avail_out = state->out_block_size;
state->stream.avail_out = (uint32_t)state->out_block_size;
/* Try to fill the output buffer. */
for (;;) {
@@ -288,7 +288,7 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p)
return (ARCHIVE_FATAL);
}
state->stream.next_in = (char *)(uintptr_t)read_buf;
state->stream.avail_in = ret;
state->stream.avail_in = (uint32_t)ret;
/* There is no more data, return whatever we have. */
if (ret == 0) {
state->eof = 1;
@@ -584,7 +584,7 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
state->out_block + prefix64k, (int)compressed_size,
state->flags.block_maximum_size,
state->out_block,
prefix64k);
(int)prefix64k);
#else
uncompressed_size = LZ4_decompress_safe_withPrefix64k(
read_buf + 4,
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#endif
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_read_private.h"
@@ -61,12 +62,17 @@ struct uudecode {
#define ST_UUEND 2
#define ST_READ_BASE64 3
#define ST_IGNORE 4
mode_t mode;
int mode_set;
char *name;
};
static int uudecode_bidder_bid(struct archive_read_filter_bidder *,
struct archive_read_filter *filter);
static int uudecode_bidder_init(struct archive_read_filter *);
static int uudecode_read_header(struct archive_read_filter *,
struct archive_entry *entry);
static ssize_t uudecode_filter_read(struct archive_read_filter *,
const void **);
static int uudecode_filter_close(struct archive_read_filter *);
@@ -359,6 +365,7 @@ static const struct archive_read_filter_vtable
uudecode_reader_vtable = {
.read = uudecode_filter_read,
.close = uudecode_filter_close,
.read_header = uudecode_read_header
};
static int
@@ -389,6 +396,8 @@ uudecode_bidder_init(struct archive_read_filter *self)
uudecode->in_allocated = IN_BUFF_SIZE;
uudecode->out_buff = out_buff;
uudecode->state = ST_FIND_HEAD;
uudecode->mode_set = 0;
uudecode->name = NULL;
self->vtable = &uudecode_reader_vtable;
return (ARCHIVE_OK);
@@ -434,6 +443,22 @@ ensure_in_buff_size(struct archive_read_filter *self,
return (ARCHIVE_OK);
}
static int
uudecode_read_header(struct archive_read_filter *self, struct archive_entry *entry)
{
struct uudecode *uudecode;
uudecode = (struct uudecode *)self->data;
if (uudecode->mode_set != 0)
archive_entry_set_mode(entry, S_IFREG | uudecode->mode);
if (uudecode->name != NULL)
archive_entry_set_pathname(entry, uudecode->name);
return (ARCHIVE_OK);
}
static ssize_t
uudecode_filter_read(struct archive_read_filter *self, const void **buff)
{
@@ -443,7 +468,7 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
ssize_t avail_in, ravail;
ssize_t used;
ssize_t total;
ssize_t len, llen, nl;
ssize_t len, llen, nl, namelen;
uudecode = (struct uudecode *)self->data;
@@ -551,6 +576,28 @@ read_more:
uudecode->state = ST_READ_UU;
else
uudecode->state = ST_READ_BASE64;
uudecode->mode = (mode_t)(
((int)(b[l] - '0') * 64) +
((int)(b[l+1] - '0') * 8) +
(int)(b[l+2] - '0'));
uudecode->mode_set = 1;
namelen = len - nl - 4 - l;
if (namelen > 1) {
if (uudecode->name != NULL)
free(uudecode->name);
uudecode->name = malloc(namelen + 1);
if (uudecode->name == NULL) {
archive_set_error(
&self->archive->archive,
ENOMEM,
"Can't allocate data for uudecode");
return (ARCHIVE_FATAL);
}
strncpy(uudecode->name,
(const char *)(b + l + 4),
namelen);
uudecode->name[namelen] = '\0';
}
}
break;
case ST_READ_UU:
@@ -683,6 +730,7 @@ uudecode_filter_close(struct archive_read_filter *self)
uudecode = (struct uudecode *)self->data;
free(uudecode->in_buff);
free(uudecode->out_buff);
free(uudecode->name);
free(uudecode);
return (ARCHIVE_OK);
@@ -115,9 +115,9 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
unsigned prefix;
/* Zstd frame magic values */
const unsigned zstd_magic = 0xFD2FB528U;
const unsigned zstd_magic_skippable_start = 0x184D2A50U;
const unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
unsigned zstd_magic = 0xFD2FB528U;
unsigned zstd_magic_skippable_start = 0x184D2A50U;
unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
(void) self; /* UNUSED */
@@ -170,7 +170,7 @@ static int
zstd_bidder_init(struct archive_read_filter *self)
{
struct private_data *state;
const size_t out_block_size = ZSTD_DStreamOutSize();
size_t out_block_size = ZSTD_DStreamOutSize();
void *out_block;
ZSTD_DStream *dstream;
@@ -211,6 +211,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
ssize_t avail_in;
ZSTD_outBuffer out;
ZSTD_inBuffer in;
size_t ret;
state = (struct private_data *)self->data;
@@ -219,7 +220,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
/* Try to fill the output buffer. */
while (out.pos < out.size && !state->eof) {
if (!state->in_frame) {
const size_t ret = ZSTD_initDStream(state->dstream);
ret = ZSTD_initDStream(state->dstream);
if (ZSTD_isError(ret)) {
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC,
@@ -249,8 +250,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
in.pos = 0;
{
const size_t ret =
ZSTD_decompressStream(state->dstream, &out, &in);
ret = ZSTD_decompressStream(state->dstream, &out, &in);
if (ZSTD_isError(ret)) {
archive_set_error(&self->archive->archive,
@@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_ZLIB_H
#include <cm3p/zlib.h>
#endif
#ifdef HAVE_ZSTD_H
#include <cm3p/zstd.h>
#endif
#ifdef __clang_analyzer__
#include <assert.h>
@@ -84,8 +87,11 @@ __FBSDID("$FreeBSD$");
#define _7Z_IA64 0x03030401
#define _7Z_ARM 0x03030501
#define _7Z_ARMTHUMB 0x03030701
#define _7Z_ARM64 0xa
#define _7Z_SPARC 0x03030805
#define _7Z_ZSTD 0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */
/*
* 7-Zip header property IDs.
*/
@@ -114,6 +120,30 @@ __FBSDID("$FreeBSD$");
#define kEncodedHeader 0x17
#define kDummy 0x19
// Check that some windows file attribute constants are defined.
// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
#ifndef FILE_ATTRIBUTE_READONLY
#define FILE_ATTRIBUTE_READONLY 0x00000001
#endif
#ifndef FILE_ATTRIBUTE_HIDDEN
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
#endif
#ifndef FILE_ATTRIBUTE_SYSTEM
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
#endif
#ifndef FILE_ATTRIBUTE_DIRECTORY
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#endif
// This value is defined in 7zip with the comment "trick for Unix".
//
// 7z archives created on unix have this bit set in the high 16 bits of
// the attr field along with the unix permissions.
#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
struct _7z_digests {
unsigned char *defineds;
uint32_t *digests;
@@ -281,6 +311,11 @@ struct _7zip {
#ifdef HAVE_ZLIB_H
z_stream stream;
int stream_valid;
#endif
/* Decoding Zstandard data. */
#if HAVE_ZSTD_H
ZSTD_DStream *zstd_dstream;
int zstdstream_valid;
#endif
/* Decoding PPMd data. */
int ppmd7_stat;
@@ -401,6 +436,9 @@ static int setup_decode_folder(struct archive_read *, struct _7z_folder *,
int);
static void x86_Init(struct _7zip *);
static size_t x86_Convert(struct _7zip *, uint8_t *, size_t);
static void arm_Init(struct _7zip *);
static size_t arm_Convert(struct _7zip *, uint8_t *, size_t);
static size_t arm64_Convert(struct _7zip *, uint8_t *, size_t);
static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
@@ -729,6 +767,37 @@ archive_read_format_7zip_read_header(struct archive_read *a,
archive_entry_set_size(entry, 0);
}
// These attributes are supported by the windows implementation of archive_write_disk.
const int supported_attrs = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
if (zip_entry->attr & supported_attrs) {
char *fflags_text, *ptr;
/* allocate for "rdonly,hidden,system," */
fflags_text = malloc(22 * sizeof(char));
if (fflags_text != NULL) {
ptr = fflags_text;
if (zip_entry->attr & FILE_ATTRIBUTE_READONLY) {
strcpy(ptr, "rdonly,");
ptr = ptr + 7;
}
if (zip_entry->attr & FILE_ATTRIBUTE_HIDDEN) {
strcpy(ptr, "hidden,");
ptr = ptr + 7;
}
if (zip_entry->attr & FILE_ATTRIBUTE_SYSTEM) {
strcpy(ptr, "system,");
ptr = ptr + 7;
}
if (ptr > fflags_text) {
/* Delete trailing comma */
*(ptr - 1) = '\0';
archive_entry_copy_fflags_text(entry,
fflags_text);
}
free(fflags_text);
}
}
/* If there's no body, force read_data() to return EOF immediately. */
if (zip->entry_bytes_remaining < 1)
zip->end_of_entry = 1;
@@ -1034,10 +1103,13 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
case _7Z_COPY:
case _7Z_BZ2:
case _7Z_DEFLATE:
case _7Z_ZSTD:
case _7Z_PPMD:
if (coder2 != NULL) {
if (coder2->codec != _7Z_X86 &&
coder2->codec != _7Z_X86_BCJ2) {
coder2->codec != _7Z_X86_BCJ2 &&
coder2->codec != _7Z_ARM &&
coder2->codec != _7Z_ARM64) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Unsupported filter %lx for %lx",
@@ -1048,6 +1120,8 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
zip->bcj_state = 0;
if (coder2->codec == _7Z_X86)
x86_Init(zip);
else if (coder2->codec == _7Z_ARM)
arm_Init(zip);
}
break;
default:
@@ -1144,6 +1218,12 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
filters[fi].id = LZMA_FILTER_ARMTHUMB;
fi++;
break;
#ifdef LZMA_FILTER_ARM64
case _7Z_ARM64:
filters[fi].id = LZMA_FILTER_ARM64;
fi++;
break;
#endif
case _7Z_SPARC:
filters[fi].id = LZMA_FILTER_SPARC;
fi++;
@@ -1229,6 +1309,22 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
"BZ2 codec is unsupported");
return (ARCHIVE_FAILED);
#endif
case _7Z_ZSTD:
{
#if defined(HAVE_ZSTD_H)
if (zip->zstdstream_valid) {
ZSTD_freeDStream(zip->zstd_dstream);
zip->zstdstream_valid = 0;
}
zip->zstd_dstream = ZSTD_createDStream();
zip->zstdstream_valid = 1;
break;
#else
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"ZSTD codec is unsupported");
return (ARCHIVE_FAILED);
#endif
}
case _7Z_DEFLATE:
#ifdef HAVE_ZLIB_H
if (zip->stream_valid)
@@ -1299,6 +1395,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
case _7Z_IA64:
case _7Z_ARM:
case _7Z_ARMTHUMB:
case _7Z_ARM64:
case _7Z_SPARC:
case _7Z_DELTA:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1443,9 +1540,9 @@ decompress(struct archive_read *a, struct _7zip *zip,
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
case _7Z_BZ2:
zip->bzstream.next_in = (char *)(uintptr_t)t_next_in;
zip->bzstream.avail_in = t_avail_in;
zip->bzstream.avail_in = (uint32_t)t_avail_in;
zip->bzstream.next_out = (char *)(uintptr_t)t_next_out;
zip->bzstream.avail_out = t_avail_out;
zip->bzstream.avail_out = (uint32_t)t_avail_out;
r = BZ2_bzDecompress(&(zip->bzstream));
switch (r) {
case BZ_STREAM_END: /* Found end of stream. */
@@ -1494,6 +1591,22 @@ decompress(struct archive_read *a, struct _7zip *zip,
t_avail_in = zip->stream.avail_in;
t_avail_out = zip->stream.avail_out;
break;
#endif
#ifdef HAVE_ZSTD_H
case _7Z_ZSTD:
{
ZSTD_inBuffer input = { t_next_in, t_avail_in, 0 }; // src, size, pos
ZSTD_outBuffer output = { t_next_out, t_avail_out, 0 }; // dst, size, pos
size_t const zret = ZSTD_decompressStream(zip->zstd_dstream, &output, &input);
if (ZSTD_isError(zret)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Zstd decompression failed: %s", ZSTD_getErrorName(zret));
return ARCHIVE_FAILED;
}
t_avail_in -= input.pos;
t_avail_out -= output.pos;
break;
}
#endif
case _7Z_PPMD:
{
@@ -1579,16 +1692,23 @@ decompress(struct archive_read *a, struct _7zip *zip,
/*
* Decord BCJ.
*/
if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
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) {
memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
zip->odd_bcj_size);
*outbytes = l;
} else
zip->odd_bcj_size = 0;
if (zip->codec != _7Z_LZMA2) {
if (zip->codec2 == _7Z_X86) {
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) {
memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
zip->odd_bcj_size);
*outbytes = l;
} else
zip->odd_bcj_size = 0;
} else if (zip->codec2 == _7Z_ARM) {
*outbytes = arm_Convert(zip, buff, *outbytes);
} else if (zip->codec2 == _7Z_ARM64) {
*outbytes = arm64_Convert(zip, buff, *outbytes);
}
}
/*
@@ -2612,6 +2732,28 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
entries[i].flg |= HAS_STREAM;
/* The high 16 bits of attributes is a posix file mode. */
entries[i].mode = entries[i].attr >> 16;
if (!(entries[i].attr & FILE_ATTRIBUTE_UNIX_EXTENSION)) {
// Only windows permissions specified for this entry. Translate to
// reasonable corresponding unix permissions.
if (entries[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
// Read-only directory.
entries[i].mode = AE_IFDIR | 0555;
} else {
// Read-write directory.
entries[i].mode = AE_IFDIR | 0755;
}
} else if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
// Readonly file.
entries[i].mode = AE_IFREG | 0444;
} else {
// Assume read-write file.
entries[i].mode = AE_IFREG | 0644;
}
}
if (entries[i].flg & HAS_STREAM) {
if ((size_t)sindex >= si->ss.unpack_streams)
return (-1);
@@ -2652,7 +2794,7 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
}
entries[i].ssIndex = -1;
}
if (entries[i].attr & 0x01)
if (entries[i].attr & FILE_ATTRIBUTE_READONLY)
entries[i].mode &= ~0222;/* Read only. */
if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) {
@@ -3737,6 +3879,116 @@ x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
return (bufferPos);
}
static void
arm_Init(struct _7zip *zip)
{
zip->bcj_ip = 8;
}
static size_t
arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
{
// This function was adapted from
// static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
// in https://git.tukaani.org/xz-embedded.git
/*
* Branch/Call/Jump (BCJ) filter decoders
*
* Authors: Lasse Collin <lasse.collin@tukaani.org>
* Igor Pavlov <https://7-zip.org/>
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*/
size_t i;
uint32_t addr;
for (i = 0; i + 4 <= size; i += 4) {
if (buf[i + 3] == 0xEB) {
// Calculate the transformed addr.
addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
| ((uint32_t)buf[i + 2] << 16);
addr <<= 2;
addr -= zip->bcj_ip + (uint32_t)i;
addr >>= 2;
// Store the transformed addr in buf.
buf[i] = (uint8_t)addr;
buf[i + 1] = (uint8_t)(addr >> 8);
buf[i + 2] = (uint8_t)(addr >> 16);
}
}
zip->bcj_ip += (uint32_t)i;
return i;
}
static size_t
arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
{
// This function was adapted from
// static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
// in https://git.tukaani.org/xz-embedded.git
/*
* Branch/Call/Jump (BCJ) filter decoders
*
* Authors: Lasse Collin <lasse.collin@tukaani.org>
* Igor Pavlov <https://7-zip.org/>
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*/
size_t i;
uint32_t instr;
uint32_t addr;
for (i = 0; i + 4 <= size; i += 4) {
instr = (uint32_t)buf[i]
| ((uint32_t)buf[i+1] << 8)
| ((uint32_t)buf[i+2] << 16)
| ((uint32_t)buf[i+3] << 24);
if ((instr >> 26) == 0x25) {
/* BL instruction */
addr = instr - ((zip->bcj_ip + (uint32_t)i) >> 2);
instr = 0x94000000 | (addr & 0x03FFFFFF);
buf[i] = (uint8_t)instr;
buf[i+1] = (uint8_t)(instr >> 8);
buf[i+2] = (uint8_t)(instr >> 16);
buf[i+3] = (uint8_t)(instr >> 24);
} else if ((instr & 0x9F000000) == 0x90000000) {
/* ADRP instruction */
addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
/* Only convert values in the range +/-512 MiB. */
if ((addr + 0x020000) & 0x1C0000)
continue;
addr -= (zip->bcj_ip + (uint32_t)i) >> 12;
instr &= 0x9000001F;
instr |= (addr & 3) << 29;
instr |= (addr & 0x03FFFC) << 3;
instr |= (0U - (addr & 0x020000)) & 0xE00000;
buf[i] = (uint8_t)instr;
buf[i+1] = (uint8_t)(instr >> 8);
buf[i+2] = (uint8_t)(instr >> 16);
buf[i+3] = (uint8_t)(instr >> 24);
}
}
zip->bcj_ip += (uint32_t)i;
return i;
}
/*
* Brought from LZMA SDK.
*
@@ -2294,10 +2294,10 @@ lzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br)
(br->cache_buffer << 48) |
((uint64_t)strm->next_in[1]) << 40 |
((uint64_t)strm->next_in[0]) << 32 |
((uint32_t)strm->next_in[3]) << 24 |
((uint32_t)strm->next_in[2]) << 16 |
((uint32_t)strm->next_in[5]) << 8 |
(uint32_t)strm->next_in[4];
((uint64_t)strm->next_in[3]) << 24 |
((uint64_t)strm->next_in[2]) << 16 |
((uint64_t)strm->next_in[5]) << 8 |
(uint64_t)strm->next_in[4];
strm->next_in += 6;
strm->avail_in -= 6;
br->cache_avail += 6 * 8;
@@ -441,7 +441,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
/* Compare name to "TRAILER!!!" to test for end-of-archive. */
if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!",
11) == 0) {
10) == 0) {
/* TODO: Store file location of start of block. */
archive_clear_error(&a->archive);
return (ARCHIVE_EOF);
@@ -985,14 +985,14 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
static int64_t
le4(const unsigned char *p)
{
return ((p[0] << 16) + (((int64_t)p[1]) << 24) + (p[2] << 0) + (p[3] << 8));
return ((p[0] << 16) | (((int64_t)p[1]) << 24) | (p[2] << 0) | (p[3] << 8));
}
static int64_t
be4(const unsigned char *p)
{
return ((((int64_t)p[0]) << 24) + (p[1] << 16) + (p[2] << 8) + (p[3]));
return ((((int64_t)p[0]) << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
}
/*
@@ -1901,7 +1901,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* NUMBER of RRIP "PX" extension.
* Note: Old mkisofs did not record that FILE SERIAL NUMBER
* in ISO images.
* Note2: xorriso set 0 to the location of a symlink file.
* Note2: xorriso set 0 to the location of a symlink file.
*/
if (file->size == 0 && location >= 0) {
/* If file->size is zero, its location points wrong place,
@@ -1955,7 +1955,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* made by makefs is not zero and its location is
* the same as those of next regular file. That is
* the same as hard like file and it causes unexpected
* error.
* error.
*/
if (file->size > 0 &&
(file->mode & AE_IFMT) == AE_IFLNK) {
@@ -2747,7 +2747,7 @@ next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
* If directory entries all which are descendant of
* rr_moved are still remaining, expose their.
*/
if (iso9660->re_files.first != NULL &&
if (iso9660->re_files.first != NULL &&
iso9660->rr_moved != NULL &&
iso9660->rr_moved->rr_moved_has_re_only)
/* Expose "rr_moved" entry. */
@@ -3182,11 +3182,11 @@ isodate17(const unsigned char *v)
static time_t
time_from_tm(struct tm *t)
{
#if HAVE_TIMEGM
#if HAVE__MKGMTIME
return _mkgmtime(t);
#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
#elif HAVE__MKGMTIME64
return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */
@@ -1819,7 +1819,7 @@ lha_crc16(uint16_t crc, const void *pp, size_t len)
* remove the statement which will not be executed. */
#undef bswap16
#ifndef __has_builtin
# define __has_builtin(x) 0
#define __has_builtin(x) 0
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1400 /* Visual Studio */
# define bswap16(x) _byteswap_ushort(x)
@@ -1827,7 +1827,7 @@ lha_crc16(uint16_t crc, const void *pp, size_t len)
/* GCC 4.8 and later has __builtin_bswap16() */
# define bswap16(x) __builtin_bswap16(x)
#elif defined(__clang__) && __has_builtin(__builtin_bswap16)
/* All clang versions have __builtin_bswap16() */
/* Newer clang versions have __builtin_bswap16() */
# define bswap16(x) __builtin_bswap16(x)
#else
# define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8))
@@ -2012,10 +2012,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
((uint64_t)strm->next_in[0]) << 48 |
((uint64_t)strm->next_in[1]) << 40 |
((uint64_t)strm->next_in[2]) << 32 |
((uint32_t)strm->next_in[3]) << 24 |
((uint32_t)strm->next_in[4]) << 16 |
((uint32_t)strm->next_in[5]) << 8 |
(uint32_t)strm->next_in[6];
((uint64_t)strm->next_in[3]) << 24 |
((uint64_t)strm->next_in[4]) << 16 |
((uint64_t)strm->next_in[5]) << 8 |
(uint64_t)strm->next_in[6];
strm->next_in += 7;
strm->avail_in -= 7;
br->cache_avail += 7 * 8;
@@ -2025,10 +2025,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
(br->cache_buffer << 48) |
((uint64_t)strm->next_in[0]) << 40 |
((uint64_t)strm->next_in[1]) << 32 |
((uint32_t)strm->next_in[2]) << 24 |
((uint32_t)strm->next_in[3]) << 16 |
((uint32_t)strm->next_in[4]) << 8 |
(uint32_t)strm->next_in[5];
((uint64_t)strm->next_in[2]) << 24 |
((uint64_t)strm->next_in[3]) << 16 |
((uint64_t)strm->next_in[4]) << 8 |
(uint64_t)strm->next_in[5];
strm->next_in += 6;
strm->avail_in -= 6;
br->cache_avail += 6 * 8;
@@ -1280,7 +1280,13 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
mtree->fd = -1;
st = NULL;
}
} else if (lstat(path, st) == -1) {
}
#ifdef HAVE_LSTAT
else if (lstat(path, st) == -1)
#else
else if (la_stat(path, st) == -1)
#endif
{
st = NULL;
}
@@ -1064,7 +1064,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
return (ARCHIVE_FATAL);
}
p = h;
crc32_val = crc32(crc32_val, (const unsigned char *)p, to_read);
crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned int)to_read);
__archive_read_consume(a, to_read);
skip -= to_read;
}
@@ -1832,13 +1832,9 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
struct tm *tm;
time_t t;
long nsec;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
if (p + 2 > endp)
return (-1);
@@ -1870,15 +1866,10 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
p++;
}
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
tm = localtime_r(&t, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = t;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
tm = NULL;
else
tm = &tmbuf;
#else
tm = localtime(&t);
#endif
@@ -3451,7 +3442,7 @@ compile_program(const uint8_t *bytes, size_t length)
prog = calloc(1, sizeof(*prog));
if (!prog)
return NULL;
prog->fingerprint = crc32(0, bytes, length) | ((uint64_t)length << 32);
prog->fingerprint = crc32(0, bytes, (unsigned int)length) | ((uint64_t)length << 32);
if (membr_bits(&br, 1))
{
@@ -2475,7 +2475,7 @@ static void update_crc(struct rar5* rar, const uint8_t* p, size_t to_read) {
* `stored_crc32` info filled in. */
if(rar->file.stored_crc32 > 0) {
rar->file.calculated_crc32 =
crc32(rar->file.calculated_crc32, p, to_read);
crc32(rar->file.calculated_crc32, p, (unsigned int)to_read);
}
/* Check if the file uses an optional BLAKE2sp checksum
@@ -530,11 +530,11 @@ strtoi_lim(const char *str, const char **ep, int llim, int ulim)
static time_t
time_from_tm(struct tm *t)
{
#if HAVE_TIMEGM
#if HAVE__MKGMTIME
return _mkgmtime(t);
#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
#elif HAVE__MKGMTIME64
return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */
@@ -1127,7 +1127,7 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
x |= p[1] - '0';
else
return (-1);
*b++ = x;
bsize--;
p += 2;
@@ -1139,11 +1139,11 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
static time_t
time_from_tm(struct tm *t)
{
#if HAVE_TIMEGM
#if HAVE__MKGMTIME
return _mkgmtime(t);
#elif HAVE_TIMEGM
/* Use platform timegm() if available. */
return (timegm(t));
#elif HAVE__MKGMTIME64
return (_mkgmtime64(t));
#else
/* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */
@@ -2186,11 +2186,11 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
/* Setup buffer boundaries. */
zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff;
zip->bzstream.avail_in = in_bytes;
zip->bzstream.avail_in = (uint32_t)in_bytes;
zip->bzstream.total_in_hi32 = 0;
zip->bzstream.total_in_lo32 = 0;
zip->bzstream.next_out = (char*) zip->uncompressed_buffer;
zip->bzstream.avail_out = zip->uncompressed_buffer_size;
zip->bzstream.avail_out = (uint32_t)zip->uncompressed_buffer_size;
zip->bzstream.total_out_hi32 = 0;
zip->bzstream.total_out_lo32 = 0;
@@ -2227,7 +2227,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
to_consume = zip->bzstream.total_in_lo32;
__archive_read_consume(a, to_consume);
total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) +
total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) |
zip->bzstream.total_out_lo32;
zip->entry_bytes_remaining -= to_consume;
@@ -1324,6 +1324,10 @@ free_sconv_object(struct archive_string_conv *sc)
}
#if defined(_WIN32) && !defined(__CYGWIN__)
# if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# define GetOEMCP() CP_OEMCP
# endif
static unsigned
my_atoi(const char *p)
{
@@ -42,9 +42,20 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
/* don't use bcrypt when XP needs to be supported */
#include <bcrypt.h>
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
#elif defined(HAVE_WINCRYPT_H)
#include <wincrypt.h>
#endif
#endif
#ifdef HAVE_ZLIB_H
#include <cm3p/zlib.h>
#endif
@@ -233,14 +244,16 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
L'u', L'v', L'w', L'x', L'y', L'z'
};
HCRYPTPROV hProv;
struct archive_wstring temp_name;
wchar_t *ws;
DWORD attr;
wchar_t *xp, *ep;
int fd;
hProv = (HCRYPTPROV)NULL;
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCRYPT_ALG_HANDLE hAlg = NULL;
#else
HCRYPTPROV hProv = (HCRYPTPROV)NULL;
#endif
fd = -1;
ws = NULL;
@@ -314,23 +327,42 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
abort();
}
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
NULL, 0))) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
#else
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
#endif
for (;;) {
wchar_t *p;
HANDLE h;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
/* Generate a random file name through CryptGenRandom(). */
p = xp;
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
(DWORD)(ep - p)*sizeof(wchar_t), 0))) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
#else
if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
(BYTE*)p)) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
#endif
for (; p < ep; p++)
*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
@@ -347,6 +379,17 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
/* mkstemp */
attr = FILE_ATTRIBUTE_NORMAL;
}
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileAttributes = attr & 0xFFFF;
createExParams.dwFileFlags = attr & 0xFFF00000;
h = CreateFile2(ws,
GENERIC_READ | GENERIC_WRITE | DELETE,
0,/* Not share */
CREATE_NEW,
&createExParams);
#else
h = CreateFileW(ws,
GENERIC_READ | GENERIC_WRITE | DELETE,
0,/* Not share */
@@ -354,6 +397,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
CREATE_NEW,/* Create a new file only */
attr,
NULL);
#endif
if (h == INVALID_HANDLE_VALUE) {
/* The same file already exists. retry with
* a new filename. */
@@ -372,8 +416,13 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
break;/* success! */
}
exit_tmpfile:
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (hAlg != NULL)
BCryptCloseAlgorithmProvider(hAlg, 0);
#else
if (hProv != (HCRYPTPROV)NULL)
CryptReleaseContext(hProv, 0);
#endif
free(ws);
if (template == temp_name.s)
archive_wstring_free(&temp_name);
@@ -234,7 +234,11 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
{
wchar_t *wpath;
HANDLE handle;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
hTemplateFile);
@@ -242,12 +246,25 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
return (handle);
if (GetLastError() != ERROR_PATH_NOT_FOUND)
return (handle);
#endif
wpath = __la_win_permissive_name(path);
if (wpath == NULL)
return (handle);
return INVALID_HANDLE_VALUE;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000;
createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000;
createExParams.lpSecurityAttributes = lpSecurityAttributes;
createExParams.hTemplateFile = hTemplateFile;
handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode,
dwCreationDisposition, &createExParams);
#else /* !WINAPI_PARTITION_DESKTOP */
handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
hTemplateFile);
#endif /* !WINAPI_PARTITION_DESKTOP */
free(wpath);
return (handle);
}
@@ -305,7 +322,10 @@ __la_open(const char *path, int flags, ...)
* "Permission denied" error.
*/
attr = GetFileAttributesA(path);
if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND)
#endif
{
ws = __la_win_permissive_name(path);
if (ws == NULL) {
errno = EINVAL;
@@ -320,7 +340,7 @@ __la_open(const char *path, int flags, ...)
}
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
HANDLE handle;
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
if (ws != NULL)
handle = CreateFileW(ws, 0, 0, NULL,
OPEN_EXISTING,
@@ -333,6 +353,15 @@ __la_open(const char *path, int flags, ...)
FILE_FLAG_BACKUP_SEMANTICS |
FILE_ATTRIBUTE_READONLY,
NULL);
#else /* !WINAPI_PARTITION_DESKTOP */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
handle = CreateFile2(ws, 0, 0,
OPEN_EXISTING, &createExParams);
#endif /* !WINAPI_PARTITION_DESKTOP */
free(ws);
if (handle == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
@@ -310,6 +310,25 @@ __archive_write_output(struct archive_write *a, const void *buff, size_t length)
return (__archive_write_filter(a->filter_first, buff, length));
}
static int
__archive_write_filters_flush(struct archive_write *a)
{
struct archive_write_filter *f;
int ret, ret1;
ret = ARCHIVE_OK;
for (f = a->filter_first; f != NULL; f = f->next_filter) {
if (f->flush != NULL && f->bytes_written > 0) {
ret1 = (f->flush)(f);
if (ret1 < ret)
ret = ret1;
if (ret1 < ARCHIVE_WARN)
f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
}
}
return (ret);
}
int
__archive_write_nulls(struct archive_write *a, size_t length)
{
@@ -740,6 +759,18 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
return (ARCHIVE_FAILED);
}
/* Flush filters at boundary. */
r2 = __archive_write_filters_flush(a);
if (r2 == ARCHIVE_FAILED) {
return (ARCHIVE_FAILED);
}
if (r2 == ARCHIVE_FATAL) {
a->archive.state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
if (r2 < ret)
ret = r2;
/* Format and write header. */
r2 = ((a->format_write_header)(a, entry));
if (r2 == ARCHIVE_FAILED) {
@@ -190,7 +190,7 @@ archive_compressor_bzip2_open(struct archive_write_filter *f)
memset(&data->stream, 0, sizeof(data->stream));
data->stream.next_out = data->compressed;
data->stream.avail_out = data->compressed_buffer_size;
data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
f->write = archive_compressor_bzip2_write;
/* Initialize compression library */
@@ -244,7 +244,7 @@ archive_compressor_bzip2_write(struct archive_write_filter *f,
/* Compress input data to output buffer */
SET_NEXT_IN(data, buff);
data->stream.avail_in = length;
data->stream.avail_in = (uint32_t)length;
if (drive_compressor(f, data, 0))
return (ARCHIVE_FATAL);
return (ARCHIVE_OK);
@@ -313,7 +313,7 @@ drive_compressor(struct archive_write_filter *f,
return (ARCHIVE_FATAL);
}
data->stream.next_out = data->compressed;
data->stream.avail_out = data->compressed_buffer_size;
data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
}
/* If there's nothing to do, we're done. */
@@ -352,7 +352,7 @@ archive_compressor_compress_write(struct archive_write_filter *f,
while (length--) {
c = *bp++;
state->in_count++;
state->cur_fcode = (c << 16) + state->cur_code;
state->cur_fcode = (c << 16) | state->cur_code;
i = ((c << HSHIFT) ^ state->cur_code); /* Xor hashing. */
if (state->hashtab[i] == state->cur_fcode) {
@@ -518,10 +518,10 @@ drive_compressor_independence(struct archive_write_filter *f, const char *p,
} else {
/* The buffer is not compressed. The compressed size was
* bigger than its uncompressed size. */
archive_le32enc(data->out, length | 0x80000000);
archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
data->out += 4;
memcpy(data->out, p, length);
outsize = length;
outsize = (uint32_t)length;
}
data->out += outsize;
if (data->block_checksum) {
@@ -603,10 +603,10 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p,
} else {
/* The buffer is not compressed. The compressed size was
* bigger than its uncompressed size. */
archive_le32enc(data->out, length | 0x80000000);
archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
data->out += 4;
memcpy(data->out, p, length);
outsize = length;
outsize = (uint32_t)length;
}
data->out += outsize;
if (data->block_checksum) {
@@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -50,10 +53,22 @@ __FBSDID("$FreeBSD$");
struct private_data {
int compression_level;
int threads;
int threads;
int long_distance;
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
enum {
running,
finishing,
resetting,
} state;
int frame_per_file;
size_t min_frame_size;
size_t max_frame_size;
size_t cur_frame;
size_t cur_frame_in;
size_t cur_frame_out;
size_t total_in;
ZSTD_CStream *cstream;
int64_t total_in;
ZSTD_outBuffer out;
#else
struct archive_write_program_data *pdata;
@@ -67,14 +82,18 @@ struct private_data {
#define CLEVEL_STD_MAX 19 /* without using --ultra */
#define CLEVEL_MAX 22
#define LONG_STD 27
#define MINVER_NEGCLEVEL 10304
#define MINVER_MINCLEVEL 10306
#define MINVER_LONG 10302
static int archive_compressor_zstd_options(struct archive_write_filter *,
const char *, const char *);
static int archive_compressor_zstd_open(struct archive_write_filter *);
static int archive_compressor_zstd_write(struct archive_write_filter *,
const void *, size_t);
static int archive_compressor_zstd_flush(struct archive_write_filter *);
static int archive_compressor_zstd_close(struct archive_write_filter *);
static int archive_compressor_zstd_free(struct archive_write_filter *);
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
@@ -103,13 +122,20 @@ archive_write_add_filter_zstd(struct archive *_a)
f->data = data;
f->open = &archive_compressor_zstd_open;
f->options = &archive_compressor_zstd_options;
f->flush = &archive_compressor_zstd_flush;
f->close = &archive_compressor_zstd_close;
f->free = &archive_compressor_zstd_free;
f->code = ARCHIVE_FILTER_ZSTD;
f->name = "zstd";
data->compression_level = CLEVEL_DEFAULT;
data->threads = 0;
data->long_distance = 0;
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
data->frame_per_file = 0;
data->min_frame_size = 0;
data->max_frame_size = SIZE_MAX;
data->cur_frame_in = 0;
data->cur_frame_out = 0;
data->cstream = ZSTD_createCStream();
if (data->cstream == NULL) {
free(data);
@@ -147,29 +173,18 @@ archive_compressor_zstd_free(struct archive_write_filter *f)
return (ARCHIVE_OK);
}
static int string_is_numeric (const char* value)
static int string_to_number(const char *string, intmax_t *numberp)
{
size_t len = strlen(value);
size_t i;
char *end;
if (len == 0) {
return (ARCHIVE_WARN);
}
else if (len == 1 && !(value[0] >= '0' && value[0] <= '9')) {
return (ARCHIVE_WARN);
}
else if (!(value[0] >= '0' && value[0] <= '9') &&
value[0] != '-' && value[0] != '+') {
return (ARCHIVE_WARN);
}
for (i = 1; i < len; i++) {
if (!(value[i] >= '0' && value[i] <= '9')) {
return (ARCHIVE_WARN);
}
}
return (ARCHIVE_OK);
if (string == NULL || *string == '\0')
return (ARCHIVE_WARN);
*numberp = strtoimax(string, &end, 10);
if (end == string || *end != '\0' || errno == EOVERFLOW) {
*numberp = 0;
return (ARCHIVE_WARN);
}
return (ARCHIVE_OK);
}
/*
@@ -182,13 +197,13 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
struct private_data *data = (struct private_data *)f->data;
if (strcmp(key, "compression-level") == 0) {
int level = atoi(value);
intmax_t level;
if (string_to_number(value, &level) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
/* If we don't have the library, hard-code the max level */
int minimum = CLEVEL_MIN;
int maximum = CLEVEL_MAX;
if (string_is_numeric(value) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
maximum = ZSTD_maxCLevel();
#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
@@ -204,21 +219,65 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
if (level < minimum || level > maximum) {
return (ARCHIVE_WARN);
}
data->compression_level = level;
data->compression_level = (int)level;
return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) {
int threads = atoi(value);
if (string_is_numeric(value) != ARCHIVE_OK) {
intmax_t threads;
if (string_to_number(value, &threads) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
int minimum = 0;
if (threads < minimum) {
if (threads < 0) {
return (ARCHIVE_WARN);
}
data->threads = threads;
data->threads = (int)threads;
return (ARCHIVE_OK);
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
} else if (strcmp(key, "frame-per-file") == 0) {
data->frame_per_file = 1;
return (ARCHIVE_OK);
} else if (strcmp(key, "min-frame-size") == 0) {
intmax_t min_frame_size;
if (string_to_number(value, &min_frame_size) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
if (min_frame_size < 0) {
return (ARCHIVE_WARN);
}
data->min_frame_size = min_frame_size;
return (ARCHIVE_OK);
} else if (strcmp(key, "max-frame-size") == 0) {
intmax_t max_frame_size;
if (string_to_number(value, &max_frame_size) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
if (max_frame_size < 1024) {
return (ARCHIVE_WARN);
}
data->max_frame_size = max_frame_size;
return (ARCHIVE_OK);
#endif
}
else if (strcmp(key, "long") == 0) {
intmax_t long_distance;
if (string_to_number(value, &long_distance) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR && ZSTD_VERSION_NUMBER >= MINVER_LONG
ZSTD_bounds bounds = ZSTD_cParam_getBounds(ZSTD_c_windowLog);
if (ZSTD_isError(bounds.error)) {
int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
if (((int)long_distance) < 10 || (int)long_distance > max_distance)
return (ARCHIVE_WARN);
} else {
if ((int)long_distance < bounds.lowerBound || (int)long_distance > bounds.upperBound)
return (ARCHIVE_WARN);
}
#else
int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
if (((int)long_distance) < 10 || (int)long_distance > max_distance)
return (ARCHIVE_WARN);
#endif
data->long_distance = (int)long_distance;
return (ARCHIVE_OK);
}
@@ -270,6 +329,10 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
#if ZSTD_VERSION_NUMBER >= MINVER_LONG
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance);
#endif
return (ARCHIVE_OK);
}
@@ -281,15 +344,22 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
size_t length)
{
struct private_data *data = (struct private_data *)f->data;
int ret;
/* Update statistics */
data->total_in += length;
return (drive_compressor(f, data, 0, buff, length));
}
if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK)
return (ret);
/*
* Flush the compressed stream.
*/
static int
archive_compressor_zstd_flush(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
return (ARCHIVE_OK);
if (data->frame_per_file && data->state == running &&
data->cur_frame_out > data->min_frame_size)
data->state = finishing;
return (drive_compressor(f, data, 1, NULL, 0));
}
/*
@@ -300,57 +370,72 @@ archive_compressor_zstd_close(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
/* Finish zstd frame */
return drive_compressor(f, data, 1, NULL, 0);
if (data->state == running)
data->state = finishing;
return (drive_compressor(f, data, 1, NULL, 0));
}
/*
* Utility function to push input data through compressor,
* writing full output blocks as necessary.
*
* Note that this handles both the regular write case (finishing ==
* false) and the end-of-archive case (finishing == true).
*/
static int
drive_compressor(struct archive_write_filter *f,
struct private_data *data, int finishing, const void *src, size_t length)
struct private_data *data, int flush, const void *src, size_t length)
{
ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 };
ZSTD_inBuffer in = { .src = src, .size = length, .pos = 0 };
size_t ipos, opos, zstdret = 0;
int ret;
for (;;) {
if (data->out.pos == data->out.size) {
const int ret = __archive_write_filter(f->next_filter,
data->out.dst, data->out.size);
ipos = in.pos;
opos = data->out.pos;
switch (data->state) {
case running:
if (in.pos == in.size)
return (ARCHIVE_OK);
zstdret = ZSTD_compressStream(data->cstream,
&data->out, &in);
if (ZSTD_isError(zstdret))
goto zstd_fatal;
break;
case finishing:
zstdret = ZSTD_endStream(data->cstream, &data->out);
if (ZSTD_isError(zstdret))
goto zstd_fatal;
if (zstdret == 0)
data->state = resetting;
break;
case resetting:
ZSTD_CCtx_reset(data->cstream, ZSTD_reset_session_only);
data->cur_frame++;
data->cur_frame_in = 0;
data->cur_frame_out = 0;
data->state = running;
break;
}
data->total_in += in.pos - ipos;
data->cur_frame_in += in.pos - ipos;
data->cur_frame_out += data->out.pos - opos;
if (data->state == running &&
data->cur_frame_in >= data->max_frame_size) {
data->state = finishing;
}
if (data->out.pos == data->out.size ||
(flush && data->out.pos > 0)) {
ret = __archive_write_filter(f->next_filter,
data->out.dst, data->out.pos);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
goto fatal;
data->out.pos = 0;
}
/* If there's nothing to do, we're done. */
if (!finishing && in.pos == in.size)
return (ARCHIVE_OK);
{
const size_t zstdret = !finishing ?
ZSTD_compressStream(data->cstream, &data->out, &in)
: ZSTD_endStream(data->cstream, &data->out);
if (ZSTD_isError(zstdret)) {
archive_set_error(f->archive,
ARCHIVE_ERRNO_MISC,
"Zstd compression failed: %s",
ZSTD_getErrorName(zstdret));
return (ARCHIVE_FATAL);
}
/* If we're finishing, 0 means nothing left to flush */
if (finishing && zstdret == 0) {
const int ret = __archive_write_filter(f->next_filter,
data->out.dst, data->out.pos);
return (ret);
}
}
}
zstd_fatal:
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
"Zstd compression failed: %s",
ZSTD_getErrorName(zstdret));
fatal:
return (ARCHIVE_FATAL);
}
#else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
@@ -367,17 +452,9 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
archive_strcpy(&as, "zstd --no-check");
if (data->compression_level < CLEVEL_STD_MIN) {
struct archive_string as2;
archive_string_init(&as2);
archive_string_sprintf(&as2, " --fast=%d", -data->compression_level);
archive_string_concat(&as, &as2);
archive_string_free(&as2);
archive_string_sprintf(&as, " --fast=%d", -data->compression_level);
} else {
struct archive_string as2;
archive_string_init(&as2);
archive_string_sprintf(&as2, " -%d", data->compression_level);
archive_string_concat(&as, &as2);
archive_string_free(&as2);
archive_string_sprintf(&as, " -%d", data->compression_level);
}
if (data->compression_level > CLEVEL_STD_MAX) {
@@ -385,11 +462,11 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
}
if (data->threads != 0) {
struct archive_string as2;
archive_string_init(&as2);
archive_string_sprintf(&as2, " --threads=%d", data->threads);
archive_string_concat(&as, &as2);
archive_string_free(&as2);
archive_string_sprintf(&as, " --threads=%d", data->threads);
}
if (data->long_distance != 0) {
archive_string_sprintf(&as, " --long=%d", data->long_distance);
}
f->write = archive_compressor_zstd_write;
@@ -407,6 +484,14 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
return __archive_write_program_write(f, data->pdata, buff, length);
}
static int
archive_compressor_zstd_flush(struct archive_write_filter *f)
{
(void)f; /* UNUSED */
return (ARCHIVE_OK);
}
static int
archive_compressor_zstd_close(struct archive_write_filter *f)
{
@@ -397,6 +397,7 @@ static int set_times_from_entry(struct archive_write_disk *);
static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
static ssize_t write_data_block(struct archive_write_disk *,
const char *, size_t);
static void close_file_descriptor(struct archive_write_disk *);
static int _archive_write_disk_close(struct archive *);
static int _archive_write_disk_free(struct archive *);
@@ -514,7 +515,12 @@ lazy_stat(struct archive_write_disk *a)
* XXX At this point, symlinks should not be hit, otherwise
* XXX a race occurred. Do we want to check explicitly for that?
*/
if (lstat(a->name, &a->st) == 0) {
#ifdef HAVE_LSTAT
if (lstat(a->name, &a->st) == 0)
#else
if (la_stat(a->name, &a->st) == 0)
#endif
{
a->pst = &a->st;
return (ARCHIVE_OK);
}
@@ -1605,12 +1611,12 @@ hfs_write_data_block(struct archive_write_disk *a, const char *buff,
"Seek failed");
return (ARCHIVE_FATAL);
} else if (a->offset > a->fd_offset) {
int64_t skip = a->offset - a->fd_offset;
uint64_t skip = a->offset - a->fd_offset;
char nullblock[1024];
memset(nullblock, 0, sizeof(nullblock));
while (skip > 0) {
if (skip > (int64_t)sizeof(nullblock))
if (skip > sizeof(nullblock))
bytes_written = hfs_write_decmpfs_block(
a, nullblock, sizeof(nullblock));
else
@@ -1725,8 +1731,10 @@ _archive_write_disk_finish_entry(struct archive *_a)
else
r = hfs_write_data_block(
a, null_d, a->file_remaining_bytes);
if (r < 0)
if (r < 0) {
close_file_descriptor(a);
return ((int)r);
}
}
#endif
} else {
@@ -1735,6 +1743,7 @@ _archive_write_disk_finish_entry(struct archive *_a)
a->filesize == 0) {
archive_set_error(&a->archive, errno,
"File size could not be restored");
close_file_descriptor(a);
return (ARCHIVE_FAILED);
}
#endif
@@ -1744,8 +1753,10 @@ _archive_write_disk_finish_entry(struct archive *_a)
* to see what happened.
*/
a->pst = NULL;
if ((ret = lazy_stat(a)) != ARCHIVE_OK)
return (ret);
if ((ret = lazy_stat(a)) != ARCHIVE_OK) {
close_file_descriptor(a);
return (ret);
}
/* We can use lseek()/write() to extend the file if
* ftruncate didn't work or isn't available. */
if (a->st.st_size < a->filesize) {
@@ -1753,11 +1764,13 @@ _archive_write_disk_finish_entry(struct archive *_a)
if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) {
archive_set_error(&a->archive, errno,
"Seek failed");
close_file_descriptor(a);
return (ARCHIVE_FATAL);
}
if (write(a->fd, &nul, 1) < 0) {
archive_set_error(&a->archive, errno,
"Write to restore size failed");
close_file_descriptor(a);
return (ARCHIVE_FATAL);
}
a->pst = NULL;
@@ -2154,7 +2167,11 @@ restore_entry(struct archive_write_disk *a)
* then don't follow it.
*/
if (r != 0 || !S_ISDIR(a->mode))
#ifdef HAVE_LSTAT
r = lstat(a->name, &a->st);
#else
r = la_stat(a->name, &a->st);
#endif
if (r != 0) {
archive_set_error(&a->archive, errno,
"Can't stat existing object");
@@ -2550,7 +2567,12 @@ _archive_write_disk_close(struct archive *_a)
goto skip_fixup_entry;
} else
#endif
if (lstat(p->name, &st) != 0 ||
if (
#ifdef HAVE_LSTAT
lstat(p->name, &st) != 0 ||
#else
la_stat(p->name, &st) != 0 ||
#endif
la_verify_filetype(st.st_mode,
p->filetype) == 0) {
goto skip_fixup_entry;
@@ -2565,7 +2587,12 @@ _archive_write_disk_close(struct archive *_a)
goto skip_fixup_entry;
} else
#endif
if (lstat(p->name, &st) != 0 ||
if (
#ifdef HAVE_LSTAT
lstat(p->name, &st) != 0 ||
#else
la_stat(p->name, &st) != 0 ||
#endif
la_verify_filetype(st.st_mode,
p->filetype) == 0) {
goto skip_fixup_entry;
@@ -2785,8 +2812,8 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
!(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT))
/* Platform doesn't have lstat, so we can't look for symlinks. */
(void)path; /* UNUSED */
(void)error_number; /* UNUSED */
(void)error_string; /* UNUSED */
(void)a_eno; /* UNUSED */
(void)a_estr; /* UNUSED */
(void)flags; /* UNUSED */
(void)checking_linkname; /* UNUSED */
return (ARCHIVE_OK);
@@ -2859,8 +2886,10 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
/* Check that we haven't hit a symlink. */
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
r = fstatat(chdir_fd, head, &st, AT_SYMLINK_NOFOLLOW);
#else
#elif defined(HAVE_LSTAT)
r = lstat(head, &st);
#else
r = la_stat(head, &st);
#endif
if (r != 0) {
tail[0] = c;
@@ -3558,7 +3587,9 @@ set_time(int fd, int mode, const char *name,
(void)fd; /* UNUSED */
(void)mode; /* UNUSED */
(void)name; /* UNUSED */
(void)atime; /* UNUSED */
(void)atime_nsec; /* UNUSED */
(void)mtime; /* UNUSED */
(void)mtime_nsec; /* UNUSED */
return (ARCHIVE_WARN);
#endif
@@ -4391,7 +4422,12 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname)
*/
archive_strncpy(&datafork, pathname, p - pathname);
archive_strcat(&datafork, p + 2);
if (lstat(datafork.s, &st) == -1 ||
if (
#ifdef HAVE_LSTAT
lstat(datafork.s, &st) == -1 ||
#else
la_stat(datafork.s, &st) == -1 ||
#endif
(st.st_mode & AE_IFMT) != AE_IFREG)
goto skip_appledouble;
@@ -4707,5 +4743,17 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
}
#endif
/*
* Close the file descriptor if one is open.
*/
static void close_file_descriptor(struct archive_write_disk* a)
{
if (a->fd >= 0) {
close(a->fd);
a->fd = -1;
}
}
#endif /* !_WIN32 || __CYGWIN__ */
@@ -254,9 +254,9 @@ static ssize_t _archive_write_disk_data_block(struct archive *, const void *,
* which is high-16-bits of nFileIndexHigh. */
#define bhfi_ino(bhfi) \
((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
+ (bhfi)->nFileIndexLow)
| (bhfi)->nFileIndexLow)
#define bhfi_size(bhfi) \
((((int64_t)(bhfi)->nFileSizeHigh) << 32) + (bhfi)->nFileSizeLow)
((((int64_t)(bhfi)->nFileSizeHigh) << 32) | (bhfi)->nFileSizeLow)
static int
file_information(struct archive_write_disk *a, wchar_t *path,
@@ -266,6 +266,9 @@ file_information(struct archive_write_disk *a, wchar_t *path,
int r;
DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
WIN32_FIND_DATAW findData;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
if (sim_lstat || mode != NULL) {
h = FindFirstFileW(path, &findData);
@@ -290,14 +293,27 @@ file_information(struct archive_write_disk *a, wchar_t *path,
(findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
flag |= FILE_FLAG_OPEN_REPARSE_POINT;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileFlags = flag;
h = CreateFile2(a->name, 0, 0,
OPEN_EXISTING, &createExParams);
#else
h = CreateFileW(a->name, 0, 0, NULL,
OPEN_EXISTING, flag, NULL);
#endif
if (h == INVALID_HANDLE_VALUE &&
GetLastError() == ERROR_INVALID_NAME) {
wchar_t *full;
full = __la_win_permissive_name_w(path);
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
h = CreateFile2(full, 0, 0,
OPEN_EXISTING, &createExParams);
#else
h = CreateFileW(full, 0, 0, NULL,
OPEN_EXISTING, flag, NULL);
#endif
free(full);
}
if (h == INVALID_HANDLE_VALUE) {
@@ -559,6 +575,7 @@ la_mktemp(struct archive_write_disk *a)
return (fd);
}
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
static void *
la_GetFunctionKernel32(const char *name)
{
@@ -574,18 +591,24 @@ la_GetFunctionKernel32(const char *name)
}
return (void *)GetProcAddress(lib, name);
}
#endif
static int
la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
{
static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
static int set;
static BOOL (WINAPI *f)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
BOOL ret;
#if _WIN32_WINNT < _WIN32_WINNT_XP
static int set;
/* CreateHardLinkW is available since XP and always loaded */
if (!set) {
set = 1;
f = la_GetFunctionKernel32("CreateHardLinkW");
}
#else
f = CreateHardLinkW;
#endif
if (!f) {
errno = ENOTSUP;
return (0);
@@ -624,7 +647,6 @@ static int
la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
int linktype) {
static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD);
static int set;
wchar_t *ttarget, *p;
size_t len;
DWORD attrs = 0;
@@ -632,10 +654,20 @@ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
DWORD newflags = 0;
BOOL ret = 0;
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
/* CreateSymbolicLinkW is available since Vista and always loaded */
static int set;
if (!set) {
set = 1;
f = la_GetFunctionKernel32("CreateSymbolicLinkW");
}
#else
# if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
f = CreateSymbolicLinkW;
# else
f = NULL;
# endif
#endif
if (!f)
return (0);
@@ -1185,6 +1217,8 @@ _archive_write_disk_finish_entry(struct archive *_a)
if (la_ftruncate(a->fh, a->filesize) == -1) {
archive_set_error(&a->archive, errno,
"File size could not be restored");
CloseHandle(a->fh);
a->fh = INVALID_HANDLE_VALUE;
return (ARCHIVE_FAILED);
}
}
@@ -1656,6 +1690,9 @@ create_filesystem_object(struct archive_write_disk *a)
mode_t final_mode, mode;
int r;
DWORD attrs = 0;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
/* We identify hard/symlinks according to the link names. */
/* Since link(2) and symlink(2) don't handle modes, we're done here. */
@@ -1719,8 +1756,16 @@ create_filesystem_object(struct archive_write_disk *a)
a->todo = 0;
a->deferred = 0;
} else if (r == 0 && a->filesize > 0) {
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
a->fh = CreateFile2(namefull, GENERIC_WRITE, 0,
TRUNCATE_EXISTING, &createExParams);
#else
a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
#endif
if (a->fh == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
r = errno;
@@ -1783,14 +1828,27 @@ create_filesystem_object(struct archive_write_disk *a)
a->tmpname = NULL;
fullname = a->name;
/* O_WRONLY | O_CREAT | O_EXCL */
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
CREATE_NEW, &createExParams);
#else
a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
#endif
if (a->fh == INVALID_HANDLE_VALUE &&
GetLastError() == ERROR_INVALID_NAME &&
fullname == a->name) {
fullname = __la_win_permissive_name_w(a->name);
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
CREATE_NEW, &createExParams);
#else
a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
#endif
}
if (a->fh == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_ACCESS_DENIED) {
@@ -2551,14 +2609,25 @@ set_times(struct archive_write_disk *a,
hw = NULL;
} else {
wchar_t *ws;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
#endif
if (S_ISLNK(mode))
return (ARCHIVE_OK);
ws = __la_win_permissive_name_w(name);
if (ws == NULL)
goto settimes_failed;
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
ZeroMemory(&createExParams, sizeof(createExParams));
createExParams.dwSize = sizeof(createExParams);
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
hw = CreateFile2(ws, FILE_WRITE_ATTRIBUTES, 0,
OPEN_EXISTING, &createExParams);
#else
hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
#endif
free(ws);
if (hw == INVALID_HANDLE_VALUE)
goto settimes_failed;
@@ -53,6 +53,7 @@ struct archive_write_filter {
const char *key, const char *value);
int (*open)(struct archive_write_filter *);
int (*write)(struct archive_write_filter *, const void *, size_t);
int (*flush)(struct archive_write_filter *);
int (*close)(struct archive_write_filter *);
int (*free)(struct archive_write_filter *);
void *data;
@@ -91,6 +91,26 @@ __FBSDID("$FreeBSD$");
#define kAttributes 0x15
#define kEncodedHeader 0x17
// Check that some windows file attribute constants are defined.
// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
#ifndef FILE_ATTRIBUTE_READONLY
#define FILE_ATTRIBUTE_READONLY 0x00000001
#endif
#ifndef FILE_ATTRIBUTE_DIRECTORY
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#endif
#ifndef FILE_ATTRIBUTE_ARCHIVE
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
#endif
// This value is defined in 7zip with the comment "trick for Unix".
//
// 7z archives created on unix have this bit set in the high 16 bits of
// the attr field along with the unix permissions.
#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
enum la_zaction {
ARCHIVE_Z_FINISH,
ARCHIVE_Z_RUN
@@ -165,7 +185,7 @@ struct file {
mode_t mode;
uint32_t crc32;
signed int dir:1;
unsigned dir:1;
};
struct _7zip {
@@ -1424,14 +1444,19 @@ make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size,
* High 16bits is unix mode.
* Low 16bits is Windows attributes.
*/
uint32_t encattr, attr;
uint32_t encattr, attr = 0;
if (file->dir)
attr = 0x8010;
attr |= FILE_ATTRIBUTE_DIRECTORY;
else
attr = 0x8020;
attr |= FILE_ATTRIBUTE_ARCHIVE;
if ((file->mode & 0222) == 0)
attr |= 1;/* Read Only. */
attr |= FILE_ATTRIBUTE_READONLY;
attr |= FILE_ATTRIBUTE_UNIX_EXTENSION;
attr |= ((uint32_t)file->mode) << 16;
archive_le32enc(&encattr, attr);
r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
if (r < 0)
@@ -1809,11 +1834,11 @@ compression_init_encoder_bzip2(struct archive *a,
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
strm->avail_in = lastrm->avail_in;
strm->avail_in = (uint32_t)lastrm->avail_in;
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
strm->next_out = (char *)lastrm->next_out;
strm->avail_out = lastrm->avail_out;
strm->avail_out = (uint32_t)lastrm->avail_out;
strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
@@ -1842,11 +1867,11 @@ compression_code_bzip2(struct archive *a,
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
strm->avail_in = lastrm->avail_in;
strm->avail_in = (uint32_t)lastrm->avail_in;
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
strm->next_out = (char *)lastrm->next_out;
strm->avail_out = lastrm->avail_out;
strm->avail_out = (uint32_t)lastrm->avail_out;
strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
r = BZ2_bzCompress(strm,
@@ -293,12 +293,12 @@ struct isoent {
struct extr_rec *current;
} extr_rec_list;
signed int virtual:1;
unsigned int virtual:1;
/* If set to one, this file type is a directory.
* A convenience flag to be used as
* "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
*/
signed int dir:1;
unsigned int dir:1;
};
struct hardlink {
@@ -656,7 +656,7 @@ struct iso_option {
#define VOLUME_IDENTIFIER_SIZE 32
/*
* Usage : !zisofs [DEFAULT]
* Usage : !zisofs [DEFAULT]
* : Disable to generate RRIP 'ZF' extension.
* : zisofs
* : Make files zisofs file and generate RRIP 'ZF'
@@ -693,7 +693,7 @@ struct iso9660 {
uint64_t bytes_remaining;
int need_multi_extent;
/* Temporary string buffer for Joliet extension. */
/* Temporary string buffer for Joliet extension. */
struct archive_string utf16be;
struct archive_string mbs;
@@ -759,9 +759,9 @@ struct iso9660 {
/* Used for making zisofs. */
struct {
signed int detect_magic:1;
signed int making:1;
signed int allzero:1;
unsigned int detect_magic:1;
unsigned int making:1;
unsigned int allzero:1;
unsigned char magic_buffer[64];
int magic_cnt;
@@ -2525,12 +2525,11 @@ get_gmoffset(struct tm *tm)
static void
get_tmfromtime(struct tm *tm, time_t *t)
{
#if HAVE_LOCALTIME_R
#if HAVE_LOCALTIME_S
localtime_s(tm, t);
#elif HAVE_LOCALTIME_R
tzset();
localtime_r(t, tm);
#elif HAVE__LOCALTIME64_S
__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
_localtime64_s(tm, &tmp_t);
#else
memcpy(tm, localtime(t), sizeof(*tm));
#endif
@@ -4078,11 +4077,8 @@ write_information_block(struct archive_write *a)
}
memset(info.s, 0, info_size);
opt = 0;
#if defined(HAVE__CTIME64_S)
{
__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
}
#if defined(HAVE_CTIME_S)
ctime_s(buf, sizeof(buf), &(iso9660->birth_time));
#elif defined(HAVE_CTIME_R)
ctime_r(&(iso9660->birth_time), buf);
#else
@@ -7811,8 +7807,8 @@ struct zisofs_extract {
uint64_t pz_uncompressed_size;
size_t uncompressed_buffer_size;
signed int initialized:1;
signed int header_passed:1;
unsigned int initialized:1;
unsigned int header_passed:1;
uint32_t pz_offset;
unsigned char *block_pointers;
@@ -100,6 +100,7 @@ static int has_non_ASCII(const char *);
static void sparse_list_clear(struct pax *);
static int sparse_list_add(struct pax *, int64_t, int64_t);
static char *url_encode(const char *in);
static time_t get_ustar_max_mtime(void);
/*
* Set output format to 'restricted pax' format.
@@ -367,10 +368,12 @@ archive_write_pax_header_xattr(struct pax *pax, const char *encoded_name,
struct archive_string s;
char *encoded_value;
if (encoded_name == NULL)
return;
if (pax->flags & WRITE_LIBARCHIVE_XATTR) {
encoded_value = base64_encode((const char *)value, value_len);
if (encoded_name != NULL && encoded_value != NULL) {
if (encoded_value != NULL) {
archive_string_init(&s);
archive_strcpy(&s, "LIBARCHIVE.xattr.");
archive_strcat(&s, encoded_name);
@@ -403,17 +406,22 @@ archive_write_pax_header_xattrs(struct archive_write *a,
archive_entry_xattr_next(entry, &name, &value, &size);
url_encoded_name = url_encode(name);
if (url_encoded_name != NULL) {
if (url_encoded_name == NULL)
goto malloc_error;
else {
/* Convert narrow-character to UTF-8. */
r = archive_strcpy_l(&(pax->l_url_encoded_name),
url_encoded_name, pax->sconv_utf8);
free(url_encoded_name); /* Done with this. */
if (r == 0)
encoded_name = pax->l_url_encoded_name.s;
else if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Linkname");
return (ARCHIVE_FATAL);
else if (r == -1)
goto malloc_error;
else {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Error encoding pax extended attribute");
return (ARCHIVE_FAILED);
}
}
@@ -422,6 +430,9 @@ archive_write_pax_header_xattrs(struct archive_write *a,
}
return (ARCHIVE_OK);
malloc_error:
archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
return (ARCHIVE_FATAL);
}
static int
@@ -595,6 +606,8 @@ archive_write_pax_header(struct archive_write *a,
need_extension = 0;
pax = (struct pax *)a->format_data;
const time_t ustar_max_mtime = get_ustar_max_mtime();
/* Sanity check. */
if (archive_entry_pathname(entry_original) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1116,16 +1129,13 @@ archive_write_pax_header(struct archive_write *a,
}
/*
* Technically, the mtime field in the ustar header can
* support 33 bits, but many platforms use signed 32-bit time
* values. The cutoff of 0x7fffffff here is a compromise.
* Yes, this check is duplicated just below; this helps to
* avoid writing an mtime attribute just to handle a
* high-resolution timestamp in "restricted pax" mode.
*/
if (!need_extension &&
((archive_entry_mtime(entry_main) < 0)
|| (archive_entry_mtime(entry_main) >= 0x7fffffff)))
|| (archive_entry_mtime(entry_main) >= ustar_max_mtime)))
need_extension = 1;
/* I use a star-compatible file flag attribute. */
@@ -1190,7 +1200,7 @@ archive_write_pax_header(struct archive_write *a,
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
need_extension) {
if (archive_entry_mtime(entry_main) < 0 ||
archive_entry_mtime(entry_main) >= 0x7fffffff ||
archive_entry_mtime(entry_main) >= ustar_max_mtime ||
archive_entry_mtime_nsec(entry_main) != 0)
add_pax_attr_time(&(pax->pax_header), "mtime",
archive_entry_mtime(entry_main),
@@ -1428,7 +1438,7 @@ archive_write_pax_header(struct archive_write *a,
/* Copy mtime, but clip to ustar limits. */
s = archive_entry_mtime(entry_main);
if (s < 0) { s = 0; }
if (s >= 0x7fffffff) { s = 0x7fffffff; }
if (s > ustar_max_mtime) { s = ustar_max_mtime; }
archive_entry_set_mtime(pax_attr_entry, s, 0);
/* Standard ustar doesn't support atime. */
@@ -1904,14 +1914,19 @@ url_encode(const char *in)
{
const char *s;
char *d;
int out_len = 0;
size_t out_len = 0;
char *out;
for (s = in; *s != '\0'; s++) {
if (*s < 33 || *s > 126 || *s == '%' || *s == '=')
if (*s < 33 || *s > 126 || *s == '%' || *s == '=') {
if (SIZE_MAX - out_len < 4)
return (NULL);
out_len += 3;
else
} else {
if (SIZE_MAX - out_len < 2)
return (NULL);
out_len++;
}
}
out = (char *)malloc(out_len + 1);
@@ -2046,3 +2061,18 @@ sparse_list_add(struct pax *pax, int64_t offset, int64_t length)
return (_sparse_list_add_block(pax, offset, length, 0));
}
static time_t
get_ustar_max_mtime(void)
{
/*
* Technically, the mtime field in the ustar header can
* support 33 bits. We are using all of them to keep
* tar/test/test_option_C_mtree.c simple and passing after 2038.
* For platforms that use signed 32-bit time values we
* use the 32-bit maximum.
*/
if (sizeof(time_t) > sizeof(int32_t))
return (time_t)0x1ffffffff;
else
return (time_t)0x7fffffff;
}
@@ -329,30 +329,21 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t)
{
/** like strftime(3) but for time_t objects */
struct tm *rt;
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
struct tm timeHere;
#endif
#if defined(HAVE__GMTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
char strtime[100];
size_t len;
#ifdef HAVE_GMTIME_R
if ((rt = gmtime_r(&t, &timeHere)) == NULL)
return;
#elif defined(HAVE__GMTIME64_S)
tmptime = t;
terr = _gmtime64_s(&timeHere, &tmptime);
if (terr)
rt = NULL;
else
rt = &timeHere;
#if defined(HAVE_GMTIME_S)
rt = gmtime_s(&timeHere, &t) ? NULL : &timeHere;
#elif defined(HAVE_GMTIME_R)
rt = gmtime_r(&t, &timeHere);
#else
if ((rt = gmtime(&t)) == NULL)
return;
rt = gmtime(&t);
#endif
if (!rt)
return;
/* leave the hard yacker to our role model strftime() */
len = strftime(strtime, sizeof(strtime)-1, fmt, rt);
archive_strncat(as, strtime, len);
@@ -212,8 +212,8 @@ struct file {
struct heap_data data;
struct archive_string script;
signed int virtual:1;
signed int dir:1;
unsigned int virtual:1;
unsigned int dir:1;
};
struct hardlink {
@@ -906,15 +906,11 @@ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
{
char timestr[100];
struct tm tm;
#if defined(HAVE__GMTIME64_S)
__time64_t tmptime;
#endif
#if defined(HAVE_GMTIME_R)
#if defined(HAVE_GMTIME_S)
gmtime_s(&tm, &t);
#elif defined(HAVE_GMTIME_R)
gmtime_r(&t, &tm);
#elif defined(HAVE__GMTIME64_S)
tmptime = t;
_gmtime64_s(&tm, &tmptime);
#else
memcpy(&tm, gmtime(&t), sizeof(tm));
#endif
@@ -1382,25 +1382,14 @@ dos_time(const time_t unix_time)
{
struct tm *t;
unsigned int dt;
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
struct tm tmbuf;
#endif
#if defined(HAVE__LOCALTIME64_S)
errno_t terr;
__time64_t tmptime;
#endif
/* This will not preserve time when creating/extracting the archive
* on two systems with different time zones. */
#if defined(HAVE_LOCALTIME_R)
#if defined(HAVE_LOCALTIME_S)
t = localtime_s(&tmbuf, &unix_time) ? NULL : &tmbuf;
#elif defined(HAVE_LOCALTIME_R)
t = localtime_r(&unix_time, &tmbuf);
#elif defined(HAVE__LOCALTIME64_S)
tmptime = unix_time;
terr = _localtime64_s(&tmbuf, &tmptime);
if (terr)
t = NULL;
else
t = &tmbuf;
#else
t = localtime(&unix_time);
#endif
@@ -257,6 +257,15 @@ If supported, the default value is read from
The value is interpreted as a decimal integer specifying the
compression level. Supported values depend on the library version,
common values are from 1 to 22.
.It Cm long
Enables long distance matching. The value is interpreted as a
decimal integer specifying log2 window size in bytes. Values from
10 to 30 for 32 bit, or 31 for 64 bit, are supported.
.It Cm threads
The value is interpreted as a decimal integer specifying the
number of threads for multi-threaded zstd compression.
If set to 0, zstd will attempt to detect and use the number
of physical CPU cores.
.El
.It Format 7zip
.Bl -tag -compact -width indent
@@ -111,6 +111,8 @@
#define HAVE_FCNTL 1
#define HAVE_FCNTL_H 1
#define HAVE_FDOPENDIR 1
#define HAVE_FNMATCH 1
#define HAVE_FNMATCH_H 1
#define HAVE_FORK 1
#define HAVE_FSEEKO 1
#define HAVE_FSTAT 1
@@ -123,6 +125,8 @@
#define HAVE_GETEUID 1
#define HAVE_GETGRGID_R 1
#define HAVE_GETGRNAM_R 1
#define HAVE_GETLINE 1
#define HAVE_GETOPT_OPTRESET 1
#define HAVE_GETPID 1
#define HAVE_GETPWNAM_R 1
#define HAVE_GETPWUID_R 1
@@ -201,6 +205,7 @@
#define HAVE_SYS_MOUNT_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_POLL_H 1
#define HAVE_SYS_QUEUE_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_STATVFS_H 1
#define HAVE_SYS_STAT_H 1
@@ -234,7 +239,7 @@
#define HAVE_WMEMCPY 1
#define HAVE_WMEMMOVE 1
#define HAVE_ZLIB_H 1
#define TIME_WITH_SYS_TIME 1
#define HAVE_SYS_TIME_H 1
#if __FreeBSD_version >= 800505
#define HAVE_LIBLZMA 1
@@ -31,6 +31,7 @@
#include "filter_fork.h"
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/* There are some editions of Windows ("nano server," for example) that
* do not host user32.dll. If we want to keep running on those editions,
* we need to delay-load WaitForInputIdle. */
@@ -224,6 +225,14 @@ fail:
__archive_cmdline_free(acmd);
return ARCHIVE_FAILED;
}
#else /* !WINAPI_PARTITION_DESKTOP */
int
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child)
{
(void)cmd; (void)child_stdin; (void) child_stdout; (void) out_child;
return ARCHIVE_FAILED;
}
#endif /* !WINAPI_PARTITION_DESKTOP */
void
__archive_check_child(int in, int out)
@@ -149,6 +149,10 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
#if GCC_VERSION >= 409
__attribute__((__no_sanitize_undefined__))
#else
# if defined(__clang__)
__attribute__((no_sanitize("undefined")))
# endif
#endif
#if defined(_MSC_VER)
static __inline U32 A32(const void * x)