Bläddra i källkod

Merge topic 'update-libarchive'

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

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !8890
Brad King 2 år sedan
förälder
incheckning
3f49c0369d
58 ändrade filer med 1354 tillägg och 440 borttagningar
  1. 2 0
      Source/Modules/CMakeBuildUtilities.cmake
  2. 1 1
      Utilities/Scripts/update-libarchive.bash
  3. 8 4
      Utilities/cmThirdPartyChecks.cmake
  4. 38 24
      Utilities/cmlibarchive/CMakeLists.txt
  5. 1 1
      Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake
  6. 60 9
      Utilities/cmlibarchive/build/cmake/config.h.in
  7. 1 1
      Utilities/cmlibarchive/build/version
  8. 15 7
      Utilities/cmlibarchive/libarchive/CMakeLists.txt
  9. 2 2
      Utilities/cmlibarchive/libarchive/archive.h
  10. 60 0
      Utilities/cmlibarchive/libarchive/archive_digest.c
  11. 10 0
      Utilities/cmlibarchive/libarchive/archive_digest_private.h
  12. 1 1
      Utilities/cmlibarchive/libarchive/archive_entry.h
  13. 29 90
      Utilities/cmlibarchive/libarchive/archive_getdate.c
  14. 10 5
      Utilities/cmlibarchive/libarchive/archive_hmac.c
  15. 2 0
      Utilities/cmlibarchive/libarchive/archive_hmac_private.h
  16. 2 1
      Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
  17. 32 3
      Utilities/cmlibarchive/libarchive/archive_random.c
  18. 6 1
      Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
  19. 28 0
      Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
  20. 70 2
      Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
  21. 2 2
      Utilities/cmlibarchive/libarchive/archive_read_open_file.c
  22. 21 0
      Utilities/cmlibarchive/libarchive/archive_read_set_options.3
  23. 2 2
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
  24. 1 1
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
  25. 49 1
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
  26. 7 7
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
  27. 266 14
      Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
  28. 4 4
      Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
  29. 3 3
      Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
  30. 6 6
      Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
  31. 10 10
      Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
  32. 7 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
  33. 6 15
      Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
  34. 1 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
  35. 3 3
      Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
  36. 4 4
      Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
  37. 3 3
      Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
  38. 4 0
      Utilities/cmlibarchive/libarchive/archive_string.c
  39. 53 4
      Utilities/cmlibarchive/libarchive/archive_util.c
  40. 32 3
      Utilities/cmlibarchive/libarchive/archive_windows.c
  41. 31 0
      Utilities/cmlibarchive/libarchive/archive_write.c
  42. 3 3
      Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
  43. 1 1
      Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
  44. 4 4
      Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
  45. 179 94
      Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
  46. 60 12
      Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
  47. 74 5
      Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
  48. 1 0
      Utilities/cmlibarchive/libarchive/archive_write_private.h
  49. 34 9
      Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
  50. 14 18
      Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
  51. 46 16
      Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
  52. 8 17
      Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
  53. 5 9
      Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
  54. 4 15
      Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
  55. 9 0
      Utilities/cmlibarchive/libarchive/archive_write_set_options.3
  56. 6 1
      Utilities/cmlibarchive/libarchive/config_freebsd.h
  57. 9 0
      Utilities/cmlibarchive/libarchive/filter_fork_windows.c
  58. 4 0
      Utilities/cmlibarchive/libarchive/xxhash.c

+ 2 - 0
Source/Modules/CMakeBuildUtilities.cmake

@@ -287,6 +287,8 @@ else()
   set(ENABLE_CPIO_SHARED OFF)
   set(ENABLE_CAT OFF)
   set(ENABLE_CAT_SHARED OFF)
+  set(ENABLE_UNZIP OFF)
+  set(ENABLE_UNZIP_SHARED OFF)
   set(ENABLE_XATTR OFF)
   set(ENABLE_ACL OFF)
   set(ENABLE_ICONV OFF)

+ 1 - 1
Utilities/Scripts/update-libarchive.bash

@@ -8,7 +8,7 @@ readonly name="LibArchive"
 readonly ownership="LibArchive Upstream <[email protected]>"
 readonly subtree="Utilities/cmlibarchive"
 readonly repo="https://github.com/libarchive/libarchive.git"
-readonly tag="v3.6.2"
+readonly tag="v3.7.2"
 readonly shortlog=false
 readonly paths="
   CMakeLists.txt

+ 8 - 4
Utilities/cmThirdPartyChecks.cmake

@@ -43,8 +43,8 @@ if(WIN32)
   set(HAVE_CHROOT 0)
   set(HAVE_COPYFILE_H 0)
   set(HAVE_CRYPTO_H 0)
-  set(HAVE__CTIME64_S 1)
   set(HAVE_CTIME_R 0)
+  set(HAVE_CTIME_S 1)
   set(HAVE_CYGWIN_CONV_PATH 0)
   set(HAVE_DES_H 0)
   set(HAVE_DIRECT_H 1)
@@ -64,6 +64,8 @@ if(WIN32)
   set(HAVE_FCNTL_H 1)
   set(HAVE_FCNTL_O_NONBLOCK 0)
   set(HAVE_FDOPENDIR 0)
+  set(HAVE_FNMATCH 0)
+  set(HAVE_FNMATCH_H 0)
   set(HAVE_FORK 0)
   set(HAVE_FREEADDRINFO 1)
   set(HAVE_FREEIFADDRS 0)
@@ -82,6 +84,7 @@ if(WIN32)
   set(HAVE_GETGRGID_R 0)
   set(HAVE_GETGRNAM_R 0)
   set(HAVE_GETHOSTBYNAME 1)
+  set(HAVE_GETLINE 0)
   set(HAVE_GETPAGESIZE 0)
   set(HAVE_GETPEERNAME 1)
   set(HAVE_GETPID 1)
@@ -94,8 +97,8 @@ if(WIN32)
   set(HAVE_GETSOCKNAME 1)
   set(HAVE_GETVFSBYNAME 0)
   set(HAVE_GLIBC_STRERROR_R 0)
-  set(HAVE__GMTIME64_S 1)
   set(HAVE_GMTIME_R 0)
+  set(HAVE_GMTIME_S 1)
   set(HAVE_GRP_H 0)
   set(HAVE_IDN2_H 0)
   set(HAVE_IFADDRS_H 0)
@@ -126,8 +129,8 @@ if(WIN32)
   set(HAVE_LINUX_FS_H 0)
   set(HAVE_LINUX_MAGIC_H 0)
   set(HAVE_LINUX_TYPES_H 0)
-  set(HAVE__LOCALTIME64_S 1)
   set(HAVE_LOCALTIME_R 0)
+  set(HAVE_LOCALTIME_S 0)
   set(HAVE_LSTAT 0)
   set(HAVE_LUTIMES 0)
   set(HAVE_MACH_ABSOLUTE_TIME 0)
@@ -136,7 +139,7 @@ if(WIN32)
   set(HAVE_MEMORY_H 1)
   set(HAVE_MKDIR 1)
   set(HAVE_MKFIFO 0)
-  set(HAVE__MKGMTIME64 1)
+  set(HAVE__MKGMTIME 1)
   set(HAVE_MKNOD 0)
   set(HAVE_MMAP 0)
   set(HAVE_MSG_NOSIGNAL 0)
@@ -216,6 +219,7 @@ if(WIN32)
   set(HAVE_SYS_MKDEV_H 0)
   set(HAVE_SYS_MOUNT_H 0)
   set(HAVE_SYS_POLL_H 0)
+  set(HAVE_SYS_QUEUE_H 0)
   set(HAVE_SYS_RESOURCE_H 0)
   set(HAVE_SYS_RICHACL_H 0)
   set(HAVE_SYS_SELECT_H 0)

+ 38 - 24
Utilities/cmlibarchive/CMakeLists.txt

@@ -69,6 +69,7 @@ SET(VERSION                    "${_major}.${_trimmed_minor}.${_trimmed_revision}
 SET(BSDCPIO_VERSION_STRING     "${VERSION}")
 SET(BSDTAR_VERSION_STRING      "${VERSION}")
 SET(BSDCAT_VERSION_STRING      "${VERSION}")
+SET(BSDUNZIP_VERSION_STRING    "${VERSION}")
 SET(LIBARCHIVE_VERSION_NUMBER  "${_version_number}")
 SET(LIBARCHIVE_VERSION_STRING  "${VERSION}")
 
@@ -224,6 +225,8 @@ ENDIF()
 # Enable CTest/CDash support
 include(CTest)
 
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
+
 OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" OFF)
 OPTION(ENABLE_NETTLE "Enable use of Nettle" OFF)
 OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
@@ -248,6 +251,13 @@ OPTION(ENABLE_CPIO "Enable cpio building" ON)
 OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
 OPTION(ENABLE_CAT "Enable cat building" ON)
 OPTION(ENABLE_CAT_SHARED "Enable dynamic build of cat" FALSE)
+IF(WIN32 AND NOT CYGWIN)
+	SET(ENABLE_UNZIP FALSE)
+	SET(ENABLE_UNZIP_SHARED FALSE)
+ELSE()
+	OPTION(ENABLE_UNZIP "Enable unzip building" ON)
+	OPTION(ENABLE_UNZIP_SHARED "Enable dynamic build of unzip" FALSE)
+ENDIF()
 OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
 OPTION(ENABLE_ACL "Enable ACL support" ON)
 OPTION(ENABLE_ICONV "Enable iconv support" ON)
@@ -324,6 +334,7 @@ ENDIF()
 
 IF(MINGW)
   ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO)
+  ADD_DEFINITIONS(-D__MINGW_USE_VC2005_COMPAT)
 ENDIF()
 
 #
@@ -394,7 +405,11 @@ MACRO (TRY_MACRO_FOR_LIBRARY INCLUDES LIBRARIES
       IF("${TRY_TYPE}" MATCHES "COMPILES")
         CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
       ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
-        CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
+        IF(CMAKE_CROSSCOMPILING)
+          MESSAGE(WARNING "Cannot test run \"${VAR}\" when cross-compiling")
+        ELSE(CMAKE_CROSSCOMPILING)
+          CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
+        ENDIF(CMAKE_CROSSCOMPILING)
       ELSE("${TRY_TYPE}" MATCHES "COMPILES")
         MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
       ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
@@ -533,15 +548,19 @@ IF(LIBLZMA_FOUND)
       COMPILES
       "#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
       "WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
+    CHECK_C_SOURCE_COMPILES(
+      "#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
+      HAVE_LZMA_STREAM_ENCODER_MT)
     IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
       ADD_DEFINITIONS(-DLZMA_API_STATIC)
-    ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
+    ENDIF()
   ELSE()
     ADD_DEFINITIONS(-DLZMA_API_STATIC)
   ENDIF()
   CMAKE_POP_CHECK_STATE()
 ELSE(LIBLZMA_FOUND)
 # LZMA not found and will not be used.
+  SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
 ENDIF(LIBLZMA_FOUND)
 #
 # Find LZO2
@@ -590,6 +609,7 @@ IF(LIBB2_FOUND)
   SET(HAVE_BLAKE2_H 1)
   SET(ARCHIVE_BLAKE2 FALSE)
   LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY})
+  INCLUDE_DIRECTORIES(${LIBB2_INCLUDE_DIR})
   CMAKE_PUSH_CHECK_STATE()
   SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY})
   SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR})
@@ -708,6 +728,7 @@ CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
 int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
 
 LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
+LA_CHECK_INCLUDE_FILE("fnmatch.h" HAVE_FNMATCH_H)
 LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
 LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
 LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
@@ -745,6 +766,7 @@ LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
 LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
 LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
 LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
+LA_CHECK_INCLUDE_FILE("sys/queue.h" HAVE_SYS_QUEUE_H)
 LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
 LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
 LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
@@ -764,9 +786,9 @@ LA_CHECK_INCLUDE_FILE("wchar.h" HAVE_WCHAR_H)
 LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
 LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
 IF(ENABLE_CNG)
-  LA_CHECK_INCLUDE_FILE("Bcrypt.h" HAVE_BCRYPT_H)
+  LA_CHECK_INCLUDE_FILE("bcrypt.h" HAVE_BCRYPT_H)
   IF(HAVE_BCRYPT_H)
-    LIST(APPEND ADDITIONAL_LIBS "Bcrypt")
+    LIST(APPEND ADDITIONAL_LIBS "bcrypt")
   ENDIF(HAVE_BCRYPT_H)
 ELSE(ENABLE_CNG)
   UNSET(HAVE_BCRYPT_H CACHE)
@@ -842,6 +864,10 @@ IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
   IF(OPENSSL_FOUND)
     SET(HAVE_LIBCRYPTO 1)
     INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
+    SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
+    SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
+    LA_CHECK_INCLUDE_FILE("openssl/evp.h" HAVE_OPENSSL_EVP_H)
+    CHECK_FUNCTION_EXISTS(PKCS5_PBKDF2_HMAC_SHA1 HAVE_PKCS5_PBKDF2_HMAC_SHA1)
   ENDIF(OPENSSL_FOUND)
 ELSE()
   SET(OPENSSL_FOUND FALSE) # Override cached value
@@ -1379,6 +1405,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD)
 CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN)
 CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL)
 CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR)
+CHECK_FUNCTION_EXISTS_GLIBC(fnmatch HAVE_FNMATCH)
 CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK)
 CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT)
 CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT)
@@ -1391,6 +1418,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
 CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
 CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE)
 CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
@@ -1443,12 +1471,12 @@ CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
 CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
 CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
 CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
-CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
 CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
 CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
-CHECK_FUNCTION_EXISTS_GLIBC(_gmtime64_s HAVE__GMTIME64_S)
-CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
-CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
+CHECK_SYMBOL_EXISTS(ctime_s "time.h" HAVE_CTIME_S)
+CHECK_SYMBOL_EXISTS(gmtime_s "time.h" HAVE_GMTIME_S)
+CHECK_SYMBOL_EXISTS(localtime_s "time.h" HAVE_LOCALTIME_S)
+CHECK_SYMBOL_EXISTS(_mkgmtime "time.h" HAVE__MKGMTIME)
 
 SET(CMAKE_REQUIRED_LIBRARIES "")
 CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
@@ -1491,7 +1519,6 @@ CHECK_C_SOURCE_COMPILES(
   "#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
   HAVE_READLINKAT)
 
-
 # To verify major(), we need to both include the header
 # of interest and verify that the result can be linked.
 # CHECK_FUNCTION_EXISTS doesn't accept a header argument,
@@ -1503,20 +1530,6 @@ CHECK_C_SOURCE_COMPILES(
   "#include <sys/sysmacros.h>\nint main() { return major(256); }"
   MAJOR_IN_SYSMACROS)
 
-IF(ENABLE_LZMA)
-CMAKE_PUSH_CHECK_STATE()
-SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
-SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
-
-CHECK_C_SOURCE_COMPILES(
-  "#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
-  HAVE_LZMA_STREAM_ENCODER_MT)
-
-CMAKE_POP_CHECK_STATE()
-ELSE()
-  SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
-ENDIF(ENABLE_LZMA)
-
 IF(HAVE_STRERROR_R)
   SET(HAVE_DECL_STRERROR_R 1)
 ENDIF(HAVE_STRERROR_R)
@@ -1578,7 +1591,7 @@ ENDIF()
 #
 #
 CHECK_STRUCT_HAS_MEMBER("struct tm" tm_sec
-    "sys/types.h;sys/time.h;time.h" TIME_WITH_SYS_TIME)
+    "sys/types.h;sys/time.h;time.h" HAVE_SYS_TIME_H)
 
 CHECK_TYPE_SIZE(dev_t       DEV_T)
 IF(NOT HAVE_DEV_T)
@@ -2076,6 +2089,7 @@ IF(0) # CMake does not build libarchive's command-line tools.
 add_subdirectory(cat)
 add_subdirectory(tar)
 add_subdirectory(cpio)
+add_subdirectory(unzip)
 ENDIF()
 
 install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibarchive)

+ 1 - 1
Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake

@@ -7,7 +7,7 @@ find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
 set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
+find_package_handle_standard_args(MbedTLS DEFAULT_MSG
     MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
 
 mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)

+ 60 - 9
Utilities/cmlibarchive/build/cmake/config.h.in

@@ -38,6 +38,9 @@
 /* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
 
+/* MD5 via ARCHIVE_CRYPTO_MD5_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_MBEDTLS 1
+
 /* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1
 
@@ -53,6 +56,9 @@
 /* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1
 
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_MBEDTLS 1
+
 /* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
 #cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1
 
@@ -62,6 +68,9 @@
 /* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
 
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_MBEDTLS 1
+
 /* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1
 
@@ -83,6 +92,9 @@
 /* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
 
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_MBEDTLS 1
+
 /* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1
 
@@ -104,6 +116,9 @@
 /* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
 
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_MBEDTLS 1
+
 /* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1
 
@@ -125,6 +140,9 @@
 /* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
 
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_MBEDTLS supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_MBEDTLS 1
+
 /* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
 #cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1
 
@@ -155,6 +173,9 @@
 /* Version number of bsdcat */
 #cmakedefine BSDCAT_VERSION_STRING "@BSDCAT_VERSION_STRING@"
 
+/* Version number of bsdunzip */
+#cmakedefine BSDUNZIP_VERSION_STRING "@BSDUNZIP_VERSION_STRING@"
+
 /* Define to 1 if you have the `acl_create_entry' function. */
 #cmakedefine HAVE_ACL_CREATE_ENTRY 1
 
@@ -197,7 +218,7 @@
 /* Define to 1 if you have the <attr/xattr.h> header file. */
 #cmakedefine HAVE_ATTR_XATTR_H 1
 
-/* Define to 1 if you have the <Bcrypt.h> header file. */
+/* Define to 1 if you have the <bcrypt.h> header file. */
 #cmakedefine HAVE_BCRYPT_H 1
 
 /* Define to 1 if you have the <bsdxml.h> header file. */
@@ -357,6 +378,12 @@
 /* Define to 1 if you have the `flistxattr' function. */
 #cmakedefine HAVE_FLISTXATTR 1
 
+/* Define to 1 if you have the `fnmatch' function. */
+#cmakedefine HAVE_FNMATCH 1
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#cmakedefine HAVE_FNMATCH_H 1
+
 /* Define to 1 if you have the `fork' function. */
 #cmakedefine HAVE_FORK 1
 
@@ -405,6 +432,9 @@
 /* Define to 1 if you have the `getgrnam_r' function. */
 #cmakedefine HAVE_GETGRNAM_R 1
 
+/* Define to 1 if you have the `getline' function. */
+#cmakedefine HAVE_GETLINE 1
+
 /* Define to 1 if you have the `getpid' function. */
 #cmakedefine HAVE_GETPID 1
 
@@ -611,6 +641,15 @@
 /* Define to 1 if you have the <lzo/lzoconf.h> header file. */
 #cmakedefine HAVE_LZO_LZOCONF_H 1
 
+/* Define to 1 if you have the <mbedtls/aes.h> header file. */
+#cmakedefine HAVE_MBEDTLS_AES_H 1
+
+/* Define to 1 if you have the <mbedtls/md.h> header file. */
+#cmakedefine HAVE_MBEDTLS_MD_H 1
+
+/* Define to 1 if you have the <mbedtls/pkcs5.h> header file. */
+#cmakedefine HAVE_MBEDTLS_PKCS5_H 1
+
 /* Define to 1 if you have the `mbrtowc' function. */
 #cmakedefine HAVE_MBRTOWC 1
 
@@ -662,6 +701,9 @@
 /* Define to 1 if you have the `openat' function. */
 #cmakedefine HAVE_OPENAT 1
 
+/* Define to 1 if you have the <openssl/evp.h> header file. */
+#cmakedefine HAVE_OPENSSL_EVP_H 1
+
 /* Define to 1 if you have the <paths.h> header file. */
 #cmakedefine HAVE_PATHS_H 1
 
@@ -771,6 +813,12 @@
 /* Define to 1 if you have the `strrchr' function. */
 #cmakedefine HAVE_STRRCHR 1
 
+/* Define to 1 if the system has the type `struct statfs'. */
+#cmakedefine HAVE_STRUCT_STATFS 1
+
+/* Define to 1 if `f_iosize' is a member of `struct statfs'. */
+#cmakedefine HAVE_STRUCT_STATFS_F_IOSIZE 1
+
 /* Define to 1 if `f_namemax' is a member of `struct statfs'. */
 #cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
 
@@ -854,6 +902,9 @@
 /* Define to 1 if you have the <sys/poll.h> header file. */
 #cmakedefine HAVE_SYS_POLL_H 1
 
+/* Define to 1 if you have the <sys/queue.h> header file. */
+#cmakedefine HAVE_SYS_QUEUE_H 1
+
 /* Define to 1 if you have the <sys/richacl.h> header file. */
 #cmakedefine HAVE_SYS_RICHACL_H 1
 
@@ -993,8 +1044,8 @@
 /* Define to 1 if you have the <zstd.h> header file. */
 #cmakedefine HAVE_ZSTD_H 1
 
-/* Define to 1 if you have the `_ctime64_s' function. */
-#cmakedefine HAVE__CTIME64_S 1
+/* Define to 1 if you have the `ctime_s' function. */
+#cmakedefine HAVE_CTIME_S 1
 
 /* Define to 1 if you have the `_fseeki64' function. */
 #cmakedefine HAVE__FSEEKI64 1
@@ -1002,14 +1053,14 @@
 /* Define to 1 if you have the `_get_timezone' function. */
 #cmakedefine HAVE__GET_TIMEZONE 1
 
-/* Define to 1 if you have the `_gmtime64_s' function. */
-#cmakedefine HAVE__GMTIME64_S 1
+/* Define to 1 if you have the `gmtime_s' function. */
+#cmakedefine HAVE_GMTIME_S 1
 
-/* Define to 1 if you have the `_localtime64_s' function. */
-#cmakedefine HAVE__LOCALTIME64_S 1
+/* Define to 1 if you have the `localtime_s' function. */
+#cmakedefine HAVE_LOCALTIME_S 1
 
-/* Define to 1 if you have the `_mkgmtime64' function. */
-#cmakedefine HAVE__MKGMTIME64 1
+/* Define to 1 if you have the `_mkgmtime' function. */
+#cmakedefine HAVE__MKGMTIME 1
 
 /* Define as const if the declaration of iconv() needs const. */
 #define ICONV_CONST @ICONV_CONST@

+ 1 - 1
Utilities/cmlibarchive/build/version

@@ -1 +1 @@
-3006002
+3007002

+ 15 - 7
Utilities/cmlibarchive/libarchive/CMakeLists.txt

@@ -252,10 +252,12 @@ endif()
 
 IF(0) # CMake does not build libarchive's full package.
 # Libarchive is a shared library
-ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
-TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
-TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
-SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
+IF(BUILD_SHARED_LIBS)
+  ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
+  TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
+  TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
+  SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
+ENDIF(BUILD_SHARED_LIBS)
 
 # archive_static is a static library
 ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
@@ -263,13 +265,19 @@ TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
 SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
   LIBARCHIVE_STATIC)
 # On Posix systems, libarchive.so and libarchive.a can co-exist.
-IF(NOT WIN32 OR CYGWIN)
+IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
   SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
-ENDIF(NOT WIN32 OR CYGWIN)
+ENDIF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
 
 IF(ENABLE_INSTALL)
   # How to install the libraries
-  INSTALL(TARGETS archive archive_static
+  IF(BUILD_SHARED_LIBS)
+    INSTALL(TARGETS archive
+            RUNTIME DESTINATION bin
+            LIBRARY DESTINATION lib
+            ARCHIVE DESTINATION lib)
+  ENDIF(BUILD_SHARED_LIBS)
+  INSTALL(TARGETS archive_static
           RUNTIME DESTINATION bin
           LIBRARY DESTINATION lib
           ARCHIVE DESTINATION lib)

+ 2 - 2
Utilities/cmlibarchive/libarchive/archive.h

@@ -36,7 +36,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006002
+#define	ARCHIVE_VERSION_NUMBER 3007002
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -154,7 +154,7 @@ __LA_DECL int		archive_version_number(void);
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.6.2"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.7.2"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 

+ 60 - 0
Utilities/cmlibarchive/libarchive/archive_digest.c

@@ -36,6 +36,11 @@
 #error Cannot use both OpenSSL and libmd.
 #endif
 
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
 /*
  * Message digest functions for Windows platform.
  */
@@ -48,6 +53,26 @@
 /*
  * Initialize a Message digest.
  */
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+static int
+win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
+{
+	NTSTATUS status;
+	ctx->valid = 0;
+
+	status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return (ARCHIVE_FAILED);
+	status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0);
+	if (!BCRYPT_SUCCESS(status)) {
+		BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
+		return (ARCHIVE_FAILED);
+	}
+
+	ctx->valid = 1;
+	return (ARCHIVE_OK);
+}
+#else
 static int
 win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
 {
@@ -70,6 +95,7 @@ win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
 	ctx->valid = 1;
 	return (ARCHIVE_OK);
 }
+#endif
 
 /*
  * Update a Message digest.
@@ -81,23 +107,37 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
 	if (!ctx->valid)
 		return (ARCHIVE_FAILED);
 
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	BCryptHashData(ctx->hHash,
+		      (PUCHAR)(uintptr_t)buf,
+		      (ULONG)len, 0);
+#else
 	CryptHashData(ctx->hash,
 		      (unsigned char *)(uintptr_t)buf,
 		      (DWORD)len, 0);
+#endif
 	return (ARCHIVE_OK);
 }
 
 static int
 win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
 {
+#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
 	DWORD siglen = (DWORD)bufsize;
+#endif
 
 	if (!ctx->valid)
 		return (ARCHIVE_FAILED);
 
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
+	BCryptDestroyHash(ctx->hHash);
+	BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
+#else
 	CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
 	CryptDestroyHash(ctx->hash);
 	CryptReleaseContext(ctx->cryptProv, 0);
+#endif
 	ctx->valid = 0;
 	return (ARCHIVE_OK);
 }
@@ -276,7 +316,11 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
 static int
 __archive_md5init(archive_md5_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
+#endif
 }
 
 static int
@@ -659,7 +703,11 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
 static int
 __archive_sha1init(archive_sha1_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
+#endif
 }
 
 static int
@@ -919,7 +967,11 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
 static int
 __archive_sha256init(archive_sha256_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
+#endif
 }
 
 static int
@@ -1155,7 +1207,11 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
 static int
 __archive_sha384init(archive_sha384_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
+#endif
 }
 
 static int
@@ -1415,7 +1471,11 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
 static int
 __archive_sha512init(archive_sha512_ctx *ctx)
 {
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+  return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
+#else
   return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
+#endif
 }
 
 static int

+ 10 - 0
Utilities/cmlibarchive/libarchive/archive_digest_private.h

@@ -164,6 +164,15 @@
   defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
   defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
   defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* don't use bcrypt when XP needs to be supported */
+#include <bcrypt.h>
+typedef struct {
+  int   valid;
+  BCRYPT_ALG_HANDLE  hAlg;
+  BCRYPT_HASH_HANDLE hHash;
+} Digest_CTX;
+#else
 #include <windows.h>
 #include <wincrypt.h>
 typedef struct {
@@ -172,6 +181,7 @@ typedef struct {
   HCRYPTHASH  hash;
 } Digest_CTX;
 #endif
+#endif
 
 /* typedefs */
 #if defined(ARCHIVE_CRYPTO_MD5_LIBC)

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_entry.h

@@ -30,7 +30,7 @@
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006002
+#define	ARCHIVE_VERSION_NUMBER 3007002
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the

+ 29 - 90
Utilities/cmlibarchive/libarchive/archive_getdate.c

@@ -700,13 +700,9 @@ Convert(time_t Month, time_t Day, time_t Year,
 	time_t		Julian;
 	int		i;
 	struct tm	*ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	if (Year < 69)
 		Year += 2000;
@@ -733,15 +729,10 @@ Convert(time_t Month, time_t Day, time_t Year,
 	Julian *= DAY;
 	Julian += Timezone;
 	Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Julian, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Julian;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Julian);
 #endif
@@ -757,36 +748,21 @@ DSTcorrect(time_t Start, time_t Future)
 	time_t		StartDay;
 	time_t		FutureDay;
 	struct tm	*ltime;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
-
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Start, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Start;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Start);
 #endif
 	StartDay = (ltime->tm_hour + 1) % 24;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	ltime = localtime_r(&Future, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Future;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		ltime = NULL;
-	else
-		ltime = &tmbuf;
 #else
 	ltime = localtime(&Future);
 #endif
@@ -801,24 +777,15 @@ RelativeDate(time_t Start, time_t zone, int dstmode,
 {
 	struct tm	*tm;
 	time_t	t, now;
-#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__GMTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	t = Start - zone;
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+	tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_GMTIME_R)
 	tm = gmtime_r(&t, &tmbuf);
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = t;
-	terr = _gmtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &tmbuf;
 #else
 	tm = gmtime(&t);
 #endif
@@ -837,25 +804,16 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
 	struct tm	*tm;
 	time_t	Month;
 	time_t	Year;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm	tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	if (RelMonth == 0)
 		return 0;
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	tm = localtime_r(&Start, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = Start;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &tmbuf;
 #else
 	tm = localtime(&Start);
 #endif
@@ -995,10 +953,6 @@ __archive_get_date(time_t now, const char *p)
 	time_t		Start;
 	time_t		tod;
 	long		tzone;
-#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
-	errno_t		terr;
-	__time64_t	tmptime;
-#endif
 
 	/* Clear out the parsed token array. */
 	memset(tokens, 0, sizeof(tokens));
@@ -1007,36 +961,26 @@ __archive_get_date(time_t now, const char *p)
 	gds = &_gds;
 
 	/* Look up the current time. */
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	tm = localtime_s(&local, &now) ? NULL : &local;
+#elif defined(HAVE_LOCALTIME_R)
 	tm = localtime_r(&now, &local);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = now;
-	terr = _localtime64_s(&local, &tmptime);
-	if (terr)
-		tm = NULL;
-	else
-		tm = &local;
 #else
 	memset(&local, 0, sizeof(local));
 	tm = localtime(&now);
 #endif
 	if (tm == NULL)
 		return -1;
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S)
 	local = *tm;
 #endif
 
 	/* Look up UTC if we can and use that to determine the current
 	 * timezone offset. */
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+	gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
+#elif defined(HAVE_GMTIME_R)
 	gmt_ptr = gmtime_r(&now, &gmt);
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = now;
-	terr = _gmtime64_s(&gmt, &tmptime);
-	if (terr)
-		gmt_ptr = NULL;
-	else
-		gmt_ptr = &gmt;
 #else
 	memset(&gmt, 0, sizeof(gmt));
 	gmt_ptr = gmtime(&now);
@@ -1078,15 +1022,10 @@ __archive_get_date(time_t now, const char *p)
 	 * time components instead of the local timezone. */
 	if (gds->HaveZone && gmt_ptr != NULL) {
 		now -= gds->Timezone;
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+		gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
+#elif defined(HAVE_GMTIME_R)
 		gmt_ptr = gmtime_r(&now, &gmt);
-#elif defined(HAVE__GMTIME64_S)
-		tmptime = now;
-		terr = _gmtime64_s(&gmt, &tmptime);
-		if (terr)
-			gmt_ptr = NULL;
-		else
-			gmt_ptr = &gmt;
 #else
 		gmt_ptr = gmtime(&now);
 #endif

+ 10 - 5
Utilities/cmlibarchive/libarchive/archive_hmac.c

@@ -231,15 +231,20 @@ static int
 __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
 {
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
-	OSSL_PARAM params[2];
+	EVP_MAC *mac;
 
-	EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+	char sha1[] = "SHA1";
+	OSSL_PARAM params[] = {
+		OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
+		OSSL_PARAM_END
+	};
+
+	mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
 	*ctx = EVP_MAC_CTX_new(mac);
+	EVP_MAC_free(mac);
 	if (*ctx == NULL)
 		return -1;
-	EVP_MAC_free(mac);
-	params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
-	params[1] = OSSL_PARAM_construct_end();
+
 	EVP_MAC_init(*ctx, key, key_len, params);
 #else
 	*ctx = HMAC_CTX_new();

+ 2 - 0
Utilities/cmlibarchive/libarchive/archive_hmac_private.h

@@ -77,6 +77,8 @@ typedef	struct hmac_sha1_ctx archive_hmac_sha1_ctx;
 #include <openssl/opensslv.h>
 #include <openssl/hmac.h>
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/params.h>
+
 typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
 
 #else

+ 2 - 1
Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h

@@ -33,7 +33,8 @@
 #include <openssl/evp.h>
 #include <openssl/opensslv.h>
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+    (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
 #include <stdlib.h> /* malloc, free */
 #include <string.h> /* memset */
 static inline EVP_MD_CTX *EVP_MD_CTX_new(void)

+ 32 - 3
Utilities/cmlibarchive/libarchive/archive_random.c

@@ -51,16 +51,27 @@ __FBSDID("$FreeBSD$");
 #include <pthread.h>
 #endif
 
-static void arc4random_buf(void *, size_t);
+static void la_arc4random_buf(void *, size_t);
 
 #endif /* HAVE_ARC4RANDOM_BUF */
 
 #include "archive.h"
 #include "archive_random_private.h"
 
-#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* don't use bcrypt when XP needs to be supported */
+#include <bcrypt.h>
+
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
+#elif defined(HAVE_WINCRYPT_H)
 #include <wincrypt.h>
 #endif
+#endif
 
 #ifndef O_CLOEXEC
 #define O_CLOEXEC	0
@@ -75,6 +86,20 @@ int
 archive_random(void *buf, size_t nbytes)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
+# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	NTSTATUS status;
+	BCRYPT_ALG_HANDLE hAlg;
+
+	status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return ARCHIVE_FAILED;
+	status = BCryptGenRandom(hAlg, buf, (ULONG)nbytes, 0);
+	BCryptCloseAlgorithmProvider(hAlg, 0);
+	if (!BCRYPT_SUCCESS(status))
+		return ARCHIVE_FAILED;
+
+	return ARCHIVE_OK;
+# else
 	HCRYPTPROV hProv;
 	BOOL success;
 
@@ -92,6 +117,10 @@ archive_random(void *buf, size_t nbytes)
 	}
 	/* TODO: Does this case really happen? */
 	return ARCHIVE_FAILED;
+# endif
+#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
+	la_arc4random_buf(buf, nbytes);
+	return ARCHIVE_OK;
 #else
 	arc4random_buf(buf, nbytes);
 	return ARCHIVE_OK;
@@ -256,7 +285,7 @@ arc4_getbyte(void)
 }
 
 static void
-arc4random_buf(void *_buf, size_t n)
+la_arc4random_buf(void *_buf, size_t n)
 {
 	uint8_t *buf = (uint8_t *)_buf;
 	_ARC4_LOCK();

+ 6 - 1
Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c

@@ -95,8 +95,13 @@ archive_read_data_into_fd(struct archive *a, int fd)
 	    "archive_read_data_into_fd");
 
 	can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
-	if (!can_lseek)
+	if (!can_lseek) {
 		nulls = calloc(1, nulls_size);
+		if (!nulls) {
+			r = ARCHIVE_FATAL;
+			goto cleanup;
+		}
+	}
 
 	while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
 	    ARCHIVE_OK) {

+ 28 - 0
Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c

@@ -1678,6 +1678,11 @@ setup_current_filesystem(struct archive_read_disk *a)
 	else
 		t->current_filesystem->name_max = nm;
 #endif
+	if (t->current_filesystem->name_max == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Cannot determine name_max");
+		return (ARCHIVE_FAILED);
+	}
 #endif /* USE_READDIR_R */
 	return (ARCHIVE_OK);
 }
@@ -1868,7 +1873,16 @@ setup_current_filesystem(struct archive_read_disk *a)
 
 #if defined(USE_READDIR_R)
 	/* Set maximum filename length. */
+#if defined(HAVE_STATVFS)
+	t->current_filesystem->name_max = svfs.f_namemax;
+#else
 	t->current_filesystem->name_max = sfs.f_namelen;
+#endif
+	if (t->current_filesystem->name_max == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Cannot determine name_max");
+		return (ARCHIVE_FAILED);
+	}
 #endif
 	return (ARCHIVE_OK);
 }
@@ -1950,6 +1964,11 @@ setup_current_filesystem(struct archive_read_disk *a)
 #if defined(USE_READDIR_R)
 	/* Set maximum filename length. */
 	t->current_filesystem->name_max = svfs.f_namemax;
+	if (t->current_filesystem->name_max == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Cannot determine name_max");
+		return (ARCHIVE_FAILED);
+	}
 #endif
 	return (ARCHIVE_OK);
 }
@@ -2004,6 +2023,11 @@ setup_current_filesystem(struct archive_read_disk *a)
 	else
 		t->current_filesystem->name_max = nm;
 #  endif /* _PC_NAME_MAX */
+	if (t->current_filesystem->name_max == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Cannot determine name_max");
+		return (ARCHIVE_FAILED);
+	}
 #endif /* USE_READDIR_R */
 	return (ARCHIVE_OK);
 }
@@ -2554,7 +2578,11 @@ tree_current_lstat(struct tree *t)
 #else
 		if (tree_enter_working_dir(t) != 0)
 			return NULL;
+#ifdef HAVE_LSTAT
 		if (lstat(tree_current_access_path(t), &t->lst) != 0)
+#else
+		if (la_stat(tree_current_access_path(t), &t->lst) != 0)
+#endif
 #endif
 			return NULL;
 		t->flags |= hasLstat;

+ 70 - 2
Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c

@@ -418,9 +418,19 @@ la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
 	    FILE_FLAG_OPEN_REPARSE_POINT;
 	int ret;
 
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileFlags = flag;
+	h = CreateFile2(path, 0,
+	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+	    OPEN_EXISTING, &createExParams);
+#else
 	h = CreateFileW(path, 0,
 	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 	    OPEN_EXISTING, flag, NULL);
+#endif
 	if (h == INVALID_HANDLE_VALUE) {
 		la_dosmaperr(GetLastError());
 		return (-1);
@@ -1067,16 +1077,29 @@ next_entry(struct archive_read_disk *a, struct tree *t,
 	if (archive_entry_filetype(entry) == AE_IFREG &&
 	    archive_entry_size(entry) > 0) {
 		DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 		if (t->async_io)
 			flags |= FILE_FLAG_OVERLAPPED;
 		if (t->direct_io)
 			flags |= FILE_FLAG_NO_BUFFERING;
 		else
 			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		ZeroMemory(&createExParams, sizeof(createExParams));
+		createExParams.dwSize = sizeof(createExParams);
+		createExParams.dwFileFlags = flags;
+		t->entry_fh = CreateFile2(tree_current_access_path(t),
+		    GENERIC_READ,
+		    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+		    OPEN_EXISTING, &createExParams);
+#else
 		t->entry_fh = CreateFileW(tree_current_access_path(t),
 		    GENERIC_READ,
 		    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
 		    NULL, OPEN_EXISTING, flags, NULL);
+#endif
 		if (t->entry_fh == INVALID_HANDLE_VALUE) {
 			la_dosmaperr(GetLastError());
 			archive_set_error(&a->archive, errno,
@@ -1547,6 +1570,9 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
 {
 	HANDLE handle;
 	int r = 0;
+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 	if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
 		return (0);
@@ -1560,8 +1586,16 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
 	if ((t->flags & needsRestoreTimes) == 0)
 		return (r);
 
+#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+	handle = CreateFile2(rt->full_path, FILE_WRITE_ATTRIBUTES,
+		    0, OPEN_EXISTING, &createExParams);
+#else
 	handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
 		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+#endif
 	if (handle == INVALID_HANDLE_VALUE) {
 		errno = EINVAL;
 		return (-1);
@@ -2046,12 +2080,24 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
 	HANDLE h;
 	int r;
 	DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
-	
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
+
 	if (sim_lstat && tree_current_is_physical_link(t))
 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileFlags = flag;
+	h = CreateFile2(tree_current_access_path(t), 0,
+	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+	    OPEN_EXISTING, &createExParams);
+#else
 	h = CreateFileW(tree_current_access_path(t), 0,
 	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 	    OPEN_EXISTING, flag, NULL);
+#endif
 	if (h == INVALID_HANDLE_VALUE) {
 		la_dosmaperr(GetLastError());
 		t->tree_errno = errno;
@@ -2257,7 +2303,10 @@ archive_read_disk_entry_from_file(struct archive *_a,
 		} else {
 			WIN32_FIND_DATAW findData;
 			DWORD flag, desiredAccess;
-	
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
+
 			h = FindFirstFileW(path, &findData);
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
@@ -2279,9 +2328,18 @@ archive_read_disk_entry_from_file(struct archive *_a,
 			} else
 				desiredAccess = GENERIC_READ;
 
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileFlags = flag;
+			h = CreateFile2(path, desiredAccess,
+			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+			    OPEN_EXISTING, &createExParams);
+#else
 			h = CreateFileW(path, desiredAccess,
 			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 			    OPEN_EXISTING, flag, NULL);
+#endif
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
 				archive_set_error(&a->archive, errno,
@@ -2342,9 +2400,19 @@ archive_read_disk_entry_from_file(struct archive *_a,
 		if (fd >= 0) {
 			h = (HANDLE)_get_osfhandle(fd);
 		} else {
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+			h = CreateFile2(path, GENERIC_READ,
+			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+			    OPEN_EXISTING, &createExParams);
+#else
 			h = CreateFileW(path, GENERIC_READ,
 			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+#endif
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
 				archive_set_error(&a->archive, errno,

+ 2 - 2
Utilities/cmlibarchive/libarchive/archive_read_open_file.c

@@ -154,10 +154,10 @@ file_skip(struct archive *a, void *client_data, int64_t request)
 #ifdef __ANDROID__
         /* fileno() isn't safe on all platforms ... see above. */
 	if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
-#elif HAVE_FSEEKO
-	if (fseeko(mine->f, skip, SEEK_CUR) != 0)
 #elif HAVE__FSEEKI64
 	if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
+#elif HAVE_FSEEKO
+	if (fseeko(mine->f, skip, SEEK_CUR) != 0)
 #else
 	if (fseek(mine->f, skip, SEEK_CUR) != 0)
 #endif

+ 21 - 0
Utilities/cmlibarchive/libarchive/archive_read_set_options.3

@@ -255,6 +255,27 @@ have been concatenated together.
 Without this option, only the contents of
 the first concatenated archive would be read.
 .El
+.It Format zip
+.Bl -tag -compact -width indent
+.It Cm compat-2x
+Libarchive 2.x incorrectly encoded Unicode filenames on
+some platforms.
+This option mimics the libarchive 2.x filename handling
+so that such archives can be read correctly.
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file names.
+.It Cm ignorecrc32
+Skip the CRC32 check.
+Mostly used for testing.
+.It Cm mac-ext
+Support Mac OS metadata extension that records data in special
+files beginning with a period and underscore.
+Defaults to enabled on Mac OS, disabled on other platforms.
+Use
+.Cm !mac-ext
+to disable.
+.El
 .El
 .\"
 .Sh ERRORS

+ 2 - 2
Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c

@@ -230,7 +230,7 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p)
 
 	/* Empty our output buffer. */
 	state->stream.next_out = state->out_block;
-	state->stream.avail_out = state->out_block_size;
+	state->stream.avail_out = (uint32_t)state->out_block_size;
 
 	/* Try to fill the output buffer. */
 	for (;;) {
@@ -288,7 +288,7 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p)
 			return (ARCHIVE_FATAL);
 		}
 		state->stream.next_in = (char *)(uintptr_t)read_buf;
-		state->stream.avail_in = ret;
+		state->stream.avail_in = (uint32_t)ret;
 		/* There is no more data, return whatever we have. */
 		if (ret == 0) {
 			state->eof = 1;

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c

@@ -584,7 +584,7 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
 		    state->out_block + prefix64k, (int)compressed_size,
 		    state->flags.block_maximum_size,
 		    state->out_block,
-		    prefix64k);
+		    (int)prefix64k);
 #else
 		uncompressed_size = LZ4_decompress_safe_withPrefix64k(
 		    read_buf + 4,

+ 49 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c

@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #include "archive.h"
+#include "archive_entry.h"
 #include "archive_private.h"
 #include "archive_read_private.h"
 
@@ -61,12 +62,17 @@ struct uudecode {
 #define ST_UUEND	2
 #define ST_READ_BASE64	3
 #define ST_IGNORE	4
+	mode_t		mode;
+	int		mode_set;
+	char		*name;
 };
 
 static int	uudecode_bidder_bid(struct archive_read_filter_bidder *,
 		    struct archive_read_filter *filter);
 static int	uudecode_bidder_init(struct archive_read_filter *);
 
+static int	uudecode_read_header(struct archive_read_filter *,
+		    struct archive_entry *entry);
 static ssize_t	uudecode_filter_read(struct archive_read_filter *,
 		    const void **);
 static int	uudecode_filter_close(struct archive_read_filter *);
@@ -359,6 +365,7 @@ static const struct archive_read_filter_vtable
 uudecode_reader_vtable = {
 	.read = uudecode_filter_read,
 	.close = uudecode_filter_close,
+	.read_header = uudecode_read_header
 };
 
 static int
@@ -389,6 +396,8 @@ uudecode_bidder_init(struct archive_read_filter *self)
 	uudecode->in_allocated = IN_BUFF_SIZE;
 	uudecode->out_buff = out_buff;
 	uudecode->state = ST_FIND_HEAD;
+	uudecode->mode_set = 0;
+	uudecode->name = NULL;
 	self->vtable = &uudecode_reader_vtable;
 
 	return (ARCHIVE_OK);
@@ -434,6 +443,22 @@ ensure_in_buff_size(struct archive_read_filter *self,
 	return (ARCHIVE_OK);
 }
 
+static int
+uudecode_read_header(struct archive_read_filter *self, struct archive_entry *entry)
+{
+
+	struct uudecode *uudecode;
+	uudecode = (struct uudecode *)self->data;
+
+	if (uudecode->mode_set != 0)
+		archive_entry_set_mode(entry, S_IFREG | uudecode->mode);
+
+	if (uudecode->name != NULL)
+		archive_entry_set_pathname(entry, uudecode->name);
+
+	return (ARCHIVE_OK);
+}
+
 static ssize_t
 uudecode_filter_read(struct archive_read_filter *self, const void **buff)
 {
@@ -443,7 +468,7 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
 	ssize_t avail_in, ravail;
 	ssize_t used;
 	ssize_t total;
-	ssize_t len, llen, nl;
+	ssize_t len, llen, nl, namelen;
 
 	uudecode = (struct uudecode *)self->data;
 
@@ -551,6 +576,28 @@ read_more:
 					uudecode->state = ST_READ_UU;
 				else
 					uudecode->state = ST_READ_BASE64;
+				uudecode->mode = (mode_t)(
+				    ((int)(b[l] - '0') * 64) +
+				    ((int)(b[l+1] - '0') * 8) +
+				     (int)(b[l+2] - '0'));
+				uudecode->mode_set = 1;
+				namelen = len - nl - 4 - l;
+				if (namelen > 1) {
+					if (uudecode->name != NULL)
+						free(uudecode->name);
+					uudecode->name = malloc(namelen + 1);
+			                if (uudecode->name == NULL) {
+					archive_set_error(
+					    &self->archive->archive,
+					    ENOMEM,
+					    "Can't allocate data for uudecode");
+						return (ARCHIVE_FATAL);
+					}
+					strncpy(uudecode->name,
+					    (const char *)(b + l + 4),
+					    namelen);
+					uudecode->name[namelen] = '\0';
+				}
 			}
 			break;
 		case ST_READ_UU:
@@ -683,6 +730,7 @@ uudecode_filter_close(struct archive_read_filter *self)
 	uudecode = (struct uudecode *)self->data;
 	free(uudecode->in_buff);
 	free(uudecode->out_buff);
+	free(uudecode->name);
 	free(uudecode);
 
 	return (ARCHIVE_OK);

+ 7 - 7
Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c

@@ -115,9 +115,9 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
 	unsigned prefix;
 
 	/* Zstd frame magic values */
-	const unsigned zstd_magic = 0xFD2FB528U;
-	const unsigned zstd_magic_skippable_start = 0x184D2A50U;
-	const unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
+	unsigned zstd_magic = 0xFD2FB528U;
+	unsigned zstd_magic_skippable_start = 0x184D2A50U;
+	unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
 
 	(void) self; /* UNUSED */
 
@@ -170,7 +170,7 @@ static int
 zstd_bidder_init(struct archive_read_filter *self)
 {
 	struct private_data *state;
-	const size_t out_block_size = ZSTD_DStreamOutSize();
+	size_t out_block_size = ZSTD_DStreamOutSize();
 	void *out_block;
 	ZSTD_DStream *dstream;
 
@@ -211,6 +211,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
 	ssize_t avail_in;
 	ZSTD_outBuffer out;
 	ZSTD_inBuffer in;
+	size_t ret;
 
 	state = (struct private_data *)self->data;
 
@@ -219,7 +220,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
 	/* Try to fill the output buffer. */
 	while (out.pos < out.size && !state->eof) {
 		if (!state->in_frame) {
-			const size_t ret = ZSTD_initDStream(state->dstream);
+			ret = ZSTD_initDStream(state->dstream);
 			if (ZSTD_isError(ret)) {
 				archive_set_error(&self->archive->archive,
 				    ARCHIVE_ERRNO_MISC,
@@ -249,8 +250,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
 		in.pos = 0;
 
 		{
-			const size_t ret =
-			    ZSTD_decompressStream(state->dstream, &out, &in);
+			ret = ZSTD_decompressStream(state->dstream, &out, &in);
 
 			if (ZSTD_isError(ret)) {
 				archive_set_error(&self->archive->archive,

+ 266 - 14
Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c

@@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$");
 #ifdef HAVE_ZLIB_H
 #include <cm3p/zlib.h>
 #endif
+#ifdef HAVE_ZSTD_H
+#include <cm3p/zstd.h>
+#endif
 
 #ifdef __clang_analyzer__
 #include <assert.h>
@@ -84,8 +87,11 @@ __FBSDID("$FreeBSD$");
 #define _7Z_IA64	0x03030401
 #define _7Z_ARM		0x03030501
 #define _7Z_ARMTHUMB	0x03030701
+#define _7Z_ARM64	0xa
 #define _7Z_SPARC	0x03030805
 
+#define _7Z_ZSTD	0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */
+
 /*
  * 7-Zip header property IDs.
  */
@@ -114,6 +120,30 @@ __FBSDID("$FreeBSD$");
 #define kEncodedHeader		0x17
 #define kDummy			0x19
 
+// Check that some windows file attribute constants are defined.
+// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
+#ifndef FILE_ATTRIBUTE_READONLY
+#define FILE_ATTRIBUTE_READONLY 0x00000001
+#endif
+
+#ifndef FILE_ATTRIBUTE_HIDDEN
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002
+#endif
+
+#ifndef FILE_ATTRIBUTE_SYSTEM
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004
+#endif
+
+#ifndef FILE_ATTRIBUTE_DIRECTORY
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#endif
+
+// This value is defined in 7zip with the comment "trick for Unix".
+//
+// 7z archives created on unix have this bit set in the high 16 bits of
+// the attr field along with the unix permissions.
+#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
+
 struct _7z_digests {
 	unsigned char	*defineds;
 	uint32_t	*digests;
@@ -281,6 +311,11 @@ struct _7zip {
 #ifdef HAVE_ZLIB_H
 	z_stream		 stream;
 	int			 stream_valid;
+#endif
+	/* Decoding Zstandard data. */
+#if HAVE_ZSTD_H
+	ZSTD_DStream		 *zstd_dstream;
+	int		         zstdstream_valid;
 #endif
 	/* Decoding PPMd data. */
 	int			 ppmd7_stat;
@@ -401,6 +436,9 @@ static int	setup_decode_folder(struct archive_read *, struct _7z_folder *,
 		    int);
 static void	x86_Init(struct _7zip *);
 static size_t	x86_Convert(struct _7zip *, uint8_t *, size_t);
+static void	arm_Init(struct _7zip *);
+static size_t	arm_Convert(struct _7zip *, uint8_t *, size_t);
+static size_t	arm64_Convert(struct _7zip *, uint8_t *, size_t);
 static ssize_t		Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
 
 
@@ -729,6 +767,37 @@ archive_read_format_7zip_read_header(struct archive_read *a,
 		archive_entry_set_size(entry, 0);
 	}
 
+	// These attributes are supported by the windows implementation of archive_write_disk.
+	const int supported_attrs = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
+
+	if (zip_entry->attr & supported_attrs) {
+		char *fflags_text, *ptr;
+		/* allocate for "rdonly,hidden,system," */
+		fflags_text = malloc(22 * sizeof(char));
+		if (fflags_text != NULL) {
+			ptr = fflags_text; 
+			if (zip_entry->attr & FILE_ATTRIBUTE_READONLY) { 
+ 			strcpy(ptr, "rdonly,"); 
+ 			ptr = ptr + 7; 
+ 		} 
+ 		if (zip_entry->attr & FILE_ATTRIBUTE_HIDDEN) { 
+ 			strcpy(ptr, "hidden,"); 
+ 			ptr = ptr + 7; 
+ 		} 
+ 		if (zip_entry->attr & FILE_ATTRIBUTE_SYSTEM) { 
+ 			strcpy(ptr, "system,"); 
+ 			ptr = ptr + 7; 
+ 		} 
+ 		if (ptr > fflags_text) { 
+ 			/* Delete trailing comma */ 
+ 			*(ptr - 1) = '\0'; 
+ 			archive_entry_copy_fflags_text(entry, 
+				fflags_text); 
+ 		} 
+ 		free(fflags_text); 
+		}
+	}
+
 	/* If there's no body, force read_data() to return EOF immediately. */
 	if (zip->entry_bytes_remaining < 1)
 		zip->end_of_entry = 1;
@@ -1034,10 +1103,13 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 	case _7Z_COPY:
 	case _7Z_BZ2:
 	case _7Z_DEFLATE:
+	case _7Z_ZSTD:
 	case _7Z_PPMD:
 		if (coder2 != NULL) {
 			if (coder2->codec != _7Z_X86 &&
-			    coder2->codec != _7Z_X86_BCJ2) {
+			    coder2->codec != _7Z_X86_BCJ2 &&
+			    coder2->codec != _7Z_ARM &&
+			    coder2->codec != _7Z_ARM64) {
 				archive_set_error(&a->archive,
 				    ARCHIVE_ERRNO_MISC,
 				    "Unsupported filter %lx for %lx",
@@ -1048,6 +1120,8 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 			zip->bcj_state = 0;
 			if (coder2->codec == _7Z_X86)
 				x86_Init(zip);
+			else if (coder2->codec == _7Z_ARM)
+				arm_Init(zip);
 		}
 		break;
 	default:
@@ -1144,6 +1218,12 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 				filters[fi].id = LZMA_FILTER_ARMTHUMB;
 				fi++;
 				break;
+#ifdef LZMA_FILTER_ARM64
+			case _7Z_ARM64:
+				filters[fi].id = LZMA_FILTER_ARM64;
+				fi++;
+				break;
+#endif
 			case _7Z_SPARC:
 				filters[fi].id = LZMA_FILTER_SPARC;
 				fi++;
@@ -1229,6 +1309,22 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 		    "BZ2 codec is unsupported");
 		return (ARCHIVE_FAILED);
 #endif
+	case _7Z_ZSTD:
+	{
+#if defined(HAVE_ZSTD_H)
+		if (zip->zstdstream_valid) {
+			ZSTD_freeDStream(zip->zstd_dstream);
+			zip->zstdstream_valid = 0;
+		}
+		zip->zstd_dstream = ZSTD_createDStream();
+		zip->zstdstream_valid = 1;
+		break;
+#else
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			"ZSTD codec is unsupported");
+		return (ARCHIVE_FAILED);
+#endif
+	}
 	case _7Z_DEFLATE:
 #ifdef HAVE_ZLIB_H
 		if (zip->stream_valid)
@@ -1299,6 +1395,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 	case _7Z_IA64:
 	case _7Z_ARM:
 	case _7Z_ARMTHUMB:
+	case _7Z_ARM64:
 	case _7Z_SPARC:
 	case _7Z_DELTA:
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1443,9 +1540,9 @@ decompress(struct archive_read *a, struct _7zip *zip,
 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
 	case _7Z_BZ2:
 		zip->bzstream.next_in = (char *)(uintptr_t)t_next_in;
-		zip->bzstream.avail_in = t_avail_in;
+		zip->bzstream.avail_in = (uint32_t)t_avail_in;
 		zip->bzstream.next_out = (char *)(uintptr_t)t_next_out;
-		zip->bzstream.avail_out = t_avail_out;
+		zip->bzstream.avail_out = (uint32_t)t_avail_out;
 		r = BZ2_bzDecompress(&(zip->bzstream));
 		switch (r) {
 		case BZ_STREAM_END: /* Found end of stream. */
@@ -1494,6 +1591,22 @@ decompress(struct archive_read *a, struct _7zip *zip,
 		t_avail_in = zip->stream.avail_in;
 		t_avail_out = zip->stream.avail_out;
 		break;
+#endif
+#ifdef HAVE_ZSTD_H
+	case _7Z_ZSTD:
+	{
+		ZSTD_inBuffer input = { t_next_in, t_avail_in, 0 }; // src, size, pos
+		ZSTD_outBuffer output = { t_next_out, t_avail_out, 0 }; // dst, size, pos
+
+		size_t const zret = ZSTD_decompressStream(zip->zstd_dstream, &output, &input);
+		if (ZSTD_isError(zret)) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Zstd decompression failed: %s", ZSTD_getErrorName(zret));
+			return ARCHIVE_FAILED;
+		}
+		t_avail_in -= input.pos;
+		t_avail_out -= output.pos;
+		break;
+	}
 #endif
 	case _7Z_PPMD:
 	{
@@ -1579,16 +1692,23 @@ decompress(struct archive_read *a, struct _7zip *zip,
 	/*
 	 * Decord BCJ.
 	 */
-	if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
-		size_t l = x86_Convert(zip, buff, *outbytes);
-		zip->odd_bcj_size = *outbytes - l;
-		if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
-		    o_avail_in && ret != ARCHIVE_EOF) {
-			memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
-			    zip->odd_bcj_size);
-			*outbytes = l;
-		} else
-			zip->odd_bcj_size = 0;
+	if (zip->codec != _7Z_LZMA2) {
+		if (zip->codec2 == _7Z_X86) {
+			size_t l = x86_Convert(zip, buff, *outbytes);
+
+			zip->odd_bcj_size = *outbytes - l;
+			if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
+		    	o_avail_in && ret != ARCHIVE_EOF) {
+				memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
+			    	zip->odd_bcj_size);
+				*outbytes = l;
+			} else
+				zip->odd_bcj_size = 0;
+		} else if (zip->codec2 == _7Z_ARM) {
+			*outbytes = arm_Convert(zip, buff, *outbytes);
+		} else if (zip->codec2 == _7Z_ARM64) {
+			*outbytes = arm64_Convert(zip, buff, *outbytes);
+		}
 	}
 
 	/*
@@ -2612,6 +2732,28 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
 			entries[i].flg |= HAS_STREAM;
 		/* The high 16 bits of attributes is a posix file mode. */
 		entries[i].mode = entries[i].attr >> 16;
+
+		if (!(entries[i].attr & FILE_ATTRIBUTE_UNIX_EXTENSION)) {
+			// Only windows permissions specified for this entry. Translate to
+			// reasonable corresponding unix permissions.
+
+			if (entries[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
+				if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
+					// Read-only directory.
+					entries[i].mode = AE_IFDIR | 0555;
+				} else {
+					// Read-write directory.
+					entries[i].mode = AE_IFDIR | 0755;
+				}
+			} else if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
+				// Readonly file.
+				entries[i].mode = AE_IFREG | 0444;
+			} else {
+				// Assume read-write file.
+				entries[i].mode = AE_IFREG | 0644;
+			}
+		}
+
 		if (entries[i].flg & HAS_STREAM) {
 			if ((size_t)sindex >= si->ss.unpack_streams)
 				return (-1);
@@ -2652,7 +2794,7 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
 			}
 			entries[i].ssIndex = -1;
 		}
-		if (entries[i].attr & 0x01)
+		if (entries[i].attr & FILE_ATTRIBUTE_READONLY)
 			entries[i].mode &= ~0222;/* Read only. */
 
 		if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) {
@@ -3737,6 +3879,116 @@ x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
 	return (bufferPos);
 }
 
+static void
+arm_Init(struct _7zip *zip)
+{
+	zip->bcj_ip = 8;
+}
+
+static size_t
+arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
+{
+	// This function was adapted from
+	// static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+	// in https://git.tukaani.org/xz-embedded.git
+
+	/*
+	 * Branch/Call/Jump (BCJ) filter decoders
+	 *
+	 * Authors: Lasse Collin <[email protected]>
+	 *          Igor Pavlov <https://7-zip.org/>
+	 *
+	 * This file has been put into the public domain.
+	 * You can do whatever you want with this file.
+	 */
+
+	size_t i;
+	uint32_t addr;
+
+	for (i = 0; i + 4 <= size; i += 4) {
+		if (buf[i + 3] == 0xEB) {
+			// Calculate the transformed addr.
+			addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
+				| ((uint32_t)buf[i + 2] << 16);
+			addr <<= 2;
+			addr -= zip->bcj_ip + (uint32_t)i;
+			addr >>= 2;
+
+			// Store the transformed addr in buf.
+			buf[i] = (uint8_t)addr;
+			buf[i + 1] = (uint8_t)(addr >> 8);
+			buf[i + 2] = (uint8_t)(addr >> 16);
+		}
+	}
+
+	zip->bcj_ip += (uint32_t)i;
+
+	return i;
+}
+
+static size_t
+arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
+{
+	// This function was adapted from
+	// static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+	// in https://git.tukaani.org/xz-embedded.git
+
+	/*
+	 * Branch/Call/Jump (BCJ) filter decoders
+	 *
+	 * Authors: Lasse Collin <[email protected]>
+	 *          Igor Pavlov <https://7-zip.org/>
+	 *
+	 * This file has been put into the public domain.
+	 * You can do whatever you want with this file.
+	 */
+
+	size_t i;
+	uint32_t instr;
+	uint32_t addr;
+
+	for (i = 0; i + 4 <= size; i += 4) {
+		instr = (uint32_t)buf[i]
+			| ((uint32_t)buf[i+1] << 8)
+			| ((uint32_t)buf[i+2] << 16)
+			| ((uint32_t)buf[i+3] << 24);
+
+		if ((instr >> 26) == 0x25) {
+			/* BL instruction */
+			addr = instr - ((zip->bcj_ip + (uint32_t)i) >> 2);
+			instr = 0x94000000 | (addr & 0x03FFFFFF);
+
+			buf[i]   = (uint8_t)instr;
+			buf[i+1] = (uint8_t)(instr >> 8);
+			buf[i+2] = (uint8_t)(instr >> 16);
+			buf[i+3] = (uint8_t)(instr >> 24);
+		} else if ((instr & 0x9F000000) == 0x90000000) {
+			/* ADRP instruction */
+			addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
+
+			/* Only convert values in the range +/-512 MiB. */
+			if ((addr + 0x020000) & 0x1C0000)
+				continue;
+
+			addr -= (zip->bcj_ip + (uint32_t)i) >> 12;
+
+			instr &= 0x9000001F;
+			instr |= (addr & 3) << 29;
+			instr |= (addr & 0x03FFFC) << 3;
+			instr |= (0U - (addr & 0x020000)) & 0xE00000;
+
+			buf[i]   = (uint8_t)instr;
+			buf[i+1] = (uint8_t)(instr >> 8);
+			buf[i+2] = (uint8_t)(instr >> 16);
+			buf[i+3] = (uint8_t)(instr >> 24);
+		}
+	}
+
+	zip->bcj_ip += (uint32_t)i;
+
+	return i;
+}
+
 /*
  * Brought from LZMA SDK.
  *

+ 4 - 4
Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c

@@ -2294,10 +2294,10 @@ lzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br)
 		 		   (br->cache_buffer << 48) |
 				    ((uint64_t)strm->next_in[1]) << 40 |
 				    ((uint64_t)strm->next_in[0]) << 32 |
-				    ((uint32_t)strm->next_in[3]) << 24 |
-				    ((uint32_t)strm->next_in[2]) << 16 |
-				    ((uint32_t)strm->next_in[5]) << 8 |
-				     (uint32_t)strm->next_in[4];
+				    ((uint64_t)strm->next_in[3]) << 24 |
+				    ((uint64_t)strm->next_in[2]) << 16 |
+				    ((uint64_t)strm->next_in[5]) << 8 |
+				     (uint64_t)strm->next_in[4];
 				strm->next_in += 6;
 				strm->avail_in -= 6;
 				br->cache_avail += 6 * 8;

+ 3 - 3
Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c

@@ -441,7 +441,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
 
 	/* Compare name to "TRAILER!!!" to test for end-of-archive. */
 	if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!",
-	    11) == 0) {
+	    10) == 0) {
 		/* TODO: Store file location of start of block. */
 		archive_clear_error(&a->archive);
 		return (ARCHIVE_EOF);
@@ -985,14 +985,14 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
 static int64_t
 le4(const unsigned char *p)
 {
-	return ((p[0] << 16) + (((int64_t)p[1]) << 24) + (p[2] << 0) + (p[3] << 8));
+	return ((p[0] << 16) | (((int64_t)p[1]) << 24) | (p[2] << 0) | (p[3] << 8));
 }
 
 
 static int64_t
 be4(const unsigned char *p)
 {
-	return ((((int64_t)p[0]) << 24) + (p[1] << 16) + (p[2] << 8) + (p[3]));
+	return ((((int64_t)p[0]) << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
 }
 
 /*

+ 6 - 6
Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c

@@ -1901,7 +1901,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
 	 * NUMBER of RRIP "PX" extension.
 	 * Note: Old mkisofs did not record that FILE SERIAL NUMBER
 	 * in ISO images.
-	 * Note2: xorriso set 0 to the location of a symlink file. 
+	 * Note2: xorriso set 0 to the location of a symlink file.
 	 */
 	if (file->size == 0 && location >= 0) {
 		/* If file->size is zero, its location points wrong place,
@@ -1955,7 +1955,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
 			 * made by makefs is not zero and its location is
 			 * the same as those of next regular file. That is
 			 * the same as hard like file and it causes unexpected
-			 * error. 
+			 * error.
 			 */
 			if (file->size > 0 &&
 			    (file->mode & AE_IFMT) == AE_IFLNK) {
@@ -2747,7 +2747,7 @@ next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
 			 * If directory entries all which are descendant of
 			 * rr_moved are still remaining, expose their.
 			 */
-			if (iso9660->re_files.first != NULL && 
+			if (iso9660->re_files.first != NULL &&
 			    iso9660->rr_moved != NULL &&
 			    iso9660->rr_moved->rr_moved_has_re_only)
 				/* Expose "rr_moved" entry. */
@@ -3182,11 +3182,11 @@ isodate17(const unsigned char *v)
 static time_t
 time_from_tm(struct tm *t)
 {
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+        return _mkgmtime(t);
+#elif HAVE_TIMEGM
         /* Use platform timegm() if available. */
         return (timegm(t));
-#elif HAVE__MKGMTIME64
-        return (_mkgmtime64(t));
 #else
         /* Else use direct calculation using POSIX assumptions. */
         /* First, fix up tm_yday based on the year/month/day. */

+ 10 - 10
Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c

@@ -1819,7 +1819,7 @@ lha_crc16(uint16_t crc, const void *pp, size_t len)
 		 * remove the statement which will not be executed. */
 #undef bswap16
 #ifndef __has_builtin
-#  define __has_builtin(x) 0
+#define __has_builtin(x) 0
 #endif
 #if defined(_MSC_VER) && _MSC_VER >= 1400  /* Visual Studio */
 #  define bswap16(x) _byteswap_ushort(x)
@@ -1827,7 +1827,7 @@ lha_crc16(uint16_t crc, const void *pp, size_t len)
 /* GCC 4.8 and later has __builtin_bswap16() */
 #  define bswap16(x) __builtin_bswap16(x)
 #elif defined(__clang__) && __has_builtin(__builtin_bswap16)
-/* All clang versions have __builtin_bswap16() */
+/* Newer clang versions have __builtin_bswap16() */
 #  define bswap16(x) __builtin_bswap16(x)
 #else
 #  define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8))
@@ -2012,10 +2012,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
 				    ((uint64_t)strm->next_in[0]) << 48 |
 				    ((uint64_t)strm->next_in[1]) << 40 |
 				    ((uint64_t)strm->next_in[2]) << 32 |
-				    ((uint32_t)strm->next_in[3]) << 24 |
-				    ((uint32_t)strm->next_in[4]) << 16 |
-				    ((uint32_t)strm->next_in[5]) << 8 |
-				     (uint32_t)strm->next_in[6];
+				    ((uint64_t)strm->next_in[3]) << 24 |
+				    ((uint64_t)strm->next_in[4]) << 16 |
+				    ((uint64_t)strm->next_in[5]) << 8 |
+				     (uint64_t)strm->next_in[6];
 				strm->next_in += 7;
 				strm->avail_in -= 7;
 				br->cache_avail += 7 * 8;
@@ -2025,10 +2025,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
 		 		   (br->cache_buffer << 48) |
 				    ((uint64_t)strm->next_in[0]) << 40 |
 				    ((uint64_t)strm->next_in[1]) << 32 |
-				    ((uint32_t)strm->next_in[2]) << 24 |
-				    ((uint32_t)strm->next_in[3]) << 16 |
-				    ((uint32_t)strm->next_in[4]) << 8 |
-				     (uint32_t)strm->next_in[5];
+				    ((uint64_t)strm->next_in[2]) << 24 |
+				    ((uint64_t)strm->next_in[3]) << 16 |
+				    ((uint64_t)strm->next_in[4]) << 8 |
+				     (uint64_t)strm->next_in[5];
 				strm->next_in += 6;
 				strm->avail_in -= 6;
 				br->cache_avail += 6 * 8;

+ 7 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c

@@ -1280,7 +1280,13 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
 				mtree->fd = -1;
 				st = NULL;
 			}
-		} else if (lstat(path, st) == -1) {
+		}
+#ifdef HAVE_LSTAT
+		else if (lstat(path, st) == -1)
+#else
+		else if (la_stat(path, st) == -1)
+#endif
+		{
 			st = NULL;
 		}
 

+ 6 - 15
Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c

@@ -1064,7 +1064,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
 		      return (ARCHIVE_FATAL);
 	      }
 	      p = h;
-	      crc32_val = crc32(crc32_val, (const unsigned char *)p, to_read);
+	      crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned int)to_read);
 	      __archive_read_consume(a, to_read);
 	      skip -= to_read;
       }
@@ -1832,13 +1832,9 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
   struct tm *tm;
   time_t t;
   long nsec;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
   struct tm tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-  errno_t terr;
-  __time64_t tmptime;
-#endif
 
   if (p + 2 > endp)
     return (-1);
@@ -1870,15 +1866,10 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
         rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
         p++;
       }
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+      tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
       tm = localtime_r(&t, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-      tmptime = t;
-      terr = _localtime64_s(&tmbuf, &tmptime);
-      if (terr)
-        tm = NULL;
-      else
-        tm = &tmbuf;
 #else
       tm = localtime(&t);
 #endif
@@ -3451,7 +3442,7 @@ compile_program(const uint8_t *bytes, size_t length)
   prog = calloc(1, sizeof(*prog));
   if (!prog)
     return NULL;
-  prog->fingerprint = crc32(0, bytes, length) | ((uint64_t)length << 32);
+  prog->fingerprint = crc32(0, bytes, (unsigned int)length) | ((uint64_t)length << 32);
 
   if (membr_bits(&br, 1))
   {

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c

@@ -2475,7 +2475,7 @@ static void update_crc(struct rar5* rar, const uint8_t* p, size_t to_read) {
 		 * `stored_crc32` info filled in. */
 		if(rar->file.stored_crc32 > 0) {
 			rar->file.calculated_crc32 =
-				crc32(rar->file.calculated_crc32, p, to_read);
+				crc32(rar->file.calculated_crc32, p, (unsigned int)to_read);
 		}
 
 		/* Check if the file uses an optional BLAKE2sp checksum

+ 3 - 3
Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c

@@ -530,11 +530,11 @@ strtoi_lim(const char *str, const char **ep, int llim, int ulim)
 static time_t
 time_from_tm(struct tm *t)
 {
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+        return _mkgmtime(t);
+#elif HAVE_TIMEGM
         /* Use platform timegm() if available. */
         return (timegm(t));
-#elif HAVE__MKGMTIME64
-        return (_mkgmtime64(t));
 #else
         /* Else use direct calculation using POSIX assumptions. */
         /* First, fix up tm_yday based on the year/month/day. */

+ 4 - 4
Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c

@@ -1127,7 +1127,7 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
 			x |= p[1] - '0';
 		else
 			return (-1);
-		
+
 		*b++ = x;
 		bsize--;
 		p += 2;
@@ -1139,11 +1139,11 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
 static time_t
 time_from_tm(struct tm *t)
 {
-#if HAVE_TIMEGM
+#if HAVE__MKGMTIME
+        return _mkgmtime(t);
+#elif HAVE_TIMEGM
         /* Use platform timegm() if available. */
         return (timegm(t));
-#elif HAVE__MKGMTIME64
-        return (_mkgmtime64(t));
 #else
         /* Else use direct calculation using POSIX assumptions. */
         /* First, fix up tm_yday based on the year/month/day. */

+ 3 - 3
Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c

@@ -2186,11 +2186,11 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
 
 	/* Setup buffer boundaries. */
 	zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff;
-	zip->bzstream.avail_in = in_bytes;
+	zip->bzstream.avail_in = (uint32_t)in_bytes;
 	zip->bzstream.total_in_hi32 = 0;
 	zip->bzstream.total_in_lo32 = 0;
 	zip->bzstream.next_out = (char*) zip->uncompressed_buffer;
-	zip->bzstream.avail_out = zip->uncompressed_buffer_size;
+	zip->bzstream.avail_out = (uint32_t)zip->uncompressed_buffer_size;
 	zip->bzstream.total_out_hi32 = 0;
 	zip->bzstream.total_out_lo32 = 0;
 
@@ -2227,7 +2227,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
 	to_consume = zip->bzstream.total_in_lo32;
 	__archive_read_consume(a, to_consume);
 
-	total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) +
+	total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) |
 	    zip->bzstream.total_out_lo32;
 
 	zip->entry_bytes_remaining -= to_consume;

+ 4 - 0
Utilities/cmlibarchive/libarchive/archive_string.c

@@ -1324,6 +1324,10 @@ free_sconv_object(struct archive_string_conv *sc)
 }
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
+# if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#  define GetOEMCP() CP_OEMCP
+# endif
+
 static unsigned
 my_atoi(const char *p)
 {

+ 53 - 4
Utilities/cmlibarchive/libarchive/archive_util.c

@@ -42,9 +42,20 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
-#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* don't use bcrypt when XP needs to be supported */
+#include <bcrypt.h>
+
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
+#elif defined(HAVE_WINCRYPT_H)
 #include <wincrypt.h>
 #endif
+#endif
 #ifdef HAVE_ZLIB_H
 #include <cm3p/zlib.h>
 #endif
@@ -233,14 +244,16 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
 		L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
 		L'u', L'v', L'w', L'x', L'y', L'z'
 	};
-	HCRYPTPROV hProv;
 	struct archive_wstring temp_name;
 	wchar_t *ws;
 	DWORD attr;
 	wchar_t *xp, *ep;
 	int fd;
-
-	hProv = (HCRYPTPROV)NULL;
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	BCRYPT_ALG_HANDLE hAlg = NULL;
+#else
+	HCRYPTPROV hProv = (HCRYPTPROV)NULL;
+#endif
 	fd = -1;
 	ws = NULL;
 
@@ -314,23 +327,42 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
 			abort();
 	}
 
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
+		NULL, 0))) {
+		la_dosmaperr(GetLastError());
+		goto exit_tmpfile;
+	}
+#else
 	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
 		CRYPT_VERIFYCONTEXT)) {
 		la_dosmaperr(GetLastError());
 		goto exit_tmpfile;
 	}
+#endif
 
 	for (;;) {
 		wchar_t *p;
 		HANDLE h;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 		/* Generate a random file name through CryptGenRandom(). */
 		p = xp;
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+		if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
+		    (DWORD)(ep - p)*sizeof(wchar_t), 0))) {
+			la_dosmaperr(GetLastError());
+			goto exit_tmpfile;
+		}
+#else
 		if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
 		    (BYTE*)p)) {
 			la_dosmaperr(GetLastError());
 			goto exit_tmpfile;
 		}
+#endif
 		for (; p < ep; p++)
 			*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
 
@@ -347,6 +379,17 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
 			/* mkstemp */
 			attr = FILE_ATTRIBUTE_NORMAL;
 		}
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		ZeroMemory(&createExParams, sizeof(createExParams));
+		createExParams.dwSize = sizeof(createExParams);
+		createExParams.dwFileAttributes = attr & 0xFFFF;
+		createExParams.dwFileFlags = attr & 0xFFF00000;
+		h = CreateFile2(ws,
+		    GENERIC_READ | GENERIC_WRITE | DELETE,
+		    0,/* Not share */
+			CREATE_NEW,
+			&createExParams);
+#else
 		h = CreateFileW(ws,
 		    GENERIC_READ | GENERIC_WRITE | DELETE,
 		    0,/* Not share */
@@ -354,6 +397,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
 		    CREATE_NEW,/* Create a new file only */
 		    attr,
 		    NULL);
+#endif
 		if (h == INVALID_HANDLE_VALUE) {
 			/* The same file already exists. retry with
 			 * a new filename. */
@@ -372,8 +416,13 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
 			break;/* success! */
 	}
 exit_tmpfile:
+#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+	if (hAlg != NULL)
+		BCryptCloseAlgorithmProvider(hAlg, 0);
+#else
 	if (hProv != (HCRYPTPROV)NULL)
 		CryptReleaseContext(hProv, 0);
+#endif
 	free(ws);
 	if (template == temp_name.s)
 		archive_wstring_free(&temp_name);

+ 32 - 3
Utilities/cmlibarchive/libarchive/archive_windows.c

@@ -234,7 +234,11 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
 {
 	wchar_t *wpath;
 	HANDLE handle;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
 	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
 	    hTemplateFile);
@@ -242,12 +246,25 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
 		return (handle);
 	if (GetLastError() != ERROR_PATH_NOT_FOUND)
 		return (handle);
+#endif
 	wpath = __la_win_permissive_name(path);
 	if (wpath == NULL)
-		return (handle);
+		return INVALID_HANDLE_VALUE;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
+	createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000;
+	createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000;
+	createExParams.lpSecurityAttributes = lpSecurityAttributes;
+	createExParams.hTemplateFile = hTemplateFile;
+	handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode,
+	    dwCreationDisposition, &createExParams);
+#else /* !WINAPI_PARTITION_DESKTOP */
 	handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
 	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
 	    hTemplateFile);
+#endif /* !WINAPI_PARTITION_DESKTOP */
 	free(wpath);
 	return (handle);
 }
@@ -305,7 +322,10 @@ __la_open(const char *path, int flags, ...)
 		 * "Permission denied" error.
 		 */
 		attr = GetFileAttributesA(path);
-		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND)
+#endif
+		{
 			ws = __la_win_permissive_name(path);
 			if (ws == NULL) {
 				errno = EINVAL;
@@ -320,7 +340,7 @@ __la_open(const char *path, int flags, ...)
 		}
 		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
 			HANDLE handle;
-
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
 			if (ws != NULL)
 				handle = CreateFileW(ws, 0, 0, NULL,
 				    OPEN_EXISTING,
@@ -333,6 +353,15 @@ __la_open(const char *path, int flags, ...)
 				    FILE_FLAG_BACKUP_SEMANTICS |
 				    FILE_ATTRIBUTE_READONLY,
 					NULL);
+#else /* !WINAPI_PARTITION_DESKTOP */
+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
+			createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+			handle = CreateFile2(ws, 0, 0,
+				OPEN_EXISTING, &createExParams);
+#endif /* !WINAPI_PARTITION_DESKTOP */
 			free(ws);
 			if (handle == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());

+ 31 - 0
Utilities/cmlibarchive/libarchive/archive_write.c

@@ -310,6 +310,25 @@ __archive_write_output(struct archive_write *a, const void *buff, size_t length)
 	return (__archive_write_filter(a->filter_first, buff, length));
 }
 
+static int
+__archive_write_filters_flush(struct archive_write *a)
+{
+	struct archive_write_filter *f;
+	int ret, ret1;
+
+	ret = ARCHIVE_OK;
+	for (f = a->filter_first; f != NULL; f = f->next_filter) {
+		if (f->flush != NULL && f->bytes_written > 0) {
+			ret1 = (f->flush)(f);
+			if (ret1 < ret)
+				ret = ret1;
+			if (ret1 < ARCHIVE_WARN)
+				f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
+		}
+	}
+	return (ret);
+}
+
 int
 __archive_write_nulls(struct archive_write *a, size_t length)
 {
@@ -740,6 +759,18 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
 		return (ARCHIVE_FAILED);
 	}
 
+	/* Flush filters at boundary. */
+	r2 = __archive_write_filters_flush(a);
+	if (r2 == ARCHIVE_FAILED) {
+		return (ARCHIVE_FAILED);
+	}
+	if (r2 == ARCHIVE_FATAL) {
+		a->archive.state = ARCHIVE_STATE_FATAL;
+		return (ARCHIVE_FATAL);
+	}
+	if (r2 < ret)
+		ret = r2;
+
 	/* Format and write header. */
 	r2 = ((a->format_write_header)(a, entry));
 	if (r2 == ARCHIVE_FAILED) {

+ 3 - 3
Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c

@@ -190,7 +190,7 @@ archive_compressor_bzip2_open(struct archive_write_filter *f)
 
 	memset(&data->stream, 0, sizeof(data->stream));
 	data->stream.next_out = data->compressed;
-	data->stream.avail_out = data->compressed_buffer_size;
+	data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
 	f->write = archive_compressor_bzip2_write;
 
 	/* Initialize compression library */
@@ -244,7 +244,7 @@ archive_compressor_bzip2_write(struct archive_write_filter *f,
 
 	/* Compress input data to output buffer */
 	SET_NEXT_IN(data, buff);
-	data->stream.avail_in = length;
+	data->stream.avail_in = (uint32_t)length;
 	if (drive_compressor(f, data, 0))
 		return (ARCHIVE_FATAL);
 	return (ARCHIVE_OK);
@@ -313,7 +313,7 @@ drive_compressor(struct archive_write_filter *f,
 				return (ARCHIVE_FATAL);
 			}
 			data->stream.next_out = data->compressed;
-			data->stream.avail_out = data->compressed_buffer_size;
+			data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
 		}
 
 		/* If there's nothing to do, we're done. */

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c

@@ -352,7 +352,7 @@ archive_compressor_compress_write(struct archive_write_filter *f,
 	while (length--) {
 		c = *bp++;
 		state->in_count++;
-		state->cur_fcode = (c << 16) + state->cur_code;
+		state->cur_fcode = (c << 16) | state->cur_code;
 		i = ((c << HSHIFT) ^ state->cur_code);	/* Xor hashing. */
 
 		if (state->hashtab[i] == state->cur_fcode) {

+ 4 - 4
Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c

@@ -518,10 +518,10 @@ drive_compressor_independence(struct archive_write_filter *f, const char *p,
 	} else {
 		/* The buffer is not compressed. The compressed size was
 		 * bigger than its uncompressed size. */
-		archive_le32enc(data->out, length | 0x80000000);
+		archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
 		data->out += 4;
 		memcpy(data->out, p, length);
-		outsize = length;
+		outsize = (uint32_t)length;
 	}
 	data->out += outsize;
 	if (data->block_checksum) {
@@ -603,10 +603,10 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p,
 	} else {
 		/* The buffer is not compressed. The compressed size was
 		 * bigger than its uncompressed size. */
-		archive_le32enc(data->out, length | 0x80000000);
+		archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
 		data->out += 4;
 		memcpy(data->out, p, length);
-		outsize = length;
+		outsize = (uint32_t)length;
 	}
 	data->out += outsize;
 	if (data->block_checksum) {

+ 179 - 94
Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c

@@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$");
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -50,10 +53,22 @@ __FBSDID("$FreeBSD$");
 
 struct private_data {
 	int		 compression_level;
-	int      threads;
+	int		 threads;
+	int		 long_distance;
 #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+	enum {
+		running,
+		finishing,
+		resetting,
+	} state;
+	int		 frame_per_file;
+	size_t		 min_frame_size;
+	size_t		 max_frame_size;
+	size_t		 cur_frame;
+	size_t		 cur_frame_in;
+	size_t		 cur_frame_out;
+	size_t		 total_in;
 	ZSTD_CStream	*cstream;
-	int64_t		 total_in;
 	ZSTD_outBuffer	 out;
 #else
 	struct archive_write_program_data *pdata;
@@ -67,14 +82,18 @@ struct private_data {
 #define CLEVEL_STD_MAX 19 /* without using --ultra */
 #define CLEVEL_MAX 22
 
+#define LONG_STD 27
+
 #define MINVER_NEGCLEVEL 10304
 #define MINVER_MINCLEVEL 10306
+#define MINVER_LONG 10302
 
 static int archive_compressor_zstd_options(struct archive_write_filter *,
 		    const char *, const char *);
 static int archive_compressor_zstd_open(struct archive_write_filter *);
 static int archive_compressor_zstd_write(struct archive_write_filter *,
 		    const void *, size_t);
+static int archive_compressor_zstd_flush(struct archive_write_filter *);
 static int archive_compressor_zstd_close(struct archive_write_filter *);
 static int archive_compressor_zstd_free(struct archive_write_filter *);
 #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
@@ -103,13 +122,20 @@ archive_write_add_filter_zstd(struct archive *_a)
 	f->data = data;
 	f->open = &archive_compressor_zstd_open;
 	f->options = &archive_compressor_zstd_options;
+	f->flush = &archive_compressor_zstd_flush;
 	f->close = &archive_compressor_zstd_close;
 	f->free = &archive_compressor_zstd_free;
 	f->code = ARCHIVE_FILTER_ZSTD;
 	f->name = "zstd";
 	data->compression_level = CLEVEL_DEFAULT;
 	data->threads = 0;
+	data->long_distance = 0;
 #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+	data->frame_per_file = 0;
+	data->min_frame_size = 0;
+	data->max_frame_size = SIZE_MAX;
+	data->cur_frame_in = 0;
+	data->cur_frame_out = 0;
 	data->cstream = ZSTD_createCStream();
 	if (data->cstream == NULL) {
 		free(data);
@@ -147,29 +173,18 @@ archive_compressor_zstd_free(struct archive_write_filter *f)
 	return (ARCHIVE_OK);
 }
 
-static int string_is_numeric (const char* value)
+static int string_to_number(const char *string, intmax_t *numberp)
 {
-       size_t len = strlen(value);
-       size_t i;
-
-       if (len == 0) {
-               return (ARCHIVE_WARN);
-       }
-       else if (len == 1 && !(value[0] >= '0' && value[0] <= '9')) {
-               return (ARCHIVE_WARN);
-       }
-       else if (!(value[0] >= '0' && value[0] <= '9') &&
-                value[0] != '-' && value[0] != '+') {
-               return (ARCHIVE_WARN);
-       }
-
-       for (i = 1; i < len; i++) {
-               if (!(value[i] >= '0' && value[i] <= '9')) {
-                       return (ARCHIVE_WARN);
-               }
-       }
-
-       return (ARCHIVE_OK);
+	char *end;
+
+	if (string == NULL || *string == '\0')
+		return (ARCHIVE_WARN);
+	*numberp = strtoimax(string, &end, 10);
+	if (end == string || *end != '\0' || errno == EOVERFLOW) {
+		*numberp = 0;
+		return (ARCHIVE_WARN);
+	}
+	return (ARCHIVE_OK);
 }
 
 /*
@@ -182,13 +197,13 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
 	struct private_data *data = (struct private_data *)f->data;
 
 	if (strcmp(key, "compression-level") == 0) {
-		int level = atoi(value);
+		intmax_t level;
+		if (string_to_number(value, &level) != ARCHIVE_OK) {
+			return (ARCHIVE_WARN);
+		}
 		/* If we don't have the library, hard-code the max level */
 		int minimum = CLEVEL_MIN;
 		int maximum = CLEVEL_MAX;
-		if (string_is_numeric(value) != ARCHIVE_OK) {
-			return (ARCHIVE_WARN);
-		}
 #if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
 		maximum = ZSTD_maxCLevel();
 #if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
@@ -204,21 +219,65 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
 		if (level < minimum || level > maximum) {
 			return (ARCHIVE_WARN);
 		}
-		data->compression_level = level;
+		data->compression_level = (int)level;
 		return (ARCHIVE_OK);
 	} else if (strcmp(key, "threads") == 0) {
-		int threads = atoi(value);
-		if (string_is_numeric(value) != ARCHIVE_OK) {
+		intmax_t threads;
+		if (string_to_number(value, &threads) != ARCHIVE_OK) {
 			return (ARCHIVE_WARN);
 		}
-
-		int minimum = 0;
-
-		if (threads < minimum) {
+		if (threads < 0) {
 			return (ARCHIVE_WARN);
 		}
-
-		data->threads = threads;
+		data->threads = (int)threads;
+		return (ARCHIVE_OK);
+#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
+	} else if (strcmp(key, "frame-per-file") == 0) {
+		data->frame_per_file = 1;
+		return (ARCHIVE_OK);
+	} else if (strcmp(key, "min-frame-size") == 0) {
+		intmax_t min_frame_size;
+		if (string_to_number(value, &min_frame_size) != ARCHIVE_OK) {
+			return (ARCHIVE_WARN);
+		}
+		if (min_frame_size < 0) {
+			return (ARCHIVE_WARN);
+		}
+		data->min_frame_size = min_frame_size;
+		return (ARCHIVE_OK);
+	} else if (strcmp(key, "max-frame-size") == 0) {
+		intmax_t max_frame_size;
+		if (string_to_number(value, &max_frame_size) != ARCHIVE_OK) {
+			return (ARCHIVE_WARN);
+		}
+		if (max_frame_size < 1024) {
+			return (ARCHIVE_WARN);
+		}
+		data->max_frame_size = max_frame_size;
+		return (ARCHIVE_OK);
+#endif
+	}
+	else if (strcmp(key, "long") == 0) {
+		intmax_t long_distance;
+		if (string_to_number(value, &long_distance) != ARCHIVE_OK) {
+			return (ARCHIVE_WARN);
+		}
+#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR && ZSTD_VERSION_NUMBER >= MINVER_LONG
+		ZSTD_bounds bounds = ZSTD_cParam_getBounds(ZSTD_c_windowLog);
+		if (ZSTD_isError(bounds.error)) {
+			int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
+			if (((int)long_distance) < 10 || (int)long_distance > max_distance)
+				return (ARCHIVE_WARN);
+		} else {
+			if ((int)long_distance < bounds.lowerBound || (int)long_distance > bounds.upperBound)
+				return (ARCHIVE_WARN);
+		}
+#else
+		int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
+		if (((int)long_distance) < 10 || (int)long_distance > max_distance)
+		    return (ARCHIVE_WARN);
+#endif
+		data->long_distance = (int)long_distance;
 		return (ARCHIVE_OK);
 	}
 
@@ -270,6 +329,10 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
 
 	ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
 
+#if ZSTD_VERSION_NUMBER >= MINVER_LONG
+	ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance);
+#endif
+
 	return (ARCHIVE_OK);
 }
 
@@ -281,15 +344,22 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
     size_t length)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int ret;
 
-	/* Update statistics */
-	data->total_in += length;
+	return (drive_compressor(f, data, 0, buff, length));
+}
 
-	if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK)
-		return (ret);
+/*
+ * Flush the compressed stream.
+ */
+static int
+archive_compressor_zstd_flush(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
 
-	return (ARCHIVE_OK);
+	if (data->frame_per_file && data->state == running &&
+	    data->cur_frame_out > data->min_frame_size)
+		data->state = finishing;
+	return (drive_compressor(f, data, 1, NULL, 0));
 }
 
 /*
@@ -300,57 +370,72 @@ archive_compressor_zstd_close(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
 
-	/* Finish zstd frame */
-	return drive_compressor(f, data, 1, NULL, 0);
+	if (data->state == running)
+		data->state = finishing;
+	return (drive_compressor(f, data, 1, NULL, 0));
 }
 
 /*
  * Utility function to push input data through compressor,
  * writing full output blocks as necessary.
- *
- * Note that this handles both the regular write case (finishing ==
- * false) and the end-of-archive case (finishing == true).
  */
 static int
 drive_compressor(struct archive_write_filter *f,
-    struct private_data *data, int finishing, const void *src, size_t length)
+    struct private_data *data, int flush, const void *src, size_t length)
 {
-	ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 };
+	ZSTD_inBuffer in = { .src = src, .size = length, .pos = 0 };
+	size_t ipos, opos, zstdret = 0;
+	int ret;
 
 	for (;;) {
-		if (data->out.pos == data->out.size) {
-			const int ret = __archive_write_filter(f->next_filter,
-			    data->out.dst, data->out.size);
+		ipos = in.pos;
+		opos = data->out.pos;
+		switch (data->state) {
+		case running:
+			if (in.pos == in.size)
+				return (ARCHIVE_OK);
+			zstdret = ZSTD_compressStream(data->cstream,
+			    &data->out, &in);
+			if (ZSTD_isError(zstdret))
+				goto zstd_fatal;
+			break;
+		case finishing:
+			zstdret = ZSTD_endStream(data->cstream, &data->out);
+			if (ZSTD_isError(zstdret))
+				goto zstd_fatal;
+			if (zstdret == 0)
+				data->state = resetting;
+			break;
+		case resetting:
+			ZSTD_CCtx_reset(data->cstream, ZSTD_reset_session_only);
+			data->cur_frame++;
+			data->cur_frame_in = 0;
+			data->cur_frame_out = 0;
+			data->state = running;
+			break;
+		}
+		data->total_in += in.pos - ipos;
+		data->cur_frame_in += in.pos - ipos;
+		data->cur_frame_out += data->out.pos - opos;
+		if (data->state == running &&
+		    data->cur_frame_in >= data->max_frame_size) {
+			data->state = finishing;
+		}
+		if (data->out.pos == data->out.size ||
+		    (flush && data->out.pos > 0)) {
+			ret = __archive_write_filter(f->next_filter,
+			    data->out.dst, data->out.pos);
 			if (ret != ARCHIVE_OK)
-				return (ARCHIVE_FATAL);
+				goto fatal;
 			data->out.pos = 0;
 		}
-
-		/* If there's nothing to do, we're done. */
-		if (!finishing && in.pos == in.size)
-			return (ARCHIVE_OK);
-
-		{
-			const size_t zstdret = !finishing ?
-			    ZSTD_compressStream(data->cstream, &data->out, &in)
-			    : ZSTD_endStream(data->cstream, &data->out);
-
-			if (ZSTD_isError(zstdret)) {
-				archive_set_error(f->archive,
-				    ARCHIVE_ERRNO_MISC,
-				    "Zstd compression failed: %s",
-				    ZSTD_getErrorName(zstdret));
-				return (ARCHIVE_FATAL);
-			}
-
-			/* If we're finishing, 0 means nothing left to flush */
-			if (finishing && zstdret == 0) {
-				const int ret = __archive_write_filter(f->next_filter,
-				    data->out.dst, data->out.pos);
-				return (ret);
-			}
-		}
 	}
+zstd_fatal:
+	archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+	    "Zstd compression failed: %s",
+	    ZSTD_getErrorName(zstdret));
+fatal:
+	return (ARCHIVE_FATAL);
 }
 
 #else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
@@ -367,17 +452,9 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
 	archive_strcpy(&as, "zstd --no-check");
 
 	if (data->compression_level < CLEVEL_STD_MIN) {
-		struct archive_string as2;
-		archive_string_init(&as2);
-		archive_string_sprintf(&as2, " --fast=%d", -data->compression_level);
-		archive_string_concat(&as, &as2);
-		archive_string_free(&as2);
+		archive_string_sprintf(&as, " --fast=%d", -data->compression_level);
 	} else {
-		struct archive_string as2;
-		archive_string_init(&as2);
-		archive_string_sprintf(&as2, " -%d", data->compression_level);
-		archive_string_concat(&as, &as2);
-		archive_string_free(&as2);
+		archive_string_sprintf(&as, " -%d", data->compression_level);
 	}
 
 	if (data->compression_level > CLEVEL_STD_MAX) {
@@ -385,11 +462,11 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
 	}
 
 	if (data->threads != 0) {
-		struct archive_string as2;
-		archive_string_init(&as2);
-		archive_string_sprintf(&as2, " --threads=%d", data->threads);
-		archive_string_concat(&as, &as2);
-		archive_string_free(&as2);
+		archive_string_sprintf(&as, " --threads=%d", data->threads);
+	}
+
+	if (data->long_distance != 0) {
+		archive_string_sprintf(&as, " --long=%d", data->long_distance);
 	}
 
 	f->write = archive_compressor_zstd_write;
@@ -407,6 +484,14 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
 	return __archive_write_program_write(f, data->pdata, buff, length);
 }
 
+static int
+archive_compressor_zstd_flush(struct archive_write_filter *f)
+{
+	(void)f; /* UNUSED */
+
+	return (ARCHIVE_OK);
+}
+
 static int
 archive_compressor_zstd_close(struct archive_write_filter *f)
 {

+ 60 - 12
Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c

@@ -397,6 +397,7 @@ static int	set_times_from_entry(struct archive_write_disk *);
 static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
 static ssize_t	write_data_block(struct archive_write_disk *,
 		    const char *, size_t);
+static void close_file_descriptor(struct archive_write_disk *);
 
 static int	_archive_write_disk_close(struct archive *);
 static int	_archive_write_disk_free(struct archive *);
@@ -514,7 +515,12 @@ lazy_stat(struct archive_write_disk *a)
 	 * XXX At this point, symlinks should not be hit, otherwise
 	 * XXX a race occurred.  Do we want to check explicitly for that?
 	 */
-	if (lstat(a->name, &a->st) == 0) {
+#ifdef HAVE_LSTAT
+	if (lstat(a->name, &a->st) == 0)
+#else
+	if (la_stat(a->name, &a->st) == 0)
+#endif
+	{
 		a->pst = &a->st;
 		return (ARCHIVE_OK);
 	}
@@ -1605,12 +1611,12 @@ hfs_write_data_block(struct archive_write_disk *a, const char *buff,
 			    "Seek failed");
 			return (ARCHIVE_FATAL);
 		} else if (a->offset > a->fd_offset) {
-			int64_t skip = a->offset - a->fd_offset;
+			uint64_t skip = a->offset - a->fd_offset;
 			char nullblock[1024];
 
 			memset(nullblock, 0, sizeof(nullblock));
 			while (skip > 0) {
-				if (skip > (int64_t)sizeof(nullblock))
+				if (skip > sizeof(nullblock))
 					bytes_written = hfs_write_decmpfs_block(
 					    a, nullblock, sizeof(nullblock));
 				else
@@ -1725,8 +1731,10 @@ _archive_write_disk_finish_entry(struct archive *_a)
 			else
 				r = hfs_write_data_block(
 				    a, null_d, a->file_remaining_bytes);
-			if (r < 0)
+			if (r < 0) {
+				close_file_descriptor(a);
 				return ((int)r);
+			}
 		}
 #endif
 	} else {
@@ -1735,6 +1743,7 @@ _archive_write_disk_finish_entry(struct archive *_a)
 		    a->filesize == 0) {
 			archive_set_error(&a->archive, errno,
 			    "File size could not be restored");
+			close_file_descriptor(a);
 			return (ARCHIVE_FAILED);
 		}
 #endif
@@ -1744,8 +1753,10 @@ _archive_write_disk_finish_entry(struct archive *_a)
 		 * to see what happened.
 		 */
 		a->pst = NULL;
-		if ((ret = lazy_stat(a)) != ARCHIVE_OK)
-			return (ret);
+        if ((ret = lazy_stat(a)) != ARCHIVE_OK) {
+            close_file_descriptor(a);
+            return (ret);
+        }
 		/* We can use lseek()/write() to extend the file if
 		 * ftruncate didn't work or isn't available. */
 		if (a->st.st_size < a->filesize) {
@@ -1753,11 +1764,13 @@ _archive_write_disk_finish_entry(struct archive *_a)
 			if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) {
 				archive_set_error(&a->archive, errno,
 				    "Seek failed");
+				close_file_descriptor(a);
 				return (ARCHIVE_FATAL);
 			}
 			if (write(a->fd, &nul, 1) < 0) {
 				archive_set_error(&a->archive, errno,
 				    "Write to restore size failed");
+				close_file_descriptor(a);
 				return (ARCHIVE_FATAL);
 			}
 			a->pst = NULL;
@@ -2154,7 +2167,11 @@ restore_entry(struct archive_write_disk *a)
 		 * then don't follow it.
 		 */
 		if (r != 0 || !S_ISDIR(a->mode))
+#ifdef HAVE_LSTAT
 			r = lstat(a->name, &a->st);
+#else
+			r = la_stat(a->name, &a->st);
+#endif
 		if (r != 0) {
 			archive_set_error(&a->archive, errno,
 			    "Can't stat existing object");
@@ -2550,7 +2567,12 @@ _archive_write_disk_close(struct archive *_a)
 					goto skip_fixup_entry;
 				} else
 #endif
-				if (lstat(p->name, &st) != 0 ||
+				if (
+#ifdef HAVE_LSTAT
+					lstat(p->name, &st) != 0 ||
+#else
+					la_stat(p->name, &st) != 0 ||
+#endif
 				    la_verify_filetype(st.st_mode,
 				    p->filetype) == 0) {
 					goto skip_fixup_entry;
@@ -2565,7 +2587,12 @@ _archive_write_disk_close(struct archive *_a)
 				goto skip_fixup_entry;
 			} else
 #endif
-			if (lstat(p->name, &st) != 0 ||
+			if (
+#ifdef HAVE_LSTAT
+				lstat(p->name, &st) != 0 ||
+#else
+				la_stat(p->name, &st) != 0 ||
+#endif
 			    la_verify_filetype(st.st_mode,
 			    p->filetype) == 0) {
 				goto skip_fixup_entry;
@@ -2785,8 +2812,8 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT))
 	/* Platform doesn't have lstat, so we can't look for symlinks. */
 	(void)path; /* UNUSED */
-	(void)error_number; /* UNUSED */
-	(void)error_string; /* UNUSED */
+	(void)a_eno; /* UNUSED */
+	(void)a_estr; /* UNUSED */
 	(void)flags; /* UNUSED */
 	(void)checking_linkname; /* UNUSED */
 	return (ARCHIVE_OK);
@@ -2859,8 +2886,10 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
 		/* Check that we haven't hit a symlink. */
 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
 		r = fstatat(chdir_fd, head, &st, AT_SYMLINK_NOFOLLOW);
-#else
+#elif defined(HAVE_LSTAT)
 		r = lstat(head, &st);
+#else
+		r = la_stat(head, &st);
 #endif
 		if (r != 0) {
 			tail[0] = c;
@@ -3558,7 +3587,9 @@ set_time(int fd, int mode, const char *name,
 	(void)fd; /* UNUSED */
 	(void)mode; /* UNUSED */
 	(void)name; /* UNUSED */
+	(void)atime; /* UNUSED */
 	(void)atime_nsec; /* UNUSED */
+	(void)mtime; /* UNUSED */
 	(void)mtime_nsec; /* UNUSED */
 	return (ARCHIVE_WARN);
 #endif
@@ -4391,7 +4422,12 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname)
 	 */
 	archive_strncpy(&datafork, pathname, p - pathname);
 	archive_strcat(&datafork, p + 2);
-	if (lstat(datafork.s, &st) == -1 ||
+	if (
+#ifdef HAVE_LSTAT
+		lstat(datafork.s, &st) == -1 ||
+#else
+		la_stat(datafork.s, &st) == -1 ||
+#endif
 	    (st.st_mode & AE_IFMT) != AE_IFREG)
 		goto skip_appledouble;
 
@@ -4707,5 +4743,17 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
 }
 #endif
 
+/*
+ * Close the file descriptor if one is open.
+ */
+static void close_file_descriptor(struct archive_write_disk* a)
+{
+	if (a->fd >= 0) {
+		close(a->fd);
+		a->fd = -1;
+	}
+}
+
+
 #endif /* !_WIN32 || __CYGWIN__ */
 

+ 74 - 5
Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c

@@ -254,9 +254,9 @@ static ssize_t	_archive_write_disk_data_block(struct archive *, const void *,
  * which is high-16-bits of nFileIndexHigh. */
 #define bhfi_ino(bhfi)	\
 	((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
-    + (bhfi)->nFileIndexLow)
+    | (bhfi)->nFileIndexLow)
 #define bhfi_size(bhfi)	\
-    ((((int64_t)(bhfi)->nFileSizeHigh) << 32) + (bhfi)->nFileSizeLow)
+    ((((int64_t)(bhfi)->nFileSizeHigh) << 32) | (bhfi)->nFileSizeLow)
 
 static int
 file_information(struct archive_write_disk *a, wchar_t *path,
@@ -266,6 +266,9 @@ file_information(struct archive_write_disk *a, wchar_t *path,
 	int r;
 	DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
 	WIN32_FIND_DATAW	findData;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 	if (sim_lstat || mode != NULL) {
 		h = FindFirstFileW(path, &findData);
@@ -290,14 +293,27 @@ file_information(struct archive_write_disk *a, wchar_t *path,
 		(findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
 
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+	ZeroMemory(&createExParams, sizeof(createExParams));
+	createExParams.dwSize = sizeof(createExParams);
+	createExParams.dwFileFlags = flag;
+	h = CreateFile2(a->name, 0, 0,
+		OPEN_EXISTING, &createExParams);
+#else
 	h = CreateFileW(a->name, 0, 0, NULL,
 	    OPEN_EXISTING, flag, NULL);
+#endif
 	if (h == INVALID_HANDLE_VALUE &&
 	    GetLastError() == ERROR_INVALID_NAME) {
 		wchar_t *full;
 		full = __la_win_permissive_name_w(path);
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		h = CreateFile2(full, 0, 0,
+			OPEN_EXISTING, &createExParams);
+#else
 		h = CreateFileW(full, 0, 0, NULL,
 		    OPEN_EXISTING, flag, NULL);
+#endif
 		free(full);
 	}
 	if (h == INVALID_HANDLE_VALUE) {
@@ -559,6 +575,7 @@ la_mktemp(struct archive_write_disk *a)
 	return (fd);
 }
 
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
 static void *
 la_GetFunctionKernel32(const char *name)
 {
@@ -574,18 +591,24 @@ la_GetFunctionKernel32(const char *name)
 	}
 	return (void *)GetProcAddress(lib, name);
 }
+#endif
 
 static int
 la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
 {
-	static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
-	static int set;
+	static BOOL (WINAPI *f)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
 	BOOL ret;
 
+#if _WIN32_WINNT < _WIN32_WINNT_XP
+	static int set;
+/* CreateHardLinkW is available since XP and always loaded */
 	if (!set) {
 		set = 1;
 		f = la_GetFunctionKernel32("CreateHardLinkW");
 	}
+#else
+	f = CreateHardLinkW;
+#endif
 	if (!f) {
 		errno = ENOTSUP;
 		return (0);
@@ -624,7 +647,6 @@ static int
 la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
     int linktype) {
 	static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD);
-	static int set;
 	wchar_t *ttarget, *p;
 	size_t len;
 	DWORD attrs = 0;
@@ -632,10 +654,20 @@ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
 	DWORD newflags = 0;
 	BOOL ret = 0;
 
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
+/* CreateSymbolicLinkW is available since Vista and always loaded */
+	static int set;
 	if (!set) {
 		set = 1;
 		f = la_GetFunctionKernel32("CreateSymbolicLinkW");
 	}
+#else
+# if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+	f = CreateSymbolicLinkW;
+# else
+	f = NULL;
+# endif
+#endif
 	if (!f)
 		return (0);
 
@@ -1185,6 +1217,8 @@ _archive_write_disk_finish_entry(struct archive *_a)
 		if (la_ftruncate(a->fh, a->filesize) == -1) {
 			archive_set_error(&a->archive, errno,
 			    "File size could not be restored");
+			CloseHandle(a->fh);
+			a->fh = INVALID_HANDLE_VALUE;
 			return (ARCHIVE_FAILED);
 		}
 	}
@@ -1656,6 +1690,9 @@ create_filesystem_object(struct archive_write_disk *a)
 	mode_t final_mode, mode;
 	int r;
 	DWORD attrs = 0;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 	/* We identify hard/symlinks according to the link names. */
 	/* Since link(2) and symlink(2) don't handle modes, we're done here. */
@@ -1719,8 +1756,16 @@ create_filesystem_object(struct archive_write_disk *a)
 			a->todo = 0;
 			a->deferred = 0;
 		} else if (r == 0 && a->filesize > 0) {
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+			a->fh = CreateFile2(namefull, GENERIC_WRITE, 0,
+			    TRUNCATE_EXISTING, &createExParams);
+#else
 			a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
 			    TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
 			if (a->fh == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
 				r = errno;
@@ -1783,14 +1828,27 @@ create_filesystem_object(struct archive_write_disk *a)
 		a->tmpname = NULL;
 		fullname = a->name;
 		/* O_WRONLY | O_CREAT | O_EXCL */
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		ZeroMemory(&createExParams, sizeof(createExParams));
+		createExParams.dwSize = sizeof(createExParams);
+		createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+		a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
+		    CREATE_NEW, &createExParams);
+#else
 		a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
 		    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
 		if (a->fh == INVALID_HANDLE_VALUE &&
 		    GetLastError() == ERROR_INVALID_NAME &&
 		    fullname == a->name) {
 			fullname = __la_win_permissive_name_w(a->name);
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+			a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
+			    CREATE_NEW, &createExParams);
+#else
 			a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
 			    CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
 		}
 		if (a->fh == INVALID_HANDLE_VALUE) {
 			if (GetLastError() == ERROR_ACCESS_DENIED) {
@@ -2551,14 +2609,25 @@ set_times(struct archive_write_disk *a,
 		hw = NULL;
 	} else {
 		wchar_t *ws;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+#endif
 
 		if (S_ISLNK(mode))
 			return (ARCHIVE_OK);
 		ws = __la_win_permissive_name_w(name);
 		if (ws == NULL)
 			goto settimes_failed;
+# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
+		ZeroMemory(&createExParams, sizeof(createExParams));
+		createExParams.dwSize = sizeof(createExParams);
+		createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+		hw = CreateFile2(ws, FILE_WRITE_ATTRIBUTES, 0,
+		    OPEN_EXISTING, &createExParams);
+#else
 		hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
 		    0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+#endif
 		free(ws);
 		if (hw == INVALID_HANDLE_VALUE)
 			goto settimes_failed;

+ 1 - 0
Utilities/cmlibarchive/libarchive/archive_write_private.h

@@ -53,6 +53,7 @@ struct archive_write_filter {
 	    const char *key, const char *value);
 	int	(*open)(struct archive_write_filter *);
 	int	(*write)(struct archive_write_filter *, const void *, size_t);
+	int	(*flush)(struct archive_write_filter *);
 	int	(*close)(struct archive_write_filter *);
 	int	(*free)(struct archive_write_filter *);
 	void	 *data;

+ 34 - 9
Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c

@@ -91,6 +91,26 @@ __FBSDID("$FreeBSD$");
 #define kAttributes		0x15
 #define kEncodedHeader		0x17
 
+// Check that some windows file attribute constants are defined.
+// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
+#ifndef FILE_ATTRIBUTE_READONLY
+#define FILE_ATTRIBUTE_READONLY 0x00000001
+#endif
+
+#ifndef FILE_ATTRIBUTE_DIRECTORY
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#endif
+
+#ifndef FILE_ATTRIBUTE_ARCHIVE
+#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
+#endif
+
+// This value is defined in 7zip with the comment "trick for Unix".
+//
+// 7z archives created on unix have this bit set in the high 16 bits of
+// the attr field along with the unix permissions.
+#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
+
 enum la_zaction {
 	ARCHIVE_Z_FINISH,
 	ARCHIVE_Z_RUN
@@ -165,7 +185,7 @@ struct file {
 	mode_t			 mode;
 	uint32_t		 crc32;
 
-	signed int		 dir:1;
+	unsigned		 dir:1;
 };
 
 struct _7zip {
@@ -1424,14 +1444,19 @@ make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size,
 		 * High 16bits is unix mode.
 		 * Low 16bits is Windows attributes.
 		 */
-		uint32_t encattr, attr;
+		uint32_t encattr, attr = 0;
+
 		if (file->dir)
-			attr = 0x8010;
+			attr |= FILE_ATTRIBUTE_DIRECTORY;
 		else
-			attr = 0x8020;
+			attr |= FILE_ATTRIBUTE_ARCHIVE;
+
 		if ((file->mode & 0222) == 0)
-			attr |= 1;/* Read Only. */
+			attr |= FILE_ATTRIBUTE_READONLY;
+
+		attr |= FILE_ATTRIBUTE_UNIX_EXTENSION;
 		attr |= ((uint32_t)file->mode) << 16;
+
 		archive_le32enc(&encattr, attr);
 		r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
 		if (r < 0)
@@ -1809,11 +1834,11 @@ compression_init_encoder_bzip2(struct archive *a,
 	 * of ugly hackery to convert a const * pointer to
 	 * a non-const pointer. */
 	strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
-	strm->avail_in = lastrm->avail_in;
+	strm->avail_in = (uint32_t)lastrm->avail_in;
 	strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
 	strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
 	strm->next_out = (char *)lastrm->next_out;
-	strm->avail_out = lastrm->avail_out;
+	strm->avail_out = (uint32_t)lastrm->avail_out;
 	strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
 	strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
 	if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
@@ -1842,11 +1867,11 @@ compression_code_bzip2(struct archive *a,
 	 * of ugly hackery to convert a const * pointer to
 	 * a non-const pointer. */
 	strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
-	strm->avail_in = lastrm->avail_in;
+	strm->avail_in = (uint32_t)lastrm->avail_in;
 	strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
 	strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
 	strm->next_out = (char *)lastrm->next_out;
-	strm->avail_out = lastrm->avail_out;
+	strm->avail_out = (uint32_t)lastrm->avail_out;
 	strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
 	strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
 	r = BZ2_bzCompress(strm,

+ 14 - 18
Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c

@@ -293,12 +293,12 @@ struct isoent {
 		struct extr_rec	*current;
 	}			 extr_rec_list;
 
-	signed int		 virtual:1;
+	unsigned int		 virtual:1;
 	/* If set to one, this file type is a directory.
 	 * A convenience flag to be used as
 	 * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
 	 */
-	signed int		 dir:1;
+	unsigned int		 dir:1;
 };
 
 struct hardlink {
@@ -656,7 +656,7 @@ struct iso_option {
 #define VOLUME_IDENTIFIER_SIZE		32
 
 	/*
-	 * Usage  : !zisofs [DEFAULT] 
+	 * Usage  : !zisofs [DEFAULT]
 	 *        :    Disable to generate RRIP 'ZF' extension.
 	 *        : zisofs
 	 *        :    Make files zisofs file and generate RRIP 'ZF'
@@ -693,7 +693,7 @@ struct iso9660 {
 	uint64_t		 bytes_remaining;
 	int			 need_multi_extent;
 
-	/* Temporary string buffer for Joliet extension. */ 
+	/* Temporary string buffer for Joliet extension. */
 	struct archive_string	 utf16be;
 	struct archive_string	 mbs;
 
@@ -759,9 +759,9 @@ struct iso9660 {
 
 	/* Used for making zisofs. */
 	struct {
-		signed int	 detect_magic:1;
-		signed int	 making:1;
-		signed int	 allzero:1;
+		unsigned int	 detect_magic:1;
+		unsigned int	 making:1;
+		unsigned int	 allzero:1;
 		unsigned char	 magic_buffer[64];
 		int		 magic_cnt;
 
@@ -2525,12 +2525,11 @@ get_gmoffset(struct tm *tm)
 static void
 get_tmfromtime(struct tm *tm, time_t *t)
 {
-#if HAVE_LOCALTIME_R
+#if HAVE_LOCALTIME_S
+	localtime_s(tm, t);
+#elif HAVE_LOCALTIME_R
 	tzset();
 	localtime_r(t, tm);
-#elif HAVE__LOCALTIME64_S
-	__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
-	_localtime64_s(tm, &tmp_t);
 #else
 	memcpy(tm, localtime(t), sizeof(*tm));
 #endif
@@ -4078,11 +4077,8 @@ write_information_block(struct archive_write *a)
 	}
 	memset(info.s, 0, info_size);
 	opt = 0;
-#if defined(HAVE__CTIME64_S)
-	{
-		__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
-		_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
-	}
+#if defined(HAVE_CTIME_S)
+	ctime_s(buf, sizeof(buf), &(iso9660->birth_time));
 #elif defined(HAVE_CTIME_R)
 	ctime_r(&(iso9660->birth_time), buf);
 #else
@@ -7811,8 +7807,8 @@ struct zisofs_extract {
 	uint64_t	 pz_uncompressed_size;
 	size_t		 uncompressed_buffer_size;
 
-	signed int	 initialized:1;
-	signed int	 header_passed:1;
+	unsigned int	 initialized:1;
+	unsigned int	 header_passed:1;
 
 	uint32_t	 pz_offset;
 	unsigned char	*block_pointers;

+ 46 - 16
Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c

@@ -100,6 +100,7 @@ static int		 has_non_ASCII(const char *);
 static void		 sparse_list_clear(struct pax *);
 static int		 sparse_list_add(struct pax *, int64_t, int64_t);
 static char		*url_encode(const char *in);
+static time_t		 get_ustar_max_mtime(void);
 
 /*
  * Set output format to 'restricted pax' format.
@@ -367,10 +368,12 @@ archive_write_pax_header_xattr(struct pax *pax, const char *encoded_name,
 	struct archive_string s;
 	char *encoded_value;
 
+	if (encoded_name == NULL)
+		return;
+
 	if (pax->flags & WRITE_LIBARCHIVE_XATTR) {
 		encoded_value = base64_encode((const char *)value, value_len);
-
-		if (encoded_name != NULL && encoded_value != NULL) {
+		if (encoded_value != NULL) {
 			archive_string_init(&s);
 			archive_strcpy(&s, "LIBARCHIVE.xattr.");
 			archive_strcat(&s, encoded_name);
@@ -403,17 +406,22 @@ archive_write_pax_header_xattrs(struct archive_write *a,
 
 		archive_entry_xattr_next(entry, &name, &value, &size);
 		url_encoded_name = url_encode(name);
-		if (url_encoded_name != NULL) {
+		if (url_encoded_name == NULL)
+			goto malloc_error;
+		else {
 			/* Convert narrow-character to UTF-8. */
 			r = archive_strcpy_l(&(pax->l_url_encoded_name),
 			    url_encoded_name, pax->sconv_utf8);
 			free(url_encoded_name); /* Done with this. */
 			if (r == 0)
 				encoded_name = pax->l_url_encoded_name.s;
-			else if (errno == ENOMEM) {
-				archive_set_error(&a->archive, ENOMEM,
-				    "Can't allocate memory for Linkname");
-				return (ARCHIVE_FATAL);
+			else if (r == -1)
+				goto malloc_error;
+			else {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Error encoding pax extended attribute");
+				return (ARCHIVE_FAILED);
 			}
 		}
 
@@ -422,6 +430,9 @@ archive_write_pax_header_xattrs(struct archive_write *a,
 
 	}
 	return (ARCHIVE_OK);
+malloc_error:
+	archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
+	return (ARCHIVE_FATAL);
 }
 
 static int
@@ -595,6 +606,8 @@ archive_write_pax_header(struct archive_write *a,
 	need_extension = 0;
 	pax = (struct pax *)a->format_data;
 
+	const time_t ustar_max_mtime = get_ustar_max_mtime();
+
 	/* Sanity check. */
 	if (archive_entry_pathname(entry_original) == NULL) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1116,16 +1129,13 @@ archive_write_pax_header(struct archive_write *a,
 	}
 
 	/*
-	 * Technically, the mtime field in the ustar header can
-	 * support 33 bits, but many platforms use signed 32-bit time
-	 * values.  The cutoff of 0x7fffffff here is a compromise.
 	 * Yes, this check is duplicated just below; this helps to
 	 * avoid writing an mtime attribute just to handle a
 	 * high-resolution timestamp in "restricted pax" mode.
 	 */
 	if (!need_extension &&
 	    ((archive_entry_mtime(entry_main) < 0)
-		|| (archive_entry_mtime(entry_main) >= 0x7fffffff)))
+		|| (archive_entry_mtime(entry_main) >= ustar_max_mtime)))
 		need_extension = 1;
 
 	/* I use a star-compatible file flag attribute. */
@@ -1190,7 +1200,7 @@ archive_write_pax_header(struct archive_write *a,
 	if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
 	    need_extension) {
 		if (archive_entry_mtime(entry_main) < 0  ||
-		    archive_entry_mtime(entry_main) >= 0x7fffffff  ||
+		    archive_entry_mtime(entry_main) >= ustar_max_mtime  ||
 		    archive_entry_mtime_nsec(entry_main) != 0)
 			add_pax_attr_time(&(pax->pax_header), "mtime",
 			    archive_entry_mtime(entry_main),
@@ -1428,7 +1438,7 @@ archive_write_pax_header(struct archive_write *a,
 		/* Copy mtime, but clip to ustar limits. */
 		s = archive_entry_mtime(entry_main);
 		if (s < 0) { s = 0; }
-		if (s >= 0x7fffffff) { s = 0x7fffffff; }
+		if (s > ustar_max_mtime) { s = ustar_max_mtime; }
 		archive_entry_set_mtime(pax_attr_entry, s, 0);
 
 		/* Standard ustar doesn't support atime. */
@@ -1904,14 +1914,19 @@ url_encode(const char *in)
 {
 	const char *s;
 	char *d;
-	int out_len = 0;
+	size_t out_len = 0;
 	char *out;
 
 	for (s = in; *s != '\0'; s++) {
-		if (*s < 33 || *s > 126 || *s == '%' || *s == '=')
+		if (*s < 33 || *s > 126 || *s == '%' || *s == '=') {
+			if (SIZE_MAX - out_len < 4)
+				return (NULL);
 			out_len += 3;
-		else
+		} else {
+			if (SIZE_MAX - out_len < 2)
+				return (NULL);
 			out_len++;
+		}
 	}
 
 	out = (char *)malloc(out_len + 1);
@@ -2046,3 +2061,18 @@ sparse_list_add(struct pax *pax, int64_t offset, int64_t length)
 	return (_sparse_list_add_block(pax, offset, length, 0));
 }
 
+static time_t
+get_ustar_max_mtime(void)
+{
+	/*
+	 * Technically, the mtime field in the ustar header can
+	 * support 33 bits. We are using all of them to keep
+	 * tar/test/test_option_C_mtree.c simple and passing after 2038.
+	 * For platforms that use signed 32-bit time values we
+	 * use the 32-bit maximum.
+	 */
+	if (sizeof(time_t) > sizeof(int32_t))
+		return (time_t)0x1ffffffff;
+	else
+		return (time_t)0x7fffffff;
+}

+ 8 - 17
Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c

@@ -329,30 +329,21 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t)
 {
 /** like strftime(3) but for time_t objects */
 	struct tm *rt;
-#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
 	struct tm timeHere;
-#endif
-#if defined(HAVE__GMTIME64_S)
-	errno_t terr;
-	__time64_t tmptime;
 #endif
 	char strtime[100];
 	size_t len;
 
-#ifdef HAVE_GMTIME_R
-	if ((rt = gmtime_r(&t, &timeHere)) == NULL)
-		return;
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = t;
-	terr = _gmtime64_s(&timeHere, &tmptime);
-	if (terr)
-		rt = NULL;
-	else
-		rt = &timeHere;
+#if defined(HAVE_GMTIME_S)
+	rt = gmtime_s(&timeHere, &t) ? NULL : &timeHere;
+#elif defined(HAVE_GMTIME_R)
+	rt = gmtime_r(&t, &timeHere);
 #else
-	if ((rt = gmtime(&t)) == NULL)
-		return;
+	rt = gmtime(&t);
 #endif
+	if (!rt)
+		return;
 	/* leave the hard yacker to our role model strftime() */
 	len = strftime(strtime, sizeof(strtime)-1, fmt, rt);
 	archive_strncat(as, strtime, len);

+ 5 - 9
Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c

@@ -212,8 +212,8 @@ struct file {
 	struct heap_data	 data;
         struct archive_string    script;
 
-	signed int		 virtual:1;
-	signed int		 dir:1;
+	unsigned int		 virtual:1;
+	unsigned int		 dir:1;
 };
 
 struct hardlink {
@@ -906,15 +906,11 @@ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
 {
 	char timestr[100];
 	struct tm tm;
-#if defined(HAVE__GMTIME64_S)
-	__time64_t tmptime;
-#endif
 
-#if defined(HAVE_GMTIME_R)
+#if defined(HAVE_GMTIME_S)
+	gmtime_s(&tm, &t);
+#elif defined(HAVE_GMTIME_R)
 	gmtime_r(&t, &tm);
-#elif defined(HAVE__GMTIME64_S)
-	tmptime = t;
-	_gmtime64_s(&tm, &tmptime);
 #else
 	memcpy(&tm, gmtime(&t), sizeof(tm));
 #endif

+ 4 - 15
Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c

@@ -1382,25 +1382,14 @@ dos_time(const time_t unix_time)
 {
 	struct tm *t;
 	unsigned int dt;
-#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
 	struct tm tmbuf;
 #endif
-#if defined(HAVE__LOCALTIME64_S)
-	errno_t terr;
-	__time64_t tmptime;
-#endif
 
-	/* This will not preserve time when creating/extracting the archive
-	 * on two systems with different time zones. */
-#if defined(HAVE_LOCALTIME_R)
+#if defined(HAVE_LOCALTIME_S)
+	t = localtime_s(&tmbuf, &unix_time) ? NULL : &tmbuf;
+#elif defined(HAVE_LOCALTIME_R)
 	t = localtime_r(&unix_time, &tmbuf);
-#elif defined(HAVE__LOCALTIME64_S)
-	tmptime = unix_time;
-	terr = _localtime64_s(&tmbuf, &tmptime);
-	if (terr)
-		t = NULL;
-	else
-		t = &tmbuf;
 #else
 	t = localtime(&unix_time);
 #endif

+ 9 - 0
Utilities/cmlibarchive/libarchive/archive_write_set_options.3

@@ -257,6 +257,15 @@ If supported, the default value is read from
 The value is interpreted as a decimal integer specifying the
 compression level. Supported values depend on the library version,
 common values are from 1 to 22.
+.It Cm long
+Enables long distance matching. The value is interpreted as a
+decimal integer specifying log2 window size in bytes. Values from
+10 to 30 for 32 bit, or 31 for 64 bit, are supported.
+.It Cm threads
+The value is interpreted as a decimal integer specifying the
+number of threads for multi-threaded zstd compression.
+If set to 0, zstd will attempt to detect and use the number
+of physical CPU cores.
 .El
 .It Format 7zip
 .Bl -tag -compact -width indent

+ 6 - 1
Utilities/cmlibarchive/libarchive/config_freebsd.h

@@ -111,6 +111,8 @@
 #define HAVE_FCNTL 1
 #define HAVE_FCNTL_H 1
 #define HAVE_FDOPENDIR 1
+#define HAVE_FNMATCH 1
+#define HAVE_FNMATCH_H 1
 #define HAVE_FORK 1
 #define HAVE_FSEEKO 1
 #define HAVE_FSTAT 1
@@ -123,6 +125,8 @@
 #define HAVE_GETEUID 1
 #define HAVE_GETGRGID_R 1
 #define HAVE_GETGRNAM_R 1
+#define HAVE_GETLINE 1
+#define HAVE_GETOPT_OPTRESET 1
 #define HAVE_GETPID 1
 #define HAVE_GETPWNAM_R 1
 #define HAVE_GETPWUID_R 1
@@ -201,6 +205,7 @@
 #define HAVE_SYS_MOUNT_H 1
 #define HAVE_SYS_PARAM_H 1
 #define HAVE_SYS_POLL_H 1
+#define HAVE_SYS_QUEUE_H 1
 #define HAVE_SYS_SELECT_H 1
 #define HAVE_SYS_STATVFS_H 1
 #define HAVE_SYS_STAT_H 1
@@ -234,7 +239,7 @@
 #define HAVE_WMEMCPY 1
 #define HAVE_WMEMMOVE 1
 #define HAVE_ZLIB_H 1
-#define TIME_WITH_SYS_TIME 1
+#define HAVE_SYS_TIME_H 1
 
 #if __FreeBSD_version >= 800505
 #define HAVE_LIBLZMA 1

+ 9 - 0
Utilities/cmlibarchive/libarchive/filter_fork_windows.c

@@ -31,6 +31,7 @@
 
 #include "filter_fork.h"
 
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
 /* There are some editions of Windows ("nano server," for example) that
  * do not host user32.dll. If we want to keep running on those editions,
  * we need to delay-load WaitForInputIdle. */
@@ -224,6 +225,14 @@ fail:
 	__archive_cmdline_free(acmd);
 	return ARCHIVE_FAILED;
 }
+#else /* !WINAPI_PARTITION_DESKTOP */
+int
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child)
+{
+	(void)cmd; (void)child_stdin; (void) child_stdout; (void) out_child;
+	return ARCHIVE_FAILED;
+}
+#endif /* !WINAPI_PARTITION_DESKTOP */
 
 void
 __archive_check_child(int in, int out)

+ 4 - 0
Utilities/cmlibarchive/libarchive/xxhash.c

@@ -149,6 +149,10 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
 
 #if GCC_VERSION >= 409
 __attribute__((__no_sanitize_undefined__))
+#else
+#  if defined(__clang__)
+__attribute__((no_sanitize("undefined")))
+#  endif
 #endif
 #if defined(_MSC_VER)
 static __inline U32 A32(const void * x)