summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Utilities/cmlibarchive/CMakeLists.txt125
-rw-r--r--Utilities/cmlibarchive/build/cmake/FindPCRE2POSIX.cmake34
-rw-r--r--Utilities/cmlibarchive/build/cmake/config.h.in20
-rwxr-xr-xUtilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh3
-rw-r--r--Utilities/cmlibarchive/build/version2
-rw-r--r--Utilities/cmlibarchive/libarchive/CMakeLists.txt7
-rw-r--r--Utilities/cmlibarchive/libarchive/archive.h12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_acl.c52
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_acl_private.h4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_check_magic.c20
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cmdline.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cmdline_private.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_crc32.h7
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cryptor.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_endian.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.c326
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.h14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_acl.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_locale.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_perms.31
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_private.h10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_sparse.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_stat.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_strmode.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_time.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_xattr.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_getdate.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_getdate.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_match.c29
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_options.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_options_private.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pack_dev.c7
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pathmatch.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pathmatch.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform.h15
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform_acl.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform_xattr.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd8.c5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_private.h14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_random.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_append_filter.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_data.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk.36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_private.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract2.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_filter.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_format.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_free.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_header.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_new.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_fd.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_file.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_filename.c112
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_memory.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_private.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_format.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_options.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_options.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_grzip.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lrzip.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c8
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c45
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c17
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c20
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c43
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c29
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c121
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c15
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c145
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c88
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c2122
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c42
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c534
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.c178
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.h3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string_composition.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string_sprintf.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.c14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_version_details.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_virtual.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.h9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.c14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_grzip.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c138
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_blocksize.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_data.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_private.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_filter.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_finish_entry.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_format.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_free.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_header.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_new.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_fd.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_file.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_filename.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_memory.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_private.h4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_binary.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_odc.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c8
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c17
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c8
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c27
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c195
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_options.311
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_options.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c36
-rw-r--r--Utilities/cmlibarchive/libarchive/config_freebsd.h3
-rw-r--r--Utilities/cmlibarchive/libarchive/cpio.52
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork_posix.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive-formats.52
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive.32
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_changes.32
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_internals.34
-rw-r--r--Utilities/cmlibarchive/libarchive/mtree.51
-rw-r--r--Utilities/cmlibarchive/libarchive/tar.52
185 files changed, 3214 insertions, 1830 deletions
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index e47184b..feeaa3b 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -1,12 +1,19 @@
#
IF(0) # CMake handles policy settings in its own build.
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
+if(APPLE AND CMAKE_VERSION VERSION_LESS "3.17.0")
+ message(WARNING "CMake>=3.17.0 required to make the generated shared library have the same Mach-O headers as autotools")
+endif()
+
if(POLICY CMP0065)
cmake_policy(SET CMP0065 NEW) #3.4 don't use `-rdynamic` with executables
endif()
if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``<PackageName>_ROOT`` variables.
endif()
+if(POLICY CMP0075)
+ cmake_policy(SET CMP0075 NEW) #3.12.0 `check_include_file()`` and friends use ``CMAKE_REQUIRED_LIBRARIES``.
+endif()
ENDIF()
#
PROJECT(libarchive C)
@@ -23,6 +30,7 @@ IF(0) # CMake handles build type selection in its own build.
# Release : Release build
# RelWithDebInfo : Release build with Debug Info
# MinSizeRel : Release Min Size build
+# None : No build type
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
@@ -33,13 +41,15 @@ IF("${cached_type}" STREQUAL "UNINITIALIZED")
SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Build Type" FORCE)
ENDIF("${cached_type}" STREQUAL "UNINITIALIZED")
# Check the Build Type.
-IF(NOT "${CMAKE_BUILD_TYPE}"
- MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
+# Convert the CMAKE_BUILD_TYPE to uppercase to perform a case-insensitive comparison.
+string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER)
+IF(NOT "${CMAKE_BUILD_TYPE_UPPER}"
+ MATCHES "^(DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL|NONE)\$")
MESSAGE(FATAL_ERROR
"Unknown keyword for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n"
- "Acceptable keywords: Debug,Release,RelWithDebInfo,MinSizeRel")
-ENDIF(NOT "${CMAKE_BUILD_TYPE}"
- MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
+ "Acceptable keywords: Debug, Release, RelWithDebInfo, MinSizeRel, None")
+ENDIF(NOT "${CMAKE_BUILD_TYPE_UPPER}"
+ MATCHES "^(DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL|NONE)\$")
ENDIF()
# On MacOS, prefer MacPorts libraries to system libraries.
@@ -81,9 +91,21 @@ SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
# libarchive 3.1 == interface version 13
math(EXPR INTERFACE_VERSION "13 + ${_minor}")
-# Set SOVERSION == Interface version
-# ?? Should there be more here ??
-SET(SOVERSION "${INTERFACE_VERSION}")
+# Set SOVERSION so it matches libtool's conventions
+# libtool accepts a string "current:revision:age"; in libarchive, that's set to
+# - current: ${INTERFACE_VERSION} = 13 + ${_minor}
+# - revision: ${_revision}
+# - age: ${_minor}
+# Since libtool computes SOVERSION as "current - age", it's just '13' again
+math(EXPR SOVERSION "${INTERFACE_VERSION} - ${_minor}")
+set(SOVERSION_FULL "${SOVERSION}.${_trimmed_minor}.${_trimmed_revision}")
+
+# Override CMake's default shared library versioning scheme, which uses SOVERSION and VERSION,
+# to match libtool's conventions (see https://github.com/mesonbuild/meson/issues/1451)
+# - compatibility version: current + 1 = ${INTERFACE_VERSION} + 1
+# - current version: ${current + 1}.${revision}
+math(EXPR MACHO_COMPATIBILITY_VERSION "${INTERFACE_VERSION} + 1")
+set(MACHO_CURRENT_VERSION "${MACHO_COMPATIBILITY_VERSION}.${_revision}")
# Enable CMAKE_PUSH_CHECK_STATE() and CMAKE_POP_CHECK_STATE() macros
# saving and restoring the state of the variables.
@@ -125,7 +147,7 @@ endif ()
# aggressive about diagnosing build problems; this can get
# relaxed somewhat in final shipping versions.
IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
- CMAKE_C_COMPILER_ID MATCHES "^Clang$")
+ CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
#################################################################
# Set compile flags for all build types.
@@ -148,8 +170,6 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
# either of the following two, yet neither is supported as of 3.0.2
# - check_linker_flag - does not exist
# - try_compile - does not support linker flags
- #
- # The CI fails with this on MacOS
IF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
# Place the functions and data into separate sections, allowing the linker
# to garbage collect the unused ones.
@@ -159,9 +179,12 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
# Printing the discarded section is "too much", so enable on demand.
#SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections")
#SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections")
+ ELSE()
+ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip")
+ SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
ENDIF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
- CMAKE_C_COMPILER_ID MATCHES "^Clang$")
+ CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
SET(CMAKE_C_COMPILER "xlc_r")
SET(CMAKE_REQUIRED_FLAGS "-qflag=e:e -qformat=sec")
@@ -241,6 +264,7 @@ OPTION(ENABLE_BZip2 "Enable the use of the system BZip2 library if found" ON)
OPTION(ENABLE_LIBXML2 "Enable the use of the system libxml2 library if found" ON)
OPTION(ENABLE_EXPAT "Enable the use of the system EXPAT library if found" ON)
OPTION(ENABLE_PCREPOSIX "Enable the use of the system PCREPOSIX library if found" ON)
+OPTION(ENABLE_PCRE2POSIX "Enable the use of the system PCRE2POSIX library if found" ON)
OPTION(ENABLE_LIBGCC "Enable the use of the system LibGCC library if found" ON)
# CNG is used for encrypt/decrypt Zip archives on Windows.
OPTION(ENABLE_CNG "Enable the use of CNG(Crypto Next Generation)" ON)
@@ -549,7 +573,7 @@ IF(LIBLZMA_FOUND)
"#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;}"
+ "#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){int ignored __attribute__((unused)); ignored = 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)
@@ -675,13 +699,13 @@ IF(ZSTD_FOUND)
INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY})
SET(HAVE_LIBZSTD 1)
- SET(HAVE_LIBZSTD_COMPRESSOR 1)
+ SET(HAVE_ZSTD_compressStream 1)
IF(0) # CMake expects the zstd library to work.
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY})
SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR})
CHECK_FUNCTION_EXISTS(ZSTD_decompressStream HAVE_LIBZSTD)
- CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD_COMPRESSOR)
+ CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_ZSTD_compressStream)
#
# TODO: test for static library.
#
@@ -766,7 +790,6 @@ 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)
@@ -1220,7 +1243,7 @@ ENDIF(ENABLE_ICONV)
#
# Find Libxml2
#
-IF(ENABLE_LIBXML2)
+IF(ENABLE_LIBXML2 AND HAVE_ICONV)
FIND_PACKAGE(LibXml2)
ELSE()
SET(LIBXML2_FOUND FALSE)
@@ -1379,6 +1402,68 @@ IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$"
MARK_AS_ADVANCED(CLEAR LIBGCC_LIBRARIES)
ENDIF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$")
+IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCRE2POSIX)$")
+ #
+ # If requested, try finding library for PCRE2POSIX
+ #
+ IF(ENABLE_LIBGCC)
+ FIND_PACKAGE(LIBGCC)
+ ELSE()
+ MESSAGE(FATAL_ERROR "libgcc not found.")
+ SET(LIBGCC_FOUND FALSE) # Override cached value
+ ENDIF()
+ IF(ENABLE_PCRE2POSIX)
+ FIND_PACKAGE(PCRE2POSIX)
+ ELSE()
+ SET(PCRE2POSIX_FOUND FALSE) # Override cached value
+ ENDIF()
+ IF(PCRE2POSIX_FOUND)
+ INCLUDE_DIRECTORIES(${PCRE2_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${PCRE2POSIX_LIBRARIES})
+ # Test if a macro is needed for the library.
+ TRY_MACRO_FOR_LIBRARY(
+ "${PCRE2_INCLUDE_DIR}" "${PCRE2POSIX_LIBRARIES}"
+ COMPILES
+ "#include <pcre2posix.h>\nint main() {regex_t r;return pcre2_regcomp(&r, \"\", 0);}"
+ "WITHOUT_PCRE2_STATIC;PCRE2_STATIC")
+ IF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+ ADD_DEFINITIONS(-DPCRE2_STATIC)
+ ELSEIF(NOT WITHOUT_PCRE2_STATIC AND NOT PCRE2_STATIC AND PCRE2_FOUND)
+ # Determine if pcre2 static libraries are to be used.
+ LIST(APPEND ADDITIONAL_LIBS ${PCRE2_LIBRARIES})
+ SET(TMP_LIBRARIES ${PCRE2POSIX_LIBRARIES} ${PCRE2_LIBRARIES})
+ MESSAGE(STATUS "trying again with -lpcre2-8 included")
+ TRY_MACRO_FOR_LIBRARY(
+ "${PCRE2_INCLUDE_DIR}" "${TMP_LIBRARIES}"
+ COMPILES
+ "#include <pcre2posix.h>\nint main() {regex_t r;return pcre2_regcomp(&r, \"\", 0);}"
+ "WITHOUT_PCRE2_STATIC;PCRE2_STATIC")
+ IF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+ ADD_DEFINITIONS(-DPCRE2_STATIC)
+ ELSEIF(NOT WITHOUT_PCRE2_STATIC AND NOT PCRE2_STATIC AND MSVC AND LIBGCC_FOUND)
+ # When doing a Visual Studio build using pcre2 static libraries
+ # built using the mingw toolchain, -lgcc is needed to resolve
+ # ___chkstk_ms.
+ MESSAGE(STATUS "Visual Studio build detected, trying again with -lgcc included")
+ LIST(APPEND ADDITIONAL_LIBS ${LIBGCC_LIBRARIES})
+ SET(TMP_LIBRARIES ${PCRE2POSIX_LIBRARIES} ${PCRE2_LIBRARIES} ${LIBGCC_LIBRARIES})
+ TRY_MACRO_FOR_LIBRARY(
+ "${PCRE2_INCLUDE_DIR}" "${TMP_LIBRARIES}"
+ COMPILES
+ "#include <pcre2posix.h>\nint main() {regex_t r;return pcre2_regcomp(&r, \"\", 0);}"
+ "WITHOUT_PCRE2_STATIC;PCRE2_STATIC")
+ IF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+ ADD_DEFINITIONS(-DPCRE2_STATIC)
+ ENDIF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+ ENDIF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+ ENDIF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+ ENDIF(PCRE2POSIX_FOUND)
+ MARK_AS_ADVANCED(CLEAR PCRE2_INCLUDE_DIR)
+ MARK_AS_ADVANCED(CLEAR PCRE2POSIX_LIBRARIES)
+ MARK_AS_ADVANCED(CLEAR PCRE2_LIBRARIES)
+ MARK_AS_ADVANCED(CLEAR LIBGCC_LIBRARIES)
+ENDIF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCRE2POSIX)$")
+
#
# Check functions
#
@@ -1460,6 +1545,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S)
CHECK_FUNCTION_EXISTS_GLIBC(strnlen HAVE_STRNLEN)
CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
+CHECK_FUNCTION_EXISTS_GLIBC(sysconf HAVE_SYSCONF)
CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT)
@@ -2077,6 +2163,11 @@ IF(APPLE)
ADD_DEFINITIONS(-Wno-deprecated-declarations)
ENDIF(APPLE)
+OPTION(DONT_FAIL_ON_CRC_ERROR "Ignore CRC errors during parsing (For fuzzing)" OFF)
+IF(DONT_FAIL_ON_CRC_ERROR)
+ ADD_DEFINITIONS(-DDONT_FAIL_ON_CRC_ERROR=1)
+ENDIF(DONT_FAIL_ON_CRC_ERROR)
+
IF(ENABLE_TEST)
ADD_CUSTOM_TARGET(run_all_tests)
ENDIF(ENABLE_TEST)
diff --git a/Utilities/cmlibarchive/build/cmake/FindPCRE2POSIX.cmake b/Utilities/cmlibarchive/build/cmake/FindPCRE2POSIX.cmake
new file mode 100644
index 0000000..76bb7a4
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/FindPCRE2POSIX.cmake
@@ -0,0 +1,34 @@
+# - Find pcre2posix
+# Find the native PCRE2-8 and PCRE2-POSIX include and libraries
+#
+# PCRE2_INCLUDE_DIR - where to find pcre2posix.h, etc.
+# PCRE2POSIX_LIBRARIES - List of libraries when using libpcre2-posix.
+# PCRE2_LIBRARIES - List of libraries when using libpcre2-8.
+# PCRE2POSIX_FOUND - True if libpcre2-posix found.
+# PCRE2_FOUND - True if libpcre2-8 found.
+
+IF (PCRE2_INCLUDE_DIR)
+ # Already in cache, be silent
+ SET(PCRE2_FIND_QUIETLY TRUE)
+ENDIF (PCRE2_INCLUDE_DIR)
+
+FIND_PATH(PCRE2_INCLUDE_DIR pcre2posix.h)
+FIND_LIBRARY(PCRE2POSIX_LIBRARY NAMES pcre2-posix libpcre2-posix pcre2-posix-static)
+FIND_LIBRARY(PCRE2_LIBRARY NAMES pcre2-8 libpcre2-8 pcre2-8-static)
+
+# handle the QUIETLY and REQUIRED arguments and set PCRE2POSIX_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2POSIX DEFAULT_MSG PCRE2POSIX_LIBRARY PCRE2_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2 DEFAULT_MSG PCRE2_LIBRARY)
+
+IF(PCRE2POSIX_FOUND)
+ SET(PCRE2POSIX_LIBRARIES ${PCRE2POSIX_LIBRARY})
+ SET(HAVE_LIBPCRE2POSIX 1)
+ SET(HAVE_PCRE2POSIX_H 1)
+ENDIF(PCRE2POSIX_FOUND)
+
+IF(PCRE2_FOUND)
+ SET(PCRE2_LIBRARIES ${PCRE2_LIBRARY})
+ SET(HAVE_LIBPCRE2 1)
+ENDIF(PCRE2_FOUND)
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index 493c388..c3b153d 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -537,6 +537,12 @@
/* Define to 1 if you have the `pcreposix' library (-lpcreposix). */
#cmakedefine HAVE_LIBPCREPOSIX 1
+/* Define to 1 if you have the `pcre2-8' library (-lpcre2-8). */
+#cmakedefine HAVE_LIBPCRE2 1
+
+/* Define to 1 if you have the `pcreposix' library (-lpcre2posix). */
+#cmakedefine HAVE_LIBPCRE2POSIX 1
+
/* Define to 1 if you have the `xml2' library (-lxml2). */
#cmakedefine HAVE_LIBXML2 1
@@ -552,9 +558,8 @@
/* Define to 1 if you have the `zstd' library (-lzstd). */
#cmakedefine HAVE_LIBZSTD 1
-/* Define to 1 if you have the `zstd' library (-lzstd) with compression
- support. */
-#cmakedefine HAVE_LIBZSTD_COMPRESSOR 1
+/* Define to 1 if you have the ZSTD_compressStream function. */
+#cmakedefine HAVE_ZSTD_compressStream 1
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H 1
@@ -710,6 +715,9 @@
/* Define to 1 if you have the <pcreposix.h> header file. */
#cmakedefine HAVE_PCREPOSIX_H 1
+/* Define to 1 if you have the <pcre2posix.h> header file. */
+#cmakedefine HAVE_PCRE2POSIX_H 1
+
/* Define to 1 if you have the `pipe' function. */
#cmakedefine HAVE_PIPE 1
@@ -867,6 +875,9 @@
/* Define to 1 if you have the `symlink' function. */
#cmakedefine HAVE_SYMLINK 1
+/* Define to 1 if you have the `sysconf' function. */
+#cmakedefine HAVE_SYSCONF 1
+
/* Define to 1 if you have the <sys/acl.h> header file. */
#cmakedefine HAVE_SYS_ACL_H 1
@@ -902,9 +913,6 @@
/* 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
diff --git a/Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh b/Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh
index 558e9c0..93012fe 100755
--- a/Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh
+++ b/Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh
@@ -39,9 +39,6 @@ cat > ${outfile} <<CR_END
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * \$FreeBSD\$
- *
*/
/*
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
index 414ae6d..49ac2b5 100644
--- a/Utilities/cmlibarchive/build/version
+++ b/Utilities/cmlibarchive/build/version
@@ -1 +1 @@
-3007002
+3007005
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index ac0bd2c..2a7d9c6 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -256,11 +256,16 @@ 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})
+ SET_TARGET_PROPERTIES(archive PROPERTIES
+ VERSION ${SOVERSION_FULL}
+ SOVERSION ${SOVERSION}
+ MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
+ MACHO_CURRENT_VERSION ${MACHO_CURRENT_VERSION})
ENDIF(BUILD_SHARED_LIBS)
# archive_static is a static library
ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
+TARGET_INCLUDE_DIRECTORIES(archive_static PUBLIC .)
TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index a89f33b..c4a0690 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.50 2008/05/26 17:00:22 kientzle Exp $
*/
#ifndef ARCHIVE_H_INCLUDED
@@ -36,7 +34,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3007002
+#define ARCHIVE_VERSION_NUMBER 3007005
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -154,7 +152,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.7.2"
+#define ARCHIVE_VERSION_ONLY_STRING "3.7.5"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@@ -532,6 +530,10 @@ __LA_DECL int archive_read_open_filenames(struct archive *,
const char **_filenames, size_t _block_size);
__LA_DECL int archive_read_open_filename_w(struct archive *,
const wchar_t *_filename, size_t _block_size);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+__LA_DECL int archive_read_open_filenames_w(struct archive *,
+ const wchar_t **_filenames, size_t _block_size);
+#endif
/* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */
__LA_DECL int archive_read_open_file(struct archive *,
const char *_filename, size_t _block_size) __LA_DEPRECATED;
@@ -890,7 +892,7 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
const char *opts);
/*
- * Set a encryption passphrase.
+ * Set an encryption passphrase.
*/
__LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p);
__LA_DECL int archive_write_set_passphrase_callback(struct archive *,
diff --git a/Utilities/cmlibarchive/libarchive/archive_acl.c b/Utilities/cmlibarchive/libarchive/archive_acl.c
index da471a5..51a0881 100644
--- a/Utilities/cmlibarchive/libarchive/archive_acl.c
+++ b/Utilities/cmlibarchive/libarchive/archive_acl.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -81,7 +80,7 @@ static int is_nfs4_flags(const char *start, const char *end,
int *result);
static int is_nfs4_perms(const char *start, const char *end,
int *result);
-static void next_field(const char **p, const char **start,
+static void next_field(const char **p, size_t *l, const char **start,
const char **end, char *sep);
static void append_entry(char **p, const char *prefix, int type,
int tag, int flags, const char *name, int perm, int id);
@@ -1628,6 +1627,13 @@ int
archive_acl_from_text_l(struct archive_acl *acl, const char *text,
int want_type, struct archive_string_conv *sc)
{
+ return archive_acl_from_text_nl(acl, text, strlen(text), want_type, sc);
+}
+
+int
+archive_acl_from_text_nl(struct archive_acl *acl, const char *text,
+ size_t length, int want_type, struct archive_string_conv *sc)
+{
struct {
const char *start;
const char *end;
@@ -1657,7 +1663,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
ret = ARCHIVE_OK;
types = 0;
- while (text != NULL && *text != '\0') {
+ while (text != NULL && length > 0 && *text != '\0') {
/*
* Parse the fields out of the next entry,
* advance 'text' to start of next entry.
@@ -1665,7 +1671,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
fields = 0;
do {
const char *start, *end;
- next_field(&text, &start, &end, &sep);
+ next_field(&text, &length, &start, &end, &sep);
if (fields < numfields) {
field[fields].start = start;
field[fields].end = end;
@@ -2058,7 +2064,7 @@ is_nfs4_flags(const char *start, const char *end, int *permset)
}
/*
- * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
+ * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *p is updated
* to point to just after the separator. *start points to the first
* character of the matched text and *end just after the last
* character of the matched identifier. In particular *end - *start
@@ -2066,42 +2072,42 @@ is_nfs4_flags(const char *start, const char *end, int *permset)
* whitespace.
*/
static void
-next_field(const char **p, const char **start,
+next_field(const char **p, size_t *l, const char **start,
const char **end, char *sep)
{
/* Skip leading whitespace to find start of field. */
- while (**p == ' ' || **p == '\t' || **p == '\n') {
+ while (*l > 0 && (**p == ' ' || **p == '\t' || **p == '\n')) {
(*p)++;
+ (*l)--;
}
*start = *p;
- /* Scan for the separator. */
- while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
- **p != '#') {
+ /* Locate end of field, trim trailing whitespace if necessary */
+ while (*l > 0 && **p != ' ' && **p != '\t' && **p != '\n' && **p != ',' && **p != ':' && **p != '#') {
(*p)++;
+ (*l)--;
}
- *sep = **p;
+ *end = *p;
- /* Locate end of field, trim trailing whitespace if necessary */
- if (*p == *start) {
- *end = *p;
- } else {
- *end = *p - 1;
- while (**end == ' ' || **end == '\t' || **end == '\n') {
- (*end)--;
- }
- (*end)++;
+ /* Scan for the separator. */
+ while (*l > 0 && **p != ',' && **p != ':' && **p != '\n' && **p != '#') {
+ (*p)++;
+ (*l)--;
}
+ *sep = **p;
/* Handle in-field comments */
if (*sep == '#') {
- while (**p != '\0' && **p != ',' && **p != '\n') {
+ while (*l > 0 && **p != ',' && **p != '\n') {
(*p)++;
+ (*l)--;
}
*sep = **p;
}
- /* Adjust scanner location. */
- if (**p != '\0')
+ /* Skip separator. */
+ if (*l > 0) {
(*p)++;
+ (*l)--;
+ }
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_acl_private.h b/Utilities/cmlibarchive/libarchive/archive_acl_private.h
index af10816..2c9b505 100644
--- a/Utilities/cmlibarchive/libarchive/archive_acl_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_acl_private.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
@@ -79,5 +77,7 @@ int archive_acl_from_text_w(struct archive_acl *, const wchar_t * /* wtext */,
int /* type */);
int archive_acl_from_text_l(struct archive_acl *, const char * /* text */,
int /* type */, struct archive_string_conv *);
+int archive_acl_from_text_nl(struct archive_acl *, const char * /* text */,
+ size_t /* size of text */, int /* type */, struct archive_string_conv *);
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_check_magic.c b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
index 1f40072..d12f0c4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_check_magic.c
+++ b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_check_magic.c 201089 2009-12-28 02:20:23Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -62,7 +61,7 @@ errmsg(const char *m)
}
}
-static __LA_DEAD void
+static __LA_NORETURN void
diediedie(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
@@ -99,13 +98,12 @@ archive_handle_type_name(unsigned m)
}
}
-
-static char *
+static void
write_all_states(char *buff, unsigned int states)
{
unsigned int lowbit;
- buff[0] = '\0';
+ *buff = '\0';
/* A trick for computing the lowest set bit. */
while ((lowbit = states & (1 + ~states)) != 0) {
@@ -114,7 +112,6 @@ write_all_states(char *buff, unsigned int states)
if (states != 0)
strcat(buff, "/");
}
- return buff;
}
/*
@@ -160,16 +157,19 @@ __archive_check_magic(struct archive *a, unsigned int magic,
if ((a->state & state) == 0) {
/* If we're already FATAL, don't overwrite the error. */
- if (a->state != ARCHIVE_STATE_FATAL)
+ if (a->state != ARCHIVE_STATE_FATAL) {
+ write_all_states(states1, a->state);
+ write_all_states(states2, state);
archive_set_error(a, -1,
"INTERNAL ERROR: Function '%s' invoked with"
" archive structure in state '%s',"
" should be in state '%s'",
function,
- write_all_states(states1, a->state),
- write_all_states(states2, state));
+ states1,
+ states2);
+ }
a->state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
- return ARCHIVE_OK;
+ return (ARCHIVE_OK);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_cmdline.c b/Utilities/cmlibarchive/libarchive/archive_cmdline.c
index 5c519cd..2e5428c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cmdline.c
+++ b/Utilities/cmlibarchive/libarchive/archive_cmdline.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_STRING_H
# include <string.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_cmdline_private.h b/Utilities/cmlibarchive/libarchive/archive_cmdline_private.h
index 57a1949..7495dfe 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cmdline_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_cmdline_private.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef ARCHIVE_CMDLINE_PRIVATE_H
diff --git a/Utilities/cmlibarchive/libarchive/archive_crc32.h b/Utilities/cmlibarchive/libarchive/archive_crc32.h
index 4f1aed3..d86a507 100644
--- a/Utilities/cmlibarchive/libarchive/archive_crc32.h
+++ b/Utilities/cmlibarchive/libarchive/archive_crc32.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_crc32.h 201102 2009-12-28 03:11:36Z kientzle $
*/
#ifndef ARCHIVE_CRC32_H
@@ -32,6 +30,8 @@
#error This header is only to be used internally to libarchive.
#endif
+#include <stddef.h>
+
/*
* When zlib is unavailable, we should still be able to validate
* uncompressed zip archives. That requires us to be able to compute
@@ -48,6 +48,9 @@ crc32(unsigned long crc, const void *_p, size_t len)
static volatile int crc_tbl_inited = 0;
static unsigned long crc_tbl[256];
+ if (_p == NULL)
+ return (0);
+
if (!crc_tbl_inited) {
for (b = 0; b < 256; ++b) {
crc2 = b;
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor.c b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
index 112baf1..437dba0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cryptor.c
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
@@ -424,8 +424,8 @@ static int
aes_ctr_release(archive_crypto_ctx *ctx)
{
EVP_CIPHER_CTX_free(ctx->ctx);
- memset(ctx->key, 0, ctx->key_len);
- memset(ctx->nonce, 0, sizeof(ctx->nonce));
+ OPENSSL_cleanse(ctx->key, ctx->key_len);
+ OPENSSL_cleanse(ctx->nonce, sizeof(ctx->nonce));
return 0;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_endian.h b/Utilities/cmlibarchive/libarchive/archive_endian.h
index e6d3f2c..83b2efa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_endian.h
+++ b/Utilities/cmlibarchive/libarchive/archive_endian.h
@@ -23,8 +23,6 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/lib/libarchive/archive_endian.h 201085 2009-12-28 02:17:15Z kientzle $
- *
* Borrowed from FreeBSD's <sys/endian.h>
*/
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.3 b/Utilities/cmlibarchive/libarchive/archive_entry.3
index 2f62a4b..0fc0f8c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.3
@@ -23,8 +23,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_ENTRY 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.c b/Utilities/cmlibarchive/libarchive/archive_entry.c
index ae6dc33..f68fee6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:27Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -119,7 +118,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:
static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear);
static const wchar_t *ae_wcstofflags(const wchar_t *stringp,
unsigned long *setp, unsigned long *clrp);
-static const char *ae_strtofflags(const char *stringp,
+static const char *ae_strtofflags(const char *stringp, size_t length,
unsigned long *setp, unsigned long *clrp);
#ifndef HAVE_WCSCPY
@@ -158,10 +157,9 @@ archive_entry_clear(struct archive_entry *entry)
return (NULL);
archive_mstring_clean(&entry->ae_fflags_text);
archive_mstring_clean(&entry->ae_gname);
- archive_mstring_clean(&entry->ae_hardlink);
+ archive_mstring_clean(&entry->ae_linkname);
archive_mstring_clean(&entry->ae_pathname);
archive_mstring_clean(&entry->ae_sourcepath);
- archive_mstring_clean(&entry->ae_symlink);
archive_mstring_clean(&entry->ae_uname);
archive_entry_copy_mac_metadata(entry, NULL, 0);
archive_acl_clear(&entry->acl);
@@ -196,10 +194,9 @@ archive_entry_clone(struct archive_entry *entry)
* character sets are different? XXX */
archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
- archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
+ archive_mstring_copy(&entry2->ae_linkname, &entry->ae_linkname);
archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
- archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
entry2->ae_set = entry->ae_set;
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
@@ -372,6 +369,12 @@ archive_entry_filetype(struct archive_entry *entry)
return (AE_IFMT & entry->acl.mode);
}
+int
+archive_entry_filetype_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_FILETYPE);
+}
+
void
archive_entry_fflags(struct archive_entry *entry,
unsigned long *set, unsigned long *clear)
@@ -425,6 +428,12 @@ archive_entry_gid(struct archive_entry *entry)
return (entry->ae_stat.aest_gid);
}
+int
+archive_entry_gid_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_GID);
+}
+
const char *
archive_entry_gname(struct archive_entry *entry)
{
@@ -466,6 +475,15 @@ _archive_entry_gname_l(struct archive_entry *entry,
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
}
+void
+archive_entry_set_link_to_hardlink(struct archive_entry *entry)
+{
+ if ((entry->ae_set & AE_SET_SYMLINK) != 0) {
+ entry->ae_set &= ~AE_SET_SYMLINK;
+ }
+ entry->ae_set |= AE_SET_HARDLINK;
+}
+
const char *
archive_entry_hardlink(struct archive_entry *entry)
{
@@ -473,7 +491,7 @@ archive_entry_hardlink(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
return (NULL);
if (archive_mstring_get_mbs(
- entry->archive, &entry->ae_hardlink, &p) == 0)
+ entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@@ -487,7 +505,7 @@ archive_entry_hardlink_utf8(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
return (NULL);
if (archive_mstring_get_utf8(
- entry->archive, &entry->ae_hardlink, &p) == 0)
+ entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@@ -501,7 +519,7 @@ archive_entry_hardlink_w(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
return (NULL);
if (archive_mstring_get_wcs(
- entry->archive, &entry->ae_hardlink, &p) == 0)
+ entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@@ -509,6 +527,12 @@ archive_entry_hardlink_w(struct archive_entry *entry)
}
int
+archive_entry_hardlink_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_HARDLINK) != 0;
+}
+
+int
_archive_entry_hardlink_l(struct archive_entry *entry,
const char **p, size_t *len, struct archive_string_conv *sc)
{
@@ -517,7 +541,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
*len = 0;
return (0);
}
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
}
la_int64_t
@@ -631,32 +655,56 @@ archive_entry_perm(struct archive_entry *entry)
return (~AE_IFMT & entry->acl.mode);
}
+int
+archive_entry_perm_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_PERM);
+}
+
+int
+archive_entry_rdev_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_RDEV);
+}
+
dev_t
archive_entry_rdev(struct archive_entry *entry)
{
- if (entry->ae_stat.aest_rdev_is_broken_down)
- return ae_makedev(entry->ae_stat.aest_rdevmajor,
- entry->ae_stat.aest_rdevminor);
- else
- return (entry->ae_stat.aest_rdev);
+ if (archive_entry_rdev_is_set(entry)) {
+ if (entry->ae_stat.aest_rdev_is_broken_down)
+ return ae_makedev(entry->ae_stat.aest_rdevmajor,
+ entry->ae_stat.aest_rdevminor);
+ else
+ return (entry->ae_stat.aest_rdev);
+ } else {
+ return 0;
+ }
}
dev_t
archive_entry_rdevmajor(struct archive_entry *entry)
{
- if (entry->ae_stat.aest_rdev_is_broken_down)
- return (entry->ae_stat.aest_rdevmajor);
- else
- return major(entry->ae_stat.aest_rdev);
+ if (archive_entry_rdev_is_set(entry)) {
+ if (entry->ae_stat.aest_rdev_is_broken_down)
+ return (entry->ae_stat.aest_rdevmajor);
+ else
+ return major(entry->ae_stat.aest_rdev);
+ } else {
+ return 0;
+ }
}
dev_t
archive_entry_rdevminor(struct archive_entry *entry)
{
- if (entry->ae_stat.aest_rdev_is_broken_down)
- return (entry->ae_stat.aest_rdevminor);
- else
- return minor(entry->ae_stat.aest_rdev);
+ if (archive_entry_rdev_is_set(entry)) {
+ if (entry->ae_stat.aest_rdev_is_broken_down)
+ return (entry->ae_stat.aest_rdevminor);
+ else
+ return minor(entry->ae_stat.aest_rdev);
+ } else {
+ return 0;
+ }
}
la_int64_t
@@ -700,13 +748,22 @@ archive_entry_symlink(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
return (NULL);
if (archive_mstring_get_mbs(
- entry->archive, &entry->ae_symlink, &p) == 0)
+ entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL);
}
+void
+archive_entry_set_link_to_symlink(struct archive_entry *entry)
+{
+ if ((entry->ae_set & AE_SET_HARDLINK) != 0) {
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ }
+ entry->ae_set |= AE_SET_SYMLINK;
+}
+
int
archive_entry_symlink_type(struct archive_entry *entry)
{
@@ -720,7 +777,7 @@ archive_entry_symlink_utf8(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
return (NULL);
if (archive_mstring_get_utf8(
- entry->archive, &entry->ae_symlink, &p) == 0)
+ entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@@ -734,7 +791,7 @@ archive_entry_symlink_w(struct archive_entry *entry)
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
return (NULL);
if (archive_mstring_get_wcs(
- entry->archive, &entry->ae_symlink, &p) == 0)
+ entry->archive, &entry->ae_linkname, &p) == 0)
return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@@ -750,7 +807,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
*len = 0;
return (0);
}
- return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
}
la_int64_t
@@ -759,6 +816,12 @@ archive_entry_uid(struct archive_entry *entry)
return (entry->ae_stat.aest_uid);
}
+int
+archive_entry_uid_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_UID);
+}
+
const char *
archive_entry_uname(struct archive_entry *entry)
{
@@ -827,6 +890,7 @@ archive_entry_set_filetype(struct archive_entry *entry, unsigned int type)
entry->stat_valid = 0;
entry->acl.mode &= ~AE_IFMT;
entry->acl.mode |= AE_IFMT & type;
+ entry->ae_set |= AE_SET_FILETYPE;
}
void
@@ -840,10 +904,17 @@ archive_entry_set_fflags(struct archive_entry *entry,
const char *
archive_entry_copy_fflags_text(struct archive_entry *entry,
- const char *flags)
+ const char *flags)
{
- archive_mstring_copy_mbs(&entry->ae_fflags_text, flags);
- return (ae_strtofflags(flags,
+ return archive_entry_copy_fflags_text_len(entry, flags, strlen(flags));
+}
+
+const char *
+archive_entry_copy_fflags_text_len(struct archive_entry *entry,
+ const char *flags, size_t flags_length)
+{
+ archive_mstring_copy_mbs_len(&entry->ae_fflags_text, flags, flags_length);
+ return (ae_strtofflags(flags, flags_length,
&entry->ae_fflags_set, &entry->ae_fflags_clear));
}
@@ -859,8 +930,12 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
void
archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
{
+ if (g < 0) {
+ g = 0;
+ }
entry->stat_valid = 0;
entry->ae_stat.aest_gid = g;
+ entry->ae_set |= AE_SET_GID;
}
void
@@ -908,6 +983,9 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
void
archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
{
+ if (ino < 0) {
+ ino = 0;
+ }
entry->stat_valid = 0;
entry->ae_set |= AE_SET_INO;
entry->ae_stat.aest_ino = ino;
@@ -916,6 +994,9 @@ archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
void
archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
{
+ if (ino < 0) {
+ ino = 0;
+ }
entry->stat_valid = 0;
entry->ae_set |= AE_SET_INO;
entry->ae_stat.aest_ino = ino;
@@ -924,17 +1005,24 @@ archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
void
archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
{
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
- if (target != NULL)
- entry->ae_set |= AE_SET_HARDLINK;
- else
+ if (target == NULL) {
entry->ae_set &= ~AE_SET_HARDLINK;
+ if (entry->ae_set & AE_SET_SYMLINK) {
+ return;
+ }
+ } else {
+ entry->ae_set |= AE_SET_HARDLINK;
+ }
+ entry->ae_set &= ~AE_SET_SYMLINK;
+ archive_mstring_copy_mbs(&entry->ae_linkname, target);
}
void
archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
{
- archive_mstring_copy_utf8(&entry->ae_hardlink, target);
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+ return;
+ archive_mstring_copy_utf8(&entry->ae_linkname, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@@ -944,7 +1032,9 @@ archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
void
archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
{
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+ return;
+ archive_mstring_copy_mbs(&entry->ae_linkname, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@@ -954,7 +1044,9 @@ archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
void
archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target)
{
- archive_mstring_copy_wcs(&entry->ae_hardlink, target);
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+ return;
+ archive_mstring_copy_wcs(&entry->ae_linkname, target);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
@@ -964,12 +1056,14 @@ archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target
int
archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target)
{
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+ return (0);
if (target != NULL)
entry->ae_set |= AE_SET_HARDLINK;
else
entry->ae_set &= ~AE_SET_HARDLINK;
if (archive_mstring_update_utf8(entry->archive,
- &entry->ae_hardlink, target) == 0)
+ &entry->ae_linkname, target) == 0)
return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@@ -982,7 +1076,9 @@ _archive_entry_copy_hardlink_l(struct archive_entry *entry,
{
int r;
- r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
+ if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+ return (0);
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
target, len, sc);
if (target != NULL && r == 0)
entry->ae_set |= AE_SET_HARDLINK;
@@ -1073,51 +1169,50 @@ archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
void
archive_entry_set_link(struct archive_entry *entry, const char *target)
{
- if (entry->ae_set & AE_SET_SYMLINK)
- archive_mstring_copy_mbs(&entry->ae_symlink, target);
- else
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
+ archive_mstring_copy_mbs(&entry->ae_linkname, target);
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+ entry->ae_set |= AE_SET_HARDLINK;
+ }
}
void
archive_entry_set_link_utf8(struct archive_entry *entry, const char *target)
{
- if (entry->ae_set & AE_SET_SYMLINK)
- archive_mstring_copy_utf8(&entry->ae_symlink, target);
- else
- archive_mstring_copy_utf8(&entry->ae_hardlink, target);
+ archive_mstring_copy_utf8(&entry->ae_linkname, target);
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+ entry->ae_set |= AE_SET_HARDLINK;
+ }
}
/* Set symlink if symlink is already set, else set hardlink. */
void
archive_entry_copy_link(struct archive_entry *entry, const char *target)
{
- if (entry->ae_set & AE_SET_SYMLINK)
- archive_mstring_copy_mbs(&entry->ae_symlink, target);
- else
- archive_mstring_copy_mbs(&entry->ae_hardlink, target);
+ archive_mstring_copy_mbs(&entry->ae_linkname, target);
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+ entry->ae_set |= AE_SET_HARDLINK;
+ }
}
/* Set symlink if symlink is already set, else set hardlink. */
void
archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target)
{
- if (entry->ae_set & AE_SET_SYMLINK)
- archive_mstring_copy_wcs(&entry->ae_symlink, target);
- else
- archive_mstring_copy_wcs(&entry->ae_hardlink, target);
+ archive_mstring_copy_wcs(&entry->ae_linkname, target);
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+ entry->ae_set |= AE_SET_HARDLINK;
+ }
}
int
archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
{
int r;
- if (entry->ae_set & AE_SET_SYMLINK)
- r = archive_mstring_update_utf8(entry->archive,
- &entry->ae_symlink, target);
- else
- r = archive_mstring_update_utf8(entry->archive,
- &entry->ae_hardlink, target);
+ r = archive_mstring_update_utf8(entry->archive,
+ &entry->ae_linkname, target);
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+ entry->ae_set |= AE_SET_HARDLINK;
+ }
if (r == 0)
return (1);
if (errno == ENOMEM)
@@ -1131,12 +1226,11 @@ _archive_entry_copy_link_l(struct archive_entry *entry,
{
int r;
- if (entry->ae_set & AE_SET_SYMLINK)
- r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
- target, len, sc);
- else
- r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
target, len, sc);
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+ entry->ae_set |= AE_SET_HARDLINK;
+ }
return (r);
}
@@ -1145,6 +1239,7 @@ archive_entry_set_mode(struct archive_entry *entry, mode_t m)
{
entry->stat_valid = 0;
entry->acl.mode = m;
+ entry->ae_set |= AE_SET_PERM | AE_SET_FILETYPE;
}
void
@@ -1220,6 +1315,7 @@ archive_entry_set_perm(struct archive_entry *entry, mode_t p)
entry->stat_valid = 0;
entry->acl.mode &= AE_IFMT;
entry->acl.mode |= ~AE_IFMT & p;
+ entry->ae_set |= AE_SET_PERM;
}
void
@@ -1228,6 +1324,9 @@ archive_entry_set_rdev(struct archive_entry *entry, dev_t m)
entry->stat_valid = 0;
entry->ae_stat.aest_rdev = m;
entry->ae_stat.aest_rdev_is_broken_down = 0;
+ entry->ae_stat.aest_rdevmajor = 0;
+ entry->ae_stat.aest_rdevminor = 0;
+ entry->ae_set |= AE_SET_RDEV;
}
void
@@ -1235,7 +1334,9 @@ archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m)
{
entry->stat_valid = 0;
entry->ae_stat.aest_rdev_is_broken_down = 1;
+ entry->ae_stat.aest_rdev = 0;
entry->ae_stat.aest_rdevmajor = m;
+ entry->ae_set |= AE_SET_RDEV;
}
void
@@ -1243,12 +1344,17 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
{
entry->stat_valid = 0;
entry->ae_stat.aest_rdev_is_broken_down = 1;
+ entry->ae_stat.aest_rdev = 0;
entry->ae_stat.aest_rdevminor = m;
+ entry->ae_set |= AE_SET_RDEV;
}
void
archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
{
+ if (s < 0) {
+ s = 0;
+ }
entry->stat_valid = 0;
entry->ae_stat.aest_size = s;
entry->ae_set |= AE_SET_SIZE;
@@ -1276,11 +1382,14 @@ archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path
void
archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
{
- archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+ return;
+ archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
+ else
+ entry->ae_set |= AE_SET_SYMLINK;
}
void
@@ -1292,42 +1401,54 @@ archive_entry_set_symlink_type(struct archive_entry *entry, int type)
void
archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
{
- archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+ return;
+ archive_mstring_copy_utf8(&entry->ae_linkname, linkname);
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
+ else
+ entry->ae_set |= AE_SET_SYMLINK;
}
void
archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
{
- archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+ return;
+ archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
+ else
+ entry->ae_set |= AE_SET_SYMLINK;
}
void
archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname)
{
- archive_mstring_copy_wcs(&entry->ae_symlink, linkname);
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+ return;
+ archive_mstring_copy_wcs(&entry->ae_linkname, linkname);
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
+ else
+ entry->ae_set |= AE_SET_SYMLINK;
}
int
archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname)
{
- if (linkname != NULL)
- entry->ae_set |= AE_SET_SYMLINK;
- else
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+ return (0);
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ if (linkname == NULL)
entry->ae_set &= ~AE_SET_SYMLINK;
+ else
+ entry->ae_set |= AE_SET_SYMLINK;
if (archive_mstring_update_utf8(entry->archive,
- &entry->ae_symlink, linkname) == 0)
+ &entry->ae_linkname, linkname) == 0)
return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
@@ -1340,20 +1461,27 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
{
int r;
- r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
+ if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+ return (0);
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
linkname, len, sc);
- if (linkname != NULL && r == 0)
- entry->ae_set |= AE_SET_SYMLINK;
- else
+ if (linkname == NULL || r != 0)
entry->ae_set &= ~AE_SET_SYMLINK;
+ else
+ entry->ae_set |= AE_SET_SYMLINK;
return (r);
}
void
archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
{
+ if (u < 0) {
+ u = 0;
+ }
entry->stat_valid = 0;
entry->ae_stat.aest_uid = u;
+ entry->ae_set |= AE_SET_UID;
}
void
@@ -2003,7 +2131,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
* provided string.
*/
static const char *
-ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
+ae_strtofflags(const char *s, size_t l, unsigned long *setp, unsigned long *clrp)
{
const char *start, *end;
const struct flag *flag;
@@ -2014,15 +2142,19 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
start = s;
failed = NULL;
/* Find start of first token. */
- while (*start == '\t' || *start == ' ' || *start == ',')
+ while (l > 0 && (*start == '\t' || *start == ' ' || *start == ',')) {
start++;
- while (*start != '\0') {
+ l--;
+ }
+ while (l > 0) {
size_t length;
/* Locate end of token. */
end = start;
- while (*end != '\0' && *end != '\t' &&
- *end != ' ' && *end != ',')
+ while (l > 0 && *end != '\t' &&
+ *end != ' ' && *end != ',') {
end++;
+ l--;
+ }
length = end - start;
for (flag = fileflags; flag->name != NULL; flag++) {
size_t flag_length = strlen(flag->name);
@@ -2046,8 +2178,10 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
/* Find start of next token. */
start = end;
- while (*start == '\t' || *start == ' ' || *start == ',')
+ while (l > 0 && (*start == '\t' || *start == ' ' || *start == ',')) {
start++;
+ l--;
+ }
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index 0e4ccbb..f89bdb9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -22,15 +22,13 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $
*/
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3007002
+#define ARCHIVE_VERSION_NUMBER 3007005
/*
* Note: archive_entry.h is for use outside of libarchive; the
@@ -248,17 +246,21 @@ __LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
+__LA_DECL int archive_entry_filetype_is_set(struct archive_entry *);
__LA_DECL void archive_entry_fflags(struct archive_entry *,
unsigned long * /* set */,
unsigned long * /* clear */);
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_gid(struct archive_entry *);
+__LA_DECL int archive_entry_gid_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
+__LA_DECL void archive_entry_set_link_to_hardlink(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
+__LA_DECL int archive_entry_hardlink_is_set(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *);
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
@@ -271,6 +273,8 @@ __LA_DECL const char *archive_entry_pathname(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
+__LA_DECL int archive_entry_perm_is_set(struct archive_entry *);
+__LA_DECL int archive_entry_rdev_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
@@ -279,11 +283,13 @@ __LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_size(struct archive_entry *);
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
+__LA_DECL void archive_entry_set_link_to_symlink(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
+__LA_DECL int archive_entry_uid_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
__LA_DECL const char *archive_entry_uname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
@@ -319,6 +325,8 @@ __LA_DECL void archive_entry_set_fflags(struct archive_entry *,
/* Note that all recognized tokens are processed, regardless. */
__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
const char *);
+__LA_DECL const char *archive_entry_copy_fflags_text_len(struct archive_entry *,
+ const char *, size_t);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t);
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3 b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
index 50dd642..4d0d8b5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
@@ -383,7 +383,7 @@ Prefix each default ACL entry with the word
The mask and other ACLs don not contain a double colon.
.El
.Pp
-The following flags are effecive only on NFSv4 ACL:
+The following flags are effective only on NFSv4 ACL:
.Bl -tag -offset indent -compact -width ARCHIV
.It Dv ARCHIVE_ENTRY_ACL_STYLE_COMPACT
Do not output minus characters for unset permissions and flags in NFSv4 ACL
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c b/Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c
index 77bf38e..d5317a5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#include "archive_private.h"
#include "archive_entry.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c b/Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c
index ac83868..f9c2e84 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03-07 00:52:02Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c b/Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c
index c7d5949..c2fd689 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 2009-12-28 03:05:31Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -202,16 +201,26 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
le = find_entry(res, *e);
if (le != NULL) {
archive_entry_unset_size(*e);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ archive_entry_copy_hardlink_w(*e,
+ archive_entry_pathname_w(le->canonical));
+#else
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
+#endif
} else
insert_entry(res, *e);
return;
case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
le = find_entry(res, *e);
if (le != NULL) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ archive_entry_copy_hardlink_w(*e,
+ archive_entry_pathname_w(le->canonical));
+#else
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
+#endif
} else
insert_entry(res, *e);
return;
@@ -230,8 +239,13 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
le->entry = t;
/* Make the old entry into a hardlink. */
archive_entry_unset_size(*e);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ archive_entry_copy_hardlink_w(*e,
+ archive_entry_pathname_w(le->canonical));
+#else
archive_entry_copy_hardlink(*e,
archive_entry_pathname(le->canonical));
+#endif
/* If we ran out of links, return the
* final entry as well. */
if (le->links == 0) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_locale.h b/Utilities/cmlibarchive/libarchive/archive_entry_locale.h
index 803c036..1b90c57 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_locale.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_locale.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3 b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
index 0291b7b..4bfbfc3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
@@ -150,6 +150,7 @@ character strings at the same time.
.Fn archive_entry_set_XXX
is an alias for
.Fn archive_entry_copy_XXX .
+The strings are copied, and don't need to outlive the call.
.Ss File Flags
File flags are transparently converted between a bitmap
representation and a textual format.
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_private.h b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
index cf4deb2..15f2a8e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $
*/
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
@@ -147,6 +145,11 @@ struct archive_entry {
#define AE_SET_SIZE 64
#define AE_SET_INO 128
#define AE_SET_DEV 256
+#define AE_SET_PERM 512
+#define AE_SET_FILETYPE 1024
+#define AE_SET_UID 2048
+#define AE_SET_GID 4096
+#define AE_SET_RDEV 8192
/*
* Use aes here so that we get transparent mbs<->wcs conversions.
@@ -155,9 +158,8 @@ struct archive_entry {
unsigned long ae_fflags_set; /* Bitmap fflags */
unsigned long ae_fflags_clear;
struct archive_mstring ae_gname; /* Name of owning group */
- struct archive_mstring ae_hardlink; /* Name of target for hardlink */
+ struct archive_mstring ae_linkname; /* Name of target for hardlink or symlink */
struct archive_mstring ae_pathname; /* Name of entry */
- struct archive_mstring ae_symlink; /* symlink contents */
struct archive_mstring ae_uname; /* Name of owner */
/* Not used within libarchive; useful for some clients. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c b/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
index 74917b3..b81684d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_entry.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_stat.c b/Utilities/cmlibarchive/libarchive/archive_entry_stat.c
index 71a407b..c490683 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_stat.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_stat.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_stat.c 201100 2009-12-28 03:05:31Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_strmode.c b/Utilities/cmlibarchive/libarchive/archive_entry_strmode.c
index af2517a..5faa2fa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_strmode.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_strmode.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.4 2008/06/15 05:14:01 kientzle Exp $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_time.3 b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
index d0563ea..0f1dbb0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_time.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
@@ -23,8 +23,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_ENTRY_TIME 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c b/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
index 5fe726b..14848a5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_xattr.c 201096 2009-12-28 02:41:27Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_getdate.c b/Utilities/cmlibarchive/libarchive/archive_getdate.c
index fc9516e..e9c6545 100644
--- a/Utilities/cmlibarchive/libarchive/archive_getdate.c
+++ b/Utilities/cmlibarchive/libarchive/archive_getdate.c
@@ -30,10 +30,6 @@
#ifndef CM_GET_DATE
#include "archive_platform.h"
#endif
-#ifdef __FreeBSD__
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
#include <ctype.h>
#include <stdio.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_getdate.h b/Utilities/cmlibarchive/libarchive/archive_getdate.h
index 900a8f6..cfd49dd 100644
--- a/Utilities/cmlibarchive/libarchive/archive_getdate.h
+++ b/Utilities/cmlibarchive/libarchive/archive_getdate.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef ARCHIVE_GETDATE_H_INCLUDED
diff --git a/Utilities/cmlibarchive/libarchive/archive_match.c b/Utilities/cmlibarchive/libarchive/archive_match.c
index 2de0045..b9af18c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_match.c
+++ b/Utilities/cmlibarchive/libarchive/archive_match.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -47,7 +46,7 @@ __FBSDID("$FreeBSD$");
struct match {
struct match *next;
- int matches;
+ int matched;
struct archive_mstring pattern;
};
@@ -600,17 +599,14 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
int64_t offset;
int r;
- ar = archive_read_new();
+ ar = archive_read_new();
if (ar == NULL) {
archive_set_error(&(a->archive), ENOMEM, "No memory");
return (ARCHIVE_FATAL);
}
r = archive_read_support_format_raw(ar);
-#ifdef __clang_analyzer__
- /* Tolerate deadcode.DeadStores to avoid modifying upstream. */
- (void)r;
-#endif
- r = archive_read_support_format_empty(ar);
+ if (r == ARCHIVE_OK)
+ r = archive_read_support_format_empty(ar);
if (r != ARCHIVE_OK) {
archive_copy_error(&(a->archive), ar);
archive_read_free(ar);
@@ -729,12 +725,12 @@ path_excluded(struct archive_match *a, int mbs, const void *pathname)
matched = NULL;
for (match = a->inclusions.first; match != NULL;
match = match->next){
- if (match->matches == 0 &&
+ if (!match->matched &&
(r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
if (r < 0)
return (r);
a->inclusions.unmatched_count--;
- match->matches++;
+ match->matched = 1;
matched = match;
}
}
@@ -757,11 +753,10 @@ path_excluded(struct archive_match *a, int mbs, const void *pathname)
for (match = a->inclusions.first; match != NULL;
match = match->next){
/* We looked at previously-unmatched inclusions already. */
- if (match->matches > 0 &&
+ if (match->matched &&
(r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
if (r < 0)
return (r);
- match->matches++;
return (0);
}
}
@@ -884,7 +879,7 @@ match_list_unmatched_inclusions_next(struct archive_match *a,
for (m = list->unmatched_next; m != NULL; m = m->next) {
int r;
- if (m->matches)
+ if (m->matched)
continue;
if (mbs) {
const char *p;
@@ -1321,7 +1316,7 @@ cmp_node_mbs(const struct archive_rb_node *n1,
return (-1);
return (strcmp(p1, p2));
}
-
+
static int
cmp_key_mbs(const struct archive_rb_node *n, const void *key)
{
@@ -1350,7 +1345,7 @@ cmp_node_wcs(const struct archive_rb_node *n1,
return (-1);
return (wcscmp(p1, p2));
}
-
+
static int
cmp_key_wcs(const struct archive_rb_node *n, const void *key)
{
@@ -1798,7 +1793,7 @@ match_owner_name_mbs(struct archive_match *a, struct match_list *list,
< 0 && errno == ENOMEM)
return (error_nomem(a));
if (p != NULL && strcmp(p, name) == 0) {
- m->matches++;
+ m->matched = 1;
return (1);
}
}
@@ -1819,7 +1814,7 @@ match_owner_name_wcs(struct archive_match *a, struct match_list *list,
< 0 && errno == ENOMEM)
return (error_nomem(a));
if (p != NULL && wcscmp(p, name) == 0) {
- m->matches++;
+ m->matched = 1;
return (1);
}
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_options.c b/Utilities/cmlibarchive/libarchive/archive_options.c
index 6496025..92647c9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_options.c
+++ b/Utilities/cmlibarchive/libarchive/archive_options.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_options_private.h b/Utilities/cmlibarchive/libarchive/archive_options_private.h
index 9a7f808..3e49222 100644
--- a/Utilities/cmlibarchive/libarchive/archive_options_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_options_private.h
@@ -27,8 +27,6 @@
#define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#include "archive_private.h"
typedef int (*option_handler)(struct archive *a,
diff --git a/Utilities/cmlibarchive/libarchive/archive_pack_dev.c b/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
index d95444d..3c6209b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
+++ b/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
@@ -33,13 +33,6 @@
#include "archive_platform.h"
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-#if !defined(lint)
-__RCSID("$NetBSD$");
-#endif /* not lint */
-
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_pathmatch.c b/Utilities/cmlibarchive/libarchive/archive_pathmatch.c
index 0867a26..19e0889 100644
--- a/Utilities/cmlibarchive/libarchive/archive_pathmatch.c
+++ b/Utilities/cmlibarchive/libarchive/archive_pathmatch.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H
#include <string.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_pathmatch.h b/Utilities/cmlibarchive/libarchive/archive_pathmatch.h
index 9995142..3f406ff 100644
--- a/Utilities/cmlibarchive/libarchive/archive_pathmatch.h
+++ b/Utilities/cmlibarchive/libarchive/archive_pathmatch.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef ARCHIVE_PATHMATCH_H
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
index 63b255e..7a3e1b5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_platform.h 201090 2009-12-28 02:22:04Z kientzle $
*/
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
@@ -87,19 +85,6 @@
* headers as required.
*/
-/* Get a real definition for __FBSDID or __RCSID if we can */
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-/* If not, define them so as to avoid dangling semicolons. */
-#ifndef __FBSDID
-#define __FBSDID(a) struct _undefined_hack
-#endif
-#ifndef __RCSID
-#define __RCSID(a) struct _undefined_hack
-#endif
-
/* Old glibc mbsnrtowcs fails assertions in our use case. */
#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1
# undef HAVE_MBSNRTOWCS
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform_acl.h b/Utilities/cmlibarchive/libarchive/archive_platform_acl.h
index 264e6de..48556f8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform_acl.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform_acl.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h b/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
index ad4b90a..2ae222f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd8.c b/Utilities/cmlibarchive/libarchive/archive_ppmd8.c
index 272ca4c..627c311 100644
--- a/Utilities/cmlibarchive/libarchive/archive_ppmd8.c
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd8.c
@@ -683,7 +683,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0)));
}
- do
+ while (numPs != 0)
{
/* Create Child */
CTX_PTR c1; /* = AllocContext(p); */
@@ -704,8 +704,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
SetSuccessor(ps[--numPs], REF(c1));
c = c1;
}
- while (numPs != 0);
-
+
return c;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_private.h b/Utilities/cmlibarchive/libarchive/archive_private.h
index b2a2cda..5c5b560 100644
--- a/Utilities/cmlibarchive/libarchive/archive_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_private.h
@@ -21,16 +21,16 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $
*/
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
#define ARCHIVE_PRIVATE_H_INCLUDED
#ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
+#endif
#if HAVE_ICONV_H
#include <iconv.h>
@@ -40,10 +40,12 @@
#include "archive_string.h"
#if defined(__GNUC__) && (__GNUC__ > 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
-#define __LA_DEAD __attribute__((__noreturn__))
+ (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
+#define __LA_NORETURN __attribute__((__noreturn__))
+#elif defined(_MSC_VER)
+#define __LA_NORETURN __declspec(noreturn)
#else
-#define __LA_DEAD
+#define __LA_NORETURN
#endif
#if defined(__GNUC__) && (__GNUC__ > 2 || \
@@ -153,7 +155,7 @@ int __archive_check_magic(struct archive *, unsigned int magic,
return ARCHIVE_FATAL; \
} while (0)
-void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
+__LA_NORETURN void __archive_errx(int retvalue, const char *msg);
void __archive_ensure_cloexec_flag(int fd);
int __archive_mktemp(const char *tmpdir);
diff --git a/Utilities/cmlibarchive/libarchive/archive_random.c b/Utilities/cmlibarchive/libarchive/archive_random.c
index a410dc0..8c48d2d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_random.c
+++ b/Utilities/cmlibarchive/libarchive/archive_random.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.3 b/Utilities/cmlibarchive/libarchive/archive_read.3
index cbedd0a..c81c98b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_READ 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.c b/Utilities/cmlibarchive/libarchive/archive_read.c
index 45a38ae..1fa3585 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read.c
@@ -32,7 +32,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read.c 201157 2009-12-29 05:30:23Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -1383,7 +1382,7 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
if (filter->client_avail <= 0) {
if (filter->end_of_file) {
if (avail != NULL)
- *avail = 0;
+ *avail = filter->avail;
return (NULL);
}
bytes_read = (filter->vtable->read)(filter,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3 b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
index ca60d4f..c35cfeb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd September 14, 2014
.Dt ARCHIVE_READ_ADD_PASSPHRASE 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
index f0b1ab9..c67d1df 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_append_filter.c b/Utilities/cmlibarchive/libarchive/archive_read_append_filter.c
index 25dc4b2..59ea5c4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_append_filter.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_append_filter.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -112,7 +111,7 @@ archive_read_append_filter(struct archive *_a, int code)
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
bidder = a->bidders;
- for (i = 0; i < number_bidders; i++, bidder++)
+ for (i = 1; i < number_bidders; i++, bidder++)
{
if (!bidder->name || !strcmp(bidder->name, str))
break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data.3 b/Utilities/cmlibarchive/libarchive/archive_read_data.3
index 78c0c90..694f292 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_READ_DATA 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c b/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
index f16ca5c..8fd5e12 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/05/23 05:01:29 cperciva Exp $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk.3 b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
index 8b568d7..990c151 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd April 3, 2017
.Dt ARCHIVE_READ_DISK 3
.Os
@@ -290,11 +288,11 @@ calls. If matched based on calls to
.Tn archive_match_time_excluded ,
or
.Tn archive_match_owner_excluded ,
-then the callback function specified by the _excluded_func parameter will execute. This function will recieve data provided to the fourth parameter, void *_client_data.
+then the callback function specified by the _excluded_func parameter will execute. This function will receive data provided to the fourth parameter, void *_client_data.
.It Fn archive_read_disk_set_metadata_filter_callback
Allows the caller to set a callback function during calls to
.Xr archive_read_header 3
-to filter out metadata for each entry. The callback function recieves the
+to filter out metadata for each entry. The callback function receives the
.Tn struct archive
object, void* custom filter data, and the
.Tn struct archive_entry .
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
index ab0270b..3a4915e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD");
/* This is the tree-walking code for POSIX systems. */
#if !defined(_WIN32) || defined(__CYGWIN__)
@@ -521,6 +520,7 @@ setup_xattr(struct archive_read_disk *a,
if (size == -1) {
archive_set_error(&a->archive, errno,
"Couldn't read extended attribute");
+ free(value);
return (ARCHIVE_WARN);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
index ab5306d..eea8259 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -29,7 +29,6 @@
#if !defined(_WIN32) || defined(__CYGWIN__)
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
index bc8abc1..cf8da99 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $
*/
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
index c7fd247..3512d34 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_set_standard_lookup.c 201109 2009-12-28 03:30:31Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
index f92a78a..285747e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
@@ -25,7 +25,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1956,6 +1955,8 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
return (t->visit_type);
}
+ /* Top stack item needs a regular visit. */
+ t->current = t->stack;
t->findData = &t->_findData;
pattern = NULL;
} else if (!FindNextFileW(t->d, &t->_findData)) {
@@ -2439,6 +2440,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
return (ARCHIVE_OK);
}
+ r = ARCHIVE_OK;
if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) {
r = setup_sparse_from_disk(a, entry, h);
if (fd < 0)
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract.3 b/Utilities/cmlibarchive/libarchive/archive_read_extract.3
index 858f397..f3feb5a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_extract.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_READ_EXTRACT 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract.c b/Utilities/cmlibarchive/libarchive/archive_read_extract.c
index b7973fa..d2159c6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_extract.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract2.c b/Utilities/cmlibarchive/libarchive/archive_read_extract2.c
index 4febd8c..e11cac1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_extract2.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract2.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_filter.3 b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
index 4f5c351..72ff240 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd June 9, 2020
.Dt ARCHIVE_READ_FILTER 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_format.3 b/Utilities/cmlibarchive/libarchive/archive_read_format.3
index f3804ce..990293c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_format.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_READ_FORMAT 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_free.3 b/Utilities/cmlibarchive/libarchive/archive_read_free.3
index 8371c3a..7dc121f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_free.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_free.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_READ_FREE 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_header.3 b/Utilities/cmlibarchive/libarchive/archive_read_header.3
index 1e97f3a..024dc41 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_header.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_header.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_READ_HEADER 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_new.3 b/Utilities/cmlibarchive/libarchive/archive_read_new.3
index 8bb6b84..c2b5cdd 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_new.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_new.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_READ_NEW 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open.3 b/Utilities/cmlibarchive/libarchive/archive_read_open.3
index f676778..081b711 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_READ_OPEN 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c b/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
index f59cd07..3ee2423 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28 03:13:49Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
index 03719e8..dcf1d46 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_file.c 201093 2009-12-28 02:28:44Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
index 561289b..dd2e160 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $");
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
@@ -155,55 +154,73 @@ no_memory:
return (ARCHIVE_FATAL);
}
+/*
+ * This function is an implementation detail of archive_read_open_filename_w,
+ * which is exposed as a separate API on Windows.
+ */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static
+#endif
int
-archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
+archive_read_open_filenames_w(struct archive *a, const wchar_t **wfilenames,
size_t block_size)
{
- struct read_file_data *mine = (struct read_file_data *)calloc(1,
- sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
- if (!mine)
+ struct read_file_data *mine;
+ const wchar_t *wfilename = NULL;
+ if (wfilenames)
+ wfilename = *(wfilenames++);
+
+ archive_clear_error(a);
+ do
{
- archive_set_error(a, ENOMEM, "No memory");
- return (ARCHIVE_FATAL);
- }
- mine->fd = -1;
- mine->block_size = block_size;
+ if (wfilename == NULL)
+ wfilename = L"";
+ mine = (struct read_file_data *)calloc(1,
+ sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
+ if (mine == NULL)
+ goto no_memory;
+ mine->block_size = block_size;
+ mine->fd = -1;
- if (wfilename == NULL || wfilename[0] == L'\0') {
- mine->filename_type = FNT_STDIN;
- } else {
+ if (wfilename == NULL || wfilename[0] == L'\0') {
+ mine->filename_type = FNT_STDIN;
+ } else {
#if defined(_WIN32) && !defined(__CYGWIN__)
- mine->filename_type = FNT_WCS;
- wcscpy(mine->filename.w, wfilename);
+ mine->filename_type = FNT_WCS;
+ wcscpy(mine->filename.w, wfilename);
#else
- /*
- * POSIX system does not support a wchar_t interface for
- * open() system call, so we have to translate a wchar_t
- * filename to multi-byte one and use it.
- */
- struct archive_string fn;
-
- archive_string_init(&fn);
- if (archive_string_append_from_wcs(&fn, wfilename,
- wcslen(wfilename)) != 0) {
- if (errno == ENOMEM)
- archive_set_error(a, errno,
- "Can't allocate memory");
- else
- archive_set_error(a, EINVAL,
- "Failed to convert a wide-character"
- " filename to a multi-byte filename");
+ /*
+ * POSIX system does not support a wchar_t interface for
+ * open() system call, so we have to translate a wchar_t
+ * filename to multi-byte one and use it.
+ */
+ struct archive_string fn;
+
+ archive_string_init(&fn);
+ if (archive_string_append_from_wcs(&fn, wfilename,
+ wcslen(wfilename)) != 0) {
+ if (errno == ENOMEM)
+ archive_set_error(a, errno,
+ "Can't allocate memory");
+ else
+ archive_set_error(a, EINVAL,
+ "Failed to convert a wide-character"
+ " filename to a multi-byte filename");
+ archive_string_free(&fn);
+ free(mine);
+ return (ARCHIVE_FATAL);
+ }
+ mine->filename_type = FNT_MBS;
+ strcpy(mine->filename.m, fn.s);
archive_string_free(&fn);
- free(mine);
- return (ARCHIVE_FATAL);
- }
- mine->filename_type = FNT_MBS;
- strcpy(mine->filename.m, fn.s);
- archive_string_free(&fn);
#endif
- }
- if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
- return (ARCHIVE_FATAL);
+ }
+ if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
+ return (ARCHIVE_FATAL);
+ if (wfilenames == NULL)
+ break;
+ wfilename = *(wfilenames++);
+ } while (wfilename != NULL && wfilename[0] != '\0');
archive_read_set_open_callback(a, file_open);
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
@@ -212,6 +229,19 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
archive_read_set_seek_callback(a, file_seek);
return (archive_read_open1(a));
+no_memory:
+ archive_set_error(a, ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+}
+
+int
+archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
+ size_t block_size)
+{
+ const wchar_t *wfilenames[2];
+ wfilenames[0] = wfilename;
+ wfilenames[1] = NULL;
+ return archive_read_open_filenames_w(a, wfilenames, block_size);
}
static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c b/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
index 311be47..a057ce6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/06 15:51:59 kientzle Exp $");
#include <errno.h>
#include <stdlib.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_private.h b/Utilities/cmlibarchive/libarchive/archive_read_private.h
index 383405d..0c374f4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_read_private.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $
*/
#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_format.c b/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
index 796dcdc..c74361b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
index 162b79d..ef18dfa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd January 31, 2020
.Dt ARCHIVE_READ_OPTIONS 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.c b/Utilities/cmlibarchive/libarchive/archive_read_set_options.c
index 2bd9b81..c0a4b42 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_options.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#include "archive_read_private.h"
#include "archive_options_private.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
index edb508c..cb46d12 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_private.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c
index 94c4af6..ce50d8c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_private.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
index 9e5f6d9..a118a03 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -192,7 +190,7 @@ bzip2_reader_init(struct archive_read_filter *self)
self->code = ARCHIVE_FILTER_BZIP2;
self->name = "bzip2";
- state = (struct private_data *)calloc(sizeof(*state), 1);
+ state = (struct private_data *)calloc(1, sizeof(*state));
out_block = (unsigned char *)malloc(out_block_size);
if (state == NULL || out_block == NULL) {
archive_set_error(&self->archive->archive, ENOMEM,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
index 05b80a5..29ae72a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
@@ -64,7 +64,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -218,7 +217,7 @@ compress_bidder_init(struct archive_read_filter *self)
self->code = ARCHIVE_FILTER_COMPRESS;
self->name = "compress (.Z)";
- state = (struct private_data *)calloc(sizeof(*state), 1);
+ state = (struct private_data *)calloc(1, sizeof(*state));
out_block = malloc(out_block_size);
if (state == NULL || out_block == NULL) {
free(out_block);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_grzip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_grzip.c
index d4d1737..15b6757 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_grzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_grzip.c
@@ -25,9 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
index 976a392..d243860 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
@@ -25,9 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -310,7 +307,7 @@ gzip_bidder_init(struct archive_read_filter *self)
self->code = ARCHIVE_FILTER_GZIP;
self->name = "gzip";
- state = (struct private_data *)calloc(sizeof(*state), 1);
+ state = (struct private_data *)calloc(1, sizeof(*state));
out_block = (unsigned char *)malloc(out_block_size);
if (state == NULL || out_block == NULL) {
free(out_block);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lrzip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lrzip.c
index a238989..a562d53 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lrzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lrzip.c
@@ -25,9 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
index d0fc1a8..bccf4fb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -225,7 +223,7 @@ lz4_reader_init(struct archive_read_filter *self)
self->code = ARCHIVE_FILTER_LZ4;
self->name = "lz4";
- state = (struct private_data *)calloc(sizeof(*state), 1);
+ state = (struct private_data *)calloc(1, sizeof(*state));
if (state == NULL) {
archive_set_error(&self->archive->archive, ENOMEM,
"Can't allocate data for lz4 decompression");
@@ -449,8 +447,8 @@ lz4_filter_read_descriptor(struct archive_read_filter *self)
chsum = __archive_xxhash.XXH32(read_buf, (int)descriptor_bytes -1, 0);
chsum = (chsum >> 8) & 0xff;
chsum_verifier = read_buf[descriptor_bytes-1] & 0xff;
- if (chsum != chsum_verifier)
#ifndef DONT_FAIL_ON_CRC_ERROR
+ if (chsum != chsum_verifier)
goto malformed_error;
#endif
@@ -522,8 +520,8 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
read_buf + 4, (int)compressed_size, 0);
unsigned int chsum_block =
archive_le32dec(read_buf + 4 + compressed_size);
- if (chsum != chsum_block)
#ifndef DONT_FAIL_ON_CRC_ERROR
+ if (chsum != chsum_block)
goto malformed_error;
#endif
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
index cc1572f..0eec716 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
@@ -26,8 +26,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -187,7 +185,7 @@ lzop_bidder_init(struct archive_read_filter *self)
self->code = ARCHIVE_FILTER_LZOP;
self->name = "lzop";
- state = (struct read_lzop *)calloc(sizeof(*state), 1);
+ state = (struct read_lzop *)calloc(1, sizeof(*state));
if (state == NULL) {
archive_set_error(&self->archive->archive, ENOMEM,
"Can't allocate data for lzop decompression");
@@ -282,8 +280,8 @@ consume_header(struct archive_read_filter *self)
checksum = crc32(crc32(0, NULL, 0), p, len);
else
checksum = adler32(adler32(0, NULL, 0), p, len);
- if (archive_be32dec(p + len) != checksum)
#ifndef DONT_FAIL_ON_CRC_ERROR
+ if (archive_be32dec(p + len) != checksum)
goto corrupted;
#endif
__archive_read_filter_consume(self->upstream, len + 4);
@@ -293,7 +291,8 @@ consume_header(struct archive_read_filter *self)
if (p == NULL)
goto truncated;
len = archive_be32dec(p);
- __archive_read_filter_consume(self->upstream, len + 4 + 4);
+ __archive_read_filter_consume(self->upstream,
+ (int64_t)len + 4 + 4);
}
state->flags = flags;
state->in_stream = 1;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c
index 95e5cfd..9eb8e54 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_private.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
index 885b2c2..0482c57 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c
index 67a979c..a55bc0c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c
@@ -39,8 +39,8 @@
struct rpm {
int64_t total_in;
- size_t hpos;
- size_t hlen;
+ uint64_t hpos;
+ uint64_t hlen;
unsigned char header[16];
enum {
ST_LEAD, /* Skipping 'Lead' section. */
@@ -53,7 +53,8 @@ struct rpm {
} state;
int first_header;
};
-#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
+#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
+#define RPM_MIN_HEAD_SIZE 16 /* Minimum size of 'Head'. */
static int rpm_bidder_bid(struct archive_read_filter_bidder *,
struct archive_read_filter *);
@@ -63,6 +64,8 @@ static ssize_t rpm_filter_read(struct archive_read_filter *,
const void **);
static int rpm_filter_close(struct archive_read_filter *);
+static inline size_t rpm_limit_bytes(uint64_t, size_t);
+
#if ARCHIVE_VERSION_NUMBER < 4000000
/* Deprecated; remove in libarchive 4.0 */
int
@@ -141,7 +144,7 @@ rpm_bidder_init(struct archive_read_filter *self)
self->code = ARCHIVE_FILTER_RPM;
self->name = "rpm";
- rpm = (struct rpm *)calloc(sizeof(*rpm), 1);
+ rpm = (struct rpm *)calloc(1, sizeof(*rpm));
if (rpm == NULL) {
archive_set_error(&self->archive->archive, ENOMEM,
"Can't allocate data for rpm");
@@ -155,15 +158,21 @@ rpm_bidder_init(struct archive_read_filter *self)
return (ARCHIVE_OK);
}
+static inline size_t
+rpm_limit_bytes(uint64_t bytes, size_t max)
+{
+ return (bytes > max ? max : (size_t)bytes);
+}
+
static ssize_t
rpm_filter_read(struct archive_read_filter *self, const void **buff)
{
struct rpm *rpm;
const unsigned char *b;
- ssize_t avail_in, total;
- size_t used, n;
- uint32_t section;
- uint32_t bytes;
+ ssize_t avail_in, total, used;
+ size_t n;
+ uint64_t section;
+ uint64_t bytes;
rpm = (struct rpm *)self->data;
*buff = NULL;
@@ -197,15 +206,14 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
}
break;
case ST_HEADER:
- n = 16 - rpm->hpos;
- if (n > avail_in - used)
- n = avail_in - used;
+ n = rpm_limit_bytes(RPM_MIN_HEAD_SIZE - rpm->hpos,
+ avail_in - used);
memcpy(rpm->header+rpm->hpos, b, n);
b += n;
used += n;
rpm->hpos += n;
- if (rpm->hpos == 16) {
+ if (rpm->hpos == RPM_MIN_HEAD_SIZE) {
if (rpm->header[0] != 0x8e ||
rpm->header[1] != 0xad ||
rpm->header[2] != 0xe8 ||
@@ -219,21 +227,20 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
}
rpm->state = ST_ARCHIVE;
*buff = rpm->header;
- total = rpm->hpos;
+ total = RPM_MIN_HEAD_SIZE;
break;
}
/* Calculate 'Header' length. */
section = archive_be32dec(rpm->header+8);
bytes = archive_be32dec(rpm->header+12);
- rpm->hlen = 16 + section * 16 + bytes;
+ rpm->hlen = rpm->hpos + section * 16 + bytes;
rpm->state = ST_HEADER_DATA;
rpm->first_header = 0;
}
break;
case ST_HEADER_DATA:
- n = rpm->hlen - rpm->hpos;
- if (n > avail_in - used)
- n = avail_in - used;
+ n = rpm_limit_bytes(rpm->hlen - rpm->hpos,
+ avail_in - used);
b += n;
used += n;
rpm->hpos += n;
@@ -241,7 +248,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
rpm->state = ST_PADDING;
break;
case ST_PADDING:
- while (used < (size_t)avail_in) {
+ while (used < avail_in) {
if (*b != 0) {
/* Read next header. */
rpm->state = ST_HEADER;
@@ -259,7 +266,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
used = avail_in;
break;
}
- if (used == (size_t)avail_in) {
+ if (used == avail_in) {
rpm->total_in += used;
__archive_read_filter_consume(self->upstream, used);
b = NULL;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
index 802165c..de61c4a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -48,11 +47,13 @@ __FBSDID("$FreeBSD$");
/* Maximum lookahead during bid phase */
#define UUENCODE_BID_MAX_READ 128*1024 /* in bytes */
+#define UUENCODE_MAX_LINE_LENGTH 34*1024 /* in bytes */
+
struct uudecode {
int64_t total;
unsigned char *in_buff;
#define IN_BUFF_SIZE (1024)
- int in_cnt;
+ ssize_t in_cnt;
size_t in_allocated;
unsigned char *out_buff;
#define OUT_BUFF_SIZE (64 * 1024)
@@ -378,7 +379,7 @@ uudecode_bidder_init(struct archive_read_filter *self)
self->code = ARCHIVE_FILTER_UU;
self->name = "uu";
- uudecode = (struct uudecode *)calloc(sizeof(*uudecode), 1);
+ uudecode = (struct uudecode *)calloc(1, sizeof(*uudecode));
out_buff = malloc(OUT_BUFF_SIZE);
in_buff = malloc(IN_BUFF_SIZE);
if (uudecode == NULL || out_buff == NULL || in_buff == NULL) {
@@ -489,6 +490,12 @@ read_more:
goto finish;
}
if (uudecode->in_cnt) {
+ if (uudecode->in_cnt > UUENCODE_MAX_LINE_LENGTH) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid format data");
+ return (ARCHIVE_FATAL);
+ }
/*
* If there is remaining data which is saved by
* previous calling, use it first.
@@ -506,7 +513,7 @@ read_more:
uudecode->in_cnt = 0;
}
for (;used < avail_in; d += llen, used += llen) {
- int64_t l, body;
+ ssize_t l, body;
b = d;
len = get_line(b, avail_in - used, &nl);
@@ -541,7 +548,7 @@ read_more:
return (ARCHIVE_FATAL);
if (uudecode->in_buff != b)
memmove(uudecode->in_buff, b, len);
- uudecode->in_cnt = (int)len;
+ uudecode->in_cnt = len;
if (total == 0) {
/* Do not return 0; it means end-of-file.
* We should try to read bytes more. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
index 90b0da2..fb9317d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
@@ -26,8 +26,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -478,7 +476,7 @@ xz_lzma_bidder_init(struct archive_read_filter *self)
struct private_data *state;
int ret;
- state = (struct private_data *)calloc(sizeof(*state), 1);
+ state = (struct private_data *)calloc(1, sizeof(*state));
out_block = (unsigned char *)malloc(out_block_size);
if (state == NULL || out_block == NULL) {
archive_set_error(&self->archive->archive, ENOMEM,
@@ -656,13 +654,16 @@ xz_filter_read(struct archive_read_filter *self, const void **p)
struct private_data *state;
size_t decompressed;
ssize_t avail_in;
+ int64_t member_in;
int ret;
state = (struct private_data *)self->data;
+ redo:
/* Empty our output buffer. */
state->stream.next_out = state->out_block;
state->stream.avail_out = state->out_block_size;
+ member_in = state->member_in;
/* Try to fill the output buffer. */
while (state->stream.avail_out > 0 && !state->eof) {
@@ -707,9 +708,18 @@ xz_filter_read(struct archive_read_filter *self, const void **p)
decompressed = state->stream.next_out - state->out_block;
state->total_out += decompressed;
state->member_out += decompressed;
- if (decompressed == 0)
+ if (decompressed == 0) {
+ if (member_in != state->member_in &&
+ self->code == ARCHIVE_FILTER_LZIP &&
+ state->eof) {
+ ret = lzip_tail(self);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ if (!state->eof)
+ goto redo;
+ }
*p = NULL;
- else {
+ } else {
*p = state->out_block;
if (self->code == ARCHIVE_FILTER_LZIP) {
state->crc32 = lzma_crc32(state->out_block,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
index 8d20d7c..885c10f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -177,7 +175,7 @@ zstd_bidder_init(struct archive_read_filter *self)
self->code = ARCHIVE_FILTER_ZSTD;
self->name = "zstd";
- state = (struct private_data *)calloc(sizeof(*state), 1);
+ state = (struct private_data *)calloc(1, sizeof(*state));
out_block = (unsigned char *)malloc(out_block_size);
dstream = ZSTD_createDStream();
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
index 0bfbf1f..8067fba 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -885,10 +884,9 @@ archive_read_format_7zip_read_data(struct archive_read *a,
if (zip->end_of_entry)
return (ARCHIVE_EOF);
- const uint64_t max_read_size = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time
- size_t bytes_to_read = max_read_size;
+ size_t bytes_to_read = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time
if ((uint64_t)bytes_to_read > zip->entry_bytes_remaining) {
- bytes_to_read = zip->entry_bytes_remaining;
+ bytes_to_read = (size_t)zip->entry_bytes_remaining;
}
bytes = read_stream(a, buff, bytes_to_read, 0);
if (bytes < 0)
@@ -1071,8 +1069,8 @@ ppmd_read(void *p)
*/
ssize_t bytes_avail = 0;
const uint8_t* data = __archive_read_ahead(a,
- zip->ppstream.stream_in+1, &bytes_avail);
- if(bytes_avail < zip->ppstream.stream_in+1) {
+ (size_t)zip->ppstream.stream_in+1, &bytes_avail);
+ if(data == NULL || bytes_avail < zip->ppstream.stream_in+1) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated 7z file data");
@@ -1775,6 +1773,10 @@ free_decompression(struct archive_read *a, struct _7zip *zip)
zip->stream_valid = 0;
}
#endif
+#ifdef HAVE_ZSTD_H
+ if (zip->zstdstream_valid)
+ ZSTD_freeDStream(zip->zstd_dstream);
+#endif
if (zip->ppmd7_valid) {
__archive_ppmd7_functions.Ppmd7_Free(
&zip->ppmd7_context);
@@ -2045,6 +2047,8 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
if (parse_7zip_uint64(
a, &(f->coders[i].propertiesSize)) < 0)
return (-1);
+ if (UMAX_ENTRY < f->coders[i].propertiesSize)
+ return (-1);
if ((p = header_bytes(
a, (size_t)f->coders[i].propertiesSize)) == NULL)
return (-1);
@@ -2314,7 +2318,7 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
usizes = ss->unpackSizes;
for (i = 0; i < numFolders; i++) {
unsigned pack;
- uint64_t sum;
+ uint64_t size, sum;
if (f[i].numUnpackStreams == 0)
continue;
@@ -2324,10 +2328,15 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
if (parse_7zip_uint64(a, usizes) < 0)
return (-1);
+ if (*usizes > UINT64_MAX - sum)
+ return (-1);
sum += *usizes++;
}
}
- *usizes++ = folder_uncompressed_size(&f[i]) - sum;
+ size = folder_uncompressed_size(&f[i]);
+ if (size < sum)
+ return (-1);
+ *usizes++ = size - sum;
}
if (type == kSize) {
@@ -2421,6 +2430,8 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
packPos = si->pi.pos;
for (i = 0; i < si->pi.numPackStreams; i++) {
si->pi.positions[i] = packPos;
+ if (packPos > UINT64_MAX - si->pi.sizes[i])
+ return (-1);
packPos += si->pi.sizes[i];
if (packPos > zip->header_offset)
return (-1);
@@ -2442,6 +2453,10 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
f = si->ci.folders;
for (i = 0; i < si->ci.numFolders; i++) {
f[i].packIndex = packIndex;
+ if (f[i].numPackedStreams > UINT32_MAX)
+ return (-1);
+ if (packIndex > UINT32_MAX - (uint32_t)f[i].numPackedStreams)
+ return (-1);
packIndex += (uint32_t)f[i].numPackedStreams;
if (packIndex > si->pi.numPackStreams)
return (-1);
@@ -3009,7 +3024,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
/* CRC check. */
if (crc32(0, (const unsigned char *)p + 12, 20)
!= archive_le32dec(p + 8)) {
-#ifdef DONT_FAIL_ON_CRC_ERROR
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, -1, "Header CRC error");
return (ARCHIVE_FATAL);
#endif
@@ -3061,8 +3076,8 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
/* Check the EncodedHeader CRC.*/
if (r == 0 && zip->header_crc32 != next_header_crc) {
- archive_set_error(&a->archive, -1,
#ifndef DONT_FAIL_ON_CRC_ERROR
+ archive_set_error(&a->archive, -1,
"Damaged 7-Zip archive");
r = -1;
#endif
@@ -3151,7 +3166,7 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
/* Copy mode. */
*buff = __archive_read_ahead(a, minimum, &bytes_avail);
- if (bytes_avail <= 0) {
+ if (*buff == NULL) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated 7-Zip file data");
@@ -3457,7 +3472,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
/*
* Skip the bytes we already has skipped in skip_stream().
*/
- while (skip_bytes) {
+ while (1) {
ssize_t skipped;
if (zip->uncompressed_buffer_bytes_remaining == 0) {
@@ -3477,6 +3492,10 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
return (ARCHIVE_FATAL);
}
}
+
+ if (!skip_bytes)
+ break;
+
skipped = get_uncompressed_data(
a, buff, (size_t)skip_bytes, 0);
if (skipped < 0)
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
index dea558b..3b53c9a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_all.c 174991 2007-12-30 04:58:22Z kientzle $");
#include "archive.h"
#include "archive_private.h"
@@ -68,7 +67,7 @@ archive_read_support_format_all(struct archive *a)
* increase the chance that a high bid from someone else will
* make it unnecessary for these to do anything at all.
*/
- /* These three have potentially large look-ahead. */
+ /* These have potentially large look-ahead. */
archive_read_support_format_7zip(a);
archive_read_support_format_cab(a);
archive_read_support_format_rar(a);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
index 296b7db..b0d1ddbc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_ar.c 201101 2009-12-28 03:06:27Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -271,7 +270,7 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
}
if (ar->strtab != NULL) {
archive_set_error(&a->archive, EINVAL,
- "More than one string tables exist");
+ "More than one string table exists");
return (ARCHIVE_FATAL);
}
@@ -440,9 +439,9 @@ archive_read_format_ar_read_header(struct archive_read *a,
if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL)
/* Broken header. */
return (ARCHIVE_EOF);
-
+
unconsumed = 60;
-
+
ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed);
if (unconsumed)
@@ -459,7 +458,6 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
uint64_t n;
/* Copy remaining header */
- archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_mtime(entry,
(time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
archive_entry_set_uid(entry,
@@ -468,6 +466,7 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
(gid_t)ar_atol10(h + AR_gid_offset, AR_gid_size));
archive_entry_set_mode(entry,
(mode_t)ar_atol8(h + AR_mode_offset, AR_mode_size));
+ archive_entry_set_filetype(entry, AE_IFREG);
n = ar_atol10(h + AR_size_offset, AR_size_size);
ar->entry_offset = 0;
@@ -516,7 +515,7 @@ archive_read_format_ar_read_data(struct archive_read *a,
if (ar->entry_padding) {
if (skipped >= 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated ar archive- failed consuming padding");
+ "Truncated ar archive - failed consuming padding");
}
return (ARCHIVE_FATAL);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
index 89e96f1..7ed045f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
index e57b8c3..d5be04b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -1682,7 +1682,7 @@ cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
cfdata->uncompressed_size - cab->xstrm.total_out;
d = __archive_read_ahead(a, 1, &bytes_avail);
- if (bytes_avail <= 0) {
+ if (d == NULL) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated CAB file data");
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
index 9adcfd3..69752cb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 201163 2009-12-29 05:50:34Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -835,6 +834,7 @@ static int
header_afiol(struct archive_read *a, struct cpio *cpio,
struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
+ int64_t t;
const void *h;
const char *header;
@@ -851,7 +851,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
archive_entry_set_dev(entry,
(dev_t)atol16(header + afiol_dev_offset, afiol_dev_size));
- archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
+ t = atol16(header + afiol_ino_offset, afiol_ino_size);
+ if (t < 0) {
+ archive_set_error(&a->archive, 0, "Nonsensical ino value");
+ return (ARCHIVE_FATAL);
+ }
+ archive_entry_set_ino(entry, t);
archive_entry_set_mode(entry,
(mode_t)atol8(header + afiol_mode_offset, afiol_mode_size));
archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
@@ -864,8 +869,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
*namelength = (size_t)atol16(header + afiol_namesize_offset, afiol_namesize_size);
*name_pad = 0; /* No padding of filename. */
- cpio->entry_bytes_remaining =
- atol16(header + afiol_filesize_offset, afiol_filesize_size);
+ t = atol16(header + afiol_filesize_offset, afiol_filesize_size);
+ if (t < 0) {
+ archive_set_error(&a->archive, 0, "Nonsensical file size");
+ return (ARCHIVE_FATAL);
+ }
+ cpio->entry_bytes_remaining = t;
archive_entry_set_size(entry, cpio->entry_bytes_remaining);
cpio->entry_padding = 0;
__archive_read_consume(a, afiol_header_size);
@@ -1003,7 +1012,7 @@ be4(const unsigned char *p)
static int64_t
atol8(const char *p, unsigned char_cnt)
{
- int64_t l;
+ uint64_t l;
int digit;
l = 0;
@@ -1011,18 +1020,18 @@ atol8(const char *p, unsigned char_cnt)
if (*p >= '0' && *p <= '7')
digit = *p - '0';
else
- return (l);
+ return ((int64_t)l);
p++;
l <<= 3;
l |= digit;
}
- return (l);
+ return ((int64_t)l);
}
static int64_t
atol16(const char *p, unsigned char_cnt)
{
- int64_t l;
+ uint64_t l;
int digit;
l = 0;
@@ -1034,12 +1043,12 @@ atol16(const char *p, unsigned char_cnt)
else if (*p >= '0' && *p <= '9')
digit = *p - '0';
else
- return (l);
+ return ((int64_t)l);
p++;
l <<= 4;
l |= digit;
}
- return (l);
+ return ((int64_t)l);
}
static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
index 53fb6cc..0dccd9d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_empty.c 191524 2009-04-26 18:24:14Z kientzle $");
#include "archive.h"
#include "archive_entry.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
index a6219fa..137206a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_iso9660.c 201246 2009-12-30 05:30:35Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -403,6 +402,9 @@ static int isJolietSVD(struct iso9660 *, const unsigned char *);
static int isSVD(struct iso9660 *, const unsigned char *);
static int isEVD(struct iso9660 *, const unsigned char *);
static int isPVD(struct iso9660 *, const unsigned char *);
+static int isRootDirectoryRecord(const unsigned char *);
+static int isValid723Integer(const unsigned char *);
+static int isValid733Integer(const unsigned char *);
static int next_cache_entry(struct archive_read *, struct iso9660 *,
struct file_info **);
static int next_entry_seek(struct archive_read *, struct iso9660 *,
@@ -774,8 +776,9 @@ isSVD(struct iso9660 *iso9660, const unsigned char *h)
/* Read Root Directory Record in Volume Descriptor. */
p = h + SVD_root_directory_record_offset;
- if (p[DR_length_offset] != 34)
+ if (!isRootDirectoryRecord(p)) {
return (0);
+ }
return (48);
}
@@ -852,8 +855,9 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
/* Read Root Directory Record in Volume Descriptor. */
p = h + PVD_root_directory_record_offset;
- if (p[DR_length_offset] != 34)
+ if (!isRootDirectoryRecord(p)) {
return (0);
+ }
return (48);
}
@@ -883,21 +887,43 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size))
return (0);
+ /* Volume space size must be encoded according to 7.3.3 */
+ if (!isValid733Integer(h + PVD_volume_space_size_offset)) {
+ return (0);
+ }
+ volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
+ if (volume_block <= SYSTEM_AREA_BLOCK+4)
+ return (0);
+
/* Reserved field must be 0. */
if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size))
return (0);
+ /* Volume set size must be encoded according to 7.2.3 */
+ if (!isValid723Integer(h + PVD_volume_set_size_offset)) {
+ return (0);
+ }
+
+ /* Volume sequence number must be encoded according to 7.2.3 */
+ if (!isValid723Integer(h + PVD_volume_sequence_number_offset)) {
+ return (0);
+ }
+
/* Logical block size must be > 0. */
/* I've looked at Ecma 119 and can't find any stronger
* restriction on this field. */
+ if (!isValid723Integer(h + PVD_logical_block_size_offset)) {
+ return (0);
+ }
logical_block_size =
archive_le16dec(h + PVD_logical_block_size_offset);
if (logical_block_size <= 0)
return (0);
- volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
- if (volume_block <= SYSTEM_AREA_BLOCK+4)
+ /* Path Table size must be encoded according to 7.3.3 */
+ if (!isValid733Integer(h + PVD_path_table_size_offset)) {
return (0);
+ }
/* File structure version must be 1 for ISO9660/ECMA119. */
if (h[PVD_file_structure_version_offset] != 1)
@@ -936,8 +962,9 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
/* Read Root Directory Record in Volume Descriptor. */
p = h + PVD_root_directory_record_offset;
- if (p[DR_length_offset] != 34)
+ if (!isRootDirectoryRecord(p)) {
return (0);
+ }
if (!iso9660->primary.location) {
iso9660->logical_block_size = logical_block_size;
@@ -953,6 +980,51 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
}
static int
+isRootDirectoryRecord(const unsigned char *p) {
+ int flags;
+
+ /* ECMA119/ISO9660 requires that the root directory record be _exactly_ 34 bytes.
+ * However, we've seen images that have root directory records up to 68 bytes. */
+ if (p[DR_length_offset] < 34 || p[DR_length_offset] > 68) {
+ return (0);
+ }
+
+ /* The root directory location must be a 7.3.3 32-bit integer. */
+ if (!isValid733Integer(p + DR_extent_offset)) {
+ return (0);
+ }
+
+ /* The root directory size must be a 7.3.3 integer. */
+ if (!isValid733Integer(p + DR_size_offset)) {
+ return (0);
+ }
+
+ /* According to the standard, certain bits must be one or zero:
+ * Bit 1: must be 1 (this is a directory)
+ * Bit 2: must be 0 (not an associated file)
+ * Bit 3: must be 0 (doesn't use extended attribute record)
+ * Bit 7: must be 0 (final directory record for this file)
+ */
+ flags = p[DR_flags_offset];
+ if ((flags & 0x8E) != 0x02) {
+ return (0);
+ }
+
+ /* Volume sequence number must be a 7.2.3 integer. */
+ if (!isValid723Integer(p + DR_volume_sequence_number_offset)) {
+ return (0);
+ }
+
+ /* Root directory name is a single zero byte... */
+ if (p[DR_name_len_offset] != 1 || p[DR_name_offset] != 0) {
+ return (0);
+ }
+
+ /* Nothing looked wrong, so let's accept it. */
+ return (1);
+}
+
+static int
read_children(struct archive_read *a, struct file_info *parent)
{
struct iso9660 *iso9660;
@@ -1213,7 +1285,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
}
}
if (iso9660->utf16be_previous_path == NULL) {
- iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX);
+ iso9660->utf16be_previous_path = calloc(1, UTF16_NAME_MAX);
if (iso9660->utf16be_previous_path == NULL) {
archive_set_error(&a->archive, ENOMEM,
"No memory");
@@ -3015,6 +3087,11 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
uint64_t file_key, parent_key;
int hole, parent;
+ /* Reserve 16 bits for possible key collisions (needed for linked items) */
+ /* For ISO files with more than 65535 entries, reordering will still occur */
+ key <<= 16;
+ key += heap->used & 0xFFFF;
+
#ifndef __clang_analyzer__ /* It cannot see heap->files remains populated. */
/* Expand our pending files list as necessary. */
if (heap->used >= heap->allocated) {
@@ -3030,7 +3107,7 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
return (ARCHIVE_FATAL);
}
new_pending_files = (struct file_info **)
- malloc(new_size * sizeof(new_pending_files[0]));
+ calloc(new_size, sizeof(new_pending_files[0]));
if (new_pending_files == NULL) {
archive_set_error(&a->archive,
ENOMEM, "Out of memory");
@@ -3125,6 +3202,32 @@ toi(const void *p, int n)
return (0);
}
+/*
+ * ECMA119/ISO9660 stores multi-byte integers in one of
+ * three different formats:
+ * * Little-endian (specified in section 7.2.1 and 7.3.1)
+ * * Big-endian (specified in section 7.2.2 and 7.3.2)
+ * * Both (specified in section 7.2.3 and 7.3.3)
+ *
+ * For values that follow section 7.2.3 (16-bit) or 7.3.3 (32-bit), we
+ * can check that the little-endian and big-endian forms agree with
+ * each other. This helps us avoid trying to decode files that are
+ * not really ISO images.
+ */
+static int
+isValid723Integer(const unsigned char *p) {
+ return (p[0] == p[3] && p[1] == p[2]);
+}
+
+static int
+isValid733Integer(const unsigned char *p)
+{
+ return (p[0] == p[7]
+ && p[1] == p[6]
+ && p[2] == p[5]
+ && p[3] == p[4]);
+}
+
static time_t
isodate7(const unsigned char *v)
{
@@ -3162,7 +3265,7 @@ isodate17(const unsigned char *v)
tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
+ (v[2] - '0') * 10 + (v[3] - '0')
- 1900;
- tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0');
+ tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0') - 1;
tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0');
tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0');
tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0');
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
index 1c64b29..e417baa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
@@ -227,7 +227,7 @@ static int lha_read_file_header_1(struct archive_read *, struct lha *);
static int lha_read_file_header_2(struct archive_read *, struct lha *);
static int lha_read_file_header_3(struct archive_read *, struct lha *);
static int lha_read_file_extended_header(struct archive_read *,
- struct lha *, uint16_t *, int, size_t, size_t *);
+ struct lha *, uint16_t *, int, uint64_t, size_t *);
static size_t lha_check_header_format(const void *);
static int lha_skip_sfx(struct archive_read *);
static time_t lha_dos_time(const unsigned char *);
@@ -945,7 +945,7 @@ lha_read_file_header_1(struct archive_read *a, struct lha *lha)
/* Read extended headers */
err2 = lha_read_file_extended_header(a, lha, NULL, 2,
- (size_t)(lha->compsize + 2), &extdsize);
+ (uint64_t)(lha->compsize + 2), &extdsize);
if (err2 < ARCHIVE_WARN)
return (err2);
if (err2 < err)
@@ -1138,7 +1138,7 @@ invalid:
*/
static int
lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
- uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
+ uint16_t *crc, int sizefield_length, uint64_t limitsize, size_t *total_size)
{
const void *h;
const unsigned char *extdheader;
@@ -1187,8 +1187,7 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
}
/* Sanity check to the extended header size. */
- if (((uint64_t)*total_size + extdsize) >
- (uint64_t)limitsize ||
+ if (((uint64_t)*total_size + extdsize) > limitsize ||
extdsize <= (size_t)sizefield_length)
goto invalid;
@@ -1347,6 +1346,8 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
lha->compsize = archive_le64dec(extdheader);
extdheader += sizeof(uint64_t);
lha->origsize = archive_le64dec(extdheader);
+ if (lha->compsize < 0 || lha->origsize < 0)
+ goto invalid;
}
break;
case EXT_CODEPAGE:
@@ -1693,7 +1694,7 @@ archive_read_format_lha_cleanup(struct archive_read *a)
* example.
* 1. a symbolic-name is 'aaa/bb/cc'
* 2. a filename is 'xxx/bbb'
- * then a archived pathname is 'xxx/bbb|aaa/bb/cc'
+ * then an archived pathname is 'xxx/bbb|aaa/bb/cc'
*/
static int
lha_parse_linkname(struct archive_wstring *linkname,
@@ -2385,7 +2386,7 @@ lzh_decode_blocks(struct lzh_stream *strm, int last)
return (100);
}
- /* lzh_br_read_ahead() always try to fill the
+ /* lzh_br_read_ahead() always tries to fill the
* cache buffer up. In specific situation we
* are close to the end of the data, the cache
* buffer will not be full and thus we have to
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index a5fa30e..6971228 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 201165 2009-12-29 05:52:13Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -417,8 +416,8 @@ next_line(struct archive_read *a,
}
/*
- * Compare characters with a mtree keyword.
- * Returns the length of a mtree keyword if matched.
+ * Compare characters with an mtree keyword.
+ * Returns the length of an mtree keyword if matched.
* Returns 0 if not matched.
*/
static int
@@ -516,7 +515,7 @@ bid_keyword(const char *p, ssize_t len)
/*
* Test whether there is a set of mtree keywords.
- * Returns the number of keyword.
+ * Returns the number of keywords.
* Returns -1 if we got incorrect sequence.
* This function expects a set of "<space characters>keyword=value".
* When "unset" is specified, expects a set of "<space characters>keyword".
@@ -761,7 +760,7 @@ detect_form(struct archive_read *a, int *is_form_d)
multiline = 1;
else {
/* We've got plenty of correct lines
- * to assume that this file is a mtree
+ * to assume that this file is an mtree
* format. */
if (++entry_cnt >= MAX_BID_ENTRY)
break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index a1c5495..2c3b4ea 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -434,7 +434,7 @@ static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
struct huffman_table_entry *, int, int);
static int expand(struct archive_read *, int64_t *);
static int copy_from_lzss_window_to_unp(struct archive_read *, const void **,
- int64_t, int);
+ int64_t, size_t);
static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
static int parse_filter(struct archive_read *, const uint8_t *, uint16_t,
uint8_t);
@@ -736,7 +736,7 @@ archive_read_support_format_rar(struct archive *_a)
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_support_format_rar");
- rar = (struct rar *)calloc(sizeof(*rar), 1);
+ rar = (struct rar *)calloc(1, sizeof(*rar));
if (rar == NULL)
{
archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data");
@@ -1375,6 +1375,8 @@ read_header(struct archive_read *a, struct archive_entry *entry,
struct archive_string_conv *sconv, *fn_sconv;
unsigned long crc32_val;
int ret = (ARCHIVE_OK), ret2;
+ char *newptr;
+ size_t newsize;
rar = (struct rar *)(a->format->data);
@@ -1471,6 +1473,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
if (rar->file_flags & FHD_LARGE)
{
+ if (p + 8 > endp) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
memcpy(packed_size, file_header.pack_size, 4);
memcpy(packed_size + 4, p, 4); /* High pack size */
p += 4;
@@ -1516,8 +1523,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
if (rar->filename_allocated < filename_size * 2 + 2) {
- char *newptr;
- size_t newsize = filename_size * 2 + 2;
+ newsize = filename_size * 2 + 2;
newptr = realloc(rar->filename, newsize);
if (newptr == NULL) {
archive_set_error(&a->archive, ENOMEM,
@@ -1541,7 +1547,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
fn_end = filename_size * 2;
filename_size = 0;
offset = (unsigned)strlen(filename) + 1;
- highbyte = *(p + offset++);
+ highbyte = offset >= end ? 0 : *(p + offset++);
flagbits = 0;
flagbyte = 0;
while (offset < end && filename_size < fn_end)
@@ -1556,14 +1562,22 @@ read_header(struct archive_read *a, struct archive_entry *entry,
switch((flagbyte >> flagbits) & 3)
{
case 0:
+ if (offset >= end)
+ continue;
filename[filename_size++] = '\0';
filename[filename_size++] = *(p + offset++);
break;
case 1:
+ if (offset >= end)
+ continue;
filename[filename_size++] = highbyte;
filename[filename_size++] = *(p + offset++);
break;
case 2:
+ if (offset >= end - 1) {
+ offset = end;
+ continue;
+ }
filename[filename_size++] = *(p + offset + 1);
filename[filename_size++] = *(p + offset);
offset += 2;
@@ -1571,9 +1585,15 @@ read_header(struct archive_read *a, struct archive_entry *entry,
case 3:
{
char extra, high;
- uint8_t length = *(p + offset++);
+ uint8_t length;
+
+ if (offset >= end)
+ continue;
+ length = *(p + offset++);
if (length & 0x80) {
+ if (offset >= end)
+ continue;
extra = *(p + offset++);
high = (char)highbyte;
} else
@@ -1654,13 +1674,16 @@ read_header(struct archive_read *a, struct archive_entry *entry,
rar->cursor++;
if (rar->cursor >= rar->nodes)
{
- rar->nodes++;
- if ((rar->dbo =
- realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL)
+ struct data_block_offsets *newdbo;
+
+ newsize = sizeof(*rar->dbo) * (rar->nodes + 1);
+ if ((newdbo = realloc(rar->dbo, newsize)) == NULL)
{
archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
return (ARCHIVE_FATAL);
}
+ rar->dbo = newdbo;
+ rar->nodes++;
rar->dbo[rar->cursor].header_size = header_size;
rar->dbo[rar->cursor].start_offset = -1;
rar->dbo[rar->cursor].end_offset = -1;
@@ -1680,9 +1703,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
- rar->filename_save = (char*)realloc(rar->filename_save,
- filename_size + 1);
- memcpy(rar->filename_save, rar->filename, filename_size + 1);
+ newsize = filename_size + 1;
+ if ((newptr = realloc(rar->filename_save, newsize)) == NULL)
+ {
+ archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
+ return (ARCHIVE_FATAL);
+ }
+ rar->filename_save = newptr;
+ memcpy(rar->filename_save, rar->filename, newsize);
rar->filename_save_size = filename_size;
/* Set info for seeking */
@@ -2062,7 +2090,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
bs = rar->unp_buffer_size - rar->unp_offset;
else
bs = (size_t)rar->bytes_uncopied;
- ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
+ ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
if (ret != ARCHIVE_OK)
return (ret);
rar->offset += bs;
@@ -2178,6 +2206,19 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
{
start = rar->offset;
end = start + rar->dictionary_size;
+
+ /* We don't want to overflow the window and overwrite data that we write
+ * at 'start'. Therefore, reduce the end length by the maximum match size,
+ * which is 260 bytes. You can compute this maximum by looking at the
+ * definition of 'expand', in particular when 'symbol >= 271'. */
+ /* NOTE: It's possible for 'dictionary_size' to be less than this 260
+ * value, however that will only be the case when 'unp_size' is small,
+ * which should only happen when the entry size is small and there's no
+ * risk of overflowing the buffer */
+ if (rar->dictionary_size > 260) {
+ end -= 260;
+ }
+
if (rar->filters.filterstart < end) {
end = rar->filters.filterstart;
}
@@ -2202,7 +2243,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
bs = rar->unp_buffer_size - rar->unp_offset;
else
bs = (size_t)rar->bytes_uncopied;
- ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
+ ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
if (ret != ARCHIVE_OK)
return (ret);
rar->offset += bs;
@@ -2568,8 +2609,7 @@ read_next_symbol(struct archive_read *a, struct huffman_code *code)
rar_br_consume(br, code->tablesize);
node = value;
- while (!(code->tree[node].branches[0] ==
- code->tree[node].branches[1]))
+ while (code->tree[node].branches[0] != code->tree[node].branches[1])
{
if (!rar_br_read_ahead(a, br, 1)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@@ -2944,7 +2984,7 @@ expand(struct archive_read *a, int64_t *end)
if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
goto bad_data;
- if (lensymbol > lengthb_min)
+ if (lensymbol >= lengthb_min)
goto bad_data;
len = lengthbases[lensymbol] + 2;
if (lengthbits[lensymbol] > 0) {
@@ -2976,7 +3016,7 @@ expand(struct archive_read *a, int64_t *end)
}
else
{
- if (symbol-271 > lengthb_min)
+ if (symbol-271 >= lengthb_min)
goto bad_data;
len = lengthbases[symbol-271]+3;
if(lengthbits[symbol-271] > 0) {
@@ -2988,7 +3028,7 @@ expand(struct archive_read *a, int64_t *end)
if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
goto bad_data;
- if (offssymbol > offsetb_min)
+ if (offssymbol >= offsetb_min)
goto bad_data;
offs = offsetbases[offssymbol]+1;
if(offsetbits[offssymbol] > 0)
@@ -3083,11 +3123,16 @@ copy_from_lzss_window(struct archive_read *a, void *buffer,
static int
copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
- int64_t startpos, int length)
+ int64_t startpos, size_t length)
{
int windowoffs, firstpart;
struct rar *rar = (struct rar *)(a->format->data);
+ if (length > rar->unp_buffer_size)
+ {
+ goto fatal;
+ }
+
if (!rar->unp_buffer)
{
if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
@@ -3099,17 +3144,17 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
}
windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
- if(windowoffs + length <= lzss_size(&rar->lzss)) {
+ if(windowoffs + length <= (size_t)lzss_size(&rar->lzss)) {
memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
length);
- } else if (length <= lzss_size(&rar->lzss)) {
+ } else if (length <= (size_t)lzss_size(&rar->lzss)) {
firstpart = lzss_size(&rar->lzss) - windowoffs;
if (firstpart < 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Bad RAR file data");
return (ARCHIVE_FATAL);
}
- if (firstpart < length) {
+ if ((size_t)firstpart < length) {
memcpy(&rar->unp_buffer[rar->unp_offset],
&rar->lzss.window[windowoffs], firstpart);
memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
@@ -3119,16 +3164,19 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
&rar->lzss.window[windowoffs], length);
}
} else {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Bad RAR file data");
- return (ARCHIVE_FATAL);
+ goto fatal;
}
- rar->unp_offset += length;
+ rar->unp_offset += (unsigned int) length;
if (rar->unp_offset >= rar->unp_buffer_size)
*buffer = rar->unp_buffer;
else
*buffer = NULL;
return (ARCHIVE_OK);
+
+fatal:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file data");
+ return (ARCHIVE_FATAL);
}
static const void *
@@ -3314,7 +3362,8 @@ create_filter(struct rar_program_code *prog, const uint8_t *globaldata, uint32_t
filter->prog = prog;
filter->globaldatalen = globaldatalen > PROGRAM_SYSTEM_GLOBAL_SIZE ? globaldatalen : PROGRAM_SYSTEM_GLOBAL_SIZE;
filter->globaldata = calloc(1, filter->globaldatalen);
- if (!filter->globaldata) {
+ if (!filter->globaldata)
+ {
free(filter);
return NULL;
}
@@ -3344,7 +3393,7 @@ run_filters(struct archive_read *a)
if (filters == NULL || filter == NULL)
return (0);
- start = filters->filterstart;
+ start = (size_t)filters->filterstart;
end = start + filter->blocklength;
filters->filterstart = INT64_MAX;
@@ -3381,10 +3430,16 @@ run_filters(struct archive_read *a)
return 0;
}
+ if (filter->blocklength > VM_MEMORY_SIZE)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Bad RAR file data");
+ return 0;
+ }
+
ret = copy_from_lzss_window(a, filters->vm->memory, start, filter->blocklength);
if (ret != ARCHIVE_OK)
return 0;
- if (!execute_filter(a, filter, filters->vm, rar->offset))
+ if (!execute_filter(a, filter, filters->vm, (size_t)rar->offset))
return 0;
lastfilteraddress = filter->filteredblockaddress;
@@ -3396,7 +3451,7 @@ run_filters(struct archive_read *a)
while ((filter = filters->stack) != NULL && (int64_t)filter->blockstartpos == filters->filterstart && filter->blocklength == lastfilterlength)
{
memmove(&filters->vm->memory[0], &filters->vm->memory[lastfilteraddress], lastfilterlength);
- if (!execute_filter(a, filter, filters->vm, rar->offset))
+ if (!execute_filter(a, filter, filters->vm, (size_t)rar->offset))
return 0;
lastfilteraddress = filter->filteredblockaddress;
@@ -3604,7 +3659,15 @@ execute_filter_delta(struct rar_filter *filter, struct rar_virtual_machine *vm)
{
uint8_t lastbyte = 0;
for (idx = i; idx < length; idx += numchannels)
+ {
+ /*
+ * The src block should not overlap with the dst block.
+ * If so it would be better to consider this archive is broken.
+ */
+ if (src >= dst)
+ return 0;
lastbyte = dst[idx] = lastbyte - *src++;
+ }
}
filter->filteredblockaddress = length;
@@ -3620,7 +3683,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
uint32_t filesize = 0x1000000;
uint32_t i;
- if (length > PROGRAM_WORK_SIZE || length < 4)
+ if (length > PROGRAM_WORK_SIZE || length <= 4)
return 0;
for (i = 0; i <= length - 5; i++)
@@ -3629,7 +3692,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
{
uint32_t currpos = (uint32_t)pos + i + 1;
int32_t address = (int32_t)vm_read_32(vm, i + 1);
- if (address < 0 && currpos >= (uint32_t)-address)
+ if (address < 0 && currpos >= (~(uint32_t)address + 1))
vm_write_32(vm, i + 1, address + filesize);
else if (address >= 0 && (uint32_t)address < filesize)
vm_write_32(vm, i + 1, address - currpos);
@@ -3652,7 +3715,7 @@ execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
uint8_t *src, *dst;
uint32_t i, j;
- if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength)
+ if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength || blocklength < 3 || byteoffset > 2)
return 0;
src = &vm->memory[0];
@@ -3662,6 +3725,13 @@ execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
uint8_t *prev = dst + i - stride;
for (j = i; j < blocklength; j += 3)
{
+ /*
+ * The src block should not overlap with the dst block.
+ * If so it would be better to consider this archive is broken.
+ */
+ if (src >= dst)
+ return 0;
+
if (prev >= dst)
{
uint32_t delta1 = abs(prev[3] - prev[0]);
@@ -3706,6 +3776,13 @@ execute_filter_audio(struct rar_filter *filter, struct rar_virtual_machine *vm)
memset(&state, 0, sizeof(state));
for (j = i; j < length; j += numchannels)
{
+ /*
+ * The src block should not overlap with the dst block.
+ * If so it would be better to consider this archive is broken.
+ */
+ if (src >= dst)
+ return 0;
+
int8_t delta = (int8_t)*src++;
uint8_t predbyte, byte;
int prederror;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
index 7f1efb8..973cd42b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
@@ -220,7 +220,7 @@ struct comp_state {
decompression. */
uint8_t* filtered_buf; /* Buffer used when applying filters. */
const uint8_t* block_buf; /* Buffer used when merging blocks. */
- size_t window_mask; /* Convenience field; window_size - 1. */
+ ssize_t window_mask; /* Convenience field; window_size - 1. */
int64_t write_ptr; /* This amount of data has been unpacked
in the window buffer. */
int64_t last_write_ptr; /* This amount of data has been stored in
@@ -361,6 +361,7 @@ static int verify_global_checksums(struct archive_read* a);
static int rar5_read_data_skip(struct archive_read *a);
static int push_data_ready(struct archive_read* a, struct rar5* rar,
const uint8_t* buf, size_t size, int64_t offset);
+static void clear_data_ready_stack(struct rar5* rar);
/* CDE_xxx = Circular Double Ended (Queue) return values. */
enum CDE_RETURN_VALUES {
@@ -495,12 +496,17 @@ uint8_t bf_is_table_present(const struct compressed_block_header* hdr) {
return (hdr->block_flags_u8 >> 7) & 1;
}
+static inline
+uint8_t bf_is_last_block(const struct compressed_block_header* hdr) {
+ return (hdr->block_flags_u8 >> 6) & 1;
+}
+
static inline struct rar5* get_context(struct archive_read* a) {
return (struct rar5*) a->format->data;
}
/* Convenience functions used by filter implementations. */
-static void circular_memcpy(uint8_t* dst, uint8_t* window, const uint64_t mask,
+static void circular_memcpy(uint8_t* dst, uint8_t* window, const ssize_t mask,
int64_t start, int64_t end)
{
if((start & mask) > (end & mask)) {
@@ -647,6 +653,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
int ret;
struct rar5* rar = get_context(a);
+ clear_data_ready_stack(rar);
free(rar->cstate.filtered_buf);
rar->cstate.filtered_buf = malloc(flt->block_length);
@@ -704,7 +711,7 @@ static int run_filter(struct archive_read* a, struct filter_info* flt) {
static void push_data(struct archive_read* a, struct rar5* rar,
const uint8_t* buf, int64_t idx_begin, int64_t idx_end)
{
- const uint64_t wmask = rar->cstate.window_mask;
+ const ssize_t wmask = rar->cstate.window_mask;
const ssize_t solid_write_ptr = (rar->cstate.solid_offset +
rar->cstate.last_write_ptr) & wmask;
@@ -1241,7 +1248,7 @@ static int process_main_locator_extra_block(struct archive_read* a,
}
static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
- ssize_t* extra_data_size)
+ int64_t* extra_data_size)
{
size_t hash_type = 0;
size_t value_len;
@@ -1291,7 +1298,7 @@ static uint64_t time_win_to_unix(uint64_t win_time) {
}
static int parse_htime_item(struct archive_read* a, char unix_time,
- uint64_t* where, ssize_t* extra_data_size)
+ uint64_t* where, int64_t* extra_data_size)
{
if(unix_time) {
uint32_t time_val;
@@ -1313,7 +1320,7 @@ static int parse_htime_item(struct archive_read* a, char unix_time,
}
static int parse_file_extra_version(struct archive_read* a,
- struct archive_entry* e, ssize_t* extra_data_size)
+ struct archive_entry* e, int64_t* extra_data_size)
{
size_t flags = 0;
size_t version = 0;
@@ -1367,7 +1374,7 @@ static int parse_file_extra_version(struct archive_read* a,
}
static int parse_file_extra_htime(struct archive_read* a,
- struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
+ struct archive_entry* e, struct rar5* rar, int64_t* extra_data_size)
{
char unix_time = 0;
size_t flags = 0;
@@ -1420,7 +1427,7 @@ static int parse_file_extra_htime(struct archive_read* a,
}
static int parse_file_extra_redir(struct archive_read* a,
- struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
+ struct archive_entry* e, struct rar5* rar, int64_t* extra_data_size)
{
uint64_t value_size = 0;
size_t target_size = 0;
@@ -1443,9 +1450,6 @@ static int parse_file_extra_redir(struct archive_read* a,
return ARCHIVE_EOF;
*extra_data_size -= target_size + 1;
- if(!read_ahead(a, target_size, &p))
- return ARCHIVE_EOF;
-
if(target_size > (MAX_NAME_IN_CHARS - 1)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Link target is too long");
@@ -1458,6 +1462,9 @@ static int parse_file_extra_redir(struct archive_read* a,
return ARCHIVE_FATAL;
}
+ if(!read_ahead(a, target_size, &p))
+ return ARCHIVE_EOF;
+
memcpy(target_utf8_buf, p, target_size);
target_utf8_buf[target_size] = 0;
@@ -1491,7 +1498,7 @@ static int parse_file_extra_redir(struct archive_read* a,
}
static int parse_file_extra_owner(struct archive_read* a,
- struct archive_entry* e, ssize_t* extra_data_size)
+ struct archive_entry* e, int64_t* extra_data_size)
{
uint64_t flags = 0;
uint64_t value_size = 0;
@@ -1571,15 +1578,15 @@ static int parse_file_extra_owner(struct archive_read* a,
}
static int process_head_file_extra(struct archive_read* a,
- struct archive_entry* e, struct rar5* rar, ssize_t extra_data_size)
+ struct archive_entry* e, struct rar5* rar, int64_t extra_data_size)
{
- size_t extra_field_size;
- size_t extra_field_id = 0;
+ uint64_t extra_field_size;
+ uint64_t extra_field_id = 0;
int ret = ARCHIVE_FATAL;
- size_t var_size;
+ uint64_t var_size;
while(extra_data_size > 0) {
- if(!read_var_sized(a, &extra_field_size, &var_size))
+ if(!read_var(a, &extra_field_size, &var_size))
return ARCHIVE_EOF;
extra_data_size -= var_size;
@@ -1587,7 +1594,7 @@ static int process_head_file_extra(struct archive_read* a,
return ARCHIVE_EOF;
}
- if(!read_var_sized(a, &extra_field_id, &var_size))
+ if(!read_var(a, &extra_field_id, &var_size))
return ARCHIVE_EOF;
extra_data_size -= var_size;
@@ -1637,7 +1644,7 @@ static int process_head_file_extra(struct archive_read* a,
static int process_head_file(struct archive_read* a, struct rar5* rar,
struct archive_entry* entry, size_t block_flags)
{
- ssize_t extra_data_size = 0;
+ int64_t extra_data_size = 0;
size_t data_size = 0;
size_t file_flags = 0;
size_t file_attr = 0;
@@ -1677,12 +1684,12 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
}
if(block_flags & HFL_EXTRA_DATA) {
- size_t edata_size = 0;
- if(!read_var_sized(a, &edata_size, NULL))
+ uint64_t edata_size = 0;
+ if(!read_var(a, &edata_size, NULL))
return ARCHIVE_EOF;
/* Intentional type cast from unsigned to signed. */
- extra_data_size = (ssize_t) edata_size;
+ extra_data_size = (int64_t) edata_size;
}
if(block_flags & HFL_DATA) {
@@ -1775,11 +1782,18 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
if(rar->cstate.window_size < (ssize_t) window_size &&
rar->cstate.window_buf)
{
+ /* The `data_ready` stack contains pointers to the `window_buf` or
+ * `filtered_buf` buffers. Since we're about to reallocate the first
+ * buffer, some of those pointers could become invalid. Therefore, we
+ * need to dispose of all entries from the stack before attempting the
+ * realloc. */
+ clear_data_ready_stack(rar);
+
/* If window_buf has been allocated before, reallocate it, so
* that its size will match new window_size. */
uint8_t* new_window_buf =
- realloc(rar->cstate.window_buf, window_size);
+ realloc(rar->cstate.window_buf, (size_t) window_size);
if(!new_window_buf) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
@@ -1871,9 +1885,6 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
if(!read_var_sized(a, &name_size, NULL))
return ARCHIVE_EOF;
- if(!read_ahead(a, name_size, &p))
- return ARCHIVE_EOF;
-
if(name_size > (MAX_NAME_IN_CHARS - 1)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Filename is too long");
@@ -1888,6 +1899,9 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
return ARCHIVE_FATAL;
}
+ if(!read_ahead(a, name_size, &p))
+ return ARCHIVE_EOF;
+
memcpy(name_utf8_buf, p, name_size);
name_utf8_buf[name_size] = 0;
if(ARCHIVE_OK != consume(a, name_size)) {
@@ -1975,7 +1989,7 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
struct archive_entry* entry, size_t block_flags)
{
int ret;
- size_t extra_data_size = 0;
+ uint64_t extra_data_size = 0;
size_t extra_field_size = 0;
size_t extra_field_id = 0;
size_t archive_flags = 0;
@@ -1997,7 +2011,7 @@ static int process_head_main(struct archive_read* a, struct rar5* rar,
(void) entry;
if(block_flags & HFL_EXTRA_DATA) {
- if(!read_var_sized(a, &extra_data_size, NULL))
+ if(!read_var(a, &extra_data_size, NULL))
return ARCHIVE_EOF;
} else {
extra_data_size = 0;
@@ -2224,10 +2238,12 @@ static int process_base_block(struct archive_read* a,
/* Verify the CRC32 of the header data. */
computed_crc = (uint32_t) crc32(0, p, (int) hdr_size);
if(computed_crc != hdr_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Header CRC error");
return ARCHIVE_FATAL;
+#endif
}
/* If the checksum is OK, we proceed with parsing. */
@@ -2448,6 +2464,8 @@ static void init_unpack(struct rar5* rar) {
rar->cstate.filtered_buf = NULL;
}
+ clear_data_ready_stack(rar);
+
rar->cstate.write_ptr = 0;
rar->cstate.last_write_ptr = 0;
@@ -2989,7 +3007,7 @@ static int decode_code_length(struct archive_read* a, struct rar5* rar,
static int copy_string(struct archive_read* a, int len, int dist) {
struct rar5* rar = get_context(a);
- const uint64_t cmask = rar->cstate.window_mask;
+ const ssize_t cmask = rar->cstate.window_mask;
const uint64_t write_ptr = rar->cstate.write_ptr +
rar->cstate.solid_offset;
int i;
@@ -3633,6 +3651,10 @@ static int use_data(struct rar5* rar, const void** buf, size_t* size,
return ARCHIVE_RETRY;
}
+static void clear_data_ready_stack(struct rar5* rar) {
+ memset(&rar->cstate.dready, 0, sizeof(rar->cstate.dready));
+}
+
/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready
* FIFO stack. Those values will be popped from this stack by the `use_data`
* function. */
@@ -3768,7 +3790,12 @@ static int do_uncompress_file(struct archive_read* a) {
if(rar->cstate.last_write_ptr ==
rar->cstate.write_ptr) {
/* The block didn't generate any new data,
- * so just process a new block. */
+ * so just process a new block if this one
+ * wasn't the last block in the file. */
+ if (bf_is_last_block(&rar->last_block_hdr)) {
+ return ARCHIVE_EOF;
+ }
+
continue;
}
@@ -4186,6 +4213,7 @@ static int rar5_cleanup(struct archive_read *a) {
free(rar->cstate.window_buf);
free(rar->cstate.filtered_buf);
+ clear_data_ready_stack(rar);
free(rar->vol.push_buf);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
index ec0520b..efdbf27 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
@@ -23,7 +23,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_raw.c 201107 2009-12-28 03:25:33Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
index 93c3fd5..af601ef 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2023 Tim Kientzle
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
* Copyright (c) 2016 Martin Matuska
* All rights reserved.
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161 2009-12-29 05:44:39Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -118,33 +117,29 @@ struct sparse_block {
};
struct tar {
- struct archive_string acl_text;
struct archive_string entry_pathname;
/* For "GNU.sparse.name" and other similar path extensions. */
struct archive_string entry_pathname_override;
- struct archive_string entry_linkpath;
struct archive_string entry_uname;
struct archive_string entry_gname;
- struct archive_string longlink;
+ struct archive_string entry_linkpath;
struct archive_string longname;
- struct archive_string pax_header;
struct archive_string pax_global;
struct archive_string line;
- int pax_hdrcharset_binary;
- int header_recursion_depth;
+ int pax_hdrcharset_utf8;
int64_t entry_bytes_remaining;
int64_t entry_offset;
int64_t entry_padding;
int64_t entry_bytes_unconsumed;
int64_t realsize;
- int sparse_allowed;
struct sparse_block *sparse_list;
struct sparse_block *sparse_last;
int64_t sparse_offset;
int64_t sparse_numbytes;
int sparse_gnu_major;
int sparse_gnu_minor;
- char sparse_gnu_pending;
+ char sparse_gnu_attributes_seen;
+ char filetype;
struct archive_string localname;
struct archive_string_conv *opt_sconv;
@@ -169,25 +164,26 @@ static int gnu_sparse_old_read(struct archive_read *, struct tar *,
static int gnu_sparse_old_parse(struct archive_read *, struct tar *,
const struct gnu_sparse *sparse, int length);
static int gnu_sparse_01_parse(struct archive_read *, struct tar *,
- const char *);
+ const char *, size_t);
static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *,
- size_t *);
+ size_t *);
static int header_Solaris_ACL(struct archive_read *, struct tar *,
struct archive_entry *, const void *, size_t *);
static int header_common(struct archive_read *, struct tar *,
struct archive_entry *, const void *);
static int header_old_tar(struct archive_read *, struct tar *,
struct archive_entry *, const void *);
-static int header_pax_extensions(struct archive_read *, struct tar *,
+static int header_pax_extension(struct archive_read *, struct tar *,
struct archive_entry *, const void *, size_t *);
static int header_pax_global(struct archive_read *, struct tar *,
struct archive_entry *, const void *h, size_t *);
-static int header_longlink(struct archive_read *, struct tar *,
+static int header_gnu_longlink(struct archive_read *, struct tar *,
struct archive_entry *, const void *h, size_t *);
-static int header_longname(struct archive_read *, struct tar *,
- struct archive_entry *, const void *h, size_t *);
-static int read_mac_metadata_blob(struct archive_read *, struct tar *,
+static int header_gnu_longname(struct archive_read *, struct tar *,
struct archive_entry *, const void *h, size_t *);
+static int is_mac_metadata_entry(struct archive_entry *entry);
+static int read_mac_metadata_blob(struct archive_read *,
+ struct archive_entry *, size_t *);
static int header_volume(struct archive_read *, struct tar *,
struct archive_entry *, const void *h, size_t *);
static int header_ustar(struct archive_read *, struct tar *,
@@ -205,21 +201,21 @@ static int archive_read_format_tar_read_header(struct archive_read *,
struct archive_entry *);
static int checksum(struct archive_read *, const void *);
static int pax_attribute(struct archive_read *, struct tar *,
- struct archive_entry *, const char *key, const char *value,
- size_t value_length);
-static int pax_attribute_acl(struct archive_read *, struct tar *,
- struct archive_entry *, const char *, int);
-static int pax_attribute_xattr(struct archive_entry *, const char *,
- const char *);
-static int pax_header(struct archive_read *, struct tar *,
- struct archive_entry *, struct archive_string *);
-static void pax_time(const char *, int64_t *sec, long *nanos);
+ struct archive_entry *, const char *key, size_t key_length,
+ size_t value_length, size_t *unconsumed);
+static int pax_attribute_LIBARCHIVE_xattr(struct archive_entry *,
+ const char *, size_t, const char *, size_t);
+static int pax_attribute_SCHILY_acl(struct archive_read *, struct tar *,
+ struct archive_entry *, size_t, int);
+static int pax_attribute_SUN_holesdata(struct archive_read *, struct tar *,
+ struct archive_entry *, const char *, size_t);
+static void pax_time(const char *, size_t, int64_t *sec, long *nanos);
static ssize_t readline(struct archive_read *, struct tar *, const char **,
ssize_t limit, size_t *);
static int read_body_to_string(struct archive_read *, struct tar *,
struct archive_string *, const void *h, size_t *);
-static int solaris_sparse_parse(struct archive_read *, struct tar *,
- struct archive_entry *, const char *);
+static int read_bytes_to_string(struct archive_read *,
+ struct archive_string *, size_t, size_t *);
static int64_t tar_atol(const char *, size_t);
static int64_t tar_atol10(const char *, size_t);
static int64_t tar_atol256(const char *, size_t);
@@ -227,9 +223,21 @@ static int64_t tar_atol8(const char *, size_t);
static int tar_read_header(struct archive_read *, struct tar *,
struct archive_entry *, size_t *);
static int tohex(int c);
-static char *url_decode(const char *);
+static char *url_decode(const char *, size_t);
static void tar_flush_unconsumed(struct archive_read *, size_t *);
+/* Sanity limits: These numbers should be low enough to
+ * prevent a maliciously-crafted archive from forcing us to
+ * allocate extreme amounts of memory. But of course, they
+ * need to be high enough for any correct value. These
+ * will likely need some adjustment as we get more experience. */
+static const size_t guname_limit = 65536; /* Longest uname or gname: 64kiB */
+static const size_t pathname_limit = 1048576; /* Longest path name: 1MiB */
+static const size_t sparse_map_limit = 8 * 1048576; /* Longest sparse map: 8MiB */
+static const size_t xattr_limit = 16 * 1048576; /* Longest xattr: 16MiB */
+static const size_t fflags_limit = 512; /* Longest fflags */
+static const size_t acl_limit = 131072; /* Longest textual ACL: 128kiB */
+static const int64_t entry_limit = 0xfffffffffffffffLL; /* 2^60 bytes = 1 ExbiByte */
int
archive_read_support_format_gnutar(struct archive *a)
@@ -284,17 +292,13 @@ archive_read_format_tar_cleanup(struct archive_read *a)
tar = (struct tar *)(a->format->data);
gnu_clear_sparse_list(tar);
- archive_string_free(&tar->acl_text);
archive_string_free(&tar->entry_pathname);
archive_string_free(&tar->entry_pathname_override);
- archive_string_free(&tar->entry_linkpath);
archive_string_free(&tar->entry_uname);
archive_string_free(&tar->entry_gname);
archive_string_free(&tar->line);
archive_string_free(&tar->pax_global);
- archive_string_free(&tar->pax_header);
archive_string_free(&tar->longname);
- archive_string_free(&tar->longlink);
archive_string_free(&tar->localname);
free(tar);
(a->format->data) = NULL;
@@ -506,6 +510,8 @@ archive_read_format_tar_read_header(struct archive_read *a,
* probably not worthwhile just to support the relatively
* obscure tar->cpio conversion case.
*/
+ /* TODO: Move this into `struct tar` to avoid conflicts
+ * when reading multiple archives */
static int default_inode;
static int default_dev;
struct tar *tar;
@@ -628,7 +634,8 @@ archive_read_format_tar_read_data(struct archive_read *a,
return (ARCHIVE_FATAL);
if (*buff == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated tar archive");
+ "Truncated tar archive"
+ " detected while reading data");
return (ARCHIVE_FATAL);
}
if (bytes_read > tar->entry_bytes_remaining)
@@ -689,7 +696,7 @@ archive_read_format_tar_skip(struct archive_read *a)
}
/*
- * This function recursively interprets all of the headers associated
+ * This function reads and interprets all of the headers associated
* with a single entry.
*/
static int
@@ -697,190 +704,259 @@ tar_read_header(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, size_t *unconsumed)
{
ssize_t bytes;
- int err, eof_vol_header;
+ int err = ARCHIVE_OK, err2;
+ int eof_fatal = 0; /* EOF is okay at some points... */
const char *h;
const struct archive_entry_header_ustar *header;
const struct archive_entry_header_gnutar *gnuheader;
- eof_vol_header = 0;
-
- /* Loop until we find a workable header record. */
- for (;;) {
- tar_flush_unconsumed(a, unconsumed);
+ /* Bitmask of what header types we've seen. */
+ int32_t seen_headers = 0;
+ static const int32_t seen_A_header = 1;
+ static const int32_t seen_g_header = 2;
+ static const int32_t seen_K_header = 4;
+ static const int32_t seen_L_header = 8;
+ static const int32_t seen_V_header = 16;
+ static const int32_t seen_x_header = 32; /* Also X */
+ static const int32_t seen_mac_metadata = 512;
+
+ tar->pax_hdrcharset_utf8 = 1;
+ tar->sparse_gnu_attributes_seen = 0;
+ archive_string_empty(&(tar->entry_gname));
+ archive_string_empty(&(tar->entry_pathname));
+ archive_string_empty(&(tar->entry_pathname_override));
+ archive_string_empty(&(tar->entry_uname));
- /* Read 512-byte header record */
- h = __archive_read_ahead(a, 512, &bytes);
- if (bytes < 0)
- return ((int)bytes);
- if (bytes == 0) { /* EOF at a block boundary. */
- /* Some writers do omit the block of nulls. <sigh> */
- return (ARCHIVE_EOF);
- }
- if (bytes < 512) { /* Short block at EOF; this is bad. */
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated tar archive");
- return (ARCHIVE_FATAL);
- }
- *unconsumed = 512;
+ /* Ensure format is set. */
+ if (a->archive.archive_format_name == NULL) {
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR;
+ a->archive.archive_format_name = "tar";
+ }
- /* Header is workable if it's not an end-of-archive mark. */
- if (h[0] != 0 || !archive_block_is_null(h))
- break;
+ /*
+ * TODO: Write global/default pax options into
+ * 'entry' struct here before overwriting with
+ * file-specific options.
+ */
- /* Ensure format is set for archives with only null blocks. */
- if (a->archive.archive_format_name == NULL) {
- a->archive.archive_format = ARCHIVE_FORMAT_TAR;
- a->archive.archive_format_name = "tar";
- }
+ /* Loop over all the headers needed for the next entry */
+ for (;;) {
- if (!tar->read_concatenated_archives) {
- /* Try to consume a second all-null record, as well. */
+ /* Find the next valid header record. */
+ while (1) {
tar_flush_unconsumed(a, unconsumed);
- h = __archive_read_ahead(a, 512, NULL);
- if (h != NULL && h[0] == 0 && archive_block_is_null(h))
- __archive_read_consume(a, 512);
- archive_clear_error(&a->archive);
- return (ARCHIVE_EOF);
- }
- /*
- * We're reading concatenated archives, ignore this block and
- * loop to get the next.
- */
- }
+ /* Read 512-byte header record */
+ h = __archive_read_ahead(a, 512, &bytes);
+ if (bytes < 0)
+ return ((int)bytes);
+ if (bytes == 0) { /* EOF at a block boundary. */
+ if (eof_fatal) {
+ /* We've read a special header already;
+ * if there's no regular header, then this is
+ * a premature EOF. */
+ archive_set_error(&a->archive, EINVAL,
+ "Damaged tar archive");
+ return (ARCHIVE_FATAL);
+ } else {
+ return (ARCHIVE_EOF);
+ }
+ }
+ if (bytes < 512) { /* Short block at EOF; this is bad. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated tar archive"
+ " detected while reading next heaader");
+ return (ARCHIVE_FATAL);
+ }
+ *unconsumed += 512;
- /*
- * Note: If the checksum fails and we return ARCHIVE_RETRY,
- * then the client is likely to just retry. This is a very
- * crude way to search for the next valid header!
- *
- * TODO: Improve this by implementing a real header scan.
- */
- if (!checksum(a, h)) {
- tar_flush_unconsumed(a, unconsumed);
- archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
- return (ARCHIVE_RETRY); /* Retryable: Invalid header */
- }
+ if (h[0] == 0 && archive_block_is_null(h)) {
+ /* We found a NULL block which indicates end-of-archive */
- if (++tar->header_recursion_depth > 32) {
- tar_flush_unconsumed(a, unconsumed);
- archive_set_error(&a->archive, EINVAL, "Too many special headers");
- return (ARCHIVE_WARN);
- }
+ if (tar->read_concatenated_archives) {
+ /* We're ignoring NULL blocks, so keep going. */
+ continue;
+ }
- /* Determine the format variant. */
- header = (const struct archive_entry_header_ustar *)h;
+ /* Try to consume a second all-null record, as well. */
+ /* If we can't, that's okay. */
+ tar_flush_unconsumed(a, unconsumed);
+ h = __archive_read_ahead(a, 512, NULL);
+ if (h != NULL && h[0] == 0 && archive_block_is_null(h))
+ __archive_read_consume(a, 512);
- switch(header->typeflag[0]) {
- case 'A': /* Solaris tar ACL */
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name = "Solaris tar";
- err = header_Solaris_ACL(a, tar, entry, h, unconsumed);
- break;
- case 'g': /* POSIX-standard 'g' header. */
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name = "POSIX pax interchange format";
- err = header_pax_global(a, tar, entry, h, unconsumed);
- if (err == ARCHIVE_EOF)
- return (err);
- break;
- case 'K': /* Long link name (GNU tar, others) */
- err = header_longlink(a, tar, entry, h, unconsumed);
- break;
- case 'L': /* Long filename (GNU tar, others) */
- err = header_longname(a, tar, entry, h, unconsumed);
- break;
- case 'V': /* GNU volume header */
- err = header_volume(a, tar, entry, h, unconsumed);
- if (err == ARCHIVE_EOF)
- eof_vol_header = 1;
- break;
- case 'X': /* Used by SUN tar; same as 'x'. */
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name =
- "POSIX pax interchange format (Sun variant)";
- err = header_pax_extensions(a, tar, entry, h, unconsumed);
- break;
- case 'x': /* POSIX-standard 'x' header. */
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
- a->archive.archive_format_name = "POSIX pax interchange format";
- err = header_pax_extensions(a, tar, entry, h, unconsumed);
- break;
- default:
- gnuheader = (const struct archive_entry_header_gnutar *)h;
- if (memcmp(gnuheader->magic, "ustar \0", 8) == 0) {
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
- a->archive.archive_format_name = "GNU tar format";
- err = header_gnutar(a, tar, entry, h, unconsumed);
- } else if (memcmp(header->magic, "ustar", 5) == 0) {
- if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
- a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
- a->archive.archive_format_name = "POSIX ustar format";
+ archive_clear_error(&a->archive);
+ return (ARCHIVE_EOF);
}
- err = header_ustar(a, tar, entry, h);
- } else {
- a->archive.archive_format = ARCHIVE_FORMAT_TAR;
- a->archive.archive_format_name = "tar (non-POSIX)";
- err = header_old_tar(a, tar, entry, h);
- }
- }
- if (err == ARCHIVE_FATAL)
- return (err);
- tar_flush_unconsumed(a, unconsumed);
-
- h = NULL;
- header = NULL;
+ /* This is NOT a null block, so it must be a valid header. */
+ if (!checksum(a, h)) {
+ tar_flush_unconsumed(a, unconsumed);
+ archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
+ /* If we've read some critical information (pax headers, etc)
+ * and _then_ see a bad header, we can't really recover. */
+ if (eof_fatal) {
+ return (ARCHIVE_FATAL);
+ } else {
+ return (ARCHIVE_RETRY);
+ }
+ }
+ break;
+ }
- --tar->header_recursion_depth;
- /* Yuck. Apple's design here ends up storing long pathname
- * extensions for both the AppleDouble extension entry and the
- * regular entry.
- */
- if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
- tar->header_recursion_depth == 0 &&
- tar->process_mac_extensions) {
- int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
- if (err2 < err)
- err = err2;
- }
-
- /* We return warnings or success as-is. Anything else is fatal. */
- if (err == ARCHIVE_WARN || err == ARCHIVE_OK) {
- if (tar->sparse_gnu_pending) {
- if (tar->sparse_gnu_major == 1 &&
- tar->sparse_gnu_minor == 0) {
- ssize_t bytes_read;
-
- tar->sparse_gnu_pending = 0;
- /* Read initial sparse map. */
- bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
- if (bytes_read < 0)
- return ((int)bytes_read);
- tar->entry_bytes_remaining -= bytes_read;
+ /* Determine the format variant. */
+ header = (const struct archive_entry_header_ustar *)h;
+ switch(header->typeflag[0]) {
+ case 'A': /* Solaris tar ACL */
+ if (seen_headers & seen_A_header) {
+ return (ARCHIVE_FATAL);
+ }
+ seen_headers |= seen_A_header;
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
+ a->archive.archive_format_name = "Solaris tar";
+ err2 = header_Solaris_ACL(a, tar, entry, h, unconsumed);
+ break;
+ case 'g': /* POSIX-standard 'g' header. */
+ if (seen_headers & seen_g_header) {
+ return (ARCHIVE_FATAL);
+ }
+ seen_headers |= seen_g_header;
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
+ a->archive.archive_format_name = "POSIX pax interchange format";
+ err2 = header_pax_global(a, tar, entry, h, unconsumed);
+ break;
+ case 'K': /* Long link name (GNU tar, others) */
+ if (seen_headers & seen_K_header) {
+ return (ARCHIVE_FATAL);
+ }
+ seen_headers |= seen_K_header;
+ err2 = header_gnu_longlink(a, tar, entry, h, unconsumed);
+ break;
+ case 'L': /* Long filename (GNU tar, others) */
+ if (seen_headers & seen_L_header) {
+ return (ARCHIVE_FATAL);
+ }
+ seen_headers |= seen_L_header;
+ err2 = header_gnu_longname(a, tar, entry, h, unconsumed);
+ break;
+ case 'V': /* GNU volume header */
+ if (seen_headers & seen_V_header) {
+ return (ARCHIVE_FATAL);
+ }
+ seen_headers |= seen_V_header;
+ err2 = header_volume(a, tar, entry, h, unconsumed);
+ break;
+ case 'X': /* Used by SUN tar; same as 'x'. */
+ if (seen_headers & seen_x_header) {
+ return (ARCHIVE_FATAL);
+ }
+ seen_headers |= seen_x_header;
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
+ a->archive.archive_format_name =
+ "POSIX pax interchange format (Sun variant)";
+ err2 = header_pax_extension(a, tar, entry, h, unconsumed);
+ break;
+ case 'x': /* POSIX-standard 'x' header. */
+ if (seen_headers & seen_x_header) {
+ return (ARCHIVE_FATAL);
+ }
+ seen_headers |= seen_x_header;
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
+ a->archive.archive_format_name = "POSIX pax interchange format";
+ err2 = header_pax_extension(a, tar, entry, h, unconsumed);
+ break;
+ default: /* Regular header: Legacy tar, GNU tar, or ustar */
+ gnuheader = (const struct archive_entry_header_gnutar *)h;
+ if (memcmp(gnuheader->magic, "ustar \0", 8) == 0) {
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
+ a->archive.archive_format_name = "GNU tar format";
+ err2 = header_gnutar(a, tar, entry, h, unconsumed);
+ } else if (memcmp(header->magic, "ustar", 5) == 0) {
+ if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
+ a->archive.archive_format_name = "POSIX ustar format";
+ }
+ err2 = header_ustar(a, tar, entry, h);
} else {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Unrecognized GNU sparse file format");
- return (ARCHIVE_WARN);
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR;
+ a->archive.archive_format_name = "tar (non-POSIX)";
+ err2 = header_old_tar(a, tar, entry, h);
}
- tar->sparse_gnu_pending = 0;
+ err = err_combine(err, err2);
+ /* We return warnings or success as-is. Anything else is fatal. */
+ if (err < ARCHIVE_WARN) {
+ return (ARCHIVE_FATAL);
+ }
+ /* Filename of the form `._filename` is an AppleDouble
+ * extension entry. The body is the macOS metadata blob;
+ * this is followed by another entry with the actual
+ * regular file data.
+ * This design has two drawbacks:
+ * = it's brittle; you might just have a file with such a name
+ * = it duplicates any long pathname extensions
+ *
+ * TODO: This probably shouldn't be here at all. Consider
+ * just returning the contents as a regular entry here and
+ * then dealing with it when we write data to disk.
+ */
+ if (tar->process_mac_extensions
+ && ((seen_headers & seen_mac_metadata) == 0)
+ && is_mac_metadata_entry(entry)) {
+ err2 = read_mac_metadata_blob(a, entry, unconsumed);
+ if (err2 < ARCHIVE_WARN) {
+ return (ARCHIVE_FATAL);
+ }
+ err = err_combine(err, err2);
+ /* Note: Other headers can appear again. */
+ seen_headers = seen_mac_metadata;
+ break;
+ }
+
+ /* Reconcile GNU sparse attributes */
+ if (tar->sparse_gnu_attributes_seen) {
+ /* Only 'S' (GNU sparse) and ustar '0' regular files can be sparse */
+ if (tar->filetype != 'S' && tar->filetype != '0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Non-regular file cannot be sparse");
+ return (ARCHIVE_WARN);
+ } else if (tar->sparse_gnu_major == 0 &&
+ tar->sparse_gnu_minor == 0) {
+ /* Sparse map already parsed from 'x' header */
+ } else if (tar->sparse_gnu_major == 0 &&
+ tar->sparse_gnu_minor == 1) {
+ /* Sparse map already parsed from 'x' header */
+ } else if (tar->sparse_gnu_major == 1 &&
+ tar->sparse_gnu_minor == 0) {
+ /* Sparse map is prepended to file contents */
+ ssize_t bytes_read;
+ bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
+ if (bytes_read < 0)
+ return ((int)bytes_read);
+ tar->entry_bytes_remaining -= bytes_read;
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Unrecognized GNU sparse file format");
+ return (ARCHIVE_WARN);
+ }
+ }
+ return (err);
}
- return (err);
- }
- if (err == ARCHIVE_EOF) {
- if (!eof_vol_header) {
- /* EOF when recursively reading a header is bad. */
- archive_set_error(&a->archive, EINVAL,
- "Damaged tar archive");
- } else {
- /* If we encounter just a GNU volume header treat
- * this situation as an empty archive */
- return (ARCHIVE_EOF);
+
+ /* We're between headers ... */
+ err = err_combine(err, err2);
+ if (err == ARCHIVE_FATAL)
+ return (err);
+
+ /* The GNU volume header and the pax `g` global header
+ * are both allowed to be the only header in an
+ * archive. If we've seen any other header, a
+ * following EOF is fatal. */
+ if ((seen_headers & ~seen_V_header & ~seen_g_header) != 0) {
+ eof_fatal = 1;
}
}
- return (ARCHIVE_FATAL);
}
/*
@@ -960,6 +1036,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h, size_t *unconsumed)
{
const struct archive_entry_header_ustar *header;
+ struct archive_string acl_text;
size_t size;
int err, acl_type;
int64_t type;
@@ -971,27 +1048,24 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
*/
header = (const struct archive_entry_header_ustar *)h;
size = (size_t)tar_atol(header->size, sizeof(header->size));
- err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
+ archive_string_init(&acl_text);
+ err = read_body_to_string(a, tar, &acl_text, h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
- /* Recursively read next header */
- err = tar_read_header(a, tar, entry, unconsumed);
- if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
- return (err);
-
/* TODO: Examine the first characters to see if this
* is an AIX ACL descriptor. We'll likely never support
* them, but it would be polite to recognize and warn when
* we do see them. */
/* Leading octal number indicates ACL type and number of entries. */
- p = acl = tar->acl_text.s;
+ p = acl = acl_text.s;
type = 0;
while (*p != '\0' && p < acl + size) {
if (*p < '0' || *p > '7') {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (invalid digit)");
+ archive_string_free(&acl_text);
return(ARCHIVE_WARN);
}
type <<= 3;
@@ -999,6 +1073,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
if (type > 077777777) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (count too large)");
+ archive_string_free(&acl_text);
return (ARCHIVE_WARN);
}
p++;
@@ -1016,6 +1091,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (unsupported type %o)",
(int)type);
+ archive_string_free(&acl_text);
return (ARCHIVE_WARN);
}
p++;
@@ -1023,6 +1099,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
if (p >= acl + size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (body overflow)");
+ archive_string_free(&acl_text);
return(ARCHIVE_WARN);
}
@@ -1036,12 +1113,17 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
if (tar->sconv_acl == NULL) {
tar->sconv_acl = archive_string_conversion_from_charset(
&(a->archive), "UTF-8", 1);
- if (tar->sconv_acl == NULL)
+ if (tar->sconv_acl == NULL) {
+ archive_string_free(&acl_text);
return (ARCHIVE_FATAL);
+ }
}
archive_strncpy(&(tar->localname), acl, p - acl);
err = archive_acl_from_text_l(archive_entry_acl(entry),
tar->localname.s, acl_type, tar->sconv_acl);
+ /* Workaround: Force perm_is_set() to be correct */
+ /* If this bit were stored in the ACL, this wouldn't be needed */
+ archive_entry_set_perm(entry, archive_entry_perm(entry));
if (err != ARCHIVE_OK) {
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
@@ -1050,6 +1132,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (unparsable)");
}
+ archive_string_free(&acl_text);
return (err);
}
@@ -1057,20 +1140,17 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
* Interpret 'K' long linkname header.
*/
static int
-header_longlink(struct archive_read *a, struct tar *tar,
+header_gnu_longlink(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h, size_t *unconsumed)
{
int err;
- err = read_body_to_string(a, tar, &(tar->longlink), h, unconsumed);
- if (err != ARCHIVE_OK)
- return (err);
- err = tar_read_header(a, tar, entry, unconsumed);
- if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
- return (err);
- /* Set symlink if symlink already set, else hardlink. */
- archive_entry_copy_link(entry, tar->longlink.s);
- return (ARCHIVE_OK);
+ struct archive_string linkpath;
+ archive_string_init(&linkpath);
+ err = read_body_to_string(a, tar, &linkpath, h, unconsumed);
+ archive_entry_set_link(entry, linkpath.s);
+ archive_string_free(&linkpath);
+ return (err);
}
static int
@@ -1092,7 +1172,7 @@ set_conversion_failed_error(struct archive_read *a,
* Interpret 'L' long filename header.
*/
static int
-header_longname(struct archive_read *a, struct tar *tar,
+header_gnu_longname(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h, size_t *unconsumed)
{
int err;
@@ -1100,17 +1180,12 @@ header_longname(struct archive_read *a, struct tar *tar,
err = read_body_to_string(a, tar, &(tar->longname), h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
- /* Read and parse "real" header, then override name. */
- err = tar_read_header(a, tar, entry, unconsumed);
- if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
- return (err);
if (archive_entry_copy_pathname_l(entry, tar->longname.s,
archive_strlen(&(tar->longname)), tar->sconv) != 0)
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
return (err);
}
-
/*
* Interpret 'V' GNU tar volume header.
*/
@@ -1118,32 +1193,33 @@ static int
header_volume(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h, size_t *unconsumed)
{
- (void)h;
+ const struct archive_entry_header_ustar *header;
+ int64_t size, to_consume;
- /* Just skip this and read the next header. */
- return (tar_read_header(a, tar, entry, unconsumed));
+ (void)a; /* UNUSED */
+ (void)tar; /* UNUSED */
+ (void)entry; /* UNUSED */
+
+ header = (const struct archive_entry_header_ustar *)h;
+ size = tar_atol(header->size, sizeof(header->size));
+ if (size > (int64_t)pathname_limit) {
+ return (ARCHIVE_FATAL);
+ }
+ to_consume = ((size + 511) & ~511);
+ *unconsumed += to_consume;
+ return (ARCHIVE_OK);
}
/*
- * Read body of an archive entry into an archive_string object.
+ * Read the next `size` bytes into the provided string.
+ * Null-terminate the string.
*/
static int
-read_body_to_string(struct archive_read *a, struct tar *tar,
- struct archive_string *as, const void *h, size_t *unconsumed)
-{
- int64_t size;
- const struct archive_entry_header_ustar *header;
+read_bytes_to_string(struct archive_read *a,
+ struct archive_string *as, size_t size,
+ size_t *unconsumed) {
const void *src;
- (void)tar; /* UNUSED */
- header = (const struct archive_entry_header_ustar *)h;
- size = tar_atol(header->size, sizeof(header->size));
- if ((size > 1048576) || (size < 0)) {
- archive_set_error(&a->archive, EINVAL,
- "Special header too large");
- return (ARCHIVE_FATAL);
- }
-
/* Fail if we can't make our buffer big enough. */
if (archive_string_ensure(as, (size_t)size+1) == NULL) {
archive_set_error(&a->archive, ENOMEM,
@@ -1154,19 +1230,55 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
tar_flush_unconsumed(a, unconsumed);
/* Read the body into the string. */
- *unconsumed = (size_t)((size + 511) & ~ 511);
- src = __archive_read_ahead(a, *unconsumed, NULL);
+ src = __archive_read_ahead(a, size, NULL);
if (src == NULL) {
+ archive_set_error(&a->archive, EINVAL,
+ "Truncated archive"
+ " detected while reading metadata");
*unconsumed = 0;
return (ARCHIVE_FATAL);
}
memcpy(as->s, src, (size_t)size);
as->s[size] = '\0';
as->length = (size_t)size;
+ *unconsumed += size;
return (ARCHIVE_OK);
}
/*
+ * Read body of an archive entry into an archive_string object.
+ */
+static int
+read_body_to_string(struct archive_read *a, struct tar *tar,
+ struct archive_string *as, const void *h, size_t *unconsumed)
+{
+ int64_t size;
+ const struct archive_entry_header_ustar *header;
+ int r;
+
+ (void)tar; /* UNUSED */
+ header = (const struct archive_entry_header_ustar *)h;
+ size = tar_atol(header->size, sizeof(header->size));
+ if (size > entry_limit) {
+ return (ARCHIVE_FATAL);
+ }
+ if ((size > (int64_t)pathname_limit) || (size < 0)) {
+ archive_string_empty(as);
+ int64_t to_consume = ((size + 511) & ~511);
+ if (to_consume != __archive_read_consume(a, to_consume)) {
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, EINVAL,
+ "Special header too large: %d > 1MiB",
+ (int)size);
+ return (ARCHIVE_WARN);
+ }
+ r = read_bytes_to_string(a, as, size, unconsumed);
+ *unconsumed += 0x1ff & (-size);
+ return(r);
+}
+
+/*
* Parse out common header elements.
*
* This would be the same as header_old_tar, except that the
@@ -1181,21 +1293,28 @@ header_common(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h)
{
const struct archive_entry_header_ustar *header;
- char tartype;
+ const char *existing_linkpath;
+ const wchar_t *existing_wcs_linkpath;
int err = ARCHIVE_OK;
header = (const struct archive_entry_header_ustar *)h;
- if (header->linkname[0])
- archive_strncpy(&(tar->entry_linkpath),
- header->linkname, sizeof(header->linkname));
- else
- archive_string_empty(&(tar->entry_linkpath));
/* Parse out the numeric fields (all are octal) */
- archive_entry_set_mode(entry,
- (mode_t)tar_atol(header->mode, sizeof(header->mode)));
- archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
- archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
+
+ /* Split mode handling: Set filetype always, perm only if not already set */
+ archive_entry_set_filetype(entry,
+ (mode_t)tar_atol(header->mode, sizeof(header->mode)));
+ if (!archive_entry_perm_is_set(entry)) {
+ archive_entry_set_perm(entry,
+ (mode_t)tar_atol(header->mode, sizeof(header->mode)));
+ }
+ if (!archive_entry_uid_is_set(entry)) {
+ archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
+ }
+ if (!archive_entry_gid_is_set(entry)) {
+ archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
+ }
+
tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
if (tar->entry_bytes_remaining < 0) {
tar->entry_bytes_remaining = 0;
@@ -1203,28 +1322,49 @@ header_common(struct archive_read *a, struct tar *tar,
"Tar entry has negative size");
return (ARCHIVE_FATAL);
}
- if (tar->entry_bytes_remaining == INT64_MAX) {
- /* Note: tar_atol returns INT64_MAX on overflow */
+ if (tar->entry_bytes_remaining > entry_limit) {
tar->entry_bytes_remaining = 0;
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Tar entry size overflow");
return (ARCHIVE_FATAL);
}
- tar->realsize = tar->entry_bytes_remaining;
- archive_entry_set_size(entry, tar->entry_bytes_remaining);
- archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
+ if (!tar->realsize_override) {
+ tar->realsize = tar->entry_bytes_remaining;
+ }
+ archive_entry_set_size(entry, tar->realsize);
+
+ if (!archive_entry_mtime_is_set(entry)) {
+ archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
+ }
/* Handle the tar type flag appropriately. */
- tartype = header->typeflag[0];
+ tar->filetype = header->typeflag[0];
- switch (tartype) {
+ /*
+ * TODO: If the linkpath came from Pax extension header, then
+ * we should obey the hdrcharset_utf8 flag when converting these.
+ */
+ switch (tar->filetype) {
case '1': /* Hard link */
- if (archive_entry_copy_hardlink_l(entry, tar->entry_linkpath.s,
- archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv,
- "Linkname");
- if (err == ARCHIVE_FATAL)
- return (err);
+ archive_entry_set_link_to_hardlink(entry);
+ existing_wcs_linkpath = archive_entry_hardlink_w(entry);
+ existing_linkpath = archive_entry_hardlink(entry);
+ if ((existing_linkpath == NULL || existing_linkpath[0] == '\0')
+ && (existing_wcs_linkpath == NULL || existing_wcs_linkpath[0] == '\0')) {
+ struct archive_string linkpath;
+ archive_string_init(&linkpath);
+ archive_strncpy(&linkpath,
+ header->linkname, sizeof(header->linkname));
+ if (archive_entry_copy_hardlink_l(entry, linkpath.s,
+ archive_strlen(&linkpath), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv,
+ "Linkname");
+ if (err == ARCHIVE_FATAL) {
+ archive_string_free(&linkpath);
+ return (err);
+ }
+ }
+ archive_string_free(&linkpath);
}
/*
* The following may seem odd, but: Technically, tar
@@ -1284,16 +1424,29 @@ header_common(struct archive_read *a, struct tar *tar,
*/
break;
case '2': /* Symlink */
+ archive_entry_set_link_to_symlink(entry);
+ existing_wcs_linkpath = archive_entry_symlink_w(entry);
+ existing_linkpath = archive_entry_symlink(entry);
+ if ((existing_linkpath == NULL || existing_linkpath[0] == '\0')
+ && (existing_wcs_linkpath == NULL || existing_wcs_linkpath[0] == '\0')) {
+ struct archive_string linkpath;
+ archive_string_init(&linkpath);
+ archive_strncpy(&linkpath,
+ header->linkname, sizeof(header->linkname));
+ if (archive_entry_copy_symlink_l(entry, linkpath.s,
+ archive_strlen(&linkpath), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv,
+ "Linkname");
+ if (err == ARCHIVE_FATAL) {
+ archive_string_free(&linkpath);
+ return (err);
+ }
+ }
+ archive_string_free(&linkpath);
+ }
archive_entry_set_filetype(entry, AE_IFLNK);
archive_entry_set_size(entry, 0);
tar->entry_bytes_remaining = 0;
- if (archive_entry_copy_symlink_l(entry, tar->entry_linkpath.s,
- archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv,
- "Linkname");
- if (err == ARCHIVE_FATAL)
- return (err);
- }
break;
case '3': /* Character device */
archive_entry_set_filetype(entry, AE_IFCHR);
@@ -1343,15 +1496,9 @@ header_common(struct archive_read *a, struct tar *tar,
* sparse information in the extended area.
*/
/* FALLTHROUGH */
- case '0':
- /*
- * Enable sparse file "read" support only for regular
- * files and explicit GNU sparse files. However, we
- * don't allow non-standard file types to be sparse.
- */
- tar->sparse_allowed = 1;
+ case '0': /* ustar "regular" file */
/* FALLTHROUGH */
- default: /* Regular file and non-standard types */
+ default: /* Non-standard file types */
/*
* Per POSIX: non-recognized types should always be
* treated as regular files.
@@ -1391,21 +1538,13 @@ header_old_tar(struct archive_read *a, struct tar *tar,
}
/*
- * Read a Mac AppleDouble-encoded blob of file metadata,
- * if there is one.
+ * Is this likely an AppleDouble extension?
*/
static int
-read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- int64_t size;
- size_t msize;
- const void *data;
+is_mac_metadata_entry(struct archive_entry *entry) {
const char *p, *name;
const wchar_t *wp, *wname;
- (void)h; /* UNUSED */
-
wname = wp = archive_entry_pathname_w(entry);
if (wp != NULL) {
/* Find the last path element. */
@@ -1417,8 +1556,8 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
* If last path element starts with "._", then
* this is a Mac extension.
*/
- if (wname[0] != L'.' || wname[1] != L'_' || wname[2] == L'\0')
- return ARCHIVE_OK;
+ if (wname[0] == L'.' && wname[1] == L'_' && wname[2] != L'\0')
+ return 1;
} else {
/* Find the last path element. */
name = p = archive_entry_pathname(entry);
@@ -1432,9 +1571,29 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
* If last path element starts with "._", then
* this is a Mac extension.
*/
- if (name[0] != '.' || name[1] != '_' || name[2] == '\0')
- return ARCHIVE_OK;
+ if (name[0] == '.' && name[1] == '_' && name[2] != '\0')
+ return 1;
}
+ /* Not a mac extension */
+ return 0;
+}
+
+/*
+ * Read a Mac AppleDouble-encoded blob of file metadata,
+ * if there is one.
+ *
+ * TODO: In Libarchive 4, we should consider ripping this
+ * out -- instead, return a file starting with `._` as
+ * a regular file and let the client (or archive_write logic)
+ * handle it.
+ */
+static int
+read_mac_metadata_blob(struct archive_read *a,
+ struct archive_entry *entry, size_t *unconsumed)
+{
+ int64_t size;
+ size_t msize;
+ const void *data;
/* Read the body as a Mac OS metadata blob. */
size = archive_entry_size(entry);
@@ -1444,6 +1603,17 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
return (ARCHIVE_FATAL);
}
+ /* TODO: Should this merely skip the overlarge entry and
+ * WARN? Or is xattr_limit sufficiently large that we can
+ * safely assume anything larger is malicious? */
+ if (size > (int64_t)xattr_limit) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Oversized AppleDouble extension has size %llu > %llu",
+ (unsigned long long)size,
+ (unsigned long long)xattr_limit);
+ return (ARCHIVE_FATAL);
+ }
+
/*
* TODO: Look beyond the body here to peek at the next header.
* If it's a regular header (not an extension header)
@@ -1456,15 +1626,16 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
* Q: Is the above idea really possible? Even
* when there are GNU or pax extension entries?
*/
+ tar_flush_unconsumed(a, unconsumed);
data = __archive_read_ahead(a, msize, NULL);
if (data == NULL) {
*unconsumed = 0;
return (ARCHIVE_FATAL);
}
+ archive_entry_clear(entry);
archive_entry_copy_mac_metadata(entry, data, msize);
*unconsumed = (msize + 511) & ~ 511;
- tar_flush_unconsumed(a, unconsumed);
- return (tar_read_header(a, tar, entry, unconsumed));
+ return (ARCHIVE_OK);
}
/*
@@ -1474,76 +1645,62 @@ static int
header_pax_global(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h, size_t *unconsumed)
{
- int err;
-
- err = read_body_to_string(a, tar, &(tar->pax_global), h, unconsumed);
- if (err != ARCHIVE_OK)
- return (err);
- err = tar_read_header(a, tar, entry, unconsumed);
- return (err);
-}
-
-static int
-header_pax_extensions(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const void *h, size_t *unconsumed)
-{
- int err, err2;
-
- err = read_body_to_string(a, tar, &(tar->pax_header), h, unconsumed);
- if (err != ARCHIVE_OK)
- return (err);
+ const struct archive_entry_header_ustar *header;
+ int64_t size, to_consume;
- /* Parse the next header. */
- err = tar_read_header(a, tar, entry, unconsumed);
- if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
- return (err);
+ (void)a; /* UNUSED */
+ (void)tar; /* UNUSED */
+ (void)entry; /* UNUSED */
- /*
- * TODO: Parse global/default options into 'entry' struct here
- * before handling file-specific options.
- *
- * This design (parse standard header, then overwrite with pax
- * extended attribute data) usually works well, but isn't ideal;
- * it would be better to parse the pax extended attributes first
- * and then skip any fields in the standard header that were
- * defined in the pax header.
- */
- err2 = pax_header(a, tar, entry, &tar->pax_header);
- err = err_combine(err, err2);
- tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
- return (err);
+ header = (const struct archive_entry_header_ustar *)h;
+ size = tar_atol(header->size, sizeof(header->size));
+ if (size > entry_limit) {
+ return (ARCHIVE_FATAL);
+ }
+ to_consume = ((size + 511) & ~511);
+ *unconsumed += to_consume;
+ return (ARCHIVE_OK);
}
-
/*
* Parse a file header for a Posix "ustar" archive entry. This also
* handles "pax" or "extended ustar" entries.
+ *
+ * In order to correctly handle pax attributes (which precede this),
+ * we have to skip parsing any field for which the entry already has
+ * contents.
*/
static int
header_ustar(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h)
{
const struct archive_entry_header_ustar *header;
- struct archive_string *as;
+ struct archive_string as;
int err = ARCHIVE_OK, r;
header = (const struct archive_entry_header_ustar *)h;
/* Copy name into an internal buffer to ensure null-termination. */
- as = &(tar->entry_pathname);
- if (header->prefix[0]) {
- archive_strncpy(as, header->prefix, sizeof(header->prefix));
- if (as->s[archive_strlen(as) - 1] != '/')
- archive_strappend_char(as, '/');
- archive_strncat(as, header->name, sizeof(header->name));
- } else {
- archive_strncpy(as, header->name, sizeof(header->name));
- }
- if (archive_entry_copy_pathname_l(entry, as->s, archive_strlen(as),
- tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Pathname");
- if (err == ARCHIVE_FATAL)
- return (err);
+ const char *existing_pathname = archive_entry_pathname(entry);
+ const wchar_t *existing_wcs_pathname = archive_entry_pathname_w(entry);
+ if ((existing_pathname == NULL || existing_pathname[0] == '\0')
+ && (existing_wcs_pathname == NULL || existing_wcs_pathname[0] == '\0')) {
+ archive_string_init(&as);
+ if (header->prefix[0]) {
+ archive_strncpy(&as, header->prefix, sizeof(header->prefix));
+ if (as.s[archive_strlen(&as) - 1] != '/')
+ archive_strappend_char(&as, '/');
+ archive_strncat(&as, header->name, sizeof(header->name));
+ } else {
+ archive_strncpy(&as, header->name, sizeof(header->name));
+ }
+ if (archive_entry_copy_pathname_l(entry, as.s, archive_strlen(&as),
+ tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+ archive_string_free(&as);
}
/* Handle rest of common fields. */
@@ -1554,26 +1711,36 @@ header_ustar(struct archive_read *a, struct tar *tar,
err = r;
/* Handle POSIX ustar fields. */
- if (archive_entry_copy_uname_l(entry,
- header->uname, sizeof(header->uname), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Uname");
- if (err == ARCHIVE_FATAL)
- return (err);
+ const char *existing_uname = archive_entry_uname(entry);
+ if (existing_uname == NULL || existing_uname[0] == '\0') {
+ if (archive_entry_copy_uname_l(entry,
+ header->uname, sizeof(header->uname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
}
- if (archive_entry_copy_gname_l(entry,
- header->gname, sizeof(header->gname), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Gname");
- if (err == ARCHIVE_FATAL)
- return (err);
+ const char *existing_gname = archive_entry_gname(entry);
+ if (existing_gname == NULL || existing_gname[0] == '\0') {
+ if (archive_entry_copy_gname_l(entry,
+ header->gname, sizeof(header->gname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Gname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
}
/* Parse out device numbers only for char and block specials. */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
- archive_entry_set_rdevmajor(entry, (dev_t)
- tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
- archive_entry_set_rdevminor(entry, (dev_t)
- tar_atol(header->rdevminor, sizeof(header->rdevminor)));
+ if (!archive_entry_rdev_is_set(entry)) {
+ archive_entry_set_rdevmajor(entry, (dev_t)
+ tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
+ archive_entry_set_rdevminor(entry, (dev_t)
+ tar_atol(header->rdevminor, sizeof(header->rdevminor)));
+ }
+ } else {
+ archive_entry_set_rdev(entry, 0);
}
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
@@ -1581,117 +1748,205 @@ header_ustar(struct archive_read *a, struct tar *tar,
return (err);
}
-
-/*
- * Parse the pax extended attributes record.
- *
- * Returns non-zero if there's an error in the data.
- */
static int
-pax_header(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, struct archive_string *in_as)
+header_pax_extension(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
{
- size_t attr_length, l, line_length, value_length;
- char *p;
- char *key, *value;
- struct archive_string *as;
+ /* Sanity checks: The largest `x` body I've ever heard of was
+ * a little over 4MB. So I doubt there has ever been a
+ * well-formed archive with an `x` body over 1GiB. Similarly,
+ * it seems plausible that no single attribute has ever been
+ * larger than 100MB. So if we see a larger value here, it's
+ * almost certainly a sign of a corrupted/malicious archive. */
+
+ /* Maximum sane size for extension body: 1 GiB */
+ /* This cannot be raised to larger than 8GiB without
+ * exceeding the maximum size for a standard ustar
+ * entry. */
+ const int64_t ext_size_limit = 1024 * 1024 * (int64_t)1024;
+ /* Maximum size for a single line/attr: 100 million characters */
+ /* This cannot be raised to more than 2GiB without exceeding
+ * a `size_t` on 32-bit platforms. */
+ const size_t max_parsed_line_length = 99999999ULL;
+ /* Largest attribute prolog: size + name. */
+ const size_t max_size_name = 512;
+
+ /* Size and padding of the full extension body */
+ int64_t ext_size, ext_padding;
+ size_t line_length, value_length, name_length;
+ ssize_t to_read, did_read;
+ const struct archive_entry_header_ustar *header;
+ const char *p, *attr_start, *name_start;
struct archive_string_conv *sconv;
- int err, err2;
- char *attr = in_as->s;
+ struct archive_string *pas = NULL;
+ struct archive_string attr_name;
+ int err = ARCHIVE_OK, r;
- attr_length = in_as->length;
- tar->pax_hdrcharset_binary = 0;
- archive_string_empty(&(tar->entry_gname));
- archive_string_empty(&(tar->entry_linkpath));
- archive_string_empty(&(tar->entry_pathname));
- archive_string_empty(&(tar->entry_pathname_override));
- archive_string_empty(&(tar->entry_uname));
- err = ARCHIVE_OK;
- while (attr_length > 0) {
- /* Parse decimal length field at start of line. */
+ header = (const struct archive_entry_header_ustar *)h;
+ ext_size = tar_atol(header->size, sizeof(header->size));
+ if (ext_size > entry_limit) {
+ return (ARCHIVE_FATAL);
+ }
+ if (ext_size < 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "pax extension header has invalid size: %lld",
+ (long long)ext_size);
+ return (ARCHIVE_FATAL);
+ }
+
+ ext_padding = 0x1ff & (-ext_size);
+ if (ext_size > ext_size_limit) {
+ /* Consume the pax extension body and return an error */
+ if (ext_size + ext_padding != __archive_read_consume(a, ext_size + ext_padding)) {
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, EINVAL,
+ "Ignoring oversized pax extensions: %d > %d",
+ (int)ext_size, (int)ext_size_limit);
+ return (ARCHIVE_WARN);
+ }
+ tar_flush_unconsumed(a, unconsumed);
+
+ /* Parse the size/name of each pax attribute in the body */
+ archive_string_init(&attr_name);
+ while (ext_size > 0) {
+ /* Read enough bytes to parse the size/name of the next attribute */
+ to_read = max_size_name;
+ if (to_read > ext_size) {
+ to_read = ext_size;
+ }
+ p = __archive_read_ahead(a, to_read, &did_read);
+ if (did_read < 0) {
+ return ((int)did_read);
+ }
+ if (did_read == 0) { /* EOF */
+ archive_set_error(&a->archive, EINVAL,
+ "Truncated tar archive"
+ " detected while reading pax attribute name");
+ return (ARCHIVE_FATAL);
+ }
+ if (did_read > ext_size) {
+ did_read = ext_size;
+ }
+
+ /* Parse size of attribute */
line_length = 0;
- l = attr_length;
- p = attr; /* Record start of line. */
- while (l>0) {
+ attr_start = p;
+ while (1) {
+ if (p >= attr_start + did_read) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring malformed pax attributes: overlarge attribute size field");
+ *unconsumed += ext_size + ext_padding;
+ return (ARCHIVE_WARN);
+ }
if (*p == ' ') {
p++;
- l--;
break;
}
if (*p < '0' || *p > '9') {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring malformed pax extended attributes");
+ "Ignoring malformed pax attributes: malformed attribute size field");
+ *unconsumed += ext_size + ext_padding;
return (ARCHIVE_WARN);
}
line_length *= 10;
line_length += *p - '0';
- if (line_length > 999999) {
+ if (line_length > max_parsed_line_length) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Rejecting pax extended attribute > 1MB");
+ "Ignoring malformed pax attribute: size > %lld",
+ (long long)max_parsed_line_length);
+ *unconsumed += ext_size + ext_padding;
return (ARCHIVE_WARN);
}
p++;
- l--;
}
- /*
- * Parsed length must be no bigger than available data,
- * at least 1, and the last character of the line must
- * be '\n'.
- */
- if (line_length > attr_length
- || line_length < 1
- || attr[line_length - 1] != '\n')
- {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Ignoring malformed pax extended attribute");
- return (ARCHIVE_WARN);
+ if ((int64_t)line_length > ext_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring malformed pax attribute: %lld > %lld",
+ (long long)line_length, (long long)ext_size);
+ *unconsumed += ext_size + ext_padding;
+ return (ARCHIVE_WARN);
}
- /* Null-terminate the line. */
- attr[line_length - 1] = '\0';
-
- /* Find end of key and null terminate it. */
- key = p;
- if (key[0] == '=')
- return (-1);
- while (*p && *p != '=')
- ++p;
- if (*p == '\0') {
+ /* Parse name of attribute */
+ if (p >= attr_start + did_read
+ || p >= attr_start + line_length
+ || *p == '=') {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Invalid pax extended attributes");
+ "Ignoring malformed pax attributes: empty name found");
+ *unconsumed += ext_size + ext_padding;
return (ARCHIVE_WARN);
}
- *p = '\0';
+ name_start = p;
+ while (1) {
+ if (p >= attr_start + did_read || p >= attr_start + line_length) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring malformed pax attributes: overlarge attribute name");
+ *unconsumed += ext_size + ext_padding;
+ return (ARCHIVE_WARN);
+ }
+ if (*p == '=') {
+ break;
+ }
+ p++;
+ }
+ name_length = p - name_start;
+ p++; // Skip '='
- value = p + 1;
+ archive_strncpy(&attr_name, name_start, name_length);
- /* Some values may be binary data */
- value_length = attr + line_length - 1 - value;
+ ext_size -= p - attr_start;
+ value_length = line_length - (p - attr_start);
- /* Identify this attribute and set it in the entry. */
- err2 = pax_attribute(a, tar, entry, key, value, value_length);
- if (err2 == ARCHIVE_FATAL)
- return (err2);
- err = err_combine(err, err2);
+ /* Consume size, name, and `=` */
+ *unconsumed += p - attr_start;
+ tar_flush_unconsumed(a, unconsumed);
+
+ /* pax_attribute will consume value_length - 1 */
+ r = pax_attribute(a, tar, entry, attr_name.s, archive_strlen(&attr_name), value_length - 1, unconsumed);
+ ext_size -= value_length - 1;
+
+ if (r < ARCHIVE_WARN) {
+ *unconsumed += ext_size + ext_padding;
+ return (r);
+ }
+ err = err_combine(err, r);
- /* Skip to next line */
- attr += line_length;
- attr_length -= line_length;
+ /* Consume the `\n` that follows the pax attribute value. */
+ tar_flush_unconsumed(a, unconsumed);
+ p = __archive_read_ahead(a, 1, &did_read);
+ if (did_read < 0) {
+ return ((int)did_read);
+ }
+ if (did_read == 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "Truncated tar archive"
+ " detected while completing pax attribute");
+ return (ARCHIVE_FATAL);
+ }
+ if (p[0] != '\n') {
+ archive_set_error(&a->archive, EINVAL,
+ "Malformed pax attributes");
+ *unconsumed += ext_size + ext_padding;
+ return (ARCHIVE_WARN);
+ }
+ ext_size -= 1;
+ *unconsumed += 1;
+ tar_flush_unconsumed(a, unconsumed);
}
+ *unconsumed += ext_size + ext_padding;
/*
- * PAX format uses UTF-8 as default charset for its metadata
- * unless hdrcharset=BINARY is present in its header.
- * We apply the charset specified by the hdrcharset option only
- * when the hdrcharset attribute(in PAX header) is BINARY because
- * we respect the charset described in PAX header and BINARY also
- * means that metadata(filename,uname and gname) character-set
- * is unknown.
+ * Some PAX values -- pathname, linkpath, uname, gname --
+ * can't be copied into the entry until we know the character
+ * set to use:
*/
- if (tar->pax_hdrcharset_binary)
+ if (!tar->pax_hdrcharset_utf8)
+ /* PAX specified "BINARY", so use the default charset */
sconv = tar->opt_sconv;
else {
+ /* PAX default UTF-8 */
sconv = archive_string_conversion_from_charset(
&(a->archive), "UTF-8", 1);
if (sconv == NULL)
@@ -1701,83 +1956,85 @@ pax_header(struct archive_read *a, struct tar *tar,
SCONV_SET_OPT_UTF8_LIBARCHIVE2X);
}
+ /* Pathname */
+ pas = NULL;
+ if (archive_strlen(&(tar->entry_pathname_override)) > 0) {
+ /* Prefer GNU.sparse.name attribute if present */
+ /* GNU sparse files store a fake name under the standard
+ * "pathname" key. */
+ pas = &(tar->entry_pathname_override);
+ } else if (archive_strlen(&(tar->entry_pathname)) > 0) {
+ /* Use standard "pathname" PAX extension */
+ pas = &(tar->entry_pathname);
+ }
+ if (pas != NULL) {
+ if (archive_entry_copy_pathname_l(entry, pas->s,
+ archive_strlen(pas), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use raw name without conversion */
+ archive_entry_copy_pathname(entry, pas->s);
+ }
+ }
+ /* Uname */
+ if (archive_strlen(&(tar->entry_uname)) > 0) {
+ if (archive_entry_copy_uname_l(entry, tar->entry_uname.s,
+ archive_strlen(&(tar->entry_uname)), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use raw name without conversion */
+ archive_entry_copy_uname(entry, tar->entry_uname.s);
+ }
+ }
+ /* Gname */
if (archive_strlen(&(tar->entry_gname)) > 0) {
if (archive_entry_copy_gname_l(entry, tar->entry_gname.s,
archive_strlen(&(tar->entry_gname)), sconv) != 0) {
err = set_conversion_failed_error(a, sconv, "Gname");
if (err == ARCHIVE_FATAL)
return (err);
- /* Use a converted an original name. */
+ /* Use raw name without conversion */
archive_entry_copy_gname(entry, tar->entry_gname.s);
}
}
+ /* Linkpath */
if (archive_strlen(&(tar->entry_linkpath)) > 0) {
if (archive_entry_copy_link_l(entry, tar->entry_linkpath.s,
archive_strlen(&(tar->entry_linkpath)), sconv) != 0) {
- err = set_conversion_failed_error(a, sconv, "Linkname");
+ err = set_conversion_failed_error(a, sconv, "Linkpath");
if (err == ARCHIVE_FATAL)
return (err);
- /* Use a converted an original name. */
+ /* Use raw name without conversion */
archive_entry_copy_link(entry, tar->entry_linkpath.s);
}
}
- /*
- * Some extensions (such as the GNU sparse file extensions)
- * deliberately store a synthetic name under the regular 'path'
- * attribute and the real file name under a different attribute.
- * Since we're supposed to not care about the order, we
- * have no choice but to store all of the various filenames
- * we find and figure it all out afterwards. This is the
- * figuring out part.
- */
- as = NULL;
- if (archive_strlen(&(tar->entry_pathname_override)) > 0)
- as = &(tar->entry_pathname_override);
- else if (archive_strlen(&(tar->entry_pathname)) > 0)
- as = &(tar->entry_pathname);
- if (as != NULL) {
- if (archive_entry_copy_pathname_l(entry, as->s,
- archive_strlen(as), sconv) != 0) {
- err = set_conversion_failed_error(a, sconv, "Pathname");
- if (err == ARCHIVE_FATAL)
- return (err);
- /* Use a converted an original name. */
- archive_entry_copy_pathname(entry, as->s);
- }
- }
- if (archive_strlen(&(tar->entry_uname)) > 0) {
- if (archive_entry_copy_uname_l(entry, tar->entry_uname.s,
- archive_strlen(&(tar->entry_uname)), sconv) != 0) {
- err = set_conversion_failed_error(a, sconv, "Uname");
- if (err == ARCHIVE_FATAL)
- return (err);
- /* Use a converted an original name. */
- archive_entry_copy_uname(entry, tar->entry_uname.s);
- }
- }
+
+ /* Extension may have given us a corrected `entry_bytes_remaining` for
+ * the main entry; update the padding appropriately. */
+ tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
return (err);
}
static int
-pax_attribute_xattr(struct archive_entry *entry,
- const char *name, const char *value)
+pax_attribute_LIBARCHIVE_xattr(struct archive_entry *entry,
+ const char *name, size_t name_length, const char *value, size_t value_length)
{
char *name_decoded;
void *value_decoded;
size_t value_len;
- if (strlen(name) < 18 || (memcmp(name, "LIBARCHIVE.xattr.", 17)) != 0)
+ if (name_length < 1)
return 3;
- name += 17;
-
/* URL-decode name */
- name_decoded = url_decode(name);
+ name_decoded = url_decode(name, name_length);
if (name_decoded == NULL)
return 2;
/* Base-64 decode value */
- value_decoded = base64_decode(value, strlen(value), &value_len);
+ value_decoded = base64_decode(value, value_length, &value_len);
if (value_decoded == NULL) {
free(name_decoded);
return 1;
@@ -1792,21 +2049,26 @@ pax_attribute_xattr(struct archive_entry *entry,
}
static int
-pax_attribute_schily_xattr(struct archive_entry *entry,
- const char *name, const char *value, size_t value_length)
+pax_attribute_SCHILY_xattr(struct archive_entry *entry,
+ const char *name, size_t name_length, const char *value, size_t value_length)
{
- if (strlen(name) < 14 || (memcmp(name, "SCHILY.xattr.", 13)) != 0)
+ if (name_length < 1 || name_length > 128) {
return 1;
+ }
- name += 13;
-
- archive_entry_xattr_add_entry(entry, name, value, value_length);
+ char * null_terminated_name = malloc(name_length + 1);
+ if (null_terminated_name != NULL) {
+ memcpy(null_terminated_name, name, name_length);
+ null_terminated_name[name_length] = '\0';
+ archive_entry_xattr_add_entry(entry, null_terminated_name, value, value_length);
+ free(null_terminated_name);
+ }
return 0;
}
static int
-pax_attribute_rht_security_selinux(struct archive_entry *entry,
+pax_attribute_RHT_security_selinux(struct archive_entry *entry,
const char *value, size_t value_length)
{
archive_entry_xattr_add_entry(entry, "security.selinux",
@@ -1816,10 +2078,11 @@ pax_attribute_rht_security_selinux(struct archive_entry *entry,
}
static int
-pax_attribute_acl(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const char *value, int type)
+pax_attribute_SCHILY_acl(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, size_t value_length, int type)
{
int r;
+ const char *p;
const char* errstr;
switch (type) {
@@ -1846,8 +2109,28 @@ pax_attribute_acl(struct archive_read *a, struct tar *tar,
return (ARCHIVE_FATAL);
}
- r = archive_acl_from_text_l(archive_entry_acl(entry), value, type,
- tar->sconv_acl);
+ if (value_length > acl_limit) {
+ __archive_read_consume(a, value_length);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unreasonably large ACL: %d > %d",
+ (int)value_length, (int)acl_limit);
+ return (ARCHIVE_WARN);
+ }
+
+ p = __archive_read_ahead(a, value_length, NULL);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated tar archive "
+ "detected while reading ACL data");
+ return (ARCHIVE_FATAL);
+ }
+
+ r = archive_acl_from_text_nl(archive_entry_acl(entry), p, value_length,
+ type, tar->sconv_acl);
+ __archive_read_consume(a, value_length);
+ /* Workaround: Force perm_is_set() to be correct */
+ /* If this bit were stored in the ACL, this wouldn't be needed */
+ archive_entry_set_perm(entry, archive_entry_perm(entry));
if (r != ARCHIVE_OK) {
if (r == ARCHIVE_FATAL) {
archive_set_error(&a->archive, ENOMEM,
@@ -1861,240 +2144,540 @@ pax_attribute_acl(struct archive_read *a, struct tar *tar,
return (r);
}
+static int
+pax_attribute_read_time(struct archive_read *a, size_t value_length, int64_t *ps, long *pn, size_t *unconsumed) {
+ struct archive_string as;
+ int r;
+
+ if (value_length > 128) {
+ __archive_read_consume(a, value_length);
+ *ps = 0;
+ *pn = 0;
+ return (ARCHIVE_FATAL);
+ }
+
+ archive_string_init(&as);
+ r = read_bytes_to_string(a, &as, value_length, unconsumed);
+ if (r < ARCHIVE_OK) {
+ archive_string_free(&as);
+ return (r);
+ }
+
+ pax_time(as.s, archive_strlen(&as), ps, pn);
+ archive_string_free(&as);
+ if (*ps < 0 || *ps == INT64_MAX) {
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+pax_attribute_read_number(struct archive_read *a, size_t value_length, int64_t *result) {
+ struct archive_string as;
+ size_t unconsumed = 0;
+ int r;
+
+ if (value_length > 64) {
+ __archive_read_consume(a, value_length);
+ *result = 0;
+ return (ARCHIVE_FATAL);
+ }
+
+ archive_string_init(&as);
+ r = read_bytes_to_string(a, &as, value_length, &unconsumed);
+ tar_flush_unconsumed(a, &unconsumed);
+ if (r < ARCHIVE_OK) {
+ archive_string_free(&as);
+ return (r);
+ }
+
+ *result = tar_atol10(as.s, archive_strlen(&as));
+ archive_string_free(&as);
+ if (*result < 0 || *result == INT64_MAX) {
+ *result = INT64_MAX;
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
/*
- * Parse a single key=value attribute. key/value pointers are
- * assumed to point into reasonably long-lived storage.
+ * Parse a single key=value attribute.
*
- * Note that POSIX reserves all-lowercase keywords. Vendor-specific
- * extensions should always have keywords of the form "VENDOR.attribute"
- * In particular, it's quite feasible to support many different
- * vendor extensions here. I'm using "LIBARCHIVE" for extensions
- * unique to this library.
+ * POSIX reserves all-lowercase keywords. Vendor-specific extensions
+ * should always have keywords of the form "VENDOR.attribute" In
+ * particular, it's quite feasible to support many different vendor
+ * extensions here. I'm using "LIBARCHIVE" for extensions unique to
+ * this library.
*
- * Investigate other vendor-specific extensions and see if
+ * TODO: Investigate other vendor-specific extensions and see if
* any of them look useful.
*/
static int
-pax_attribute(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const char *key, const char *value, size_t value_length)
+pax_attribute(struct archive_read *a, struct tar *tar, struct archive_entry *entry,
+ const char *key, size_t key_length, size_t value_length, size_t *unconsumed)
{
- int64_t s;
+ int64_t t;
long n;
- int err = ARCHIVE_OK, r;
+ const char *p;
+ ssize_t bytes_read;
+ int err = ARCHIVE_OK;
- if (value == NULL)
- value = ""; /* Disable compiler warning; do not pass
- * NULL pointer to strlen(). */
switch (key[0]) {
case 'G':
- /* Reject GNU.sparse.* headers on non-regular files. */
- if (strncmp(key, "GNU.sparse", 10) == 0 &&
- !tar->sparse_allowed) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Non-regular file cannot be sparse");
- return (ARCHIVE_FATAL);
- }
-
- /* GNU "0.0" sparse pax format. */
- if (strcmp(key, "GNU.sparse.numblocks") == 0) {
- tar->sparse_offset = -1;
- tar->sparse_numbytes = -1;
- tar->sparse_gnu_major = 0;
- tar->sparse_gnu_minor = 0;
- }
- if (strcmp(key, "GNU.sparse.offset") == 0) {
- tar->sparse_offset = tar_atol10(value, strlen(value));
- if (tar->sparse_numbytes != -1) {
- if (gnu_add_sparse_entry(a, tar,
- tar->sparse_offset, tar->sparse_numbytes)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- tar->sparse_offset = -1;
- tar->sparse_numbytes = -1;
+ /* GNU.* extensions */
+ if (key_length > 4 && memcmp(key, "GNU.", 4) == 0) {
+ key += 4;
+ key_length -= 4;
+
+ /* GNU.sparse marks the existence of GNU sparse information */
+ if (key_length == 6 && memcmp(key, "sparse", 6) == 0) {
+ tar->sparse_gnu_attributes_seen = 1;
}
- }
- if (strcmp(key, "GNU.sparse.numbytes") == 0) {
- tar->sparse_numbytes = tar_atol10(value, strlen(value));
- if (tar->sparse_offset != -1) {
- if (gnu_add_sparse_entry(a, tar,
- tar->sparse_offset, tar->sparse_numbytes)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- tar->sparse_offset = -1;
- tar->sparse_numbytes = -1;
- }
- }
- if (strcmp(key, "GNU.sparse.size") == 0) {
- tar->realsize = tar_atol10(value, strlen(value));
- archive_entry_set_size(entry, tar->realsize);
- tar->realsize_override = 1;
- }
-
- /* GNU "0.1" sparse pax format. */
- if (strcmp(key, "GNU.sparse.map") == 0) {
- tar->sparse_gnu_major = 0;
- tar->sparse_gnu_minor = 1;
- if (gnu_sparse_01_parse(a, tar, value) != ARCHIVE_OK)
- return (ARCHIVE_WARN);
- }
- /* GNU "1.0" sparse pax format */
- if (strcmp(key, "GNU.sparse.major") == 0) {
- tar->sparse_gnu_major = (int)tar_atol10(value, strlen(value));
- tar->sparse_gnu_pending = 1;
- }
- if (strcmp(key, "GNU.sparse.minor") == 0) {
- tar->sparse_gnu_minor = (int)tar_atol10(value, strlen(value));
- tar->sparse_gnu_pending = 1;
- }
- if (strcmp(key, "GNU.sparse.name") == 0) {
- /*
- * The real filename; when storing sparse
- * files, GNU tar puts a synthesized name into
- * the regular 'path' attribute in an attempt
- * to limit confusion. ;-)
- */
- archive_strcpy(&(tar->entry_pathname_override), value);
- }
- if (strcmp(key, "GNU.sparse.realsize") == 0) {
- tar->realsize = tar_atol10(value, strlen(value));
- archive_entry_set_size(entry, tar->realsize);
- tar->realsize_override = 1;
+ /* GNU.sparse.* extensions */
+ else if (key_length > 7 && memcmp(key, "sparse.", 7) == 0) {
+ tar->sparse_gnu_attributes_seen = 1;
+ key += 7;
+ key_length -= 7;
+
+ /* GNU "0.0" sparse pax format. */
+ if (key_length == 9 && memcmp(key, "numblocks", 9) == 0) {
+ /* GNU.sparse.numblocks */
+ tar->sparse_offset = -1;
+ tar->sparse_numbytes = -1;
+ tar->sparse_gnu_major = 0;
+ tar->sparse_gnu_minor = 0;
+ }
+ else if (key_length == 6 && memcmp(key, "offset", 6) == 0) {
+ /* GNU.sparse.offset */
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ tar->sparse_offset = t;
+ if (tar->sparse_numbytes != -1) {
+ if (gnu_add_sparse_entry(a, tar,
+ tar->sparse_offset, tar->sparse_numbytes)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ tar->sparse_offset = -1;
+ tar->sparse_numbytes = -1;
+ }
+ }
+ return (err);
+ }
+ else if (key_length == 8 && memcmp(key, "numbytes", 8) == 0) {
+ /* GNU.sparse.numbytes */
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ tar->sparse_numbytes = t;
+ if (tar->sparse_offset != -1) {
+ if (gnu_add_sparse_entry(a, tar,
+ tar->sparse_offset, tar->sparse_numbytes)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ tar->sparse_offset = -1;
+ tar->sparse_numbytes = -1;
+ }
+ }
+ return (err);
+ }
+ else if (key_length == 4 && memcmp(key, "size", 4) == 0) {
+ /* GNU.sparse.size */
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ tar->realsize = t;
+ archive_entry_set_size(entry, tar->realsize);
+ tar->realsize_override = 1;
+ }
+ return (err);
+ }
+
+ /* GNU "0.1" sparse pax format. */
+ else if (key_length == 3 && memcmp(key, "map", 3) == 0) {
+ /* GNU.sparse.map */
+ tar->sparse_gnu_major = 0;
+ tar->sparse_gnu_minor = 1;
+ if (value_length > sparse_map_limit) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unreasonably large sparse map: %d > %d",
+ (int)value_length, (int)sparse_map_limit);
+ err = ARCHIVE_FAILED;
+ } else {
+ p = __archive_read_ahead(a, value_length, &bytes_read);
+ if (p != NULL) {
+ if (gnu_sparse_01_parse(a, tar, p, value_length) != ARCHIVE_OK) {
+ err = ARCHIVE_WARN;
+ }
+ } else {
+ return (ARCHIVE_FATAL);
+ }
+ }
+ __archive_read_consume(a, value_length);
+ return (err);
+ }
+
+ /* GNU "1.0" sparse pax format */
+ else if (key_length == 5 && memcmp(key, "major", 5) == 0) {
+ /* GNU.sparse.major */
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK
+ && t >= 0
+ && t <= 10) {
+ tar->sparse_gnu_major = (int)t;
+ }
+ return (err);
+ }
+ else if (key_length == 5 && memcmp(key, "minor", 5) == 0) {
+ /* GNU.sparse.minor */
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK
+ && t >= 0
+ && t <= 10) {
+ tar->sparse_gnu_minor = (int)t;
+ }
+ return (err);
+ }
+ else if (key_length == 4 && memcmp(key, "name", 4) == 0) {
+ /* GNU.sparse.name */
+ /*
+ * The real filename; when storing sparse
+ * files, GNU tar puts a synthesized name into
+ * the regular 'path' attribute in an attempt
+ * to limit confusion. ;-)
+ */
+ if (value_length > pathname_limit) {
+ *unconsumed += value_length;
+ err = ARCHIVE_WARN;
+ } else {
+ err = read_bytes_to_string(a, &(tar->entry_pathname_override),
+ value_length, unconsumed);
+ }
+ return (err);
+ }
+ else if (key_length == 8 && memcmp(key, "realsize", 8) == 0) {
+ /* GNU.sparse.realsize */
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ tar->realsize = t;
+ archive_entry_set_size(entry, tar->realsize);
+ tar->realsize_override = 1;
+ }
+ return (err);
+ }
+ }
}
break;
case 'L':
- /* Our extensions */
-/* TODO: Handle arbitrary extended attributes... */
-/*
- if (strcmp(key, "LIBARCHIVE.xxxxxxx") == 0)
- archive_entry_set_xxxxxx(entry, value);
-*/
- if (strcmp(key, "LIBARCHIVE.creationtime") == 0) {
- pax_time(value, &s, &n);
- archive_entry_set_birthtime(entry, s, n);
- }
- if (strcmp(key, "LIBARCHIVE.symlinktype") == 0) {
- if (strcmp(value, "file") == 0) {
- archive_entry_set_symlink_type(entry,
- AE_SYMLINK_TYPE_FILE);
- } else if (strcmp(value, "dir") == 0) {
- archive_entry_set_symlink_type(entry,
- AE_SYMLINK_TYPE_DIRECTORY);
+ /* LIBARCHIVE extensions */
+ if (key_length > 11 && memcmp(key, "LIBARCHIVE.", 11) == 0) {
+ key_length -= 11;
+ key += 11;
+
+ /* TODO: Handle arbitrary extended attributes... */
+ /*
+ if (strcmp(key, "LIBARCHIVE.xxxxxxx") == 0)
+ archive_entry_set_xxxxxx(entry, value);
+ */
+ if (key_length == 12 && memcmp(key, "creationtime", 12) == 0) {
+ /* LIBARCHIVE.creationtime */
+ if ((err = pax_attribute_read_time(a, value_length, &t, &n, unconsumed)) == ARCHIVE_OK) {
+ archive_entry_set_birthtime(entry, t, n);
+ }
+ return (err);
+ }
+ else if (key_length == 11 && memcmp(key, "symlinktype", 11) == 0) {
+ /* LIBARCHIVE.symlinktype */
+ if (value_length < 16) {
+ p = __archive_read_ahead(a, value_length, &bytes_read);
+ if (p != NULL) {
+ if (value_length == 4 && memcmp(p, "file", 4) == 0) {
+ archive_entry_set_symlink_type(entry,
+ AE_SYMLINK_TYPE_FILE);
+ } else if (value_length == 3 && memcmp(p, "dir", 3) == 0) {
+ archive_entry_set_symlink_type(entry,
+ AE_SYMLINK_TYPE_DIRECTORY);
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unrecognized symlink type");
+ err = ARCHIVE_WARN;
+ }
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated tar archive "
+ "detected while reading `symlinktype` attribute");
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "symlink type is very long"
+ "(longest recognized value is 4 bytes, this is %d)",
+ (int)value_length);
+ err = ARCHIVE_WARN;
+ }
+ __archive_read_consume(a, value_length);
+ return (err);
+ }
+ else if (key_length > 6 && memcmp(key, "xattr.", 6) == 0) {
+ key_length -= 6;
+ key += 6;
+ if (value_length > xattr_limit) {
+ err = ARCHIVE_WARN;
+ } else {
+ p = __archive_read_ahead(a, value_length, &bytes_read);
+ if (p == NULL
+ || pax_attribute_LIBARCHIVE_xattr(entry, key, key_length, p, value_length)) {
+ /* TODO: Unable to parse xattr */
+ err = ARCHIVE_WARN;
+ }
+ }
+ __archive_read_consume(a, value_length);
+ return (err);
}
}
- if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
- pax_attribute_xattr(entry, key, value);
break;
case 'R':
/* GNU tar uses RHT.security header to store SELinux xattrs
* SCHILY.xattr.security.selinux == RHT.security.selinux */
- if (strcmp(key, "RHT.security.selinux") == 0) {
- pax_attribute_rht_security_selinux(entry, value,
- value_length);
+ if (key_length == 20 && memcmp(key, "RHT.security.selinux", 20) == 0) {
+ if (value_length > xattr_limit) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring unreasonably large security.selinux attribute:"
+ " %d > %d",
+ (int)value_length, (int)xattr_limit);
+ /* TODO: Should this be FAILED instead? */
+ err = ARCHIVE_WARN;
+ } else {
+ p = __archive_read_ahead(a, value_length, &bytes_read);
+ if (p == NULL
+ || pax_attribute_RHT_security_selinux(entry, p, value_length)) {
+ /* TODO: Unable to parse xattr */
+ err = ARCHIVE_WARN;
+ }
}
+ __archive_read_consume(a, value_length);
+ return (err);
+ }
break;
case 'S':
- /* We support some keys used by the "star" archiver */
- if (strcmp(key, "SCHILY.acl.access") == 0) {
- r = pax_attribute_acl(a, tar, entry, value,
- ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
- if (r == ARCHIVE_FATAL)
- return (r);
- } else if (strcmp(key, "SCHILY.acl.default") == 0) {
- r = pax_attribute_acl(a, tar, entry, value,
- ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
- if (r == ARCHIVE_FATAL)
- return (r);
- } else if (strcmp(key, "SCHILY.acl.ace") == 0) {
- r = pax_attribute_acl(a, tar, entry, value,
- ARCHIVE_ENTRY_ACL_TYPE_NFS4);
- if (r == ARCHIVE_FATAL)
- return (r);
- } else if (strcmp(key, "SCHILY.devmajor") == 0) {
- archive_entry_set_rdevmajor(entry,
- (dev_t)tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.devminor") == 0) {
- archive_entry_set_rdevminor(entry,
- (dev_t)tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.fflags") == 0) {
- archive_entry_copy_fflags_text(entry, value);
- } else if (strcmp(key, "SCHILY.dev") == 0) {
- archive_entry_set_dev(entry,
- (dev_t)tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.ino") == 0) {
- archive_entry_set_ino(entry,
- tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.nlink") == 0) {
- archive_entry_set_nlink(entry, (unsigned)
- tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "SCHILY.realsize") == 0) {
- tar->realsize = tar_atol10(value, strlen(value));
- tar->realsize_override = 1;
- archive_entry_set_size(entry, tar->realsize);
- } else if (strncmp(key, "SCHILY.xattr.", 13) == 0) {
- pax_attribute_schily_xattr(entry, key, value,
- value_length);
- } else if (strcmp(key, "SUN.holesdata") == 0) {
- /* A Solaris extension for sparse. */
- r = solaris_sparse_parse(a, tar, entry, value);
- if (r < err) {
- if (r == ARCHIVE_FATAL)
- return (r);
- err = r;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Parse error: SUN.holesdata");
+ /* SCHILY.* extensions used by "star" archiver */
+ if (key_length > 7 && memcmp(key, "SCHILY.", 7) == 0) {
+ key_length -= 7;
+ key += 7;
+
+ if (key_length == 10 && memcmp(key, "acl.access", 10) == 0) {
+ err = pax_attribute_SCHILY_acl(a, tar, entry, value_length,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+ // TODO: Mark mode as set
+ return (err);
+ }
+ else if (key_length == 11 && memcmp(key, "acl.default", 11) == 0) {
+ err = pax_attribute_SCHILY_acl(a, tar, entry, value_length,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
+ return (err);
+ }
+ else if (key_length == 7 && memcmp(key, "acl.ace", 7) == 0) {
+ err = pax_attribute_SCHILY_acl(a, tar, entry, value_length,
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4);
+ // TODO: Mark mode as set
+ return (err);
+ }
+ else if (key_length == 8 && memcmp(key, "devmajor", 8) == 0) {
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ archive_entry_set_rdevmajor(entry, (dev_t)t);
+ }
+ return (err);
+ }
+ else if (key_length == 8 && memcmp(key, "devminor", 8) == 0) {
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ archive_entry_set_rdevminor(entry, (dev_t)t);
+ }
+ return (err);
+ }
+ else if (key_length == 6 && memcmp(key, "fflags", 6) == 0) {
+ if (value_length < fflags_limit) {
+ p = __archive_read_ahead(a, value_length, &bytes_read);
+ if (p != NULL) {
+ archive_entry_copy_fflags_text_len(entry, p, value_length);
+ err = ARCHIVE_OK;
+ } else {
+ /* Truncated archive */
+ err = ARCHIVE_FATAL;
+ }
+ } else {
+ /* Overlong fflags field */
+ err = ARCHIVE_WARN;
+ }
+ __archive_read_consume(a, value_length);
+ return (err);
+ }
+ else if (key_length == 3 && memcmp(key, "dev", 3) == 0) {
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ archive_entry_set_dev(entry, (dev_t)t);
+ }
+ return (err);
+ }
+ else if (key_length == 3 && memcmp(key, "ino", 3) == 0) {
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ archive_entry_set_ino(entry, t);
+ }
+ return (err);
+ }
+ else if (key_length == 5 && memcmp(key, "nlink", 5) == 0) {
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ archive_entry_set_nlink(entry, (unsigned int)t);
+ }
+ return (err);
+ }
+ else if (key_length == 8 && memcmp(key, "realsize", 8) == 0) {
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ tar->realsize = t;
+ tar->realsize_override = 1;
+ archive_entry_set_size(entry, tar->realsize);
+ }
+ return (err);
+ }
+ else if (key_length > 6 && memcmp(key, "xattr.", 6) == 0) {
+ key_length -= 6;
+ key += 6;
+ if (value_length < xattr_limit) {
+ p = __archive_read_ahead(a, value_length, &bytes_read);
+ if (p == NULL
+ || pax_attribute_SCHILY_xattr(entry, key, key_length, p, value_length)) {
+ /* TODO: Unable to parse xattr */
+ err = ARCHIVE_WARN;
+ }
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unreasonably large xattr: %d > %d",
+ (int)value_length, (int)xattr_limit);
+ err = ARCHIVE_WARN;
+ }
+ __archive_read_consume(a, value_length);
+ return (err);
+ }
+ }
+ /* SUN.* extensions from Solaris tar */
+ if (key_length > 4 && memcmp(key, "SUN.", 4) == 0) {
+ key_length -= 4;
+ key += 4;
+
+ if (key_length == 9 && memcmp(key, "holesdata", 9) == 0) {
+ /* SUN.holesdata */
+ if (value_length < sparse_map_limit) {
+ p = __archive_read_ahead(a, value_length, &bytes_read);
+ if (p != NULL) {
+ err = pax_attribute_SUN_holesdata(a, tar, entry, p, value_length);
+ if (err < ARCHIVE_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SUN.holesdata");
+ }
+ } else {
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unreasonably large sparse map: %d > %d",
+ (int)value_length, (int)sparse_map_limit);
+ err = ARCHIVE_FAILED;
+ }
+ __archive_read_consume(a, value_length);
+ return (err);
}
}
break;
case 'a':
- if (strcmp(key, "atime") == 0) {
- pax_time(value, &s, &n);
- archive_entry_set_atime(entry, s, n);
+ if (key_length == 5 && memcmp(key, "atime", 5) == 0) {
+ if ((err = pax_attribute_read_time(a, value_length, &t, &n, unconsumed)) == ARCHIVE_OK) {
+ archive_entry_set_atime(entry, t, n);
+ }
+ return (err);
}
break;
case 'c':
- if (strcmp(key, "ctime") == 0) {
- pax_time(value, &s, &n);
- archive_entry_set_ctime(entry, s, n);
- } else if (strcmp(key, "charset") == 0) {
+ if (key_length == 5 && memcmp(key, "ctime", 5) == 0) {
+ if ((err = pax_attribute_read_time(a, value_length, &t, &n, unconsumed)) == ARCHIVE_OK) {
+ archive_entry_set_ctime(entry, t, n);
+ }
+ return (err);
+ } else if (key_length == 7 && memcmp(key, "charset", 7) == 0) {
/* TODO: Publish charset information in entry. */
- } else if (strcmp(key, "comment") == 0) {
+ } else if (key_length == 7 && memcmp(key, "comment", 7) == 0) {
/* TODO: Publish comment in entry. */
}
break;
case 'g':
- if (strcmp(key, "gid") == 0) {
- archive_entry_set_gid(entry,
- tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "gname") == 0) {
- archive_strcpy(&(tar->entry_gname), value);
+ if (key_length == 3 && memcmp(key, "gid", 3) == 0) {
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ archive_entry_set_gid(entry, t);
+ }
+ return (err);
+ } else if (key_length == 5 && memcmp(key, "gname", 5) == 0) {
+ if (value_length > guname_limit) {
+ *unconsumed += value_length;
+ err = ARCHIVE_WARN;
+ } else {
+ err = read_bytes_to_string(a, &(tar->entry_gname), value_length, unconsumed);
+ }
+ return (err);
}
break;
case 'h':
- if (strcmp(key, "hdrcharset") == 0) {
- if (strcmp(value, "BINARY") == 0)
- /* Binary mode. */
- tar->pax_hdrcharset_binary = 1;
- else if (strcmp(value, "ISO-IR 10646 2000 UTF-8") == 0)
- tar->pax_hdrcharset_binary = 0;
+ if (key_length == 10 && memcmp(key, "hdrcharset", 10) == 0) {
+ if (value_length < 64) {
+ p = __archive_read_ahead(a, value_length, &bytes_read);
+ if (p != NULL) {
+ if (value_length == 6
+ && memcmp(p, "BINARY", 6) == 0) {
+ /* Binary mode. */
+ tar->pax_hdrcharset_utf8 = 0;
+ err = ARCHIVE_OK;
+ } else if (value_length == 23
+ && memcmp(p, "ISO-IR 10646 2000 UTF-8", 23) == 0) {
+ tar->pax_hdrcharset_utf8 = 1;
+ err = ARCHIVE_OK;
+ } else {
+ /* TODO: Unrecognized character set */
+ err = ARCHIVE_WARN;
+ }
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated tar archive "
+ "detected while reading hdrcharset attribute");
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "hdrcharset attribute is unreasonably large (%d bytes)",
+ (int)value_length);
+ err = ARCHIVE_WARN;
+ }
+ __archive_read_consume(a, value_length);
+ return (err);
}
break;
case 'l':
/* pax interchange doesn't distinguish hardlink vs. symlink. */
- if (strcmp(key, "linkpath") == 0) {
- archive_strcpy(&(tar->entry_linkpath), value);
+ if (key_length == 8 && memcmp(key, "linkpath", 8) == 0) {
+ if (value_length > pathname_limit) {
+ *unconsumed += value_length;
+ err = ARCHIVE_WARN;
+ } else {
+ err = read_bytes_to_string(a, &tar->entry_linkpath, value_length, unconsumed);
+ }
+ return (err);
}
break;
case 'm':
- if (strcmp(key, "mtime") == 0) {
- pax_time(value, &s, &n);
- archive_entry_set_mtime(entry, s, n);
+ if (key_length == 5 && memcmp(key, "mtime", 5) == 0) {
+ if ((err = pax_attribute_read_time(a, value_length, &t, &n, unconsumed)) == ARCHIVE_OK) {
+ archive_entry_set_mtime(entry, t, n);
+ }
+ return (err);
}
break;
case 'p':
- if (strcmp(key, "path") == 0) {
- archive_strcpy(&(tar->entry_pathname), value);
+ if (key_length == 4 && memcmp(key, "path", 4) == 0) {
+ if (value_length > pathname_limit) {
+ *unconsumed += value_length;
+ err = ARCHIVE_WARN;
+ } else {
+ err = read_bytes_to_string(a, &(tar->entry_pathname), value_length, unconsumed);
+ }
+ return (err);
}
break;
case 'r':
@@ -2103,48 +2686,54 @@ pax_attribute(struct archive_read *a, struct tar *tar,
case 's':
/* POSIX has reserved 'security.*' */
/* Someday: if (strcmp(key, "security.acl") == 0) { ... } */
- if (strcmp(key, "size") == 0) {
+ if (key_length == 4 && memcmp(key, "size", 4) == 0) {
/* "size" is the size of the data in the entry. */
- tar->entry_bytes_remaining
- = tar_atol10(value, strlen(value));
- if (tar->entry_bytes_remaining < 0) {
- tar->entry_bytes_remaining = 0;
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "Tar size attribute is negative");
- return (ARCHIVE_FATAL);
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ tar->entry_bytes_remaining = t;
+ /*
+ * The "size" pax header keyword always overrides the
+ * "size" field in the tar header.
+ * GNU.sparse.realsize, GNU.sparse.size and
+ * SCHILY.realsize override this value.
+ */
+ if (!tar->realsize_override) {
+ archive_entry_set_size(entry,
+ tar->entry_bytes_remaining);
+ tar->realsize
+ = tar->entry_bytes_remaining;
+ }
}
- if (tar->entry_bytes_remaining == INT64_MAX) {
- /* Note: tar_atol returns INT64_MAX on overflow */
+ else if (t == INT64_MAX) {
+ /* Note: pax_attr_read_number returns INT64_MAX on overflow or < 0 */
tar->entry_bytes_remaining = 0;
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Tar size attribute overflow");
return (ARCHIVE_FATAL);
}
- /*
- * The "size" pax header keyword always overrides the
- * "size" field in the tar header.
- * GNU.sparse.realsize, GNU.sparse.size and
- * SCHILY.realsize override this value.
- */
- if (!tar->realsize_override) {
- archive_entry_set_size(entry,
- tar->entry_bytes_remaining);
- tar->realsize
- = tar->entry_bytes_remaining;
- }
+ return (err);
}
break;
case 'u':
- if (strcmp(key, "uid") == 0) {
- archive_entry_set_uid(entry,
- tar_atol10(value, strlen(value)));
- } else if (strcmp(key, "uname") == 0) {
- archive_strcpy(&(tar->entry_uname), value);
+ if (key_length == 3 && memcmp(key, "uid", 3) == 0) {
+ if ((err = pax_attribute_read_number(a, value_length, &t)) == ARCHIVE_OK) {
+ archive_entry_set_uid(entry, t);
+ }
+ return (err);
+ } else if (key_length == 5 && memcmp(key, "uname", 5) == 0) {
+ if (value_length > guname_limit) {
+ *unconsumed += value_length;
+ err = ARCHIVE_WARN;
+ } else {
+ err = read_bytes_to_string(a, &(tar->entry_uname), value_length, unconsumed);
+ }
+ return (err);
}
break;
}
+
+ /* Unrecognized key, just skip the entire value. */
+ __archive_read_consume(a, value_length);
return (err);
}
@@ -2154,7 +2743,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
* parse a decimal time value, which may include a fractional portion
*/
static void
-pax_time(const char *p, int64_t *ps, long *pn)
+pax_time(const char *p, size_t length, int64_t *ps, long *pn)
{
char digit;
int64_t s;
@@ -2165,13 +2754,18 @@ pax_time(const char *p, int64_t *ps, long *pn)
limit = INT64_MAX / 10;
last_digit_limit = INT64_MAX % 10;
+ if (length <= 0) {
+ *ps = 0;
+ return;
+ }
s = 0;
sign = 1;
if (*p == '-') {
sign = -1;
p++;
+ length--;
}
- while (*p >= '0' && *p <= '9') {
+ while (length > 0 && *p >= '0' && *p <= '9') {
digit = *p - '0';
if (s > limit ||
(s == limit && digit > last_digit_limit)) {
@@ -2180,6 +2774,7 @@ pax_time(const char *p, int64_t *ps, long *pn)
}
s = (s * 10) + digit;
++p;
+ --length;
}
*ps = s * sign;
@@ -2187,13 +2782,14 @@ pax_time(const char *p, int64_t *ps, long *pn)
/* Calculate nanoseconds. */
*pn = 0;
- if (*p != '.')
+ if (length <= 0 || *p != '.')
return;
l = 100000000UL;
do {
++p;
- if (*p >= '0' && *p <= '9')
+ --length;
+ if (length > 0 && *p >= '0' && *p <= '9')
*pn += (*p - '0') * l;
else
break;
@@ -2224,49 +2820,65 @@ header_gnutar(struct archive_read *a, struct tar *tar,
/* Copy filename over (to ensure null termination). */
header = (const struct archive_entry_header_gnutar *)h;
- if (archive_entry_copy_pathname_l(entry,
- header->name, sizeof(header->name), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Pathname");
- if (err == ARCHIVE_FATAL)
- return (err);
+ const char *existing_pathname = archive_entry_pathname(entry);
+ if (existing_pathname == NULL || existing_pathname[0] == '\0') {
+ if (archive_entry_copy_pathname_l(entry,
+ header->name, sizeof(header->name), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
}
/* Fields common to ustar and GNU */
/* XXX Can the following be factored out since it's common
* to ustar and gnu tar? Is it okay to move it down into
* header_common, perhaps? */
- if (archive_entry_copy_uname_l(entry,
- header->uname, sizeof(header->uname), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Uname");
- if (err == ARCHIVE_FATAL)
- return (err);
+ const char *existing_uname = archive_entry_uname(entry);
+ if (existing_uname == NULL || existing_uname[0] == '\0') {
+ if (archive_entry_copy_uname_l(entry,
+ header->uname, sizeof(header->uname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
}
- if (archive_entry_copy_gname_l(entry,
- header->gname, sizeof(header->gname), tar->sconv) != 0) {
- err = set_conversion_failed_error(a, tar->sconv, "Gname");
- if (err == ARCHIVE_FATAL)
- return (err);
+ const char *existing_gname = archive_entry_gname(entry);
+ if (existing_gname == NULL || existing_gname[0] == '\0') {
+ if (archive_entry_copy_gname_l(entry,
+ header->gname, sizeof(header->gname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Gname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
}
/* Parse out device numbers only for char and block specials */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
- archive_entry_set_rdevmajor(entry, (dev_t)
- tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
- archive_entry_set_rdevminor(entry, (dev_t)
- tar_atol(header->rdevminor, sizeof(header->rdevminor)));
- } else
+ if (!archive_entry_rdev_is_set(entry)) {
+ archive_entry_set_rdevmajor(entry, (dev_t)
+ tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
+ archive_entry_set_rdevminor(entry, (dev_t)
+ tar_atol(header->rdevminor, sizeof(header->rdevminor)));
+ }
+ } else {
archive_entry_set_rdev(entry, 0);
+ }
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
/* Grab GNU-specific fields. */
- t = tar_atol(header->atime, sizeof(header->atime));
- if (t > 0)
- archive_entry_set_atime(entry, t, 0);
- t = tar_atol(header->ctime, sizeof(header->ctime));
- if (t > 0)
- archive_entry_set_ctime(entry, t, 0);
+ if (!archive_entry_atime_is_set(entry)) {
+ t = tar_atol(header->atime, sizeof(header->atime));
+ if (t > 0)
+ archive_entry_set_atime(entry, t, 0);
+ }
+ if (!archive_entry_ctime_is_set(entry)) {
+ t = tar_atol(header->ctime, sizeof(header->ctime));
+ if (t > 0)
+ archive_entry_set_ctime(entry, t, 0);
+ }
if (header->realsize[0] != 0) {
tar->realsize
@@ -2418,19 +3030,19 @@ gnu_sparse_old_parse(struct archive_read *a, struct tar *tar,
* importantly, the sparse data was lost when extracted by archivers
* that didn't recognize this extension.
*/
-
static int
-gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p)
+gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p, size_t length)
{
const char *e;
int64_t offset = -1, size = -1;
for (;;) {
e = p;
- while (*e != '\0' && *e != ',') {
+ while (length > 0 && *e != ',') {
if (*e < '0' || *e > '9')
return (ARCHIVE_WARN);
e++;
+ length--;
}
if (offset < 0) {
offset = tar_atol10(p, e - p);
@@ -2445,9 +3057,10 @@ gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p)
return (ARCHIVE_FATAL);
offset = -1;
}
- if (*e == '\0')
+ if (length == 0)
return (ARCHIVE_OK);
p = e + 1;
+ length--;
}
}
@@ -2569,8 +3182,8 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
* consist of both data and hole.
*/
static int
-solaris_sparse_parse(struct archive_read *a, struct tar *tar,
- struct archive_entry *entry, const char *p)
+pax_attribute_SUN_holesdata(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const char *p, size_t length)
{
const char *e;
int64_t start, end;
@@ -2579,16 +3192,21 @@ solaris_sparse_parse(struct archive_read *a, struct tar *tar,
(void)entry; /* UNUSED */
end = 0;
- if (*p == ' ')
+ if (length <= 0)
+ return (ARCHIVE_WARN);
+ if (*p == ' ') {
p++;
- else
+ length--;
+ } else {
return (ARCHIVE_WARN);
+ }
for (;;) {
e = p;
- while (*e != '\0' && *e != ' ') {
+ while (length > 0 && *e != ' ') {
if (*e < '0' || *e > '9')
return (ARCHIVE_WARN);
e++;
+ length--;
}
start = end;
end = tar_atol10(p, e - p);
@@ -2600,9 +3218,15 @@ solaris_sparse_parse(struct archive_read *a, struct tar *tar,
return (ARCHIVE_FATAL);
tar->sparse_last->hole = hole;
}
- if (*e == '\0')
- return (ARCHIVE_OK);
+ if (length == 0 || *e == '\n') {
+ if (length == 0 && *e == '\n') {
+ return (ARCHIVE_OK);
+ } else {
+ return (ARCHIVE_WARN);
+ }
+ }
p = e + 1;
+ length--;
hole = hole == 0;
}
}
@@ -2904,22 +3528,23 @@ base64_decode(const char *s, size_t len, size_t *out_len)
}
static char *
-url_decode(const char *in)
+url_decode(const char *in, size_t length)
{
char *out, *d;
const char *s;
- out = (char *)malloc(strlen(in) + 1);
+ out = (char *)malloc(length + 1);
if (out == NULL)
return (NULL);
- for (s = in, d = out; *s != '\0'; ) {
- if (s[0] == '%' && s[1] != '\0' && s[2] != '\0') {
+ for (s = in, d = out; length > 0 && *s != '\0'; ) {
+ if (s[0] == '%' && length > 2) {
/* Try to convert % escape */
int digit1 = tohex(s[1]);
int digit2 = tohex(s[2]);
if (digit1 >= 0 && digit2 >= 0) {
/* Looks good, consume three chars */
s += 3;
+ length -= 3;
/* Convert output */
*d++ = ((digit1 << 4) | digit2);
continue;
@@ -2927,6 +3552,7 @@ url_decode(const char *in)
/* Else fall through and treat '%' as normal char */
}
*d++ = *s++;
+ --length;
}
*d = '\0';
return (out);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
index 61ab29e..fcec5bc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
/**
* WARC is standardised by ISO TC46/SC4/WG12 and currently available as
@@ -216,6 +215,7 @@ _warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
const char *buf;
ssize_t nrd;
const char *eoh;
+ char *tmp;
/* for the file name, saves some strndup()'ing */
warc_string_t fnam;
/* warc record type, not that we really use it a lot */
@@ -322,7 +322,14 @@ start_over:
* malloc()+free() roundtrip */
if (fnam.len + 1U > w->pool.len) {
w->pool.len = ((fnam.len + 64U) / 64U) * 64U;
- w->pool.str = realloc(w->pool.str, w->pool.len);
+ tmp = realloc(w->pool.str, w->pool.len);
+ if (tmp == NULL) {
+ archive_set_error(
+ &a->archive, ENOMEM,
+ "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ w->pool.str = tmp;
}
memcpy(w->pool.str, fnam.str, fnam.len);
w->pool.str[fnam.len] = '\0';
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
index efed86d..3e66ca1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -23,7 +23,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -417,7 +416,7 @@ static void unknowntag_end(struct xar *, const char *);
static int xml_start(struct archive_read *,
const char *, struct xmlattr_list *);
static void xml_end(void *, const char *);
-static void xml_data(void *, const char *, int);
+static void xml_data(void *, const char *, size_t);
static int xml_parse_file_flags(struct xar *, const char *);
static int xml_parse_file_ext2(struct xar *, const char *);
#if defined(HAVE_LIBXML_XMLREADER_H)
@@ -623,8 +622,8 @@ read_toc(struct archive_read *a)
(size_t)xar->toc_chksum_size, NULL, 0);
__archive_read_consume(a, xar->toc_chksum_size);
xar->offset += xar->toc_chksum_size;
- if (r != ARCHIVE_OK)
#ifndef DONT_FAIL_ON_CRC_ERROR
+ if (r != ARCHIVE_OK)
return (ARCHIVE_FATAL);
#endif
}
@@ -1243,7 +1242,7 @@ heap_add_entry(struct archive_read *a,
return (ARCHIVE_FATAL);
}
new_pending_files = (struct xar_file **)
- malloc(new_size * sizeof(new_pending_files[0]));
+ calloc(new_size, sizeof(new_pending_files[0]));
if (new_pending_files == NULL) {
archive_set_error(&a->archive,
ENOMEM, "Out of memory");
@@ -1617,9 +1616,9 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
switch (xar->rd_encoding) {
case GZIP:
xar->stream.next_in = (Bytef *)(uintptr_t)b;
- xar->stream.avail_in = avail_in;
+ xar->stream.avail_in = (uInt)avail_in;
xar->stream.next_out = (unsigned char *)outbuff;
- xar->stream.avail_out = avail_out;
+ xar->stream.avail_out = (uInt)avail_out;
r = inflate(&(xar->stream), 0);
switch (r) {
case Z_OK: /* Decompressor made some progress.*/
@@ -1636,9 +1635,9 @@ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
case BZIP2:
xar->bzstream.next_in = (char *)(uintptr_t)b;
- xar->bzstream.avail_in = avail_in;
+ xar->bzstream.avail_in = (unsigned int)avail_in;
xar->bzstream.next_out = (char *)outbuff;
- xar->bzstream.avail_out = avail_out;
+ xar->bzstream.avail_out = (unsigned int)avail_out;
r = BZ2_bzDecompress(&(xar->bzstream));
switch (r) {
case BZ_STREAM_END: /* Found end of stream. */
@@ -2056,6 +2055,12 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
attr = attr->next) {
if (strcmp(attr->name, "link") != 0)
continue;
+ if (xar->file->hdnext != NULL || xar->file->link != 0 ||
+ xar->file == xar->hdlink_orgs) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "File with multiple link attributes");
+ return (ARCHIVE_FATAL);
+ }
if (strcmp(attr->value, "original") == 0) {
xar->file->hdnext = xar->hdlink_orgs;
xar->hdlink_orgs = xar->file;
@@ -2669,7 +2674,7 @@ is_string(const char *known, const char *data, size_t len)
}
static void
-xml_data(void *userData, const char *s, int len)
+xml_data(void *userData, const char *s, size_t len)
{
struct archive_read *a;
struct xar *xar;
@@ -2702,6 +2707,9 @@ xml_data(void *userData, const char *s, int len)
switch (xar->xmlsts) {
case FILE_NAME:
+ if (xar->file->has & HAS_PATHNAME)
+ break;
+
if (xar->file->parent != NULL) {
archive_string_concat(&(xar->file->pathname),
&(xar->file->parent->pathname));
@@ -3185,8 +3193,11 @@ xml2_read_toc(struct archive_read *a)
if (r == ARCHIVE_OK)
r = xml_start(a, name, &list);
xmlattr_cleanup(&list);
- if (r != ARCHIVE_OK)
+ if (r != ARCHIVE_OK) {
+ xmlFreeTextReader(reader);
+ xmlCleanupParser();
return (r);
+ }
if (empty)
xml_end(a, name);
break;
@@ -3252,6 +3263,9 @@ expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts)
struct xmlattr_list list;
int r;
+ if (ud->state != ARCHIVE_OK)
+ return;
+
r = expat_xmlattr_setup(a, &list, atts);
if (r == ARCHIVE_OK)
r = xml_start(a, (const char *)name, &list);
@@ -3272,7 +3286,7 @@ expat_data_cb(void *userData, const XML_Char *s, int len)
{
struct expat_userData *ud = (struct expat_userData *)userData;
- xml_data(ud->archive, s, len);
+ xml_data(ud->archive, s, (size_t)len);
}
static int
@@ -3308,14 +3322,16 @@ expat_read_toc(struct archive_read *a)
d = NULL;
r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
- if (r != ARCHIVE_OK)
+ if (r != ARCHIVE_OK) {
+ XML_ParserFree(parser);
return (r);
+ }
xar->toc_remaining -= used;
xar->offset += used;
xar->toc_total += outbytes;
PRINT_TOC(d, outbytes);
- xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0);
+ xr = XML_Parse(parser, d, (int)outbytes, xar->toc_remaining == 0);
__archive_read_consume(a, used);
if (xr == XML_STATUS_ERROR) {
XML_ParserFree(parser);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index e8b20f5..59db86c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102 2009-12-28 03:11:36Z kientzle $");
/*
* The definitive documentation of the Zip file format is:
@@ -119,7 +118,7 @@ struct trad_enc_ctx {
/* Bits used in zip_flags. */
#define ZIP_ENCRYPTED (1 << 0)
-#define ZIP_LENGTH_AT_END (1 << 3)
+#define ZIP_LENGTH_AT_END (1 << 3) /* Also called "Streaming bit" */
#define ZIP_STRONG_ENCRYPTED (1 << 6)
#define ZIP_UTF8_NAME (1 << 11)
/* See "7.2 Single Password Symmetric Encryption Method"
@@ -166,8 +165,8 @@ struct zip {
int64_t entry_compressed_bytes_read;
int64_t entry_uncompressed_bytes_read;
- /* Running CRC32 of the decompressed data */
- unsigned long entry_crc32;
+ /* Running CRC32 of the decompressed and decrypted data */
+ unsigned long computed_crc32;
unsigned long (*crc32func)(unsigned long, const void *,
size_t);
char ignore_crc32;
@@ -945,7 +944,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
zip->end_of_entry = 0;
zip->entry_uncompressed_bytes_read = 0;
zip->entry_compressed_bytes_read = 0;
- zip->entry_crc32 = zip->crc32func(0, NULL, 0);
+ zip->computed_crc32 = zip->crc32func(0, NULL, 0);
/* Setup default conversion. */
if (zip->sconv == NULL && !zip->init_default_conversion) {
@@ -1140,7 +1139,8 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
"Inconsistent CRC32 values");
ret = ARCHIVE_WARN;
}
- if (zip_entry->compressed_size == 0) {
+ if (zip_entry->compressed_size == 0
+ || zip_entry->compressed_size == 0xffffffff) {
zip_entry->compressed_size
= zip_entry_central_dir.compressed_size;
} else if (zip_entry->compressed_size
@@ -1284,7 +1284,8 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
return ARCHIVE_FATAL;
}
} else if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
- || zip_entry->uncompressed_size > 0) {
+ || (zip_entry->uncompressed_size > 0
+ && zip_entry->uncompressed_size != 0xffffffff)) {
/* Set the size only if it's meaningful. */
archive_entry_set_size(entry, zip_entry->uncompressed_size);
}
@@ -1343,25 +1344,267 @@ check_authentication_code(struct archive_read *a, const void *_p)
}
/*
- * Read "uncompressed" data. There are three cases:
- * 1) We know the size of the data. This is always true for the
- * seeking reader (we've examined the Central Directory already).
- * 2) ZIP_LENGTH_AT_END was set, but only the CRC was deferred.
- * Info-ZIP seems to do this; we know the size but have to grab
- * the CRC from the data descriptor afterwards.
- * 3) We're streaming and ZIP_LENGTH_AT_END was specified and
- * we have no size information. In this case, we can do pretty
- * well by watching for the data descriptor record. The data
- * descriptor is 16 bytes and includes a computed CRC that should
- * provide a strong check.
+ * The Zip end-of-file marker is inherently ambiguous. The specification
+ * in APPNOTE.TXT allows any of four possible formats, and there is no
+ * guaranteed-correct way for a reader to know a priori which one the writer
+ * will have used. The four formats are:
+ * 1. 32-bit format with an initial PK78 marker
+ * 2. 32-bit format without that marker
+ * 3. 64-bit format with the marker
+ * 4. 64-bit format without the marker
*
- * TODO: Technically, the PK\007\010 signature is optional.
- * In the original spec, the data descriptor contained CRC
- * and size fields but had no leading signature. In practice,
- * newer writers seem to provide the signature pretty consistently.
+ * Mark Adler's `sunzip` streaming unzip program solved this ambiguity
+ * by just looking at every possible combination and accepting the
+ * longest one that matches the expected values. His approach always
+ * consumes the longest possible matching EOF marker, based on an
+ * analysis of all the possible failures and how the values could
+ * overlap.
*
- * For uncompressed data, the PK\007\010 marker seems essential
- * to be sure we've actually seen the end of the entry.
+ * For example, suppose both of the first two formats listed
+ * above match. In that case, we know the next four
+ * 32-bit words match this pattern:
+ * ```
+ * [PK\07\08] [CRC32] [compressed size] [uncompressed size]
+ * ```
+ * but we know they must also match this pattern:
+ * ```
+ * [CRC32] [compressed size] [uncompressed size] [other PK marker]
+ * ```
+ *
+ * Since the first word here matches both the PK78 signature in the
+ * first form and the CRC32 in the second, we know those two values
+ * are equal, the CRC32 must be exactly 0x08074b50. Similarly, the
+ * compressed and uncompressed size must also be exactly this value.
+ * So we know these four words are all 0x08074b50. If we were to
+ * accept the shorter pattern, it would be immediately followed by
+ * another PK78 marker, which is not possible in a well-formed ZIP
+ * archive unless there is garbage between entries. This implies we
+ * should not accept the shorter form in such a case; we should accept
+ * the longer form.
+ *
+ * If the second and third possibilities above both match, we
+ * have a slightly different situation. The following words
+ * must match both the 32-bit format
+ * ```
+ * [CRC32] [compressed size] [uncompressed size] [other PK marker]
+ * ```
+ * and the 64-bit format
+ * ```
+ * [CRC32] [compressed low] [compressed high] [uncompressed low] [uncompressed high] [other PK marker]
+ * ```
+ * Since the 32-bit and 64-bit compressed sizes both match, the
+ * actual size must fit in 32 bits, which implies the high-order
+ * word of the compressed size is zero. So we know the uncompressed
+ * low word is zero, which again implies that if we accept the shorter
+ * format, there will not be a valid PK marker following it.
+ *
+ * Similar considerations rule out the shorter form in every other
+ * possibly-ambiguous pair. So if two of the four possible formats
+ * match, we should accept the longer option.
+ *
+ * If none of the four formats matches, we know the archive must be
+ * corrupted in some fashion. In particular, it's possible that the
+ * length-at-end bit was incorrect and we should not really be looking
+ * for an EOF marker at all. To allow for this possibility, we
+ * evaluate the following words to collect data for a later error
+ * report but do not consume any bytes. We instead rely on the later
+ * search for a new PK marker to re-sync to the next well-formed
+ * entry.
+ */
+static void
+consume_end_of_file_marker(struct archive_read *a, struct zip *zip)
+{
+ const char *marker;
+ const char *p;
+ uint64_t compressed32, uncompressed32;
+ uint64_t compressed64, uncompressed64;
+ uint64_t compressed_actual, uncompressed_actual;
+ uint32_t crc32_actual;
+ const uint32_t PK78 = 0x08074B50ULL;
+ uint8_t crc32_ignored, crc32_may_be_zero;
+
+ /* If there shouldn't be a marker, don't consume it. */
+ if ((zip->entry->zip_flags & ZIP_LENGTH_AT_END) == 0) {
+ return;
+ }
+
+ /* The longest Zip end-of-file record is 24 bytes. Since an
+ * end-of-file record can never appear at the end of the
+ * archive, we know 24 bytes will be available unless
+ * the archive is severely truncated. */
+ if (NULL == (marker = __archive_read_ahead(a, 24, NULL))) {
+ return;
+ }
+ p = marker;
+
+ /* The end-of-file record comprises:
+ * = Optional PK\007\010 marker
+ * = 4-byte CRC32
+ * = Compressed size
+ * = Uncompressed size
+ *
+ * The last two fields are either both 32 bits or both 64
+ * bits. We check all possible layouts and accept any one
+ * that gives us a complete match, else we make a best-effort
+ * attempt to parse out the pieces.
+ */
+
+ /* CRC32 checking can be tricky:
+ * * Test suites sometimes ignore the CRC32
+ * * AES AE-2 always writes zero for the CRC32
+ * * AES AE-1 sometimes writes zero for the CRC32
+ */
+ crc32_ignored = zip->ignore_crc32;
+ crc32_may_be_zero = 0;
+ crc32_actual = zip->computed_crc32;
+ if (zip->hctx_valid) {
+ switch (zip->entry->aes_extra.vendor) {
+ case AES_VENDOR_AE_2:
+ crc32_actual = 0;
+ break;
+ case AES_VENDOR_AE_1:
+ default:
+ crc32_may_be_zero = 1;
+ break;
+ }
+ }
+
+ /* Values computed from the actual data in the archive. */
+ compressed_actual = (uint64_t)zip->entry_compressed_bytes_read;
+ uncompressed_actual = (uint64_t)zip->entry_uncompressed_bytes_read;
+
+
+ /* Longest: PK78 marker, all 64-bit fields (24 bytes total) */
+ if (archive_le32dec(p) == PK78
+ && ((archive_le32dec(p + 4) == crc32_actual)
+ || (crc32_may_be_zero && (archive_le32dec(p + 4) == 0))
+ || crc32_ignored)
+ && (archive_le64dec(p + 8) == compressed_actual)
+ && (archive_le64dec(p + 16) == uncompressed_actual)) {
+ if (!crc32_ignored) {
+ zip->entry->crc32 = crc32_actual;
+ }
+ zip->entry->compressed_size = compressed_actual;
+ zip->entry->uncompressed_size = uncompressed_actual;
+ zip->unconsumed += 24;
+ return;
+ }
+
+ /* No PK78 marker, 64-bit fields (20 bytes total) */
+ if (((archive_le32dec(p) == crc32_actual)
+ || (crc32_may_be_zero && (archive_le32dec(p + 4) == 0))
+ || crc32_ignored)
+ && (archive_le64dec(p + 4) == compressed_actual)
+ && (archive_le64dec(p + 12) == uncompressed_actual)) {
+ if (!crc32_ignored) {
+ zip->entry->crc32 = crc32_actual;
+ }
+ zip->entry->compressed_size = compressed_actual;
+ zip->entry->uncompressed_size = uncompressed_actual;
+ zip->unconsumed += 20;
+ return;
+ }
+
+ /* PK78 marker and 32-bit fields (16 bytes total) */
+ if (archive_le32dec(p) == PK78
+ && ((archive_le32dec(p + 4) == crc32_actual)
+ || (crc32_may_be_zero && (archive_le32dec(p + 4) == 0))
+ || crc32_ignored)
+ && (archive_le32dec(p + 8) == compressed_actual)
+ && (archive_le32dec(p + 12) == uncompressed_actual)) {
+ if (!crc32_ignored) {
+ zip->entry->crc32 = crc32_actual;
+ }
+ zip->entry->compressed_size = compressed_actual;
+ zip->entry->uncompressed_size = uncompressed_actual;
+ zip->unconsumed += 16;
+ return;
+ }
+
+ /* Shortest: No PK78 marker, all 32-bit fields (12 bytes total) */
+ if (((archive_le32dec(p) == crc32_actual)
+ || (crc32_may_be_zero && (archive_le32dec(p + 4) == 0))
+ || crc32_ignored)
+ && (archive_le32dec(p + 4) == compressed_actual)
+ && (archive_le32dec(p + 8) == uncompressed_actual)) {
+ if (!crc32_ignored) {
+ zip->entry->crc32 = crc32_actual;
+ }
+ zip->entry->compressed_size = compressed_actual;
+ zip->entry->uncompressed_size = uncompressed_actual;
+ zip->unconsumed += 12;
+ return;
+ }
+
+ /* If none of the above patterns gives us a full exact match,
+ * then there's something definitely amiss. The fallback code
+ * below will parse out some plausible values for error
+ * reporting purposes. Note that this won't actually
+ * consume anything:
+ *
+ * = If there really is a marker here, the logic to resync to
+ * the next entry will suffice to skip it.
+ *
+ * = There might not really be a marker: Corruption or bugs
+ * may have set the length-at-end bit without a marker ever
+ * having actually been written. In this case, we
+ * explicitly should not consume any bytes, since that would
+ * prevent us from correctly reading the next entry.
+ */
+ if (archive_le32dec(p) == PK78) {
+ p += 4; /* Ignore PK78 if it appears to be present */
+ }
+ zip->entry->crc32 = archive_le32dec(p); /* Parse CRC32 */
+ p += 4;
+
+ /* Consider both 32- and 64-bit interpretations */
+ compressed32 = archive_le32dec(p);
+ uncompressed32 = archive_le32dec(p + 4);
+ compressed64 = archive_le64dec(p);
+ uncompressed64 = archive_le64dec(p + 8);
+
+ /* The earlier patterns may have failed because of CRC32
+ * mismatch, so it's still possible that both sizes match.
+ * Try to match as many as we can...
+ */
+ if (compressed32 == compressed_actual
+ && uncompressed32 == uncompressed_actual) {
+ /* Both 32-bit fields match */
+ zip->entry->compressed_size = compressed32;
+ zip->entry->uncompressed_size = uncompressed32;
+ } else if (compressed64 == compressed_actual
+ || uncompressed64 == uncompressed_actual) {
+ /* One or both 64-bit fields match */
+ zip->entry->compressed_size = compressed64;
+ zip->entry->uncompressed_size = uncompressed64;
+ } else {
+ /* Zero or one 32-bit fields match */
+ zip->entry->compressed_size = compressed32;
+ zip->entry->uncompressed_size = uncompressed32;
+ }
+}
+
+/*
+ * Read "uncompressed" data.
+ *
+ * This is straightforward if we know the size of the data. This is
+ * always true for the seeking reader (we've examined the Central
+ * Directory already), and will often be true for the streaming reader
+ * (the writer was writing uncompressed so probably knows the size).
+ *
+ * If we don't know the size, then life is more interesting. Note
+ * that a careful reading of the Zip specification says that a writer
+ * must use ZIP_LENGTH_AT_END if it cannot write the CRC into the
+ * local header. And if it uses ZIP_LENGTH_AT_END, then it is
+ * prohibited from storing the sizes in the local header. This
+ * prevents fully-compliant streaming writers from providing any size
+ * clues to a streaming reader. In this case, we have to scan the
+ * data as we read to try to locate the end-of-file marker.
+ *
+ * We assume here that the end-of-file marker always has the
+ * PK\007\010 signature. Although it's technically optional, newer
+ * writers seem to provide it pretty consistently, and it's not clear
+ * how to efficiently recognize an end-of-file marker that lacks it.
*
* Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
* zip->end_of_entry if it consumes all of the data.
@@ -1373,18 +1616,18 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
struct zip *zip;
const char *buff;
ssize_t bytes_avail;
+ ssize_t trailing_extra;
int r;
(void)offset; /* UNUSED */
zip = (struct zip *)(a->format->data);
+ trailing_extra = zip->hctx_valid ? AUTH_CODE_SIZE : 0;
if (zip->entry->zip_flags & ZIP_LENGTH_AT_END) {
const char *p;
- ssize_t grabbing_bytes = 24;
+ ssize_t grabbing_bytes = 24 + trailing_extra;
- if (zip->hctx_valid)
- grabbing_bytes += AUTH_CODE_SIZE;
/* Grab at least 24 bytes. */
buff = __archive_read_ahead(a, grabbing_bytes, &bytes_avail);
if (bytes_avail < grabbing_bytes) {
@@ -1399,44 +1642,19 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
}
/* Check for a complete PK\007\010 signature, followed
* by the correct 4-byte CRC. */
- p = buff;
- if (zip->hctx_valid)
- p += AUTH_CODE_SIZE;
+ p = buff + trailing_extra;
if (p[0] == 'P' && p[1] == 'K'
&& p[2] == '\007' && p[3] == '\010'
- && (archive_le32dec(p + 4) == zip->entry_crc32
+ && (archive_le32dec(p + 4) == zip->computed_crc32
|| zip->ignore_crc32
|| (zip->hctx_valid
&& zip->entry->aes_extra.vendor == AES_VENDOR_AE_2))) {
- if (zip->entry->flags & LA_USED_ZIP64) {
- uint64_t compressed, uncompressed;
- zip->entry->crc32 = archive_le32dec(p + 4);
- compressed = archive_le64dec(p + 8);
- uncompressed = archive_le64dec(p + 16);
- if (compressed > INT64_MAX || uncompressed >
- INT64_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Overflow of 64-bit file sizes");
- return ARCHIVE_FAILED;
- }
- zip->entry->compressed_size = compressed;
- zip->entry->uncompressed_size = uncompressed;
- zip->unconsumed = 24;
- } else {
- zip->entry->crc32 = archive_le32dec(p + 4);
- zip->entry->compressed_size =
- archive_le32dec(p + 8);
- zip->entry->uncompressed_size =
- archive_le32dec(p + 12);
- zip->unconsumed = 16;
- }
+ zip->end_of_entry = 1;
if (zip->hctx_valid) {
r = check_authentication_code(a, buff);
if (r != ARCHIVE_OK)
return (r);
}
- zip->end_of_entry = 1;
return (ARCHIVE_OK);
}
/* If not at EOF, ensure we consume at least one byte. */
@@ -1452,11 +1670,10 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
else if (p[3] == '\007') { p += 1; }
else if (p[3] == '\010' && p[2] == '\007'
&& p[1] == 'K' && p[0] == 'P') {
- if (zip->hctx_valid)
- p -= AUTH_CODE_SIZE;
break;
} else { p += 4; }
}
+ p -= trailing_extra;
bytes_avail = p - buff;
} else {
if (zip->entry_bytes_remaining == 0) {
@@ -1499,59 +1716,15 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
bytes_avail = dec_size;
buff = (const char *)zip->decrypted_buffer;
}
- *size = bytes_avail;
zip->entry_bytes_remaining -= bytes_avail;
zip->entry_uncompressed_bytes_read += bytes_avail;
zip->entry_compressed_bytes_read += bytes_avail;
zip->unconsumed += bytes_avail;
+ *size = bytes_avail;
*_buff = buff;
return (ARCHIVE_OK);
}
-static int
-consume_optional_marker(struct archive_read *a, struct zip *zip)
-{
- if (zip->end_of_entry && (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
- const char *p;
-
- if (NULL == (p = __archive_read_ahead(a, 24, NULL))) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP end-of-file record");
- return (ARCHIVE_FATAL);
- }
- /* Consume the optional PK\007\010 marker. */
- if (p[0] == 'P' && p[1] == 'K' &&
- p[2] == '\007' && p[3] == '\010') {
- p += 4;
- zip->unconsumed = 4;
- }
- if (zip->entry->flags & LA_USED_ZIP64) {
- uint64_t compressed, uncompressed;
- zip->entry->crc32 = archive_le32dec(p);
- compressed = archive_le64dec(p + 4);
- uncompressed = archive_le64dec(p + 12);
- if (compressed > INT64_MAX ||
- uncompressed > INT64_MAX) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Overflow of 64-bit file sizes");
- return ARCHIVE_FAILED;
- }
- zip->entry->compressed_size = compressed;
- zip->entry->uncompressed_size = uncompressed;
- zip->unconsumed += 20;
- } else {
- zip->entry->crc32 = archive_le32dec(p);
- zip->entry->compressed_size = archive_le32dec(p + 4);
- zip->entry->uncompressed_size = archive_le32dec(p + 8);
- zip->unconsumed += 12;
- }
- }
-
- return (ARCHIVE_OK);
-}
-
#if HAVE_LZMA_H && HAVE_LIBLZMA
static int
zipx_xz_init(struct archive_read *a, struct zip *zip)
@@ -1751,7 +1924,7 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
- in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
+ in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
zip->zipx_lzma_stream.next_in = compressed_buf;
zip->zipx_lzma_stream.avail_in = in_bytes;
zip->zipx_lzma_stream.total_in = 0;
@@ -1793,20 +1966,16 @@ zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
break;
}
- to_consume = zip->zipx_lzma_stream.total_in;
+ to_consume = (ssize_t)zip->zipx_lzma_stream.total_in;
__archive_read_consume(a, to_consume);
zip->entry_bytes_remaining -= to_consume;
zip->entry_compressed_bytes_read += to_consume;
zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
- *size = zip->zipx_lzma_stream.total_out;
+ *size = (size_t)zip->zipx_lzma_stream.total_out;
*buff = zip->uncompressed_buffer;
- ret = consume_optional_marker(a, zip);
- if (ret != ARCHIVE_OK)
- return (ret);
-
return (ARCHIVE_OK);
}
@@ -1845,7 +2014,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
}
/* Set decompressor parameters. */
- in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
+ in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
zip->zipx_lzma_stream.next_in = compressed_buf;
zip->zipx_lzma_stream.avail_in = in_bytes;
@@ -1855,7 +2024,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
/* These lzma_alone streams lack end of stream marker, so let's
* make sure the unpacker won't try to unpack more than it's
* supposed to. */
- zipmin((int64_t) zip->uncompressed_buffer_size,
+ (size_t)zipmin((int64_t) zip->uncompressed_buffer_size,
zip->entry->uncompressed_size -
zip->entry_uncompressed_bytes_read);
zip->zipx_lzma_stream.total_out = 0;
@@ -1871,8 +2040,6 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
/* This case is optional in lzma alone format. It can happen,
* but most of the files don't have it. (GitHub #1257) */
case LZMA_STREAM_END:
- lzma_end(&zip->zipx_lzma_stream);
- zip->zipx_lzma_valid = 0;
if((int64_t) zip->zipx_lzma_stream.total_in !=
zip->entry_bytes_remaining)
{
@@ -1894,7 +2061,7 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
- to_consume = zip->zipx_lzma_stream.total_in;
+ to_consume = (ssize_t)zip->zipx_lzma_stream.total_in;
/* Update pointers. */
__archive_read_consume(a, to_consume);
@@ -1906,21 +2073,18 @@ zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
zip->end_of_entry = 1;
}
- /* Return values. */
- *size = zip->zipx_lzma_stream.total_out;
- *buff = zip->uncompressed_buffer;
-
- /* Behave the same way as during deflate decompression. */
- ret = consume_optional_marker(a, zip);
- if (ret != ARCHIVE_OK)
- return (ret);
-
/* Free lzma decoder handle because we'll no longer need it. */
+ /* This cannot be folded into LZMA_STREAM_END handling above
+ * because the stream end marker is not required in this format. */
if(zip->end_of_entry) {
lzma_end(&zip->zipx_lzma_stream);
zip->zipx_lzma_valid = 0;
}
+ /* Return values. */
+ *size = (size_t)zip->zipx_lzma_stream.total_out;
+ *buff = zip->uncompressed_buffer;
+
/* If we're here, then we're good! */
return (ARCHIVE_OK);
}
@@ -2078,10 +2242,6 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
++consumed_bytes;
} while(consumed_bytes < zip->uncompressed_buffer_size);
- /* Update pointers for libarchive. */
- *buff = zip->uncompressed_buffer;
- *size = consumed_bytes;
-
/* Update pointers so we can continue decompression in another call. */
zip->entry_bytes_remaining -= zip->zipx_ppmd_read_compressed;
zip->entry_compressed_bytes_read += zip->zipx_ppmd_read_compressed;
@@ -2093,10 +2253,9 @@ zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
zip->ppmd8_valid = 0;
}
- /* Seek for optional marker, same way as in each zip entry. */
- ret = consume_optional_marker(a, zip);
- if (ret != ARCHIVE_OK)
- return ret;
+ /* Update pointers for libarchive. */
+ *buff = zip->uncompressed_buffer;
+ *size = consumed_bytes;
return ARCHIVE_OK;
}
@@ -2172,7 +2331,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
- in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
+ in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
if(in_bytes < 1) {
/* libbz2 doesn't complain when caller feeds avail_in == 0.
* It will actually return success in this case, which is
@@ -2235,14 +2394,9 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
zip->entry_uncompressed_bytes_read += total_out;
/* Give libarchive its due. */
- *size = total_out;
+ *size = (size_t)total_out;
*buff = zip->uncompressed_buffer;
- /* Seek for optional marker, like in other entries. */
- r = consume_optional_marker(a, zip);
- if(r != ARCHIVE_OK)
- return r;
-
return ARCHIVE_OK;
}
@@ -2324,7 +2478,7 @@ zip_read_data_zipx_zstd(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
- in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
+ in_bytes = (ssize_t)zipmin(zip->entry_bytes_remaining, bytes_avail);
if(in_bytes < 1) {
/* zstd doesn't complain when caller feeds avail_in == 0.
* It will actually return success in this case, which is
@@ -2370,14 +2524,9 @@ zip_read_data_zipx_zstd(struct archive_read *a, const void **buff,
zip->entry_uncompressed_bytes_read += total_out;
/* Give libarchive its due. */
- *size = total_out;
+ *size = (size_t)total_out;
*buff = zip->uncompressed_buffer;
- /* Seek for optional marker, like in other entries. */
- r = consume_optional_marker(a, zip);
- if(r != ARCHIVE_OK)
- return r;
-
return ARCHIVE_OK;
}
#endif
@@ -2413,7 +2562,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
size_t *size, int64_t *offset)
{
struct zip *zip;
- ssize_t bytes_avail;
+ ssize_t bytes_avail, to_consume = 0;
const void *compressed_buff, *sp;
int r;
@@ -2534,34 +2683,33 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
}
/* Consume as much as the compressor actually used. */
- bytes_avail = zip->stream.total_in;
+ to_consume = zip->stream.total_in;
+ __archive_read_consume(a, to_consume);
+ zip->entry_bytes_remaining -= to_consume;
+ zip->entry_compressed_bytes_read += to_consume;
+ zip->entry_uncompressed_bytes_read += zip->stream.total_out;
+
if (zip->tctx_valid || zip->cctx_valid) {
- zip->decrypted_bytes_remaining -= bytes_avail;
+ zip->decrypted_bytes_remaining -= to_consume;
if (zip->decrypted_bytes_remaining == 0)
zip->decrypted_ptr = zip->decrypted_buffer;
else
- zip->decrypted_ptr += bytes_avail;
+ zip->decrypted_ptr += to_consume;
}
- /* Calculate compressed data as much as we used.*/
if (zip->hctx_valid)
- archive_hmac_sha1_update(&zip->hctx, sp, bytes_avail);
- __archive_read_consume(a, bytes_avail);
- zip->entry_bytes_remaining -= bytes_avail;
- zip->entry_compressed_bytes_read += bytes_avail;
-
- *size = zip->stream.total_out;
- zip->entry_uncompressed_bytes_read += zip->stream.total_out;
- *buff = zip->uncompressed_buffer;
+ archive_hmac_sha1_update(&zip->hctx, sp, to_consume);
- if (zip->end_of_entry && zip->hctx_valid) {
- r = check_authentication_code(a, NULL);
- if (r != ARCHIVE_OK)
- return (r);
+ if (zip->end_of_entry) {
+ if (zip->hctx_valid) {
+ r = check_authentication_code(a, NULL);
+ if (r != ARCHIVE_OK) {
+ return (r);
+ }
+ }
}
- r = consume_optional_marker(a, zip);
- if (r != ARCHIVE_OK)
- return (r);
+ *size = zip->stream.total_out;
+ *buff = zip->uncompressed_buffer;
return (ARCHIVE_OK);
}
@@ -3029,13 +3177,27 @@ archive_read_format_zip_read_data(struct archive_read *a,
}
if (r != ARCHIVE_OK)
return (r);
- /* Update checksum */
- if (*size)
- zip->entry_crc32 = zip->crc32func(zip->entry_crc32, *buff,
- (unsigned)*size);
- /* If we hit the end, swallow any end-of-data marker. */
+ if (*size > 0) {
+ zip->computed_crc32 = zip->crc32func(zip->computed_crc32, *buff,
+ (unsigned)*size);
+ }
+ /* If we hit the end, swallow any end-of-data marker and
+ * verify the final check values. */
if (zip->end_of_entry) {
- /* Check file size, CRC against these values. */
+ consume_end_of_file_marker(a, zip);
+
+ /* Check computed CRC against header */
+ if ((!zip->hctx_valid ||
+ zip->entry->aes_extra.vendor != AES_VENDOR_AE_2) &&
+ zip->entry->crc32 != zip->computed_crc32
+ && !zip->ignore_crc32) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "ZIP bad CRC: 0x%lx should be 0x%lx",
+ (unsigned long)zip->computed_crc32,
+ (unsigned long)zip->entry->crc32);
+ return (ARCHIVE_FAILED);
+ }
+ /* Check file size against header. */
if (zip->entry->compressed_size !=
zip->entry_compressed_bytes_read) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -3043,7 +3205,7 @@ archive_read_format_zip_read_data(struct archive_read *a,
"(read %jd, expected %jd)",
(intmax_t)zip->entry_compressed_bytes_read,
(intmax_t)zip->entry->compressed_size);
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
/* Size field only stores the lower 32 bits of the actual
* size. */
@@ -3054,18 +3216,7 @@ archive_read_format_zip_read_data(struct archive_read *a,
"(read %jd, expected %jd)\n",
(intmax_t)zip->entry_uncompressed_bytes_read,
(intmax_t)zip->entry->uncompressed_size);
- return (ARCHIVE_WARN);
- }
- /* Check computed CRC against header */
- if ((!zip->hctx_valid ||
- zip->entry->aes_extra.vendor != AES_VENDOR_AE_2) &&
- zip->entry->crc32 != zip->entry_crc32
- && !zip->ignore_crc32) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP bad CRC: 0x%lx should be 0x%lx",
- (unsigned long)zip->entry_crc32,
- (unsigned long)zip->entry->crc32);
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FAILED);
}
}
@@ -3529,7 +3680,7 @@ read_eocd(struct zip *zip, const char *p, int64_t current_offset)
if (archive_le16dec(p + 10) != archive_le16dec(p + 8))
return 0;
/* Central directory can't extend beyond start of EOCD record. */
- if (cd_offset + cd_size > current_offset)
+ if ((int64_t)cd_offset + cd_size > current_offset)
return 0;
/* Save the central directory location for later use. */
@@ -3932,6 +4083,17 @@ slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
} else {
/* Generate resource fork name to find its
* resource file at zip->tree_rsrc. */
+
+ /* If this is an entry ending with slash,
+ * make the resource for name slash-less
+ * as the actual resource fork doesn't end with '/'.
+ */
+ size_t tmp_length = filename_length;
+ if (tmp_length > 0 && name[tmp_length - 1] == '/') {
+ tmp_length--;
+ r = rsrc_basename(name, tmp_length);
+ }
+
archive_strcpy(&(zip_entry->rsrcname),
"__MACOSX/");
archive_strncat(&(zip_entry->rsrcname),
@@ -3939,7 +4101,7 @@ slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
archive_strcat(&(zip_entry->rsrcname), "._");
archive_strncat(&(zip_entry->rsrcname),
name + (r - name),
- filename_length - (r - name));
+ tmp_length - (r - name));
/* Register an entry to RB tree to sort it by
* file offset. */
__archive_rb_tree_insert_node(&zip->tree,
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index accf526..41bfe7a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33:22Z kientzle $");
/*
* Basic resizable string support, to simplify manipulating arbitrary-sized
@@ -553,6 +552,8 @@ archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest,
} else
mbflag = MB_PRECOMPOSED;
+ mbflag |= MB_ERR_INVALID_CHARS;
+
buffsize = dest->length + length + 1;
do {
/* Allocate memory for WCS. */
@@ -1527,7 +1528,7 @@ get_current_codepage(void)
p = strrchr(locale, '.');
if (p == NULL)
return (GetACP());
- if (strcmp(p+1, "utf8") == 0)
+ if ((strcmp(p+1, "utf8") == 0) || (strcmp(p+1, "UTF-8") == 0))
return CP_UTF8;
cp = my_atoi(p+1);
if ((int)cp <= 0)
@@ -2639,81 +2640,69 @@ unicode_to_utf16le(char *p, size_t remaining, uint32_t uc)
}
/*
- * Copy UTF-8 string in checking surrogate pair.
- * If any surrogate pair are found, it would be canonicalized.
+ * Append new UTF-8 string to existing UTF-8 string.
+ * Existing string is assumed to already be in proper form;
+ * the new string will have invalid sequences replaced and
+ * surrogate pairs canonicalized.
*/
static int
-strncat_from_utf8_to_utf8(struct archive_string *as, const void *_p,
+strncat_from_utf8_to_utf8(struct archive_string *as, const void *_src,
size_t len, struct archive_string_conv *sc)
{
- const char *s;
- char *p, *endp;
- int n, ret = 0;
-
+ int ret = 0;
+ const char *src = _src;
(void)sc; /* UNUSED */
+ /* Pre-extend the destination */
if (archive_string_ensure(as, as->length + len + 1) == NULL)
return (-1);
- s = (const char *)_p;
- p = as->s + as->length;
- endp = as->s + as->buffer_length -1;
- do {
+ /* Invariant: src points to the first UTF8 byte that hasn't
+ * been copied to the destination `as`. */
+ for (;;) {
+ int n;
uint32_t uc;
- const char *ss = s;
- size_t w;
+ const char *e = src;
- /*
- * Forward byte sequence until a conversion of that is needed.
- */
- while ((n = utf8_to_unicode(&uc, s, len)) > 0) {
- s += n;
+ /* Skip UTF-8 sequences until we reach end-of-string or
+ * a code point that needs conversion. */
+ while ((n = utf8_to_unicode(&uc, e, len)) > 0) {
+ e += n;
len -= n;
}
- if (ss < s) {
- if (p + (s - ss) > endp) {
- as->length = p - as->s;
- if (archive_string_ensure(as,
- as->buffer_length + len + 1) == NULL)
- return (-1);
- p = as->s + as->length;
- endp = as->s + as->buffer_length -1;
- }
-
- memcpy(p, ss, s - ss);
- p += s - ss;
+ /* Copy the part that doesn't need conversion */
+ if (e > src) {
+ if (archive_string_append(as, src, e - src) == NULL)
+ return (-1);
+ src = e;
}
- /*
- * If n is negative, current byte sequence needs a replacement.
- */
- if (n < 0) {
+ if (n == 0) {
+ /* We reached end-of-string */
+ return (ret);
+ } else {
+ /* Next code point needs conversion */
+ char t[4];
+ size_t w;
+
+ /* Try decoding a surrogate pair */
if (n == -3 && IS_SURROGATE_PAIR_LA(uc)) {
- /* Current byte sequence may be CESU-8. */
- n = cesu8_to_unicode(&uc, s, len);
+ n = cesu8_to_unicode(&uc, src, len);
}
+ /* Not a (valid) surrogate, so use a replacement char */
if (n < 0) {
- ret = -1;
- n *= -1;/* Use a replaced unicode character. */
+ ret = -1; /* Return -1 if we used any replacement */
+ n *= -1;
}
-
- /* Rebuild UTF-8 byte sequence. */
- while ((w = unicode_to_utf8(p, endp - p, uc)) == 0) {
- as->length = p - as->s;
- if (archive_string_ensure(as,
- as->buffer_length + len + 1) == NULL)
- return (-1);
- p = as->s + as->length;
- endp = as->s + as->buffer_length -1;
- }
- p += w;
- s += n;
+ /* Consume converted code point */
+ src += n;
len -= n;
+ /* Convert and append new UTF-8 sequence. */
+ w = unicode_to_utf8(t, sizeof(t), uc);
+ if (archive_string_append(as, t, w) == NULL)
+ return (-1);
}
- } while (n > 0);
- as->length = p - as->s;
- as->s[as->length] = '\0';
- return (ret);
+ }
}
static int
@@ -3885,6 +3874,30 @@ archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
}
*p = NULL;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * On Windows, first try converting from WCS because (1) there's no
+ * guarantee that the conversion to MBS will succeed, e.g. when using
+ * CP_ACP, and (2) that's more efficient than converting to MBS, just to
+ * convert back to WCS again before finally converting to UTF-8
+ */
+ if ((aes->aes_set & AES_SET_WCS) != 0) {
+ sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
+ if (sc == NULL)
+ return (-1);/* Couldn't allocate memory for sc. */
+ archive_string_empty(&(aes->aes_utf8));
+ r = archive_string_append_from_wcs_in_codepage(&(aes->aes_utf8),
+ aes->aes_wcs.s, aes->aes_wcs.length, sc);
+ if (a == NULL)
+ free_sconv_object(sc);
+ if (r == 0) {
+ aes->aes_set |= AES_SET_UTF8;
+ *p = aes->aes_utf8.s;
+ return (0);/* success. */
+ } else
+ return (-1);/* failure. */
+ }
+#endif
/* Try converting WCS to MBS first if MBS does not exist yet. */
if ((aes->aes_set & AES_SET_MBS) == 0) {
const char *pm; /* unused */
@@ -3969,6 +3982,32 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
}
*wp = NULL;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * On Windows, prefer converting from UTF-8 directly to WCS because:
+ * (1) there's no guarantee that the string can be represented in MBS (e.g.
+ * with CP_ACP), and (2) in order to convert from UTF-8 to MBS, we're going
+ * to need to convert from UTF-8 to WCS anyway and its wasteful to throw
+ * away that intermediate result
+ */
+ if (aes->aes_set & AES_SET_UTF8) {
+ struct archive_string_conv *sc;
+
+ sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
+ if (sc != NULL) {
+ archive_wstring_empty((&aes->aes_wcs));
+ r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
+ aes->aes_utf8.s, aes->aes_utf8.length, sc);
+ if (a == NULL)
+ free_sconv_object(sc);
+ if (r == 0) {
+ aes->aes_set |= AES_SET_WCS;
+ *wp = aes->aes_wcs.s;
+ return (0);
+ }
+ }
+ }
+#endif
/* Try converting UTF8 to MBS first if MBS does not exist yet. */
if ((aes->aes_set & AES_SET_MBS) == 0) {
const char *p; /* unused */
@@ -4222,11 +4261,32 @@ archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
aes->aes_set = AES_SET_UTF8; /* Only UTF8 is set now. */
- /* Try converting UTF-8 to MBS, return false on failure. */
sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
if (sc == NULL)
return (-1);/* Couldn't allocate memory for sc. */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* On Windows, there's no good way to convert from UTF8 -> MBS directly, so
+ * prefer to first convert to WCS as (1) it's wasteful to throw away the
+ * intermediate result, and (2) WCS will still be set even if we fail to
+ * convert to MBS (e.g. with ACP that can't represent the characters) */
+ r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
+ aes->aes_utf8.s, aes->aes_utf8.length, sc);
+
+ if (a == NULL)
+ free_sconv_object(sc);
+ if (r != 0)
+ return (-1); /* This will guarantee we can't convert to MBS */
+ aes->aes_set = AES_SET_UTF8 | AES_SET_WCS; /* Both UTF8 and WCS set. */
+
+ /* Try converting WCS to MBS, return false on failure. */
+ if (archive_string_append_from_wcs(&(aes->aes_mbs), aes->aes_wcs.s,
+ aes->aes_wcs.length))
+ return (-1);
+#else
+ /* Try converting UTF-8 to MBS, return false on failure. */
r = archive_strcpy_l(&(aes->aes_mbs), utf8, sc);
+
if (a == NULL)
free_sconv_object(sc);
if (r != 0)
@@ -4237,8 +4297,10 @@ archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
if (archive_wstring_append_from_mbs(&(aes->aes_wcs), aes->aes_mbs.s,
aes->aes_mbs.length))
return (-1);
- aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
+#endif
/* All conversions succeeded. */
+ aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
+
return (0);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.h b/Utilities/cmlibarchive/libarchive/archive_string.h
index 49d7d30..e898786 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.h
+++ b/Utilities/cmlibarchive/libarchive/archive_string.h
@@ -21,9 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_string.h 201092 2009-12-28 02:26:06Z kientzle $
- *
*/
#ifndef ARCHIVE_STRING_H_INCLUDED
diff --git a/Utilities/cmlibarchive/libarchive/archive_string_composition.h b/Utilities/cmlibarchive/libarchive/archive_string_composition.h
index d0ac340..e917036 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string_composition.h
+++ b/Utilities/cmlibarchive/libarchive/archive_string_composition.h
@@ -22,8 +22,6 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
- *
*/
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
index 969a560..c785e12 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03-06 05:14:55Z kientzle $");
/*
* The use of printf()-family functions can be troublesome
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.3 b/Utilities/cmlibarchive/libarchive/archive_util.3
index d5d4e7d..3aa508f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.3
+++ b/Utilities/cmlibarchive/libarchive/archive_util.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_UTIL 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
index 0680711..148921d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.c
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -256,10 +255,9 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
#endif
fd = -1;
ws = NULL;
+ archive_string_init(&temp_name);
if (template == NULL) {
- archive_string_init(&temp_name);
-
/* Get a temporary directory. */
if (tmpdir == NULL) {
size_t l;
@@ -282,7 +280,8 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
strlen(tmpdir)) < 0)
goto exit_tmpfile;
- if (temp_name.s[temp_name.length-1] != L'/')
+ if (temp_name.length == 0 ||
+ temp_name.s[temp_name.length-1] != L'/')
archive_wstrappend_wchar(&temp_name, L'/');
}
@@ -456,7 +455,7 @@ get_tempdir(struct archive_string *temppath)
tmp = "/tmp";
#endif
archive_strcpy(temppath, tmp);
- if (temppath->s[temppath->length-1] != '/')
+ if (temppath->length == 0 || temppath->s[temppath->length-1] != '/')
archive_strappend_char(temppath, '/');
return (ARCHIVE_OK);
}
@@ -479,7 +478,8 @@ __archive_mktemp(const char *tmpdir)
goto exit_tmpfile;
} else {
archive_strcpy(&temp_name, tmpdir);
- if (temp_name.s[temp_name.length-1] != '/')
+ if (temp_name.length == 0 ||
+ temp_name.s[temp_name.length-1] != '/')
archive_strappend_char(&temp_name, '/');
}
#ifdef O_TMPFILE
@@ -540,7 +540,7 @@ __archive_mktempx(const char *tmpdir, char *template)
goto exit_tmpfile;
} else
archive_strcpy(&temp_name, tmpdir);
- if (temp_name.s[temp_name.length-1] == '/') {
+ if (temp_name.length > 0 && temp_name.s[temp_name.length-1] == '/') {
temp_name.s[temp_name.length-1] = '\0';
temp_name.length --;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_version_details.c b/Utilities/cmlibarchive/libarchive/archive_version_details.c
index 5f5a5b7..2d2b6ba 100644
--- a/Utilities/cmlibarchive/libarchive/archive_version_details.c
+++ b/Utilities/cmlibarchive/libarchive/archive_version_details.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_virtual.c b/Utilities/cmlibarchive/libarchive/archive_virtual.c
index f509ee5..97e0b8a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_virtual.c
+++ b/Utilities/cmlibarchive/libarchive/archive_virtual.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_virtual.c 201098 2009-12-28 02:58:14Z kientzle $");
#include "archive.h"
#include "archive_entry.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.c b/Utilities/cmlibarchive/libarchive/archive_windows.c
index ebc5eef..bb540da 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.c
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.h b/Utilities/cmlibarchive/libarchive/archive_windows.h
index dda63b8..b8b2ce9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.h
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.h
@@ -23,8 +23,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/*
@@ -300,12 +298,17 @@ typedef int mbstate_t;
size_t wcrtomb(char *, wchar_t, mbstate_t *);
#endif
-#if defined(_MSC_VER) && _MSC_VER < 1300
+#if !WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) && NTDDI_VERSION < NTDDI_WIN10_VB
+// not supported in UWP SDK before 20H1
+#define GetVolumePathNameW(f, v, c) (0)
+#elif defined(_MSC_VER) && _MSC_VER < 1300
WINBASEAPI BOOL WINAPI GetVolumePathNameW(
LPCWSTR lpszFileName,
LPWSTR lpszVolumePathName,
DWORD cchBufferLength
);
+#endif
+#if defined(_MSC_VER) && _MSC_VER < 1300
# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
LARGE_INTEGER FileOffset;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.3 b/Utilities/cmlibarchive/libarchive/archive_write.3
index e7f7f13..227e4e0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_WRITE 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index ec3c95c..e1a4f34 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:00Z kientzle $");
/*
* This file contains the "essential" portions of the write API, that
@@ -115,7 +114,7 @@ archive_write_new(void)
/* Initialize a block of nulls for padding purposes. */
a->null_length = 1024;
- nulls = (unsigned char *)calloc(1, a->null_length);
+ nulls = (unsigned char *)calloc(a->null_length, sizeof(unsigned char));
if (nulls == NULL) {
free(a);
return (NULL);
@@ -133,12 +132,17 @@ archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
struct archive_write *a = (struct archive_write *)_a;
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
+
+ if (bytes_per_block < 0) {
+ // Do nothing if the bytes_per_block is negative
+ return 0;
+ }
a->bytes_per_block = bytes_per_block;
return (ARCHIVE_OK);
}
/*
- * Get the current block size. -1 if it has never been set.
+ * Get the current block size.
*/
int
archive_write_get_bytes_per_block(struct archive *_a)
@@ -146,6 +150,10 @@ archive_write_get_bytes_per_block(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
+ if (a->bytes_per_block < 0) {
+ // Don't return a negative value
+ return 1;
+ }
return (a->bytes_per_block);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
index 203f414..aa96251 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c
index 87fdb73..3aca6d8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -85,7 +83,7 @@ archive_write_add_filter_b64encode(struct archive *_a)
struct private_b64encode *state;
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_uu");
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_b64encode");
state = (struct private_b64encode *)calloc(1, sizeof(*state));
if (state == NULL) {
@@ -151,7 +149,7 @@ archive_filter_b64encode_open(struct archive_write_filter *f)
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
+ /* Buffer size should be a multiple number of the bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
index ffa633c..fc62458 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
index 9c2144a..4ee3bcf 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
@@ -26,8 +26,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_bzip2.c 201091 2009-12-28 02:22:41Z kientzle $");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -170,7 +168,7 @@ archive_compressor_bzip2_open(struct archive_write_filter *f)
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
+ /* Buffer size should be a multiple number of the bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
index 3ed269f..e547e88 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
@@ -58,8 +58,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_compress.c 201111 2009-12-28 03:33:05Z kientzle $");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -160,7 +158,7 @@ archive_compressor_compress_open(struct archive_write_filter *f)
}
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
+ /* Buffer size should be a multiple number of the bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_grzip.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_grzip.c
index 371102d..f8bb886 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_grzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_grzip.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
index 3e26605..a272703 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_gzip.c 201081 2009-12-28 02:04:42Z kientzle $");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c
index e215f89..fe974c9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
index 6ac4503..24061a1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
index 3bd9062..8580e58 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
@@ -25,7 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
//#undef HAVE_LZO_LZOCONF_H
//#undef HAVE_LZO_LZO1X_H
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c
index 3c06c64..b7aa6d4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_none.c 201080 2009-12-28 02:03:54Z kientzle $");
#include "archive.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
index c096e72..c661cc7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_program.c 201104 2009-12-28 03:14:30Z kientzle $");
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c
index 1ad4589..42dec8d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c
@@ -25,8 +25,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
index 0cc03b1..5886f3a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
@@ -26,8 +26,6 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_xz.c 201108 2009-12-28 03:28:21Z kientzle $");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -312,7 +310,7 @@ archive_compressor_xz_open(struct archive_write_filter *f)
if (data->compressed == NULL) {
size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
- /* Buffer size should be a multiple number of the of bytes
+ /* Buffer size should be a multiple number of the bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
index 3d6b3d1..8a0b67a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2017 Sean Purcell
+ * Copyright (c) 2023-2024 Klara, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,12 +26,12 @@
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
@@ -40,6 +41,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H
#include <string.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#ifdef HAVE_ZSTD_H
#include <cm3p/zstd.h>
#endif
@@ -55,15 +59,17 @@ struct private_data {
int compression_level;
int threads;
int long_distance;
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
enum {
running,
finishing,
resetting,
} state;
int frame_per_file;
- size_t min_frame_size;
- size_t max_frame_size;
+ size_t min_frame_in;
+ size_t max_frame_in;
+ size_t min_frame_out;
+ size_t max_frame_out;
size_t cur_frame;
size_t cur_frame_in;
size_t cur_frame_out;
@@ -96,7 +102,7 @@ static int archive_compressor_zstd_write(struct archive_write_filter *,
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
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
static int drive_compressor(struct archive_write_filter *,
struct private_data *, int, const void *, size_t);
#endif
@@ -130,10 +136,12 @@ archive_write_add_filter_zstd(struct archive *_a)
data->compression_level = CLEVEL_DEFAULT;
data->threads = 0;
data->long_distance = 0;
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
data->frame_per_file = 0;
- data->min_frame_size = 0;
- data->max_frame_size = SIZE_MAX;
+ data->min_frame_in = 0;
+ data->max_frame_in = SIZE_MAX;
+ data->min_frame_out = 0;
+ data->max_frame_out = SIZE_MAX;
data->cur_frame_in = 0;
data->cur_frame_out = 0;
data->cstream = ZSTD_createCStream();
@@ -162,7 +170,7 @@ static int
archive_compressor_zstd_free(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
ZSTD_freeCStream(data->cstream);
free(data->out.dst);
#else
@@ -173,7 +181,8 @@ archive_compressor_zstd_free(struct archive_write_filter *f)
return (ARCHIVE_OK);
}
-static int string_to_number(const char *string, intmax_t *numberp)
+static int
+string_to_number(const char *string, intmax_t *numberp)
{
char *end;
@@ -187,6 +196,43 @@ static int string_to_number(const char *string, intmax_t *numberp)
return (ARCHIVE_OK);
}
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
+static int
+string_to_size(const char *string, size_t *numberp)
+{
+ uintmax_t number;
+ char *end;
+ unsigned int shift = 0;
+
+ if (string == NULL || *string == '\0' || *string == '-')
+ return (ARCHIVE_WARN);
+ number = strtoumax(string, &end, 10);
+ if (end > string) {
+ if (*end == 'K' || *end == 'k') {
+ shift = 10;
+ end++;
+ } else if (*end == 'M' || *end == 'm') {
+ shift = 20;
+ end++;
+ } else if (*end == 'G' || *end == 'g') {
+ shift = 30;
+ end++;
+ }
+ if (*end == 'B' || *end == 'b') {
+ end++;
+ }
+ }
+ if (end == string || *end != '\0' || errno == EOVERFLOW) {
+ return (ARCHIVE_WARN);
+ }
+ if (number > (uintmax_t)SIZE_MAX >> shift) {
+ return (ARCHIVE_WARN);
+ }
+ *numberp = (size_t)(number << shift);
+ return (ARCHIVE_OK);
+}
+#endif
+
/*
* Set write options.
*/
@@ -204,7 +250,7 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
/* If we don't have the library, hard-code the max level */
int minimum = CLEVEL_MIN;
int maximum = CLEVEL_MAX;
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
maximum = ZSTD_maxCLevel();
#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
if (ZSTD_versionNumber() >= MINVER_MINCLEVEL) {
@@ -226,34 +272,51 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
if (string_to_number(value, &threads) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
- if (threads < 0) {
+
+#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
+ if (threads == 0) {
+ threads = sysconf(_SC_NPROCESSORS_ONLN);
+ }
+#elif !defined(__CYGWIN__) && defined(_WIN32_WINNT) && \
+ _WIN32_WINNT >= 0x0601 /* _WIN32_WINNT_WIN7 */
+ if (threads == 0) {
+ DWORD winCores = GetActiveProcessorCount(
+ ALL_PROCESSOR_GROUPS);
+ threads = (intmax_t)winCores;
+ }
+#endif
+ if (threads < 0 || threads > INT_MAX) {
return (ARCHIVE_WARN);
}
data->threads = (int)threads;
return (ARCHIVE_OK);
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
} 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) {
+ } else if (strcmp(key, "min-frame-in") == 0) {
+ if (string_to_size(value, &data->min_frame_in) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
- if (min_frame_size < 0) {
+ return (ARCHIVE_OK);
+ } else if (strcmp(key, "min-frame-out") == 0 ||
+ strcmp(key, "min-frame-size") == 0) {
+ if (string_to_size(value, &data->min_frame_out) != ARCHIVE_OK) {
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) {
+ } else if (strcmp(key, "max-frame-in") == 0 ||
+ strcmp(key, "max-frame-size") == 0) {
+ if (string_to_size(value, &data->max_frame_in) != ARCHIVE_OK ||
+ data->max_frame_in < 1024) {
return (ARCHIVE_WARN);
}
- if (max_frame_size < 1024) {
+ return (ARCHIVE_OK);
+ } else if (strcmp(key, "max-frame-out") == 0) {
+ if (string_to_size(value, &data->max_frame_out) != ARCHIVE_OK ||
+ data->max_frame_out < 1024) {
return (ARCHIVE_WARN);
}
- data->max_frame_size = max_frame_size;
return (ARCHIVE_OK);
#endif
}
@@ -262,7 +325,7 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
if (string_to_number(value, &long_distance) != ARCHIVE_OK) {
return (ARCHIVE_WARN);
}
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR && ZSTD_VERSION_NUMBER >= MINVER_LONG
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream && 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));
@@ -287,7 +350,7 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
return (ARCHIVE_WARN);
}
-#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+#if HAVE_ZSTD_H && HAVE_ZSTD_compressStream
/*
* Setup callback.
*/
@@ -356,9 +419,12 @@ archive_compressor_zstd_flush(struct archive_write_filter *f)
{
struct private_data *data = (struct private_data *)f->data;
- if (data->frame_per_file && data->state == running &&
- data->cur_frame_out > data->min_frame_size)
- data->state = finishing;
+ if (data->frame_per_file && data->state == running) {
+ if (data->cur_frame_in > data->min_frame_in &&
+ data->cur_frame_out > data->min_frame_out) {
+ data->state = finishing;
+ }
+ }
return (drive_compressor(f, data, 1, NULL, 0));
}
@@ -417,9 +483,11 @@ drive_compressor(struct archive_write_filter *f,
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->state == running) {
+ if (data->cur_frame_in >= data->max_frame_in ||
+ data->cur_frame_out >= data->max_frame_out) {
+ data->state = finishing;
+ }
}
if (data->out.pos == data->out.size ||
(flush && data->out.pos > 0)) {
@@ -438,7 +506,7 @@ fatal:
return (ARCHIVE_FATAL);
}
-#else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
+#else /* HAVE_ZSTD_H && HAVE_ZSTD_compressStream */
static int
archive_compressor_zstd_open(struct archive_write_filter *f)
@@ -500,4 +568,4 @@ archive_compressor_zstd_close(struct archive_write_filter *f)
return __archive_write_program_close(f, data->pdata);
}
-#endif /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
+#endif /* HAVE_ZSTD_H && HAVE_ZSTD_compressStream */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3 b/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
index 4973f99..3508851 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_WRITE_BLOCKSIZE 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_data.3 b/Utilities/cmlibarchive/libarchive/archive_write_data.3
index bc208b4..9f239f7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_data.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 28, 2017
.Dt ARCHIVE_WRITE_DATA 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk.3 b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
index 97f3fcd..b046168 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd January 19, 2020
.Dt ARCHIVE_WRITE_DISK 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index d676ed6..ad02a6c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#if !defined(_WIN32) || defined(__CYGWIN__)
@@ -4197,7 +4196,7 @@ copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
}
for (xattr_i = 0; xattr_i < xattr_size;
xattr_i += strlen(xattr_names + xattr_i) + 1) {
- char *xattr_val_saved;
+ char *p;
ssize_t s;
int f;
@@ -4208,15 +4207,14 @@ copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
ret = ARCHIVE_WARN;
goto exit_xattr;
}
- xattr_val_saved = xattr_val;
- xattr_val = realloc(xattr_val, s);
- if (xattr_val == NULL) {
+ p = realloc(xattr_val, s);
+ if (p == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Failed to get metadata(xattr)");
ret = ARCHIVE_WARN;
- free(xattr_val_saved);
goto exit_xattr;
}
+ xattr_val = p;
s = fgetxattr(tmpfd, xattr_names + xattr_i, xattr_val, s, 0, 0);
if (s == -1) {
archive_set_error(&a->archive, errno,
@@ -4362,8 +4360,7 @@ set_mac_metadata(struct archive_write_disk *a, const char *pathname,
* silly dance of writing the data to disk just so that
* copyfile() can read it back in again. */
archive_string_init(&tmp);
- archive_strcpy(&tmp, pathname);
- archive_strcat(&tmp, ".XXXXXX");
+ archive_strcpy(&tmp, "tar.mmd.XXXXXX");
fd = mkstemp(tmp.s);
if (fd < 0) {
@@ -4428,7 +4425,8 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname)
#else
la_stat(datafork.s, &st) == -1 ||
#endif
- (st.st_mode & AE_IFMT) != AE_IFREG)
+ (((st.st_mode & AE_IFMT) != AE_IFREG) &&
+ ((st.st_mode & AE_IFMT) != AE_IFDIR)))
goto skip_appledouble;
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
index 557d7e2..3efe2ba 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
@@ -22,8 +22,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_write_disk_private.h 201086 2009-12-28 02:17:53Z kientzle $
*/
#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
index 5fccdb9..9641698 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk_set_standard_lookup.c 201083 2009-12-28 02:09:57Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 7b9ea74..774151a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -2595,7 +2594,7 @@ set_times(struct archive_write_disk *a,
{
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
- + (((nsec)/1000)*10))
+ + ((nsec)/100))
HANDLE hw = 0;
ULARGE_INTEGER wintm;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_filter.3 b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
index c83eb77..b39cabe 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd August 14, 2014
.Dt ARCHIVE_WRITE_FILTER 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3 b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
index 5797e16..574d600 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 28, 2017
.Dt ARCHIVE_WRITE_FINISH_ENTRY 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_format.3 b/Utilities/cmlibarchive/libarchive/archive_write_format.3
index 653089f..9e33136 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_format.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 14, 2013
.Dt ARCHIVE_WRITE_FORMAT 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_free.3 b/Utilities/cmlibarchive/libarchive/archive_write_free.3
index 5210e2a..f6b84ea 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_free.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_free.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_WRITE_FREE 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_header.3 b/Utilities/cmlibarchive/libarchive/archive_write_header.3
index 2217b18..9c6ecec 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_header.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_header.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_WRITE_HEADER 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_new.3 b/Utilities/cmlibarchive/libarchive/archive_write_new.3
index 788cbb8..15a7c40 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_new.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_new.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd February 2, 2012
.Dt ARCHIVE_WRITE_NEW 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open.3 b/Utilities/cmlibarchive/libarchive/archive_write_open.3
index 6bceb96..b12d097 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd November 12, 2020
.Dt ARCHIVE_WRITE_OPEN 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c b/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
index b8d491f..a58ae04 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_fd.c 201093 2009-12-28 02:28:44Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_file.c b/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
index bf5b55a..d787da3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_open_file.c,v 1.19 2007/01/09 08:05:56 kientzle Exp $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
index 9ceefb1..7dc73d5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_filename.c 191165 2009-04-17 00:39:35Z kientzle $");
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c b/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c
index a8a0b81..609cc47 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_open_memory.c,v 1.3 2007/01/09 08:05:56 kientzle Exp $");
#include <errno.h>
#include <stdlib.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_private.h b/Utilities/cmlibarchive/libarchive/archive_write_private.h
index 6522e65..f259ccb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_private.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_write_private.h 201155 2009-12-29 05:20:12Z kientzle $
*/
#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED
@@ -160,7 +158,7 @@ int __archive_write_program_write(struct archive_write_filter *,
struct archive_write_program_data *, const void *, size_t);
/*
- * Get a encryption passphrase.
+ * Get an encryption passphrase.
*/
const char * __archive_write_get_passphrase(struct archive_write *a);
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
index 1f65fa4..f636cff 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format.c 201168 2009-12-29 06:15:32Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
index 1d7249f..004e8ee 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
index fc0de1e..38689d8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ar.c 201108 2009-12-28 03:28:21Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
index bfb4b35..09519b1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 201168 2009-12-29 06:15:32Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_binary.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_binary.c
index d6ce35a..a22d06e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_binary.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_binary.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -578,6 +577,9 @@ archive_write_binary_close(struct archive_write *a)
struct archive_entry *trailer;
trailer = archive_entry_new2(NULL);
+ if (trailer == NULL) {
+ return ARCHIVE_FATAL;
+ }
/* nlink = 1 here for GNU cpio compat. */
archive_entry_set_nlink(trailer, 1);
archive_entry_set_size(trailer, 0);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
index f0f3980..006736a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio_newc.c 201160 2009-12-29 05:41:57Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_odc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_odc.c
index 091925a..6dce78b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_odc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_odc.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -468,6 +467,9 @@ archive_write_odc_close(struct archive_write *a)
struct archive_entry *trailer;
trailer = archive_entry_new2(NULL);
+ if (trailer == NULL) {
+ return ARCHIVE_FATAL;
+ }
/* nlink = 1 here for GNU cpio compat. */
archive_entry_set_nlink(trailer, 1);
archive_entry_set_size(trailer, 0);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c
index 9fe21e4..1bb33b0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 201168 2009-12-29 06:15:32Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
index ec29c5c..8979078 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
@@ -27,8 +27,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 191579 2009-04-27 18:35:03Z gastal $");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -298,7 +296,7 @@ archive_write_gnutar_header(struct archive_write *a,
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
archive_entry_symlink(entry) != NULL ||
- !(archive_entry_filetype(entry) == AE_IFREG))
+ archive_entry_filetype(entry) != AE_IFREG)
archive_entry_set_size(entry, 0);
if (AE_IFDIR == archive_entry_filetype(entry)) {
@@ -389,7 +387,7 @@ archive_write_gnutar_header(struct archive_write *a,
if (r != 0) {
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Pathame");
+ "Can't allocate memory for pathname");
ret = ARCHIVE_FATAL;
goto exit_write_header;
}
@@ -525,7 +523,7 @@ archive_write_gnutar_header(struct archive_write *a,
goto exit_write_header;
}
- if (archive_entry_hardlink(entry) != NULL) {
+ if (archive_entry_hardlink_is_set(entry)) {
tartype = '1';
} else
switch (archive_entry_filetype(entry)) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
index 1b03170..fdca748 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
@@ -2241,7 +2241,7 @@ set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
int onepad;
if (s == NULL)
- s = "";
+ s = "\0\0";
if (l & 0x01) {
onepad = 1;
l &= ~1;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
index 619b771..6db9d27 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171 2009-12-29 06:39:07Z kientzle $");
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
index 1eb9a9a..4aace46 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_pax.c 201162 2009-12-29 05:47:46Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -609,7 +608,15 @@ archive_write_pax_header(struct archive_write *a,
const time_t ustar_max_mtime = get_ustar_max_mtime();
/* Sanity check. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* NOTE: If the caller supplied a pathname that fails WCS conversion (e.g.
+ * if it is invalid UTF-8), we are expected to return ARCHIVE_WARN later on
+ * in execution, hence the check for both pointers */
+ if ((archive_entry_pathname_w(entry_original) == NULL) &&
+ (archive_entry_pathname(entry_original) == NULL)) {
+#else
if (archive_entry_pathname(entry_original) == NULL) {
+#endif
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't record entry in tar file without pathname");
return (ARCHIVE_FAILED);
@@ -1033,6 +1040,14 @@ archive_write_pax_header(struct archive_write *a,
archive_entry_set_symlink(entry_main,
"././@LongSymLink");
}
+ else {
+ /* Otherwise, has non-ASCII characters; update the paths to
+ * however they got decoded above */
+ if (hardlink != NULL)
+ archive_entry_set_hardlink(entry_main, linkpath);
+ else
+ archive_entry_set_symlink(entry_main, linkpath);
+ }
need_extension = 1;
}
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h b/Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h
index e200227..ef9dee9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
index 9e4931c..da2bc0c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
@@ -25,7 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_shar.c 189438 2009-03-06 05:58:56Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -210,6 +209,10 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
if (archive_entry_filetype(entry) != AE_IFDIR) {
/* Try to create the dir. */
p = strdup(name);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
pp = strrchr(p, '/');
/* If there is a / character, try to create the dir. */
if (pp != NULL) {
@@ -292,6 +295,10 @@ archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
free(shar->last_dir);
shar->last_dir = strdup(name);
+ if (shar->last_dir == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
/* Trim a trailing '/'. */
pp = strrchr(shar->last_dir, '/');
if (pp != NULL && pp[1] == '\0')
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c
index d1a06bc..9dc6e71 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c
@@ -25,8 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ustar.c 191579 2009-04-27 18:35:03Z kientzle $");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -256,7 +254,11 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
sconv = ustar->opt_sconv;
/* Sanity check. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (archive_entry_pathname_w(entry) == NULL) {
+#else
if (archive_entry_pathname(entry) == NULL) {
+#endif
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't record entry in tar file without pathname");
return (ARCHIVE_FAILED);
@@ -265,7 +267,7 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
archive_entry_symlink(entry) != NULL ||
- !(archive_entry_filetype(entry) == AE_IFREG))
+ archive_entry_filetype(entry) != AE_IFREG)
archive_entry_set_size(entry, 0);
if (AE_IFDIR == archive_entry_filetype(entry)) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c
index 5994071..ffb420f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c
@@ -25,8 +25,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -243,7 +241,7 @@ archive_write_v7tar_header(struct archive_write *a, struct archive_entry *entry)
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
archive_entry_symlink(entry) != NULL ||
- !(archive_entry_filetype(entry) == AE_IFREG))
+ archive_entry_filetype(entry) != AE_IFREG)
archive_entry_set_size(entry, 0);
if (AE_IFDIR == archive_entry_filetype(entry)) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
index 0ef003e..3d22e1f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
@@ -26,7 +26,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
index 1e82aa2..0fcd31f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -797,7 +796,7 @@ xar_finish_entry(struct archive_write *a)
if (w > 0)
xar->bytes_remaining -= w;
else
- return (w);
+ return ((int)w);
}
file = xar->cur_file;
checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
@@ -1164,7 +1163,7 @@ make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
/*
* Make a file name entry, "<name>".
*/
- l = ll = archive_strlen(&(file->basename));
+ l = ll = (int)archive_strlen(&(file->basename));
tmp = malloc(l);
if (tmp == NULL) {
archive_set_error(&a->archive, ENOMEM,
@@ -1190,7 +1189,7 @@ make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
return (ARCHIVE_FATAL);
}
r = xmlTextWriterWriteBase64(writer, file->basename.s,
- 0, archive_strlen(&(file->basename)));
+ 0, (int)archive_strlen(&(file->basename)));
if (r < 0) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
@@ -2232,10 +2231,10 @@ get_path_component(char *name, int n, const char *fn)
p = strchr(fn, '/');
if (p == NULL) {
- if ((l = strlen(fn)) == 0)
+ if ((l = (int)strlen(fn)) == 0)
return (0);
} else
- l = p - fn;
+ l = (int)(p - fn);
if (l > n -1)
return (-1);
memcpy(name, fn, l);
@@ -2652,10 +2651,10 @@ compression_init_encoder_gzip(struct archive *a,
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = lastrm->avail_in;
+ strm->avail_in = (uInt)lastrm->avail_in;
strm->total_in = (uLong)lastrm->total_in;
strm->next_out = lastrm->next_out;
- strm->avail_out = lastrm->avail_out;
+ strm->avail_out = (uInt)lastrm->avail_out;
strm->total_out = (uLong)lastrm->total_out;
if (deflateInit2(strm, level, Z_DEFLATED,
(withheader)?15:-15,
@@ -2685,10 +2684,10 @@ compression_code_gzip(struct archive *a,
* of ugly hackery to convert a const * pointer to
* a non-const pointer. */
strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
- strm->avail_in = lastrm->avail_in;
+ strm->avail_in = (uInt)lastrm->avail_in;
strm->total_in = (uLong)lastrm->total_in;
strm->next_out = lastrm->next_out;
- strm->avail_out = lastrm->avail_out;
+ strm->avail_out = (uInt)lastrm->avail_out;
strm->total_out = (uLong)lastrm->total_out;
r = deflate(strm,
(action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
@@ -2749,11 +2748,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 = (unsigned int)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 = (unsigned int)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) {
@@ -2782,11 +2781,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 = (unsigned int)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 = (unsigned int)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,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
index d610300..40c3b0c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
@@ -30,7 +30,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 2009-12-29 06:15:32Z kientzle $");
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -132,7 +131,6 @@ struct zip {
enum compression entry_compression;
enum encryption entry_encryption;
int entry_flags;
- int entry_uses_zip64;
int experiments;
struct trad_enc_ctx tctx;
char tctx_valid;
@@ -523,6 +521,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
int ret, ret2 = ARCHIVE_OK;
mode_t type;
int version_needed = 10;
+#define MIN_VERSION_NEEDED(x) do { if (version_needed < x) { version_needed = x; } } while (0)
/* Ignore types of entries that we don't support. */
type = archive_entry_filetype(entry);
@@ -557,12 +556,12 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
/* Reset information from last entry. */
zip->entry_offset = zip->written_bytes;
zip->entry_uncompressed_limit = INT64_MAX;
+ /* Zero size values implies that we're using a trailing data descriptor */
zip->entry_compressed_size = 0;
zip->entry_uncompressed_size = 0;
zip->entry_compressed_written = 0;
zip->entry_uncompressed_written = 0;
zip->entry_flags = 0;
- zip->entry_uses_zip64 = 0;
zip->entry_crc32 = zip->crc32func(0, NULL, 0);
zip->entry_encryption = 0;
archive_entry_free(zip->entry);
@@ -610,7 +609,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
const char *p;
size_t len;
- if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
+ if (archive_entry_pathname_l(zip->entry, &p, &len, sconv) != 0) {
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Pathname");
@@ -619,7 +618,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Can't translate Pathname '%s' to %s",
- archive_entry_pathname(entry),
+ archive_entry_pathname(zip->entry),
archive_string_conversion_charset_name(sconv));
ret2 = ARCHIVE_WARN;
}
@@ -632,7 +631,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
* for filename.
*/
if (type == AE_IFLNK) {
- if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
+ if (archive_entry_symlink_l(zip->entry, &p, &len, sconv)) {
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory "
@@ -672,11 +671,11 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
zip->entry_crc32 = zip->crc32func(zip->entry_crc32,
(const unsigned char *)slink, slink_size);
zip->entry_compression = COMPRESSION_STORE;
- version_needed = 20;
+ MIN_VERSION_NEEDED(20);
} else if (type != AE_IFREG) {
zip->entry_compression = COMPRESSION_STORE;
zip->entry_uncompressed_limit = 0;
- version_needed = 20;
+ MIN_VERSION_NEEDED(20);
} else if (archive_entry_size_is_set(zip->entry)) {
int64_t size = archive_entry_size(zip->entry);
int64_t additional_size = 0;
@@ -689,27 +688,27 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
if (zip->entry_compression == COMPRESSION_STORE) {
zip->entry_compressed_size = size;
zip->entry_uncompressed_size = size;
- version_needed = 10;
+ MIN_VERSION_NEEDED(10);
} else {
zip->entry_uncompressed_size = size;
- version_needed = 20;
+ MIN_VERSION_NEEDED(20);
}
if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
switch (zip->entry_encryption) {
case ENCRYPTION_TRADITIONAL:
additional_size = TRAD_HEADER_SIZE;
- version_needed = 20;
+ MIN_VERSION_NEEDED(20);
break;
case ENCRYPTION_WINZIP_AES128:
additional_size = WINZIP_AES128_HEADER_SIZE
+ AUTH_CODE_SIZE;
- version_needed = 20;
+ MIN_VERSION_NEEDED(20);
break;
case ENCRYPTION_WINZIP_AES256:
additional_size = WINZIP_AES256_HEADER_SIZE
+ AUTH_CODE_SIZE;
- version_needed = 20;
+ MIN_VERSION_NEEDED(20);
break;
case ENCRYPTION_NONE:
default:
@@ -733,8 +732,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|| (zip->entry_uncompressed_size + additional_size > ZIP_4GB_MAX)
|| (zip->entry_uncompressed_size > ZIP_4GB_MAX_UNCOMPRESSED
&& zip->entry_compression != COMPRESSION_STORE)) {
- zip->entry_uses_zip64 = 1;
- version_needed = 45;
+ MIN_VERSION_NEEDED(45);
}
/* We may know the size, but never the CRC. */
@@ -742,7 +740,6 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
} else {
/* We don't know the size. Use the default
* compression unless specified otherwise.
- * We enable Zip64 extensions unless we're told not to.
*/
zip->entry_compression = zip->requested_compression;
@@ -752,12 +749,12 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END;
if ((zip->flags & ZIP_FLAG_AVOID_ZIP64) == 0) {
- zip->entry_uses_zip64 = 1;
- version_needed = 45;
+ /* We might use zip64 extensions, so require 4.5 */
+ MIN_VERSION_NEEDED(45);
} else if (zip->entry_compression == COMPRESSION_STORE) {
- version_needed = 10;
+ MIN_VERSION_NEEDED(10);
} else {
- version_needed = 20;
+ MIN_VERSION_NEEDED(20);
}
if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
@@ -765,8 +762,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
case ENCRYPTION_TRADITIONAL:
case ENCRYPTION_WINZIP_AES128:
case ENCRYPTION_WINZIP_AES256:
- if (version_needed < 20)
- version_needed = 20;
+ MIN_VERSION_NEEDED(20);
break;
case ENCRYPTION_NONE:
default:
@@ -787,16 +783,8 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
archive_le16enc(local_header + 8, zip->entry_compression);
archive_le32enc(local_header + 10,
dos_time(archive_entry_mtime(zip->entry)));
- archive_le32enc(local_header + 14, zip->entry_crc32);
- if (zip->entry_uses_zip64) {
- /* Zip64 data in the local header "must" include both
- * compressed and uncompressed sizes AND those fields
- * are included only if these are 0xffffffff;
- * THEREFORE these must be set this way, even if we
- * know one of them is smaller. */
- archive_le32enc(local_header + 18, ZIP_4GB_MAX);
- archive_le32enc(local_header + 22, ZIP_4GB_MAX);
- } else {
+ if ((zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END) == 0) {
+ archive_le32enc(local_header + 14, zip->entry_crc32);
archive_le32enc(local_header + 18, (uint32_t)zip->entry_compressed_size);
archive_le32enc(local_header + 22, (uint32_t)zip->entry_uncompressed_size);
}
@@ -842,42 +830,19 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
* the local file header and the central directory.
* We format them once and then duplicate them. */
- /* UT timestamp, length depends on what timestamps are set. */
- memcpy(e, "UT", 2);
- archive_le16enc(e + 2,
- 1
- + (archive_entry_mtime_is_set(entry) ? 4 : 0)
- + (archive_entry_atime_is_set(entry) ? 4 : 0)
- + (archive_entry_ctime_is_set(entry) ? 4 : 0));
- e += 4;
- *e++ =
- (archive_entry_mtime_is_set(entry) ? 1 : 0)
- | (archive_entry_atime_is_set(entry) ? 2 : 0)
- | (archive_entry_ctime_is_set(entry) ? 4 : 0);
- if (archive_entry_mtime_is_set(entry)) {
- archive_le32enc(e, (uint32_t)archive_entry_mtime(entry));
- e += 4;
- }
- if (archive_entry_atime_is_set(entry)) {
- archive_le32enc(e, (uint32_t)archive_entry_atime(entry));
+ /* ux Unix extra data, length 11, version 1 */
+ if (archive_entry_uid_is_set(entry) || archive_entry_gid_is_set(entry)) {
+ /* TODO: If uid < 64k, use 2 bytes, ditto for gid. */
+ memcpy(e, "ux\013\000\001", 5);
+ e += 5;
+ *e++ = 4; /* Length of following UID */
+ archive_le32enc(e, (uint32_t)archive_entry_uid(entry));
e += 4;
- }
- if (archive_entry_ctime_is_set(entry)) {
- archive_le32enc(e, (uint32_t)archive_entry_ctime(entry));
+ *e++ = 4; /* Length of following GID */
+ archive_le32enc(e, (uint32_t)archive_entry_gid(entry));
e += 4;
}
- /* ux Unix extra data, length 11, version 1 */
- /* TODO: If uid < 64k, use 2 bytes, ditto for gid. */
- memcpy(e, "ux\013\000\001", 5);
- e += 5;
- *e++ = 4; /* Length of following UID */
- archive_le32enc(e, (uint32_t)archive_entry_uid(entry));
- e += 4;
- *e++ = 4; /* Length of following GID */
- archive_le32enc(e, (uint32_t)archive_entry_gid(entry));
- e += 4;
-
/* AES extra data field: WinZIP AES information, ID=0x9901 */
if ((zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED)
&& (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
@@ -904,7 +869,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
e += 2;
}
- /* Copy UT ,ux, and AES-extra into central directory as well. */
+ /* Copy ux, AES-extra into central directory as well. */
zip->file_header_extra_offset = zip->central_directory_bytes;
cd_extra = cd_alloc(zip, e - local_extra);
memcpy(cd_extra, local_extra, e - local_extra);
@@ -916,17 +881,50 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
* archive_write_zip_finish_entry() below.
*/
- /* "[Zip64 entry] in the local header MUST include BOTH
- * original [uncompressed] and compressed size fields." */
- if (zip->entry_uses_zip64) {
- unsigned char *zip64_start = e;
- memcpy(e, "\001\000\020\000", 4);
+ /* UT timestamp: length depends on what timestamps are set.
+ * This header appears in the Central Directory also, but
+ * according to Info-Zip specification, the CD form
+ * only holds mtime, so we format it separately. */
+ if (archive_entry_mtime_is_set(entry)
+ || archive_entry_atime_is_set(entry)
+ || archive_entry_ctime_is_set(entry)) {
+ unsigned char *ut = e;
+ memcpy(e, "UT\000\000", 4);
+ e += 4;
+ *e++ = (archive_entry_mtime_is_set(entry) ? 1 : 0)
+ | (archive_entry_atime_is_set(entry) ? 2 : 0)
+ | (archive_entry_ctime_is_set(entry) ? 4 : 0);
+ if (archive_entry_mtime_is_set(entry)) {
+ archive_le32enc(e, (uint32_t)archive_entry_mtime(entry));
+ e += 4;
+ }
+ if (archive_entry_atime_is_set(entry)) {
+ archive_le32enc(e, (uint32_t)archive_entry_atime(entry));
+ e += 4;
+ }
+ if (archive_entry_ctime_is_set(entry)) {
+ archive_le32enc(e, (uint32_t)archive_entry_ctime(entry));
+ e += 4;
+ }
+ archive_le16enc(ut + 2, (uint16_t)(e - ut - 4));
+ }
+
+ /*
+ * Note about Zip64 Extended Information Extra Field:
+ * Because libarchive always writes in a streaming
+ * fashion, we never know the CRC when we're writing
+ * the local header. So we have to use length-at-end, which
+ * prevents us from putting size information into a Zip64
+ * extra field. However, apparently some readers find it
+ * a helpful clue to have an empty such field so they
+ * can expect a 64-bit length-at-end marker.
+ */
+ if (archive_entry_size_is_set(zip->entry)
+ && (zip->entry_uncompressed_size > ZIP_4GB_MAX
+ || zip->entry_compressed_size > ZIP_4GB_MAX)) {
+ /* Header ID 0x0001, size 0 */
+ memcpy(e, "\001\000\000\000", 4);
e += 4;
- archive_le64enc(e, zip->entry_uncompressed_size);
- e += 8;
- archive_le64enc(e, zip->entry_compressed_size);
- e += 8;
- archive_le16enc(zip64_start + 2, (uint16_t)(e - (zip64_start + 4)));
}
if (zip->flags & ZIP_FLAG_EXPERIMENT_xl) {
@@ -1205,7 +1203,9 @@ archive_write_zip_finish_entry(struct archive_write *a)
archive_le32enc(d + 4, 0);/* no CRC.*/
else
archive_le32enc(d + 4, zip->entry_crc32);
- if (zip->entry_uses_zip64) {
+ if (zip->entry_compressed_written > ZIP_4GB_MAX
+ || zip->entry_uncompressed_written > ZIP_4GB_MAX
+ || zip->flags & ZIP_FLAG_FORCE_ZIP64) {
archive_le64enc(d + 8,
(uint64_t)zip->entry_compressed_written);
archive_le64enc(d + 16,
@@ -1224,23 +1224,60 @@ archive_write_zip_finish_entry(struct archive_write *a)
return (ARCHIVE_FATAL);
}
- /* Append Zip64 extra data to central directory information. */
- if (zip->entry_compressed_written > ZIP_4GB_MAX
- || zip->entry_uncompressed_written > ZIP_4GB_MAX
+ /* UT timestamp: Info-Zip specifies that _only_ the mtime should
+ * be recorded here; ctime and atime are also included in the
+ * local file descriptor. */
+ if (archive_entry_mtime_is_set(zip->entry)) {
+ unsigned char ut[9];
+ unsigned char *u = ut, *ud;
+ memcpy(u, "UT\005\000\001", 5);
+ u += 5;
+ archive_le32enc(u, (uint32_t)archive_entry_mtime(zip->entry));
+ u += 4;
+ ud = cd_alloc(zip, u - ut);
+ if (ud == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip data");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(ud, ut, u - ut);
+ }
+
+ /* Fill in size information in the central directory entry. */
+ /* Fix up central directory file header. */
+ if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2)
+ archive_le32enc(zip->file_header + 16, 0);/* no CRC.*/
+ else
+ archive_le32enc(zip->file_header + 16, zip->entry_crc32);
+ /* Truncate to 32 bits; we'll fix up below. */
+ archive_le32enc(zip->file_header + 20, (uint32_t)zip->entry_compressed_written);
+ archive_le32enc(zip->file_header + 24, (uint32_t)zip->entry_uncompressed_written);
+ archive_le16enc(zip->file_header + 30,
+ (uint16_t)(zip->central_directory_bytes - zip->file_header_extra_offset));
+ archive_le32enc(zip->file_header + 42, (uint32_t)zip->entry_offset);
+
+ /* If any of the values immediately above are too large, we'll
+ * need to put the corresponding value in a Zip64 extra field
+ * and set the central directory value to 0xffffffff as a flag. */
+ if (zip->entry_compressed_written >= ZIP_4GB_MAX
+ || zip->entry_uncompressed_written >= ZIP_4GB_MAX
|| zip->entry_offset > ZIP_4GB_MAX) {
unsigned char zip64[32];
unsigned char *z = zip64, *zd;
memcpy(z, "\001\000\000\000", 4);
z += 4;
if (zip->entry_uncompressed_written >= ZIP_4GB_MAX) {
+ archive_le32enc(zip->file_header + 24, ZIP_4GB_MAX);
archive_le64enc(z, zip->entry_uncompressed_written);
z += 8;
}
if (zip->entry_compressed_written >= ZIP_4GB_MAX) {
+ archive_le32enc(zip->file_header + 20, ZIP_4GB_MAX);
archive_le64enc(z, zip->entry_compressed_written);
z += 8;
}
if (zip->entry_offset >= ZIP_4GB_MAX) {
+ archive_le32enc(zip->file_header + 42, ZIP_4GB_MAX);
archive_le64enc(z, zip->entry_offset);
z += 8;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
index f4b5081..454c796 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd January 31, 2020
.Dt ARCHIVE_WRITE_OPTIONS 3
.Os
@@ -272,6 +270,7 @@ of physical CPU cores.
.It Cm compression
The value is one of
.Dq store ,
+.Dq copy ,
.Dq deflate ,
.Dq bzip2 ,
.Dq lzma1 ,
@@ -279,12 +278,18 @@ The value is one of
or
.Dq ppmd
to indicate how the following entries should be compressed.
+The values
+.Dq store
+and
+.Dq copy
+are synonyms.
Note that this setting is ignored for directories, symbolic links,
and other special entries.
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
compression level.
-Values between 0 and 9 are supported.
+Values between 0 and 9 are supported, with the exception of bzip2
+which only supports values between 1 and 9.
The interpretation of the compression level depends on the chosen
compression method.
.El
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.c b/Utilities/cmlibarchive/libarchive/archive_write_set_options.c
index 962309a..be2a606 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_options.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.c
@@ -24,7 +24,6 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#include "archive_write_private.h"
#include "archive_options_private.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3
index 2db7703..629e059 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd September 21, 2014
.Dt ARCHIVE_WRITE_SET_PASSPHRASE 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c
index 710ecba..f871c8e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c
@@ -24,21 +24,15 @@
*/
#include "archive_platform.h"
-__FBSDID("$FreeBSD$");
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "archive_write_private.h"
-int
-archive_write_set_passphrase(struct archive *_a, const char *p)
+static int
+set_passphrase(struct archive_write *a, const char *p)
{
- struct archive_write *a = (struct archive_write *)_a;
-
- archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
- "archive_write_set_passphrase");
-
if (p == NULL || p[0] == '\0') {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Empty passphrase is unacceptable");
@@ -56,6 +50,18 @@ archive_write_set_passphrase(struct archive *_a, const char *p)
int
+archive_write_set_passphrase(struct archive *_a, const char *p)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_write_set_passphrase");
+
+ return (set_passphrase(a, p));
+}
+
+
+int
archive_write_set_passphrase_callback(struct archive *_a, void *client_data,
archive_passphrase_callback *cb)
{
@@ -81,15 +87,9 @@ __archive_write_get_passphrase(struct archive_write *a)
const char *p;
p = a->passphrase_callback(&a->archive,
a->passphrase_client_data);
- if (p != NULL) {
- a->passphrase = strdup(p);
- if (a->passphrase == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for passphrase");
- return (NULL);
- }
- return (a->passphrase);
- }
+ set_passphrase(a, p);
+ a->passphrase_callback = NULL;
+ a->passphrase_client_data = NULL;
}
- return (NULL);
+ return (a->passphrase);
}
diff --git a/Utilities/cmlibarchive/libarchive/config_freebsd.h b/Utilities/cmlibarchive/libarchive/config_freebsd.h
index 669f272..a1bf0df 100644
--- a/Utilities/cmlibarchive/libarchive/config_freebsd.h
+++ b/Utilities/cmlibarchive/libarchive/config_freebsd.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
@@ -205,7 +203,6 @@
#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
diff --git a/Utilities/cmlibarchive/libarchive/cpio.5 b/Utilities/cmlibarchive/libarchive/cpio.5
index c71018b..21c30d7 100644
--- a/Utilities/cmlibarchive/libarchive/cpio.5
+++ b/Utilities/cmlibarchive/libarchive/cpio.5
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd December 23, 2011
.Dt CPIO 5
.Os
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork.h b/Utilities/cmlibarchive/libarchive/filter_fork.h
index 2bf290c..aeab70a 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork.h
+++ b/Utilities/cmlibarchive/libarchive/filter_fork.h
@@ -21,8 +21,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/filter_fork.h 201087 2009-12-28 02:18:26Z kientzle $
*/
#ifndef FILTER_FORK_H
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
index 62085a7..c895c08 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
@@ -30,8 +30,6 @@
#if defined(HAVE_PIPE) && defined(HAVE_FCNTL) && \
(defined(HAVE_FORK) || defined(HAVE_VFORK) || defined(HAVE_POSIX_SPAWNP))
-__FBSDID("$FreeBSD: head/lib/libarchive/filter_fork.c 182958 2008-09-12 05:33:00Z kientzle $");
-
#if defined(HAVE_SYS_TYPES_H)
# include <sys/types.h>
#endif
diff --git a/Utilities/cmlibarchive/libarchive/libarchive-formats.5 b/Utilities/cmlibarchive/libarchive/libarchive-formats.5
index 5a118ff..fab2f86 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive-formats.5
+++ b/Utilities/cmlibarchive/libarchive/libarchive-formats.5
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd December 27, 2016
.Dt LIBARCHIVE-FORMATS 5
.Os
diff --git a/Utilities/cmlibarchive/libarchive/libarchive.3 b/Utilities/cmlibarchive/libarchive/libarchive.3
index 6490562..c67172b 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd March 18, 2012
.Dt LIBARCHIVE 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_changes.3 b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
index 6bf8db0..fd0e721 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive_changes.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd December 23, 2011
.Dt LIBARCHIVE_CHANGES 3
.Os
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_internals.3 b/Utilities/cmlibarchive/libarchive/libarchive_internals.3
index d672f3e..2978b48 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive_internals.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive_internals.3
@@ -22,8 +22,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd January 26, 2011
.Dt LIBARCHIVE_INTERNALS 3
.Os
@@ -126,7 +124,7 @@ to read the entire file into memory at once and return the
entire file to libarchive as a single block;
other clients may begin asynchronous I/O operations for the
next block on each request.
-.Ss Decompresssion Layer
+.Ss Decompression Layer
The decompression layer not only handles decompression,
it also buffers data so that the format handlers see a
much nicer I/O model.
diff --git a/Utilities/cmlibarchive/libarchive/mtree.5 b/Utilities/cmlibarchive/libarchive/mtree.5
index 8147796..5ea5361 100644
--- a/Utilities/cmlibarchive/libarchive/mtree.5
+++ b/Utilities/cmlibarchive/libarchive/mtree.5
@@ -26,7 +26,6 @@
.\" SUCH DAMAGE.
.\"
.\" From: @(#)mtree.8 8.2 (Berkeley) 12/11/93
-.\" $FreeBSD$
.\"
.Dd September 4, 2013
.Dt MTREE 5
diff --git a/Utilities/cmlibarchive/libarchive/tar.5 b/Utilities/cmlibarchive/libarchive/tar.5
index 34ad4f7..725a7d6 100644
--- a/Utilities/cmlibarchive/libarchive/tar.5
+++ b/Utilities/cmlibarchive/libarchive/tar.5
@@ -23,8 +23,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd December 27, 2016
.Dt TAR 5
.Os