Browse Source

Merge topic 'update-libarchive'

6744e44970 Update CMake pre-cached values for libarchive 3.3.3
6a4b1006f9 Merge branch 'upstream-LibArchive' into update-libarchive
2aaed7a050 LibArchive 2018-09-03 (5fe69dd0)
710f37c47a libarchive: Update script to get 3.3.3
97e1213a88 Merge branch 'libarchive-libressl-2.7' into update-libarchive

Acked-by: Kitware Robot <[email protected]>
Merge-request: !2417
Brad King 7 years ago
parent
commit
abe25dd79f
54 changed files with 1004 additions and 204 deletions
  1. 1 0
      CMakeLists.txt
  2. 1 1
      Utilities/Scripts/update-libarchive.bash
  3. 40 9
      Utilities/cmlibarchive/CMakeLists.txt
  4. 10 0
      Utilities/cmlibarchive/build/cmake/config.h.in
  5. 1 0
      Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
  6. 1 1
      Utilities/cmlibarchive/build/version
  7. 2 0
      Utilities/cmlibarchive/libarchive/CMakeLists.txt
  8. 6 2
      Utilities/cmlibarchive/libarchive/archive.h
  9. 2 0
      Utilities/cmlibarchive/libarchive/archive_acl.c
  10. 3 3
      Utilities/cmlibarchive/libarchive/archive_cmdline.c
  11. 1 1
      Utilities/cmlibarchive/libarchive/archive_cryptor.c
  12. 1 1
      Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
  13. 2 0
      Utilities/cmlibarchive/libarchive/archive_disk_acl_freebsd.c
  14. 2 2
      Utilities/cmlibarchive/libarchive/archive_entry.c
  15. 2 1
      Utilities/cmlibarchive/libarchive/archive_entry.h
  16. 2 2
      Utilities/cmlibarchive/libarchive/archive_match.c
  17. 3 0
      Utilities/cmlibarchive/libarchive/archive_pack_dev.c
  18. 6 0
      Utilities/cmlibarchive/libarchive/archive_platform.h
  19. 5 5
      Utilities/cmlibarchive/libarchive/archive_ppmd7.c
  20. 2 2
      Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h
  21. 0 7
      Utilities/cmlibarchive/libarchive/archive_ppmd_private.h
  22. 7 5
      Utilities/cmlibarchive/libarchive/archive_read.c
  23. 4 0
      Utilities/cmlibarchive/libarchive/archive_read_append_filter.c
  24. 1 1
      Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
  25. 4 4
      Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
  26. 10 9
      Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
  27. 5 1
      Utilities/cmlibarchive/libarchive/archive_read_filter.3
  28. 2 0
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
  29. 292 0
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
  30. 4 17
      Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
  31. 7 0
      Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
  32. 17 12
      Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
  33. 6 0
      Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
  34. 70 39
      Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
  35. 10 20
      Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
  36. 5 5
      Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
  37. 23 9
      Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
  38. 31 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
  39. 2 1
      Utilities/cmlibarchive/libarchive/archive_string.c
  40. 2 2
      Utilities/cmlibarchive/libarchive/archive_util.c
  41. 18 0
      Utilities/cmlibarchive/libarchive/archive_version_details.c
  42. 6 5
      Utilities/cmlibarchive/libarchive/archive_virtual.c
  43. 1 1
      Utilities/cmlibarchive/libarchive/archive_write.3
  44. 1 1
      Utilities/cmlibarchive/libarchive/archive_write.c
  45. 1 0
      Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
  46. 1 0
      Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
  47. 6 1
      Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
  48. 335 0
      Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
  49. 8 4
      Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
  50. 15 4
      Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
  51. 5 1
      Utilities/cmlibarchive/libarchive/archive_write_filter.3
  52. 2 15
      Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
  53. 9 8
      Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
  54. 1 1
      Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c

+ 1 - 0
CMakeLists.txt

@@ -513,6 +513,7 @@ macro (CMAKE_BUILD_UTILITIES)
     set(ENABLE_NETTLE OFF CACHE INTERNAL "Enable use of Nettle")
     set(ENABLE_OPENSSL ${CMAKE_USE_OPENSSL} CACHE INTERNAL "Enable use of OpenSSL")
     set(ENABLE_LZMA ON CACHE INTERNAL "Enable the use of the system LZMA library if found")
+    set(ENABLE_LZ4 OFF CACHE INTERNAL "Enable the use of the system LZ4 library if found")
     set(ENABLE_LZO OFF CACHE INTERNAL "Enable the use of the system LZO library if found")
     set(ENABLE_ZLIB ON CACHE INTERNAL "Enable the use of the system ZLIB library if found")
     set(ENABLE_BZip2 ON CACHE INTERNAL "Enable the use of the system BZip2 library if found")

+ 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.3.2"
+readonly tag="v3.3.3"
 readonly shortlog=false
 readonly paths="
   CMakeLists.txt

+ 40 - 9
Utilities/cmlibarchive/CMakeLists.txt

@@ -71,6 +71,7 @@ include(CTest)
 
 OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
 OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
+OPTION(ENABLE_LZ4 "Enable the use of the system LZ4 library if found" ON)
 OPTION(ENABLE_LZO "Enable the use of the system LZO library if found" OFF)
 OPTION(ENABLE_LZMA "Enable the use of the system LZMA library if found" ON)
 
@@ -328,7 +329,7 @@ IF(ENABLE_LZO)
   INCLUDE(FindPackageHandleStandardArgs)
   FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZO2 DEFAULT_MSG LZO2_LIBRARY LZO2_INCLUDE_DIR)
 ELSE(ENABLE_LZO)
-  SET(LIBZMA_FOUND FALSE) # Override cached value
+  SET(LZO2_FOUND FALSE) # Override cached value
 ENDIF(ENABLE_LZO)
 IF(LZO2_FOUND)
   SET(HAVE_LIBLZO2 1)
@@ -347,15 +348,19 @@ IF(0) # CMake does not need LZ4 support in libarchive
 #
 # Find LZ4
 #
-IF (LZ4_INCLUDE_DIR)
-  # Already in cache, be silent
-  SET(LZ4_FIND_QUIETLY TRUE)
-ENDIF (LZ4_INCLUDE_DIR)
+IF(ENABLE_LZ4)
+  IF (LZ4_INCLUDE_DIR)
+    # Already in cache, be silent
+    SET(LZ4_FIND_QUIETLY TRUE)
+  ENDIF (LZ4_INCLUDE_DIR)
 
-FIND_PATH(LZ4_INCLUDE_DIR lz4.h)
-FIND_LIBRARY(LZ4_LIBRARY NAMES lz4 liblz4)
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZ4 DEFAULT_MSG LZ4_LIBRARY LZ4_INCLUDE_DIR)
+  FIND_PATH(LZ4_INCLUDE_DIR lz4.h)
+  FIND_LIBRARY(LZ4_LIBRARY NAMES lz4 liblz4)
+  INCLUDE(FindPackageHandleStandardArgs)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZ4 DEFAULT_MSG LZ4_LIBRARY LZ4_INCLUDE_DIR)
+ELSE(ENABLE_LZ4)
+  SET(LZ4_FOUND FALSE) # Override cached value
+ENDIF(ENABLE_LZ4)
 IF(LZ4_FOUND)
   SET(HAVE_LIBLZ4 1)
   SET(HAVE_LZ4_H 1)
@@ -371,6 +376,31 @@ IF(LZ4_FOUND)
 ENDIF(LZ4_FOUND)
 MARK_AS_ADVANCED(CLEAR LZ4_INCLUDE_DIR)
 MARK_AS_ADVANCED(CLEAR LZ4_LIBRARY)
+#
+# Find Zstd
+#
+IF (ZSTD_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(ZSTD_FIND_QUIETLY TRUE)
+ENDIF (ZSTD_INCLUDE_DIR)
+
+FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
+FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
+IF(ZSTD_FOUND)
+  SET(HAVE_ZSTD_H 1)
+  INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR})
+  LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY})
+  SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY})
+  SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR})
+  CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD)
+  #
+  # TODO: test for static library.
+  #
+ENDIF(ZSTD_FOUND)
+MARK_AS_ADVANCED(CLEAR ZSTD_INCLUDE_DIR)
+MARK_AS_ADVANCED(CLEAR ZSTD_LIBRARY)
 ENDIF()
 
 #
@@ -451,6 +481,7 @@ LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
 LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
 LA_CHECK_INCLUDE_FILE("sys/statfs.h" HAVE_SYS_STATFS_H)
 LA_CHECK_INCLUDE_FILE("sys/statvfs.h" HAVE_SYS_STATVFS_H)
+LA_CHECK_INCLUDE_FILE("sys/sysmacros.h" HAVE_SYS_SYSMACROS_H)
 LA_CHECK_INCLUDE_FILE("sys/time.h" HAVE_SYS_TIME_H)
 LA_CHECK_INCLUDE_FILE("sys/utime.h" HAVE_SYS_UTIME_H)
 LA_CHECK_INCLUDE_FILE("sys/utsname.h" HAVE_SYS_UTSNAME_H)

+ 10 - 0
Utilities/cmlibarchive/build/cmake/config.h.in

@@ -728,6 +728,9 @@ typedef uint64_t uintmax_t;
 /* Define to 1 if you have the `z' library (-lz). */
 #cmakedefine HAVE_LIBZ 1
 
+/* Define to 1 if you have the `zstd' library (-lzstd). */
+#cmakedefine HAVE_LIBZSTD 1
+
 /* Define to 1 if you have the <limits.h> header file. */
 #cmakedefine HAVE_LIMITS_H 1
 
@@ -1071,6 +1074,10 @@ typedef uint64_t uintmax_t;
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #cmakedefine HAVE_SYS_STAT_H 1
 
+
+/* Define to 1 if you have the <sys/sysmacros.h> header file. */
+#cmakedefine HAVE_SYS_SYSMACROS_H 1
+
 /* Define to 1 if you have the <sys/time.h> header file. */
 #cmakedefine HAVE_SYS_TIME_H 1
 
@@ -1185,6 +1192,9 @@ typedef uint64_t uintmax_t;
 /* Define to 1 if you have the <zlib.h> header file. */
 #cmakedefine HAVE_ZLIB_H 1
 
+/* 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
 

+ 1 - 0
Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in

@@ -7,5 +7,6 @@ Name: libarchive
 Description: library that can create and read several streaming archive formats
 Version: @VERSION@
 Cflags: -I${includedir}
+Cflags.private: -DLIBARCHIVE_STATIC
 Libs: -L${libdir} -larchive
 Libs.private: @LIBS@

+ 1 - 1
Utilities/cmlibarchive/build/version

@@ -1 +1 @@
-3003002
+3003003

+ 2 - 0
Utilities/cmlibarchive/libarchive/CMakeLists.txt

@@ -88,6 +88,7 @@ SET(libarchive_SOURCES
   archive_read_support_filter_rpm.c
   archive_read_support_filter_uu.c
   archive_read_support_filter_xz.c
+  archive_read_support_filter_zstd.c
   archive_read_support_format_7zip.c
   archive_read_support_format_all.c
   archive_read_support_format_ar.c
@@ -134,6 +135,7 @@ SET(libarchive_SOURCES
   archive_write_add_filter_program.c
   archive_write_add_filter_uuencode.c
   archive_write_add_filter_xz.c
+  archive_write_add_filter_zstd.c
   archive_write_set_format.c
   archive_write_set_format_7zip.c
   archive_write_set_format_ar.c

+ 6 - 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 3003002
+#define	ARCHIVE_VERSION_NUMBER 3003003
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -152,7 +152,7 @@ __LA_DECL int		archive_version_number(void);
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.3.2"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.3.3"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
@@ -174,6 +174,7 @@ __LA_DECL const char *  archive_zlib_version(void);
 __LA_DECL const char *  archive_liblzma_version(void);
 __LA_DECL const char *  archive_bzlib_version(void);
 __LA_DECL const char *  archive_liblz4_version(void);
+__LA_DECL const char *  archive_libzstd_version(void);
 
 /* Declare our basic types. */
 struct archive;
@@ -273,6 +274,7 @@ typedef const char *archive_passphrase_callback(struct archive *,
 #define	ARCHIVE_FILTER_LZOP	11
 #define	ARCHIVE_FILTER_GRZIP	12
 #define	ARCHIVE_FILTER_LZ4	13
+#define	ARCHIVE_FILTER_ZSTD	14
 
 #if ARCHIVE_VERSION_NUMBER < 4000000
 #define	ARCHIVE_COMPRESSION_NONE	ARCHIVE_FILTER_NONE
@@ -430,6 +432,7 @@ __LA_DECL int archive_read_support_filter_program_signature
 __LA_DECL int archive_read_support_filter_rpm(struct archive *);
 __LA_DECL int archive_read_support_filter_uu(struct archive *);
 __LA_DECL int archive_read_support_filter_xz(struct archive *);
+__LA_DECL int archive_read_support_filter_zstd(struct archive *);
 
 __LA_DECL int archive_read_support_format_7zip(struct archive *);
 __LA_DECL int archive_read_support_format_all(struct archive *);
@@ -775,6 +778,7 @@ __LA_DECL int archive_write_add_filter_program(struct archive *,
 		     const char *cmd);
 __LA_DECL int archive_write_add_filter_uuencode(struct archive *);
 __LA_DECL int archive_write_add_filter_xz(struct archive *);
+__LA_DECL int archive_write_add_filter_zstd(struct archive *);
 
 
 /* A convenience function to set the format based on the code or name. */

+ 2 - 0
Utilities/cmlibarchive/libarchive/archive_acl.c

@@ -1159,6 +1159,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
 	switch (want_type) {
 	case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
 		want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+		__LA_FALLTHROUGH;
 	case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
 	case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
 		numfields = 5;
@@ -1626,6 +1627,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
 	switch (want_type) {
 	case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
 		want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+		__LA_FALLTHROUGH;
 	case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
 	case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
 		numfields = 5;

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

@@ -100,10 +100,10 @@ get_argument(struct archive_string *as, const char *p)
 
 /*
  * Set up command line arguments.
- * Returns ARChIVE_OK if everything okey.
- * Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an
+ * Returns ARCHIVE_OK if everything okey.
+ * Returns ARCHIVE_FAILED if there is a lack of the `"' terminator or an
  * empty command line.
- * Returns ARChIVE_FATAL if no memory.
+ * Returns ARCHIVE_FATAL if no memory.
  */
 int
 __archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)

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

@@ -153,7 +153,7 @@ aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
 	CCCryptorStatus r;
 
 	r = CCCryptorReset(ref, NULL);
-	if (r != kCCSuccess)
+	if (r != kCCSuccess && r != kCCUnimplemented)
 		return -1;
 	r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf,
 	    AES_BLOCK_SIZE, NULL);

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

@@ -64,7 +64,7 @@ typedef struct {
 } archive_crypto_ctx;
 
 #elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
-#include <Bcrypt.h>
+#include <bcrypt.h>
 
 /* Common in other bcrypt implementations, but missing from VS2008. */
 #ifndef BCRYPT_SUCCESS

+ 2 - 0
Utilities/cmlibarchive/libarchive/archive_disk_acl_freebsd.c

@@ -93,7 +93,9 @@ static const acl_perm_map_t acl_nfs4_flag_map[] = {
 	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
 	{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
 	{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
+#ifdef ACL_ENTRY_INHERITED
 	{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
+#endif
 };
 
 static const int acl_nfs4_flag_map_size =

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

@@ -1491,7 +1491,7 @@ archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
  * the style of the generated ACL.
  */
 wchar_t *
-archive_entry_acl_to_text_w(struct archive_entry *entry, ssize_t *len,
+archive_entry_acl_to_text_w(struct archive_entry *entry, la_ssize_t *len,
     int flags)
 {
 	return (archive_acl_to_text_w(&entry->acl, len, flags,
@@ -1499,7 +1499,7 @@ archive_entry_acl_to_text_w(struct archive_entry *entry, ssize_t *len,
 }
 
 char *
-archive_entry_acl_to_text(struct archive_entry *entry, ssize_t *len,
+archive_entry_acl_to_text(struct archive_entry *entry, la_ssize_t *len,
     int flags)
 {
 	return (archive_acl_to_text_l(&entry->acl, len, flags, NULL));

+ 2 - 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 3003002
+#define	ARCHIVE_VERSION_NUMBER 3003003
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
@@ -42,6 +42,7 @@
 
 #include <sys/types.h>
 #include <stddef.h>  /* for wchar_t */
+#include <stdint.h>
 #include <time.h>
 
 #if defined(_WIN32) && !defined(__CYGWIN__)

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

@@ -1582,7 +1582,7 @@ time_excluded(struct archive_match *a, struct archive_entry *entry)
  */
 
 int
-archive_match_include_uid(struct archive *_a, int64_t uid)
+archive_match_include_uid(struct archive *_a, la_int64_t uid)
 {
 	struct archive_match *a;
 
@@ -1593,7 +1593,7 @@ archive_match_include_uid(struct archive *_a, int64_t uid)
 }
 
 int
-archive_match_include_gid(struct archive *_a, int64_t gid)
+archive_match_include_gid(struct archive *_a, la_int64_t gid)
 {
 	struct archive_match *a;
 

+ 3 - 0
Utilities/cmlibarchive/libarchive/archive_pack_dev.c

@@ -57,6 +57,9 @@ __RCSID("$NetBSD$");
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
+#ifdef HAVE_SYS_SYSMACROS_H
+#include <sys/sysmacros.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif

+ 6 - 0
Utilities/cmlibarchive/libarchive/archive_platform.h

@@ -196,4 +196,10 @@
 #define	ARCHIVE_ERRNO_MISC (-1)
 #endif
 
+#if defined(__GNUC__) && (__GNUC__ >= 7)
+#define	__LA_FALLTHROUGH	__attribute__((fallthrough))
+#else
+#define	__LA_FALLTHROUGH
+#endif
+
 #endif /* !ARCHIVE_PLATFORM_H_INCLUDED */

+ 5 - 5
Utilities/cmlibarchive/libarchive/archive_ppmd7.c

@@ -115,14 +115,14 @@ static void Ppmd7_Construct(CPpmd7 *p)
   memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
 }
 
-static void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
+static void Ppmd7_Free(CPpmd7 *p)
 {
-  alloc->Free(alloc, p->Base);
+  free(p->Base);
   p->Size = 0;
   p->Base = 0;
 }
 
-static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
+static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size)
 {
   if (p->Base == 0 || p->Size != size)
   {
@@ -131,14 +131,14 @@ static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
     if (size < UNIT_SIZE) {
       return False;
     }
-    Ppmd7_Free(p, alloc);
+    Ppmd7_Free(p);
     p->AlignOffset =
       #ifdef PPMD_32BIT
         (4 - size) & 3;
       #else
         4 - (size & 3);
       #endif
-    if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
+    if ((p->Base = (Byte *)malloc(p->AlignOffset + size
         #ifndef PPMD_32BIT
         + UNIT_SIZE
         #endif

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

@@ -95,8 +95,8 @@ typedef struct
 {
   /* Base Functions */
   void (*Ppmd7_Construct)(CPpmd7 *p);
-  Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
-  void (*Ppmd7_Free)(CPpmd7 *p, ISzAlloc *alloc);
+  Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size);
+  void (*Ppmd7_Free)(CPpmd7 *p);
   void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder);
   #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
 

+ 0 - 7
Utilities/cmlibarchive/libarchive/archive_ppmd_private.h

@@ -69,13 +69,6 @@ typedef struct
   void (*Write)(void *p, Byte b);
 } IByteOut;
 
-
-typedef struct
-{
-  void *(*Alloc)(void *p, size_t size);
-  void (*Free)(void *p, void *address); /* address can be 0 */
-} ISzAlloc;
-
 /*** End defined in Types.h ***/
 /*** Begin defined in CpuArch.h ***/
 

+ 7 - 5
Utilities/cmlibarchive/libarchive/archive_read.c

@@ -120,7 +120,8 @@ archive_read_new(void)
  * Record the do-not-extract-to file. This belongs in archive_read_extract.c.
  */
 void
-archive_read_extract_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+archive_read_extract_set_skip_file(struct archive *_a, la_int64_t d,
+    la_int64_t i)
 {
 	struct archive_read *a = (struct archive_read *)_a;
 
@@ -747,7 +748,7 @@ choose_format(struct archive_read *a)
  * Return the file offset (within the uncompressed data stream) where
  * the last header started.
  */
-int64_t
+la_int64_t
 archive_read_header_position(struct archive *_a)
 {
 	struct archive_read *a = (struct archive_read *)_a;
@@ -820,7 +821,7 @@ archive_read_format_capabilities(struct archive *_a)
  * DO NOT intermingle calls to this function and archive_read_data_block
  * to read a single entry body.
  */
-ssize_t
+la_ssize_t
 archive_read_data(struct archive *_a, void *buff, size_t s)
 {
 	struct archive *a = (struct archive *)_a;
@@ -943,7 +944,7 @@ archive_read_data_skip(struct archive *_a)
 	return (r);
 }
 
-int64_t
+la_int64_t
 archive_seek_data(struct archive *_a, int64_t offset, int whence)
 {
 	struct archive_read *a = (struct archive_read *)_a;
@@ -1626,7 +1627,8 @@ __archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
 	switch (whence) {
 	case SEEK_CUR:
 		/* Adjust the offset and use SEEK_SET instead */
-		offset += filter->position;			
+		offset += filter->position;
+		__LA_FALLTHROUGH;
 	case SEEK_SET:
 		cursor = 0;
 		while (1)

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

@@ -89,6 +89,10 @@ archive_read_append_filter(struct archive *_a, int code)
       strcpy(str, "lz4");
       r1 = archive_read_support_filter_lz4(_a);
       break;
+    case ARCHIVE_FILTER_ZSTD:
+      strcpy(str, "zstd");
+      r1 = archive_read_support_filter_zstd(_a);
+      break;
     case ARCHIVE_FILTER_LZIP:
       strcpy(str, "lzip");
       r1 = archive_read_support_filter_lzip(_a);

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

@@ -127,7 +127,7 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
 /*
  * Enter working directory and return working pathname of archive_entry.
  * If a pointer to an integer is provided and its value is below zero
- * open a file descriptor on this pahtname.
+ * open a file descriptor on this pathname.
  */
 const char *
 archive_read_disk_entry_setup_path(struct archive_read_disk *a,

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

@@ -387,7 +387,7 @@ archive_read_disk_vtable(void)
 }
 
 const char *
-archive_read_disk_gname(struct archive *_a, int64_t gid)
+archive_read_disk_gname(struct archive *_a, la_int64_t gid)
 {
 	struct archive_read_disk *a = (struct archive_read_disk *)_a;
 	if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
@@ -399,7 +399,7 @@ archive_read_disk_gname(struct archive *_a, int64_t gid)
 }
 
 const char *
-archive_read_disk_uname(struct archive *_a, int64_t uid)
+archive_read_disk_uname(struct archive *_a, la_int64_t uid)
 {
 	struct archive_read_disk *a = (struct archive_read_disk *)_a;
 	if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
@@ -413,7 +413,7 @@ archive_read_disk_uname(struct archive *_a, int64_t uid)
 int
 archive_read_disk_set_gname_lookup(struct archive *_a,
     void *private_data,
-    const char * (*lookup_gname)(void *private, int64_t gid),
+    const char * (*lookup_gname)(void *private, la_int64_t gid),
     void (*cleanup_gname)(void *private))
 {
 	struct archive_read_disk *a = (struct archive_read_disk *)_a;
@@ -432,7 +432,7 @@ archive_read_disk_set_gname_lookup(struct archive *_a,
 int
 archive_read_disk_set_uname_lookup(struct archive *_a,
     void *private_data,
-    const char * (*lookup_uname)(void *private, int64_t uid),
+    const char * (*lookup_uname)(void *private, la_int64_t uid),
     void (*cleanup_uname)(void *private))
 {
 	struct archive_read_disk *a = (struct archive_read_disk *)_a;

+ 10 - 9
Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c

@@ -117,7 +117,7 @@ struct filesystem {
  */
 
 #define MAX_OVERLAPPED	8
-#define BUFFER_SIZE	(1024 * 8)
+#define READ_BUFFER_SIZE	(1024 * 64) /* Default to 64KB per https://technet.microsoft.com/en-us/library/cc938632.aspx */
 #define DIRECT_IO	0/* Disabled */
 #define ASYNC_IO	1/* Enabled */
 
@@ -320,7 +320,7 @@ archive_read_disk_vtable(void)
 }
 
 const char *
-archive_read_disk_gname(struct archive *_a, int64_t gid)
+archive_read_disk_gname(struct archive *_a, la_int64_t gid)
 {
 	struct archive_read_disk *a = (struct archive_read_disk *)_a;
 	if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
@@ -332,7 +332,7 @@ archive_read_disk_gname(struct archive *_a, int64_t gid)
 }
 
 const char *
-archive_read_disk_uname(struct archive *_a, int64_t uid)
+archive_read_disk_uname(struct archive *_a, la_int64_t uid)
 {
 	struct archive_read_disk *a = (struct archive_read_disk *)_a;
 	if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
@@ -346,7 +346,7 @@ archive_read_disk_uname(struct archive *_a, int64_t uid)
 int
 archive_read_disk_set_gname_lookup(struct archive *_a,
     void *private_data,
-    const char * (*lookup_gname)(void *private, int64_t gid),
+    const char * (*lookup_gname)(void *private, la_int64_t gid),
     void (*cleanup_gname)(void *private))
 {
 	struct archive_read_disk *a = (struct archive_read_disk *)_a;
@@ -567,7 +567,7 @@ start_next_async_read(struct archive_read_disk *a, struct tree *t)
 	/* Allocate read buffer. */
 	if (olp->buff == NULL) {
 		void *p;
-		size_t s = (size_t)align_num_per_sector(t, BUFFER_SIZE);
+		size_t s = (size_t)align_num_per_sector(t, READ_BUFFER_SIZE);
 		p = VirtualAlloc(NULL, s, MEM_COMMIT, PAGE_READWRITE);
 		if (p == NULL) {
 			archive_set_error(&a->archive, ENOMEM,
@@ -683,7 +683,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
 				break;
 		} while (r == ARCHIVE_OK && t->ol_num_doing < MAX_OVERLAPPED);
 	} else {
-		if (start_next_async_read(a, t) == ARCHIVE_FATAL)
+		if ((r = start_next_async_read(a, t)) == ARCHIVE_FATAL)
 			goto abort_read_data;
 	}
 
@@ -923,6 +923,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
 		t->entry_fh = CreateFileW(tree_current_access_path(t),
 		    GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
 		if (t->entry_fh == INVALID_HANDLE_VALUE) {
+			la_dosmaperr(GetLastError());
 			archive_set_error(&a->archive, errno,
 			    "Couldn't open %ls", tree_current_path(a->tree));
 			return (ARCHIVE_FAILED);
@@ -2275,10 +2276,10 @@ setup_sparse_from_disk(struct archive_read_disk *a,
 				if (range.Length.QuadPart > 0)
 					continue;
 			} else {
-				/* The remaining data is hole. */
+				/* The entire file is a hole. Add one data block of size 0 at the end. */
 				archive_entry_sparse_add_entry(entry,
-				    range.FileOffset.QuadPart,
-				    range.Length.QuadPart);
+				    entry_size,
+				    0);
 			}
 			break;
 		} else {

+ 5 - 1
Utilities/cmlibarchive/libarchive/archive_read_filter.3

@@ -38,6 +38,7 @@
 .Nm archive_read_support_filter_rpm ,
 .Nm archive_read_support_filter_uu ,
 .Nm archive_read_support_filter_xz ,
+.Nm archive_read_support_filter_zstd ,
 .Nm archive_read_support_filter_program ,
 .Nm archive_read_support_filter_program_signature
 .Nd functions for reading streaming archives
@@ -73,6 +74,8 @@ Streaming Archive Library (libarchive, -larchive)
 .Ft int
 .Fn archive_read_support_filter_xz "struct archive *"
 .Ft int
+.Fn archive_read_support_filter_zstd "struct archive *"
+.Ft int
 .Fo archive_read_support_filter_program
 .Fa "struct archive *"
 .Fa "const char *cmd"
@@ -99,7 +102,8 @@ Streaming Archive Library (libarchive, -larchive)
 .Fn archive_read_support_filter_none ,
 .Fn archive_read_support_filter_rpm ,
 .Fn archive_read_support_filter_uu ,
-.Fn archive_read_support_filter_xz
+.Fn archive_read_support_filter_xz ,
+.Fn archive_read_support_filter_zstd ,
 .Xc
 Enables auto-detection code and decompression support for the
 specified compression.

+ 2 - 0
Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c

@@ -71,6 +71,8 @@ archive_read_support_filter_all(struct archive *a)
 	archive_read_support_filter_grzip(a);
 	/* Lz4 falls back to "lz4 -d" command-line program. */
 	archive_read_support_filter_lz4(a);
+	/* Zstd falls back to "zstd -d" command-line program. */
+	archive_read_support_filter_zstd(a);
 
 	/* Note: We always return ARCHIVE_OK here, even if some of the
 	 * above return ARCHIVE_WARN.  The intent here is to enable

+ 292 - 0
Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c

@@ -0,0 +1,292 @@
+/*-
+ * Copyright (c) 2009-2011 Sean Purcell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ZSTD_H
+#include <zstd.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+
+struct private_data {
+	ZSTD_DStream	*dstream;
+	unsigned char	*out_block;
+	size_t		 out_block_size;
+	int64_t		 total_out;
+	char		 in_frame; /* True = in the middle of a zstd frame. */
+	char		 eof; /* True = found end of compressed data. */
+};
+
+/* Zstd Filter. */
+static ssize_t	zstd_filter_read(struct archive_read_filter *, const void**);
+static int	zstd_filter_close(struct archive_read_filter *);
+#endif
+
+/*
+ * Note that we can detect zstd compressed files even if we can't decompress
+ * them.  (In fact, we like detecting them because we can give better error
+ * messages.)  So the bid framework here gets compiled even if no zstd library
+ * is available.
+ */
+static int	zstd_bidder_bid(struct archive_read_filter_bidder *,
+		    struct archive_read_filter *);
+static int	zstd_bidder_init(struct archive_read_filter *);
+
+int
+archive_read_support_filter_zstd(struct archive *_a)
+{
+	struct archive_read *a = (struct archive_read *)_a;
+	struct archive_read_filter_bidder *bidder;
+
+	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_read_support_filter_zstd");
+
+	if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+		return (ARCHIVE_FATAL);
+
+	bidder->data = NULL;
+	bidder->name = "zstd";
+	bidder->bid = zstd_bidder_bid;
+	bidder->init = zstd_bidder_init;
+	bidder->options = NULL;
+	bidder->free = NULL;
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+	return (ARCHIVE_OK);
+#else
+	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+	    "Using external zstd program for zstd decompression");
+	return (ARCHIVE_WARN);
+#endif
+}
+
+/*
+ * Test whether we can handle this data.
+ */
+static int
+zstd_bidder_bid(struct archive_read_filter_bidder *self,
+    struct archive_read_filter *filter)
+{
+	const unsigned char *buffer;
+	ssize_t avail;
+	unsigned prefix;
+
+	/* Zstd frame magic values */
+	const unsigned zstd_magic = 0xFD2FB528U;
+
+	(void) self; /* UNUSED */
+
+	buffer = __archive_read_filter_ahead(filter, 4, &avail);
+	if (buffer == NULL)
+		return (0);
+
+	prefix = archive_le32dec(buffer);
+	if (prefix == zstd_magic)
+		return (32);
+
+	return (0);
+}
+
+#if !(HAVE_ZSTD_H && HAVE_LIBZSTD)
+
+/*
+ * If we don't have the library on this system, we can't do the
+ * decompression directly.  We can, however, try to run "zstd -d"
+ * in case that's available.
+ */
+static int
+zstd_bidder_init(struct archive_read_filter *self)
+{
+	int r;
+
+	r = __archive_read_program(self, "zstd -d -qq");
+	/* Note: We set the format here even if __archive_read_program()
+	 * above fails.  We do, after all, know what the format is
+	 * even if we weren't able to read it. */
+	self->code = ARCHIVE_FILTER_ZSTD;
+	self->name = "zstd";
+	return (r);
+}
+
+#else
+
+/*
+ * Initialize the filter object
+ */
+static int
+zstd_bidder_init(struct archive_read_filter *self)
+{
+	struct private_data *state;
+	const size_t out_block_size = ZSTD_DStreamOutSize();
+	void *out_block;
+	ZSTD_DStream *dstream;
+
+	self->code = ARCHIVE_FILTER_ZSTD;
+	self->name = "zstd";
+
+	state = (struct private_data *)calloc(sizeof(*state), 1);
+	out_block = (unsigned char *)malloc(out_block_size);
+	dstream = ZSTD_createDStream();
+
+	if (state == NULL || out_block == NULL || dstream == NULL) {
+		free(out_block);
+		free(state);
+		ZSTD_freeDStream(dstream); /* supports free on NULL */
+		archive_set_error(&self->archive->archive, ENOMEM,
+		    "Can't allocate data for zstd decompression");
+		return (ARCHIVE_FATAL);
+	}
+
+	self->data = state;
+
+	state->out_block_size = out_block_size;
+	state->out_block = out_block;
+	state->dstream = dstream;
+	self->read = zstd_filter_read;
+	self->skip = NULL; /* not supported */
+	self->close = zstd_filter_close;
+
+	state->eof = 0;
+	state->in_frame = 0;
+
+	return (ARCHIVE_OK);
+}
+
+static ssize_t
+zstd_filter_read(struct archive_read_filter *self, const void **p)
+{
+	struct private_data *state;
+	size_t decompressed;
+	ssize_t avail_in;
+	ZSTD_outBuffer out;
+	ZSTD_inBuffer in;
+
+	state = (struct private_data *)self->data;
+
+	out = (ZSTD_outBuffer) { state->out_block, state->out_block_size, 0 };
+
+	/* 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);
+			if (ZSTD_isError(ret)) {
+				archive_set_error(&self->archive->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Error initializing zstd decompressor: %s",
+				    ZSTD_getErrorName(ret));
+				return (ARCHIVE_FATAL);
+			}
+		}
+		in.src = __archive_read_filter_ahead(self->upstream, 1,
+		    &avail_in);
+		if (avail_in < 0) {
+			return avail_in;
+		}
+		if (in.src == NULL && avail_in == 0) {
+			if (!state->in_frame) {
+				/* end of stream */
+				state->eof = 1;
+				break;
+			} else {
+				archive_set_error(&self->archive->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Truncated zstd input");
+				return (ARCHIVE_FATAL);
+			}
+		}
+		in.size = avail_in;
+		in.pos = 0;
+
+		{
+			const size_t ret =
+			    ZSTD_decompressStream(state->dstream, &out, &in);
+
+			if (ZSTD_isError(ret)) {
+				archive_set_error(&self->archive->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Zstd decompression failed: %s",
+				    ZSTD_getErrorName(ret));
+				return (ARCHIVE_FATAL);
+			}
+
+			/* Decompressor made some progress */
+			__archive_read_filter_consume(self->upstream, in.pos);
+
+			/* ret guaranteed to be > 0 if frame isn't done yet */
+			state->in_frame = (ret != 0);
+		}
+	}
+
+	decompressed = out.pos;
+	state->total_out += decompressed;
+	if (decompressed == 0)
+		*p = NULL;
+	else
+		*p = state->out_block;
+	return (decompressed);
+}
+
+/*
+ * Clean up the decompressor.
+ */
+static int
+zstd_filter_close(struct archive_read_filter *self)
+{
+	struct private_data *state;
+
+	state = (struct private_data *)self->data;
+
+	ZSTD_freeDStream(state->dstream);
+	free(state->out_block);
+	free(state);
+
+	return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_ZLIB_H && HAVE_LIBZSTD */

+ 4 - 17
Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c

@@ -975,18 +975,6 @@ decode_codec_id(const unsigned char *codecId, size_t id_size)
 	return (id);
 }
 
-static void *
-ppmd_alloc(void *p, size_t size)
-{
-	(void)p;
-	return malloc(size);
-}
-static void
-ppmd_free(void *p, void *address)
-{
-	(void)p;
-	free(address);
-}
 static Byte
 ppmd_read(void *p)
 {
@@ -1006,8 +994,6 @@ ppmd_read(void *p)
 	return (b);
 }
 
-static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
-
 static int
 init_decompression(struct archive_read *a, struct _7zip *zip,
     const struct _7z_coder *coder1, const struct _7z_coder *coder2)
@@ -1237,7 +1223,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 
 		if (zip->ppmd7_valid) {
 			__archive_ppmd7_functions.Ppmd7_Free(
-			    &zip->ppmd7_context, &g_szalloc);
+			    &zip->ppmd7_context);
 			zip->ppmd7_valid = 0;
 		}
 
@@ -1256,7 +1242,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 		}
 		__archive_ppmd7_functions.Ppmd7_Construct(&zip->ppmd7_context);
 		r = __archive_ppmd7_functions.Ppmd7_Alloc(
-			&zip->ppmd7_context, msize, &g_szalloc);
+			&zip->ppmd7_context, msize);
 		if (r == 0) {
 			archive_set_error(&a->archive, ENOMEM,
 			    "Coludn't allocate memory for PPMd");
@@ -1636,7 +1622,7 @@ free_decompression(struct archive_read *a, struct _7zip *zip)
 #endif
 	if (zip->ppmd7_valid) {
 		__archive_ppmd7_functions.Ppmd7_Free(
-			&zip->ppmd7_context, &g_szalloc);
+			&zip->ppmd7_context);
 		zip->ppmd7_valid = 0;
 	}
 	return (r);
@@ -2569,6 +2555,7 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
 		case kDummy:
 			if (ll == 0)
 				break;
+			__LA_FALLTHROUGH;
 		default:
 			if (header_bytes(a, ll) == NULL)
 				return (-1);

+ 7 - 0
Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c

@@ -633,6 +633,13 @@ header_newc(struct archive_read *a, struct cpio *cpio,
 	/* Pad name to 2 more than a multiple of 4. */
 	*name_pad = (2 - *namelength) & 3;
 
+	/* Make sure that the padded name length fits into size_t. */
+	if (*name_pad > SIZE_MAX - *namelength) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "cpio archive has invalid namelength");
+		return (ARCHIVE_FATAL);
+	}
+
 	/*
 	 * Note: entry_bytes_remaining is at least 64 bits and
 	 * therefore guaranteed to be big enough for a 33-bit file

+ 17 - 12
Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c

@@ -409,7 +409,8 @@ static int	next_entry_seek(struct archive_read *, struct iso9660 *,
 		    struct file_info **);
 static struct file_info *
 		parse_file_info(struct archive_read *a,
-		    struct file_info *parent, const unsigned char *isodirrec);
+		    struct file_info *parent, const unsigned char *isodirrec,
+		    size_t reclen);
 static int	parse_rockridge(struct archive_read *a,
 		    struct file_info *file, const unsigned char *start,
 		    const unsigned char *end);
@@ -1022,7 +1023,7 @@ read_children(struct archive_read *a, struct file_info *parent)
 			if (*(p + DR_name_len_offset) == 1
 			    && *(p + DR_name_offset) == '\001')
 				continue;
-			child = parse_file_info(a, parent, p);
+			child = parse_file_info(a, parent, p, b - p);
 			if (child == NULL) {
 				__archive_read_consume(a, skip_size);
 				return (ARCHIVE_FATAL);
@@ -1112,7 +1113,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
 	 */
 	seenJoliet = iso9660->seenJoliet;/* Save flag. */
 	iso9660->seenJoliet = 0;
-	file = parse_file_info(a, NULL, block);
+	file = parse_file_info(a, NULL, block, vd->size);
 	if (file == NULL)
 		return (ARCHIVE_FATAL);
 	iso9660->seenJoliet = seenJoliet;
@@ -1144,7 +1145,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660)
 			return (ARCHIVE_FATAL);
 		}
 		iso9660->seenJoliet = 0;
-		file = parse_file_info(a, NULL, block);
+		file = parse_file_info(a, NULL, block, vd->size);
 		if (file == NULL)
 			return (ARCHIVE_FATAL);
 		iso9660->seenJoliet = seenJoliet;
@@ -1749,7 +1750,7 @@ archive_read_format_iso9660_cleanup(struct archive_read *a)
  */
 static struct file_info *
 parse_file_info(struct archive_read *a, struct file_info *parent,
-    const unsigned char *isodirrec)
+    const unsigned char *isodirrec, size_t reclen)
 {
 	struct iso9660 *iso9660;
 	struct file_info *file, *filep;
@@ -1763,16 +1764,20 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
 
 	iso9660 = (struct iso9660 *)(a->format->data);
 
-	dr_len = (size_t)isodirrec[DR_length_offset];
-	name_len = (size_t)isodirrec[DR_name_len_offset];
-	location = archive_le32dec(isodirrec + DR_extent_offset);
-	fsize = toi(isodirrec + DR_size_offset, DR_size_size);
-	/* Sanity check that dr_len needs at least 34. */
-	if (dr_len < 34) {
+	if (reclen != 0)
+		dr_len = (size_t)isodirrec[DR_length_offset];
+	/*
+	 * Sanity check that reclen is not zero and dr_len is greater than
+	 * reclen but at least 34
+	 */
+	if (reclen == 0 || reclen < dr_len || dr_len < 34) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Invalid length of directory record");
+			"Invalid length of directory record");
 		return (NULL);
 	}
+	name_len = (size_t)isodirrec[DR_name_len_offset];
+	location = archive_le32dec(isodirrec + DR_extent_offset);
+	fsize = toi(isodirrec + DR_size_offset, DR_size_size);
 	/* Sanity check that name_len doesn't exceed dr_len. */
 	if (dr_len - 33 < name_len || name_len == 0) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,

+ 6 - 0
Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c

@@ -701,6 +701,12 @@ archive_read_format_lha_read_header(struct archive_read *a,
 	 * Prepare variables used to read a file content.
 	 */
 	lha->entry_bytes_remaining = lha->compsize;
+	if (lha->entry_bytes_remaining < 0) {
+		archive_set_error(&a->archive,
+		    ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Invalid LHa entry size");
+		return (ARCHIVE_FATAL);
+	}
 	lha->entry_offset = 0;
 	lha->entry_crc_calculated = 0;
 

+ 70 - 39
Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c

@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
 #include "archive.h"
 #include "archive_entry.h"
 #include "archive_private.h"
+#include "archive_rb.h"
 #include "archive_read_private.h"
 #include "archive_string.h"
 #include "archive_pack_dev.h"
@@ -75,7 +76,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
 #define	MTREE_HAS_OPTIONAL	0x0800
 #define	MTREE_HAS_NOCHANGE	0x1000 /* FreeBSD specific */
 
-#define	MTREE_HASHTABLE_SIZE 1024
+#define	MAX_LINE_LEN		(1024 * 1024)
 
 struct mtree_option {
 	struct mtree_option *next;
@@ -83,13 +84,13 @@ struct mtree_option {
 };
 
 struct mtree_entry {
+	struct archive_rb_node rbnode;
+	struct mtree_entry *next_dup;
 	struct mtree_entry *next;
 	struct mtree_option *options;
 	char *name;
 	char full;
 	char used;
-	unsigned int name_hash;
-	struct mtree_entry *hashtable_next;
 };
 
 struct mtree {
@@ -102,11 +103,12 @@ struct mtree {
 	const char		*archive_format_name;
 	struct mtree_entry	*entries;
 	struct mtree_entry	*this_entry;
-	struct mtree_entry	*entry_hashtable[MTREE_HASHTABLE_SIZE];
+	struct archive_rb_tree	 entry_rbtree;
 	struct archive_string	 current_dir;
 	struct archive_string	 contents_name;
 
 	struct archive_entry_linkresolver *resolver;
+	struct archive_rb_tree rbtree;
 
 	int64_t			 cur_size;
 	char checkfs;
@@ -115,7 +117,6 @@ struct mtree {
 static int	bid_keycmp(const char *, const char *, ssize_t);
 static int	cleanup(struct archive_read *);
 static int	detect_form(struct archive_read *, int *);
-static unsigned int	hash(const char *);
 static int	mtree_bid(struct archive_read *, int);
 static int	parse_file(struct archive_read *, struct archive_entry *,
 		    struct mtree *, struct mtree_entry *, int *);
@@ -217,9 +218,30 @@ free_options(struct mtree_option *head)
 	}
 }
 
+static int
+mtree_cmp_node(const struct archive_rb_node *n1,
+    const struct archive_rb_node *n2)
+{
+	const struct mtree_entry *e1 = (const struct mtree_entry *)n1;
+	const struct mtree_entry *e2 = (const struct mtree_entry *)n2;
+
+	return (strcmp(e1->name, e2->name));
+}
+
+static int
+mtree_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+	const struct mtree_entry *e = (const struct mtree_entry *)n;
+
+	return (strcmp(e->name, key));
+}
+
 int
 archive_read_support_format_mtree(struct archive *_a)
 {
+	static const struct archive_rb_tree_ops rb_ops = {
+		mtree_cmp_node, mtree_cmp_key,
+	};
 	struct archive_read *a = (struct archive_read *)_a;
 	struct mtree *mtree;
 	int r;
@@ -235,6 +257,8 @@ archive_read_support_format_mtree(struct archive *_a)
 	}
 	mtree->fd = -1;
 
+	__archive_rb_tree_init(&mtree->rbtree, &rb_ops);
+
 	r = __archive_read_register_format(a, mtree, "mtree",
            mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
 
@@ -334,6 +358,14 @@ next_line(struct archive_read *a,
 		size_t nbytes_req = (*ravail+1023) & ~1023U;
 		ssize_t tested;
 
+		/*
+		 * Place an arbitrary limit on the line length.
+		 * mtree is almost free-form input and without line length limits,
+		 * it can consume a lot of memory.
+		 */
+		if (len >= MAX_LINE_LEN)
+			return (-1);
+
 		/* Increase reading bytes if it is not enough to at least
 		 * new two lines. */
 		if (nbytes_req < (size_t)*ravail + 160)
@@ -865,12 +897,11 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
     struct mtree_option **global, const char *line, ssize_t line_len,
     struct mtree_entry **last_entry, int is_form_d)
 {
-	struct mtree_entry *entry, *ht_iter;
+	struct mtree_entry *entry;
 	struct mtree_option *iter;
 	const char *next, *eq, *name, *end;
 	size_t name_len, len;
 	int r, i;
-	unsigned int ht_idx;
 
 	if ((entry = malloc(sizeof(*entry))) == NULL) {
 		archive_set_error(&a->archive, errno, "Can't allocate memory");
@@ -881,8 +912,6 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
 	entry->name = NULL;
 	entry->used = 0;
 	entry->full = 0;
-	entry->name_hash = 0;
-	entry->hashtable_next = NULL;
 
 	/* Add this entry to list. */
 	if (*last_entry == NULL)
@@ -935,15 +964,17 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
 	memcpy(entry->name, name, name_len);
 	entry->name[name_len] = '\0';
 	parse_escapes(entry->name, entry);
-	entry->name_hash = hash(entry->name);
 
-	ht_idx = entry->name_hash % MTREE_HASHTABLE_SIZE;
-	if ((ht_iter = mtree->entry_hashtable[ht_idx]) != NULL) {
-		while (ht_iter->hashtable_next)
-			ht_iter = ht_iter->hashtable_next;
-		ht_iter->hashtable_next = entry;
-	} else {
-		mtree->entry_hashtable[ht_idx] = entry;
+	entry->next_dup = NULL;
+	if (entry->full) {
+		if (!__archive_rb_tree_insert_node(&mtree->rbtree, &entry->rbnode)) {
+			struct mtree_entry *alt;
+			alt = (struct mtree_entry *)__archive_rb_tree_find_node(
+			    &mtree->rbtree, entry->name);
+			while (alt->next_dup)
+				alt = alt->next_dup;
+			alt->next_dup = entry;
+		}
 	}
 
 	for (iter = *global; iter != NULL; iter = iter->next) {
@@ -1138,14 +1169,13 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
 		 * with pathname canonicalization, which is a very
 		 * tricky subject.)
 		 */
-		for (mp = mentry->hashtable_next; mp != NULL; mp = mp->hashtable_next) {
-			if (mp->full && !mp->used
-					&& mentry->name_hash == mp->name_hash
-					&& strcmp(mentry->name, mp->name) == 0) {
+		mp = (struct mtree_entry *)__archive_rb_tree_find_node(
+		    &mtree->rbtree, mentry->name);
+		for (; mp; mp = mp->next_dup) {
+			if (mp->full && !mp->used) {
 				/* Later lines override earlier ones. */
 				mp->used = 1;
-				r1 = parse_line(a, entry, mtree, mp,
-				    &parsed_kws);
+				r1 = parse_line(a, entry, mtree, mp, &parsed_kws);
 				if (r1 < r)
 					r = r1;
 			}
@@ -1489,6 +1519,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 		}
 		if (strcmp(key, "cksum") == 0)
 			break;
+		__LA_FALLTHROUGH;
 	case 'd':
 		if (strcmp(key, "device") == 0) {
 			/* stat(2) st_rdev field, e.g. the major/minor IDs
@@ -1502,12 +1533,14 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 				archive_entry_set_rdev(entry, dev);
 			return r;
 		}
+		__LA_FALLTHROUGH;
 	case 'f':
 		if (strcmp(key, "flags") == 0) {
 			*parsed_kws |= MTREE_HAS_FFLAGS;
 			archive_entry_copy_fflags_text(entry, val);
 			break;
 		}
+		__LA_FALLTHROUGH;
 	case 'g':
 		if (strcmp(key, "gid") == 0) {
 			*parsed_kws |= MTREE_HAS_GID;
@@ -1519,16 +1552,19 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			archive_entry_copy_gname(entry, val);
 			break;
 		}
+		__LA_FALLTHROUGH;
 	case 'i':
 		if (strcmp(key, "inode") == 0) {
 			archive_entry_set_ino(entry, mtree_atol(&val, 10));
 			break;
 		}
+		__LA_FALLTHROUGH;
 	case 'l':
 		if (strcmp(key, "link") == 0) {
 			archive_entry_copy_symlink(entry, val);
 			break;
 		}
+		__LA_FALLTHROUGH;
 	case 'm':
 		if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
 			break;
@@ -1545,6 +1581,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			}
 			break;
 		}
+		__LA_FALLTHROUGH;
 	case 'n':
 		if (strcmp(key, "nlink") == 0) {
 			*parsed_kws |= MTREE_HAS_NLINK;
@@ -1552,6 +1589,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 				(unsigned int)mtree_atol(&val, 10));
 			break;
 		}
+		__LA_FALLTHROUGH;
 	case 'r':
 		if (strcmp(key, "resdevice") == 0) {
 			/* stat(2) st_dev field, e.g. the device ID where the
@@ -1567,6 +1605,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 		if (strcmp(key, "rmd160") == 0 ||
 		    strcmp(key, "rmd160digest") == 0)
 			break;
+		__LA_FALLTHROUGH;
 	case 's':
 		if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0)
 			break;
@@ -1583,6 +1622,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			archive_entry_set_size(entry, mtree_atol(&val, 10));
 			break;
 		}
+		__LA_FALLTHROUGH;
 	case 't':
 		if (strcmp(key, "tags") == 0) {
 			/*
@@ -1625,18 +1665,21 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 					archive_entry_set_filetype(entry, AE_IFBLK);
 					break;
 				}
+				__LA_FALLTHROUGH;
 			case 'c':
 				if (strcmp(val, "char") == 0) {
 					archive_entry_set_filetype(entry,
 						AE_IFCHR);
 					break;
 				}
+				__LA_FALLTHROUGH;
 			case 'd':
 				if (strcmp(val, "dir") == 0) {
 					archive_entry_set_filetype(entry,
 						AE_IFDIR);
 					break;
 				}
+				__LA_FALLTHROUGH;
 			case 'f':
 				if (strcmp(val, "fifo") == 0) {
 					archive_entry_set_filetype(entry,
@@ -1648,12 +1691,14 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 						AE_IFREG);
 					break;
 				}
+				__LA_FALLTHROUGH;
 			case 'l':
 				if (strcmp(val, "link") == 0) {
 					archive_entry_set_filetype(entry,
 						AE_IFLNK);
 					break;
 				}
+				__LA_FALLTHROUGH;
 			default:
 				archive_set_error(&a->archive,
 				    ARCHIVE_ERRNO_FILE_FORMAT,
@@ -1665,6 +1710,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			*parsed_kws |= MTREE_HAS_TYPE;
 			break;
 		}
+		__LA_FALLTHROUGH;
 	case 'u':
 		if (strcmp(key, "uid") == 0) {
 			*parsed_kws |= MTREE_HAS_UID;
@@ -1676,6 +1722,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			archive_entry_copy_uname(entry, val);
 			break;
 		}
+		__LA_FALLTHROUGH;
 	default:
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Unrecognized key %s=%s", key, val);
@@ -1962,19 +2009,3 @@ readline(struct archive_read *a, struct mtree *mtree, char **start,
 		find_off = u - mtree->line.s;
 	}
 }
-
-static unsigned int
-hash(const char *p)
-{
-	/* A 32-bit version of Peter Weinberger's (PJW) hash algorithm,
-	   as used by ELF for hashing function names. */
-	unsigned g, h = 0;
-	while (*p != '\0') {
-		h = (h << 4) + *p++;
-		if ((g = h & 0xF0000000) != 0) {
-			h ^= g >> 24;
-			h &= 0x0FFFFFFF;
-		}
-	}
-	return h;
-}

+ 10 - 20
Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c

@@ -604,20 +604,6 @@ lzss_emit_match(struct rar *rar, int offset, int length)
   rar->lzss.position += length;
 }
 
-static void *
-ppmd_alloc(void *p, size_t size)
-{
-  (void)p;
-  return malloc(size);
-}
-static void
-ppmd_free(void *p, void *address)
-{
-  (void)p;
-  free(address);
-}
-static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
-
 static Byte
 ppmd_read(void *p)
 {
@@ -1038,7 +1024,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
   case COMPRESS_METHOD_BEST:
     ret = read_data_compressed(a, buff, size, offset);
     if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
-      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
     break;
 
   default:
@@ -1253,7 +1239,7 @@ archive_read_format_rar_cleanup(struct archive_read *a)
   free(rar->dbo);
   free(rar->unp_buffer);
   free(rar->lzss.window);
-  __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+  __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
   free(rar);
   (a->format->data) = NULL;
   return (ARCHIVE_OK);
@@ -1496,7 +1482,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
         return (ARCHIVE_FATAL);
       }
       filename[filename_size++] = '\0';
-      filename[filename_size++] = '\0';
+      /*
+       * Do not increment filename_size here as the computations below
+       * add the space for the terminating NUL explicitly.
+       */
+      filename[filename_size] = '\0';
 
       /* Decoded unicode form is UTF-16BE, so we have to update a string
        * conversion object for it. */
@@ -1654,7 +1644,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
   rar->unp_offset = 0;
   rar->unp_buffer_size = UNP_BUFFER_SIZE;
   memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
-  __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+  __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
   rar->ppmd_valid = rar->ppmd_eod = 0;
 
   /* Don't set any archive entries for non-file header types */
@@ -2118,7 +2108,7 @@ parse_codes(struct archive_read *a)
 
       /* Make sure ppmd7_contest is freed before Ppmd7_Construct
        * because reading a broken file cause this abnormal sequence. */
-      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
 
       rar->bytein.a = a;
       rar->bytein.Read = &ppmd_read;
@@ -2133,7 +2123,7 @@ parse_codes(struct archive_read *a)
       }
 
       if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,
-        rar->dictionary_size, &g_szalloc))
+        rar->dictionary_size))
       {
         archive_set_error(&a->archive, ENOMEM,
                           "Out of memory");

+ 5 - 5
Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c

@@ -251,15 +251,15 @@ archive_read_support_format_tar(struct archive *_a)
 	    ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
 
 	tar = (struct tar *)calloc(1, sizeof(*tar));
-#ifdef HAVE_COPYFILE_H
-	/* Set this by default on Mac OS. */
-	tar->process_mac_extensions = 1;
-#endif
 	if (tar == NULL) {
 		archive_set_error(&a->archive, ENOMEM,
 		    "Can't allocate tar data");
 		return (ARCHIVE_FATAL);
 	}
+#ifdef HAVE_COPYFILE_H
+	/* Set this by default on Mac OS. */
+	tar->process_mac_extensions = 1;
+#endif
 
 	r = __archive_read_register_format(a, tar, "tar",
 	    archive_read_format_tar_bid,
@@ -2241,7 +2241,7 @@ gnu_add_sparse_entry(struct archive_read *a, struct tar *tar,
 	else
 		tar->sparse_list = p;
 	tar->sparse_last = p;
-	if (remaining < 0 || offset < 0) {
+	if (remaining < 0 || offset < 0 || offset > INT64_MAX - remaining) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data");
 		return (ARCHIVE_FATAL);
 	}

+ 23 - 9
Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c

@@ -1040,6 +1040,9 @@ atol10(const char *p, size_t char_cnt)
 	uint64_t l;
 	int digit;
 
+	if (char_cnt == 0)
+		return (0);
+
 	l = 0;
 	digit = *p - '0';
 	while (digit >= 0 && digit < 10  && char_cnt-- > 0) {
@@ -1054,7 +1057,10 @@ atol8(const char *p, size_t char_cnt)
 {
 	int64_t l;
 	int digit;
-        
+
+	if (char_cnt == 0)
+		return (0);
+
 	l = 0;
 	while (char_cnt-- > 0) {
 		if (*p >= '0' && *p <= '7')
@@ -2623,6 +2629,14 @@ strappend_base64(struct xar *xar,
 		archive_strncat(as, (const char *)buff, len);
 }
 
+static int
+is_string(const char *known, const char *data, size_t len)
+{
+	if (strlen(known) != len)
+		return -1;
+	return memcmp(data, known, len);
+}
+
 static void
 xml_data(void *userData, const char *s, int len)
 {
@@ -2674,26 +2688,26 @@ xml_data(void *userData, const char *s, int len)
 		archive_strncpy(&(xar->file->symlink), s, len);
 		break;
 	case FILE_TYPE:
-		if (strncmp("file", s, len) == 0 ||
-		    strncmp("hardlink", s, len) == 0)
+		if (is_string("file", s, len) == 0 ||
+		    is_string("hardlink", s, len) == 0)
 			xar->file->mode =
 			    (xar->file->mode & ~AE_IFMT) | AE_IFREG;
-		if (strncmp("directory", s, len) == 0)
+		if (is_string("directory", s, len) == 0)
 			xar->file->mode =
 			    (xar->file->mode & ~AE_IFMT) | AE_IFDIR;
-		if (strncmp("symlink", s, len) == 0)
+		if (is_string("symlink", s, len) == 0)
 			xar->file->mode =
 			    (xar->file->mode & ~AE_IFMT) | AE_IFLNK;
-		if (strncmp("character special", s, len) == 0)
+		if (is_string("character special", s, len) == 0)
 			xar->file->mode =
 			    (xar->file->mode & ~AE_IFMT) | AE_IFCHR;
-		if (strncmp("block special", s, len) == 0)
+		if (is_string("block special", s, len) == 0)
 			xar->file->mode =
 			    (xar->file->mode & ~AE_IFMT) | AE_IFBLK;
-		if (strncmp("socket", s, len) == 0)
+		if (is_string("socket", s, len) == 0)
 			xar->file->mode =
 			    (xar->file->mode & ~AE_IFMT) | AE_IFSOCK;
-		if (strncmp("fifo", s, len) == 0)
+		if (is_string("fifo", s, len) == 0)
 			xar->file->mode =
 			    (xar->file->mode & ~AE_IFMT) | AE_IFIFO;
 		xar->file->has |= HAS_TYPE;

+ 31 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c

@@ -511,7 +511,13 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
 		case 0x5455:
 		{
 			/* Extended time field "UT". */
-			int flags = p[offset];
+			int flags;
+			if (datasize == 0) {
+				archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Incomplete extended time field");
+				return ARCHIVE_FAILED;
+			}
+			flags = p[offset];
 			offset++;
 			datasize--;
 			/* Flag bits indicate which dates are present. */
@@ -723,6 +729,11 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
 		}
 		case 0x9901:
 			/* WinZip AES extra data field. */
+			if (datasize < 6) {
+				archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Incomplete AES field");
+				return ARCHIVE_FAILED;
+			}
 			if (p[offset + 2] == 'A' && p[offset + 3] == 'E') {
 				/* Vendor version. */
 				zip_entry->aes_extra.vendor =
@@ -881,6 +892,24 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
 		zip_entry->mode |= 0664;
 	}
 
+	/* Windows archivers sometimes use backslash as the directory separator.
+	   Normalize to slash. */
+	if (zip_entry->system == 0 &&
+	    (wp = archive_entry_pathname_w(entry)) != NULL) {
+		if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) {
+			size_t i;
+			struct archive_wstring s;
+			archive_string_init(&s);
+			archive_wstrcpy(&s, wp);
+			for (i = 0; i < archive_strlen(&s); i++) {
+				if (s.s[i] == '\\')
+					s.s[i] = '/';
+			}
+			archive_entry_copy_pathname_w(entry, s.s);
+			archive_wstring_free(&s);
+		}
+	}
+
 	/* Make sure that entries with a trailing '/' are marked as directories
 	 * even if the External File Attributes contains bogus values.  If this
 	 * is not a directory and there is no type, assume regularfile. */
@@ -1056,6 +1085,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
 		zip->end_of_entry = 1;
 
 	/* Set up a more descriptive format name. */
+        archive_string_empty(&zip->format_name);
 	archive_string_sprintf(&zip->format_name, "ZIP %d.%d (%s)",
 	    version / 10, version % 10,
 	    compression_name(zip->entry->compression));

+ 2 - 1
Utilities/cmlibarchive/libarchive/archive_string.c

@@ -214,7 +214,8 @@ archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s)
 {
 	if (archive_wstring_ensure(as, as->length + s + 1) == NULL)
 		return (NULL);
-	wmemmove(as->s + as->length, p, s);
+	if (s)
+		wmemmove(as->s + as->length, p, s);
 	as->length += s;
 	as->s[as->length] = 0;
 	return (as);

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

@@ -140,7 +140,7 @@ archive_compression_name(struct archive *a)
 /*
  * Return a count of the number of compressed bytes processed.
  */
-int64_t
+la_int64_t
 archive_position_compressed(struct archive *a)
 {
 	return archive_filter_bytes(a, -1);
@@ -149,7 +149,7 @@ archive_position_compressed(struct archive *a)
 /*
  * Return a count of the number of uncompressed bytes processed.
  */
-int64_t
+la_int64_t
 archive_position_uncompressed(struct archive *a)
 {
 	return archive_filter_bytes(a, 0);

+ 18 - 0
Utilities/cmlibarchive/libarchive/archive_version_details.c

@@ -45,6 +45,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
 #ifdef HAVE_LZ4_H
 #include <lz4.h>
 #endif
+#ifdef HAVE_ZSTD_H
+#include <zstd.h>
+#endif
 
 #include "archive.h"
 #include "archive_private.h"
@@ -59,6 +62,7 @@ archive_version_details(void)
 	const char *liblzma = archive_liblzma_version();
 	const char *bzlib = archive_bzlib_version();
 	const char *liblz4 = archive_liblz4_version();
+	const char *libzstd = archive_libzstd_version();
 
 	if (!init) {
 		archive_string_init(&str);
@@ -84,6 +88,10 @@ archive_version_details(void)
 			archive_strcat(&str, " liblz4/");
 			archive_strcat(&str, liblz4);
 		}
+		if (libzstd) {
+			archive_strcat(&str, " libzstd/");
+			archive_strcat(&str, libzstd);
+		}
 	}
 	return str.s;
 }
@@ -131,3 +139,13 @@ archive_liblz4_version(void)
 	return NULL;
 #endif
 }
+
+const char *
+archive_libzstd_version(void)
+{
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+	return ZSTD_VERSION_STRING;
+#else
+	return NULL;
+#endif
+}

+ 6 - 5
Utilities/cmlibarchive/libarchive/archive_virtual.c

@@ -48,7 +48,7 @@ archive_filter_name(struct archive *a, int n)
 	return ((a->vtable->archive_filter_name)(a, n));
 }
 
-int64_t
+la_int64_t
 archive_filter_bytes(struct archive *a, int n)
 {
 	return ((a->vtable->archive_filter_bytes)(a, n));
@@ -124,14 +124,15 @@ archive_write_finish_entry(struct archive *a)
 	return ((a->vtable->archive_write_finish_entry)(a));
 }
 
-ssize_t
+la_ssize_t
 archive_write_data(struct archive *a, const void *buff, size_t s)
 {
 	return ((a->vtable->archive_write_data)(a, buff, s));
 }
 
-ssize_t
-archive_write_data_block(struct archive *a, const void *buff, size_t s, int64_t o)
+la_ssize_t
+archive_write_data_block(struct archive *a, const void *buff, size_t s,
+    la_int64_t o)
 {
 	if (a->vtable->archive_write_data_block == NULL) {
 		archive_set_error(a, ARCHIVE_ERRNO_MISC,
@@ -156,7 +157,7 @@ archive_read_next_header2(struct archive *a, struct archive_entry *entry)
 
 int
 archive_read_data_block(struct archive *a,
-    const void **buff, size_t *s, int64_t *o)
+    const void **buff, size_t *s, la_int64_t *o)
 {
 	return ((a->vtable->archive_read_data_block)(a, buff, s, o));
 }

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_write.3

@@ -71,7 +71,7 @@ support.
 .\"
 .Ss Set options
 See
-.Xr archive_read_set_options 3 .
+.Xr archive_write_set_options 3 .
 .\"
 .Ss Open archive
 See

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

@@ -190,7 +190,7 @@ archive_write_get_bytes_in_last_block(struct archive *_a)
  * an archive to itself recursively.
  */
 int
-archive_write_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+archive_write_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
 {
 	struct archive_write *a = (struct archive_write *)_a;
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,

+ 1 - 0
Utilities/cmlibarchive/libarchive/archive_write_add_filter.c

@@ -53,6 +53,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
 	{ ARCHIVE_FILTER_LZOP,		archive_write_add_filter_lzip },
 	{ ARCHIVE_FILTER_UU,		archive_write_add_filter_uuencode },
 	{ ARCHIVE_FILTER_XZ,		archive_write_add_filter_xz },
+	{ ARCHIVE_FILTER_ZSTD,		archive_write_add_filter_zstd },
 	{ -1,			NULL }
 };
 

+ 1 - 0
Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c

@@ -57,6 +57,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
 	{ "lzop",		archive_write_add_filter_lzop },
 	{ "uuencode",		archive_write_add_filter_uuencode },
 	{ "xz",			archive_write_add_filter_xz },
+	{ "zstd",		archive_write_add_filter_zstd },
 	{ NULL,			NULL }
 };
 

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

@@ -226,7 +226,12 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
 		data->compressed[7] = (uint8_t)(t>>24)&0xff;
 	} else
 		memset(&data->compressed[4], 0, 4);
-	data->compressed[8] = 0; /* No deflate options */
+    if (data->compression_level == 9)
+	    data->compressed[8] = 2;
+    else if(data->compression_level == 1)
+	    data->compressed[8] = 4;
+    else
+	    data->compressed[8] = 0;
 	data->compressed[9] = 3; /* OS=Unix */
 	data->stream.next_out += 10;
 	data->stream.avail_out -= 10;

+ 335 - 0
Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c

@@ -0,0 +1,335 @@
+/*-
+ * Copyright (c) 2017 Sean Purcell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_ZSTD_H
+#include <zstd.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_string.h"
+#include "archive_write_private.h"
+
+/* Don't compile this if we don't have zstd.h */
+
+struct private_data {
+	int		 compression_level;
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+	ZSTD_CStream	*cstream;
+	int64_t		 total_in;
+	ZSTD_outBuffer	 out;
+#else
+	struct archive_write_program_data *pdata;
+#endif
+};
+
+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_close(struct archive_write_filter *);
+static int archive_compressor_zstd_free(struct archive_write_filter *);
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+static int drive_compressor(struct archive_write_filter *,
+		    struct private_data *, int, const void *, size_t);
+#endif
+
+
+/*
+ * Add a zstd compression filter to this write handle.
+ */
+int
+archive_write_add_filter_zstd(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+	struct private_data *data;
+	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_add_filter_zstd");
+
+	data = calloc(1, sizeof(*data));
+	if (data == NULL) {
+		archive_set_error(&a->archive, ENOMEM, "Out of memory");
+		return (ARCHIVE_FATAL);
+	}
+	f->data = data;
+	f->open = &archive_compressor_zstd_open;
+	f->options = &archive_compressor_zstd_options;
+	f->close = &archive_compressor_zstd_close;
+	f->free = &archive_compressor_zstd_free;
+	f->code = ARCHIVE_FILTER_ZSTD;
+	f->name = "zstd";
+	data->compression_level = 3; /* Default level used by the zstd CLI */
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+	data->cstream = ZSTD_createCStream();
+	if (data->cstream == NULL) {
+		free(data);
+		archive_set_error(&a->archive, ENOMEM,
+		    "Failed to allocate zstd compressor object");
+		return (ARCHIVE_FATAL);
+	}
+
+	return (ARCHIVE_OK);
+#else
+	data->pdata = __archive_write_program_allocate("zstd");
+	if (data->pdata == NULL) {
+		free(data);
+		archive_set_error(&a->archive, ENOMEM, "Out of memory");
+		return (ARCHIVE_FATAL);
+	}
+	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+	    "Using external zstd program");
+	return (ARCHIVE_WARN);
+#endif
+}
+
+static int
+archive_compressor_zstd_free(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+	ZSTD_freeCStream(data->cstream);
+	free(data->out.dst);
+#else
+	__archive_write_program_free(data->pdata);
+#endif
+	free(data);
+	f->data = NULL;
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
+    const char *value)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	if (strcmp(key, "compression-level") == 0) {
+		int level = atoi(value);
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+		if (level < 1 || level > ZSTD_maxCLevel()) {
+#else
+		/* If we don't have the library, hard-code the max level */
+		if (level < 1 || level > 22) {
+#endif
+			return (ARCHIVE_WARN);
+		}
+		data->compression_level = level;
+		return (ARCHIVE_OK);
+	}
+
+	/* Note: The "warn" return is just to inform the options
+	 * supervisor that we didn't handle it.  It will generate
+	 * a suitable error if no one used this option. */
+	return (ARCHIVE_WARN);
+}
+
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_zstd_open(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	int ret;
+
+	ret = __archive_write_open_filter(f->next_filter);
+	if (ret != ARCHIVE_OK)
+		return (ret);
+
+	if (data->out.dst == NULL) {
+		size_t bs = ZSTD_CStreamOutSize(), bpb;
+		if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
+			/* Buffer size should be a multiple number of
+			 * the of bytes per block for performance. */
+			bpb = archive_write_get_bytes_per_block(f->archive);
+			if (bpb > bs)
+				bs = bpb;
+			else if (bpb != 0)
+				bs -= bs % bpb;
+		}
+		data->out.size = bs;
+		data->out.pos = 0;
+		data->out.dst
+		    = (unsigned char *)malloc(data->out.size);
+		if (data->out.dst == NULL) {
+			archive_set_error(f->archive, ENOMEM,
+			    "Can't allocate data for compression buffer");
+			return (ARCHIVE_FATAL);
+		}
+	}
+
+	f->write = archive_compressor_zstd_write;
+
+	if (ZSTD_isError(ZSTD_initCStream(data->cstream,
+	    data->compression_level))) {
+		archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+		    "Internal error initializing zstd compressor object");
+		return (ARCHIVE_FATAL);
+	}
+
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+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;
+
+	if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK)
+		return (ret);
+
+	return (ARCHIVE_OK);
+}
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_zstd_close(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	int r1, r2;
+
+	/* Finish zstd frame */
+	r1 = drive_compressor(f, data, 1, NULL, 0);
+
+	r2 = __archive_write_close_filter(f->next_filter);
+
+	return r1 < r2 ? r1 : r2;
+}
+
+/*
+ * 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)
+{
+	ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 };
+
+	for (;;) {
+		if (data->out.pos == data->out.size) {
+			const int ret = __archive_write_filter(f->next_filter,
+			    data->out.dst, data->out.size);
+			if (ret != ARCHIVE_OK)
+				return (ARCHIVE_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);
+			}
+		}
+	}
+}
+
+#else /* HAVE_ZSTD_H && HAVE_LIBZSTD */
+
+static int
+archive_compressor_zstd_open(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+	struct archive_string as;
+	int r;
+
+	archive_string_init(&as);
+	archive_string_sprintf(&as, "zstd -%d", data->compression_level);
+
+	f->write = archive_compressor_zstd_write;
+	r = __archive_write_program_open(f, data->pdata, as.s);
+	archive_string_free(&as);
+	return (r);
+}
+
+static int
+archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
+    size_t length)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	return __archive_write_program_write(f, data->pdata, buff, length);
+}
+
+static int
+archive_compressor_zstd_close(struct archive_write_filter *f)
+{
+	struct private_data *data = (struct private_data *)f->data;
+
+	return __archive_write_program_close(f, data->pdata);
+}
+
+#endif /* HAVE_ZSTD_H && HAVE_LIBZSTD */

+ 8 - 4
Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c

@@ -835,7 +835,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
 }
 
 int
-archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+archive_write_disk_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
 {
 	struct archive_write_disk *a = (struct archive_write_disk *)_a;
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
@@ -1786,7 +1786,7 @@ finish_metadata:
 int
 archive_write_disk_set_group_lookup(struct archive *_a,
     void *private_data,
-    int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
+    la_int64_t (*lookup_gid)(void *private, const char *gname, la_int64_t gid),
     void (*cleanup_gid)(void *private))
 {
 	struct archive_write_disk *a = (struct archive_write_disk *)_a;
@@ -1822,7 +1822,7 @@ archive_write_disk_set_user_lookup(struct archive *_a,
 }
 
 int64_t
-archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+archive_write_disk_gid(struct archive *_a, const char *name, la_int64_t id)
 {
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
@@ -1833,7 +1833,7 @@ archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
 }
  
 int64_t
-archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id)
 {
 	struct archive_write_disk *a = (struct archive_write_disk *)_a;
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
@@ -1981,6 +1981,10 @@ restore_entry(struct archive_write_disk *a)
 	if ((en == EISDIR || en == EEXIST)
 	    && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
 		/* If we're not overwriting, we're done. */
+		if (S_ISDIR(a->mode)) {
+			/* Don't overwrite any settings on existing directories. */
+			a->todo = 0;
+		}
 		archive_entry_unset_size(a->entry);
 		return (ARCHIVE_OK);
 	}

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

@@ -906,7 +906,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
 }
 
 int
-archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+archive_write_disk_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
 {
 	struct archive_write_disk *a = (struct archive_write_disk *)_a;
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
@@ -1156,7 +1156,7 @@ _archive_write_disk_finish_entry(struct archive *_a)
 int
 archive_write_disk_set_group_lookup(struct archive *_a,
     void *private_data,
-    int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
+    la_int64_t (*lookup_gid)(void *private, const char *gname, la_int64_t gid),
     void (*cleanup_gid)(void *private))
 {
 	struct archive_write_disk *a = (struct archive_write_disk *)_a;
@@ -1192,7 +1192,7 @@ archive_write_disk_set_user_lookup(struct archive *_a,
 }
 
 int64_t
-archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+archive_write_disk_gid(struct archive *_a, const char *name, la_int64_t id)
 {
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
@@ -1203,7 +1203,7 @@ archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
 }
  
 int64_t
-archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id)
 {
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
@@ -1322,9 +1322,20 @@ restore_entry(struct archive_write_disk *a)
 		}
 	}
 
+	if ((en == ENOENT) && (archive_entry_hardlink(a->entry) != NULL)) {
+		archive_set_error(&a->archive, en,
+			"Hard-link target '%s' does not exist.",
+			archive_entry_hardlink(a->entry));
+		return (ARCHIVE_FAILED);
+	}
+
 	if ((en == EISDIR || en == EEXIST)
 	    && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
 		/* If we're not overwriting, we're done. */
+		if (S_ISDIR(a->mode)) {
+			/* Don't overwrite any settings on existing directories. */
+			a->todo = 0;
+		}
 		archive_entry_unset_size(a->entry);
 		return (ARCHIVE_OK);
 	}

+ 5 - 1
Utilities/cmlibarchive/libarchive/archive_write_filter.3

@@ -42,7 +42,8 @@
 .Nm archive_write_add_filter_none ,
 .Nm archive_write_add_filter_program ,
 .Nm archive_write_add_filter_uuencode ,
-.Nm archive_write_add_filter_xz
+.Nm archive_write_add_filter_xz ,
+.Nm archive_write_add_filter_zstd ,
 .Nd functions enabling output filters
 .Sh LIBRARY
 Streaming Archive Library (libarchive, -larchive)
@@ -76,6 +77,8 @@ Streaming Archive Library (libarchive, -larchive)
 .Fn archive_write_add_filter_uuencode "struct archive *"
 .Ft int
 .Fn archive_write_add_filter_xz "struct archive *"
+.Ft int
+.Fn archive_write_add_filter_zstd "struct archive *"
 .Sh DESCRIPTION
 .Bl -tag -width indent
 .It Xo
@@ -89,6 +92,7 @@ Streaming Archive Library (libarchive, -larchive)
 .Fn archive_write_add_filter_lzma ,
 .Fn archive_write_add_filter_lzop ,
 .Fn archive_write_add_filter_xz ,
+.Fn archive_write_add_filter_zstd ,
 .Xc
 The resulting archive will be compressed as specified.
 Note that the compressed output is always properly blocked.

+ 2 - 15
Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c

@@ -2095,19 +2095,6 @@ compression_init_encoder_lzma2(struct archive *a,
 /*
  * _7_PPMD compressor.
  */
-static void *
-ppmd_alloc(void *p, size_t size)
-{
-	(void)p;
-	return malloc(size);
-}
-static void
-ppmd_free(void *p, void *address)
-{
-	(void)p;
-	free(address);
-}
-static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
 static void
 ppmd_write(void *p, Byte b)
 {
@@ -2167,7 +2154,7 @@ compression_init_encoder_ppmd(struct archive *a,
 	archive_le32enc(props+1, msize);
 	__archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context);
 	r = __archive_ppmd7_functions.Ppmd7_Alloc(
-		&strm->ppmd7_context, msize, &g_szalloc);
+		&strm->ppmd7_context, msize);
 	if (r == 0) {
 		free(strm->buff);
 		free(strm);
@@ -2243,7 +2230,7 @@ compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
 	(void)a; /* UNUSED */
 
 	strm = (struct ppmd_stream *)lastrm->real_stream;
-	__archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context, &g_szalloc);
+	__archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context);
 	free(strm->buff);
 	free(strm);
 	lastrm->real_stream = NULL;

+ 9 - 8
Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c

@@ -180,7 +180,7 @@ archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
 	}
 
 	memset(buff, ' ', 60);
-	strncpy(&buff[AR_fmag_offset], "`\n", 2);
+	memcpy(&buff[AR_fmag_offset], "`\n", 2);
 
 	if (strcmp(pathname, "/") == 0 ) {
 		/* Entry is archive symbol table in GNU format */
@@ -189,7 +189,7 @@ archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
 	}
 	if (strcmp(pathname, "__.SYMDEF") == 0) {
 		/* Entry is archive symbol table in BSD format */
-		strncpy(buff + AR_name_offset, "__.SYMDEF", 9);
+		memcpy(buff + AR_name_offset, "__.SYMDEF", 9);
 		goto stat;
 	}
 	if (strcmp(pathname, "//") == 0) {
@@ -225,7 +225,7 @@ archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
 		 * actually 15 bytes.
 		 */
 		if (strlen(filename) <= 15) {
-			strncpy(&buff[AR_name_offset], 
+			memcpy(&buff[AR_name_offset],
 			    filename, strlen(filename));
 			buff[AR_name_offset + strlen(filename)] = '/';
 		} else {
@@ -248,7 +248,7 @@ archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
 				return (ARCHIVE_FATAL);
 			}
 
-			strncpy(se, filename, strlen(filename));
+			memcpy(se, filename, strlen(filename));
 			strcpy(se + strlen(filename), "/\n");
 
 			ss = strstr(ar->strtab, se);
@@ -285,11 +285,11 @@ archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
 		 * archive header.
 		 */
 		if (strlen(filename) <= 16 && strchr(filename, ' ') == NULL) {
-			strncpy(&buff[AR_name_offset], filename, strlen(filename));
+			memcpy(&buff[AR_name_offset], filename, strlen(filename));
 			buff[AR_name_offset + strlen(filename)] = ' ';
 		}
 		else {
-			strncpy(buff + AR_name_offset, "#1/", 3);
+			memcpy(buff + AR_name_offset, "#1/", 3);
 			if (format_decimal(strlen(filename),
 			    buff + AR_name_offset + 3,
 			    AR_name_size - 3)) {
@@ -374,13 +374,14 @@ archive_write_ar_data(struct archive_write *a, const void *buff, size_t s)
 			return (ARCHIVE_WARN);
 		}
 
-		ar->strtab = (char *)malloc(s);
+		ar->strtab = (char *)malloc(s + 1);
 		if (ar->strtab == NULL) {
 			archive_set_error(&a->archive, ENOMEM,
 			    "Can't allocate strtab buffer");
 			return (ARCHIVE_FATAL);
 		}
-		strncpy(ar->strtab, buff, s);
+		memcpy(ar->strtab, buff, s);
+		ar->strtab[s] = '\0';
 		ar->has_strtab = 1;
 	}
 

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

@@ -1654,7 +1654,7 @@ build_pax_attribute_name(char *dest, const char *src)
  * GNU PAX Format 1.0 requires the special name, which pattern is:
  * <dir>/GNUSparseFile.<pid>/<original file name>
  *
- * Since reproducable archives are more important, use 0 as pid.
+ * Since reproducible archives are more important, use 0 as pid.
  *
  * This function is used for only Sparse file, a file type of which
  * is regular file.