Bladeren bron

Merge branch 'upstream-LibArchive' into update-libarchive

* upstream-LibArchive:
  LibArchive 2024-09-13 (12ecf841)
Brad King 1 jaar geleden
bovenliggende
commit
fe3f0d469f
100 gewijzigde bestanden met toevoegingen van 939 en 497 verwijderingen
  1. 108 17
      Utilities/cmlibarchive/CMakeLists.txt
  2. 34 0
      Utilities/cmlibarchive/build/cmake/FindPCRE2POSIX.cmake
  3. 14 6
      Utilities/cmlibarchive/build/cmake/config.h.in
  4. 0 3
      Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh
  5. 1 1
      Utilities/cmlibarchive/build/version
  6. 6 1
      Utilities/cmlibarchive/libarchive/CMakeLists.txt
  7. 7 5
      Utilities/cmlibarchive/libarchive/archive.h
  8. 29 23
      Utilities/cmlibarchive/libarchive/archive_acl.c
  9. 2 2
      Utilities/cmlibarchive/libarchive/archive_acl_private.h
  10. 10 10
      Utilities/cmlibarchive/libarchive/archive_check_magic.c
  11. 0 2
      Utilities/cmlibarchive/libarchive/archive_cmdline.c
  12. 0 2
      Utilities/cmlibarchive/libarchive/archive_cmdline_private.h
  13. 5 2
      Utilities/cmlibarchive/libarchive/archive_crc32.h
  14. 2 2
      Utilities/cmlibarchive/libarchive/archive_cryptor.c
  15. 0 2
      Utilities/cmlibarchive/libarchive/archive_endian.h
  16. 0 2
      Utilities/cmlibarchive/libarchive/archive_entry.3
  17. 230 96
      Utilities/cmlibarchive/libarchive/archive_entry.c
  18. 11 3
      Utilities/cmlibarchive/libarchive/archive_entry.h
  19. 1 1
      Utilities/cmlibarchive/libarchive/archive_entry_acl.3
  20. 0 1
      Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c
  21. 0 1
      Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c
  22. 15 1
      Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c
  23. 0 2
      Utilities/cmlibarchive/libarchive/archive_entry_locale.h
  24. 1 0
      Utilities/cmlibarchive/libarchive/archive_entry_perms.3
  25. 6 4
      Utilities/cmlibarchive/libarchive/archive_entry_private.h
  26. 0 1
      Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
  27. 0 1
      Utilities/cmlibarchive/libarchive/archive_entry_stat.c
  28. 0 1
      Utilities/cmlibarchive/libarchive/archive_entry_strmode.c
  29. 0 2
      Utilities/cmlibarchive/libarchive/archive_entry_time.3
  30. 0 1
      Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
  31. 0 4
      Utilities/cmlibarchive/libarchive/archive_getdate.c
  32. 0 2
      Utilities/cmlibarchive/libarchive/archive_getdate.h
  33. 12 17
      Utilities/cmlibarchive/libarchive/archive_match.c
  34. 0 1
      Utilities/cmlibarchive/libarchive/archive_options.c
  35. 0 2
      Utilities/cmlibarchive/libarchive/archive_options_private.h
  36. 0 7
      Utilities/cmlibarchive/libarchive/archive_pack_dev.c
  37. 0 1
      Utilities/cmlibarchive/libarchive/archive_pathmatch.c
  38. 0 2
      Utilities/cmlibarchive/libarchive/archive_pathmatch.h
  39. 0 15
      Utilities/cmlibarchive/libarchive/archive_platform.h
  40. 0 2
      Utilities/cmlibarchive/libarchive/archive_platform_acl.h
  41. 0 2
      Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
  42. 2 3
      Utilities/cmlibarchive/libarchive/archive_ppmd8.c
  43. 8 6
      Utilities/cmlibarchive/libarchive/archive_private.h
  44. 0 1
      Utilities/cmlibarchive/libarchive/archive_random.c
  45. 0 2
      Utilities/cmlibarchive/libarchive/archive_read.3
  46. 1 2
      Utilities/cmlibarchive/libarchive/archive_read.c
  47. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
  48. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
  49. 1 2
      Utilities/cmlibarchive/libarchive/archive_read_append_filter.c
  50. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_data.3
  51. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
  52. 2 4
      Utilities/cmlibarchive/libarchive/archive_read_disk.3
  53. 1 1
      Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
  54. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
  55. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
  56. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
  57. 3 1
      Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
  58. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_extract.3
  59. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_extract.c
  60. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_extract2.c
  61. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_filter.3
  62. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_format.3
  63. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_free.3
  64. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_header.3
  65. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_new.3
  66. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_open.3
  67. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
  68. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_open_file.c
  69. 71 41
      Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
  70. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
  71. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_private.h
  72. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_set_format.c
  73. 0 2
      Utilities/cmlibarchive/libarchive/archive_read_set_options.3
  74. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_set_options.c
  75. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
  76. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c
  77. 1 3
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
  78. 1 2
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
  79. 0 3
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_grzip.c
  80. 1 4
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
  81. 0 3
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_lrzip.c
  82. 3 5
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
  83. 4 5
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
  84. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c
  85. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
  86. 26 19
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c
  87. 12 5
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
  88. 15 5
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
  89. 1 3
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
  90. 31 12
      Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
  91. 1 2
      Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
  92. 5 6
      Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
  93. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
  94. 1 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
  95. 19 10
      Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
  96. 0 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
  97. 112 9
      Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
  98. 8 7
      Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
  99. 4 5
      Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
  100. 111 34
      Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c

+ 108 - 17
Utilities/cmlibarchive/CMakeLists.txt

@@ -1,12 +1,19 @@
 #
 IF(0) # CMake handles policy settings in its own build.
 CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
+if(APPLE AND CMAKE_VERSION VERSION_LESS "3.17.0")
+  message(WARNING "CMake>=3.17.0 required to make the generated shared library have the same Mach-O headers as autotools")
+endif()
+
 if(POLICY CMP0065)
   cmake_policy(SET CMP0065 NEW) #3.4 don't use `-rdynamic` with executables
 endif()
 if(POLICY CMP0074)
   cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``<PackageName>_ROOT`` variables.
 endif()
+if(POLICY CMP0075)
+  cmake_policy(SET CMP0075 NEW) #3.12.0 `check_include_file()`` and friends use ``CMAKE_REQUIRED_LIBRARIES``.
+endif()
 ENDIF()
 #
 PROJECT(libarchive C)
@@ -23,6 +30,7 @@ IF(0) # CMake handles build type selection in its own build.
 #   Release        : Release build
 #   RelWithDebInfo : Release build with Debug Info
 #   MinSizeRel     : Release Min Size build
+#   None           : No build type
 IF(NOT CMAKE_BUILD_TYPE)
   SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
 ENDIF(NOT CMAKE_BUILD_TYPE)
@@ -33,13 +41,15 @@ IF("${cached_type}" STREQUAL "UNINITIALIZED")
   SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Build Type" FORCE)
 ENDIF("${cached_type}" STREQUAL "UNINITIALIZED")
 # Check the Build Type.
-IF(NOT "${CMAKE_BUILD_TYPE}"
-       MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
+# Convert the CMAKE_BUILD_TYPE to uppercase to perform a case-insensitive comparison.
+string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER)
+IF(NOT "${CMAKE_BUILD_TYPE_UPPER}"
+       MATCHES "^(DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL|NONE)\$")
   MESSAGE(FATAL_ERROR
           "Unknown keyword for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n"
-          "Acceptable keywords: Debug,Release,RelWithDebInfo,MinSizeRel")
-ENDIF(NOT "${CMAKE_BUILD_TYPE}"
-          MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
+          "Acceptable keywords: Debug, Release, RelWithDebInfo, MinSizeRel, None")
+ENDIF(NOT "${CMAKE_BUILD_TYPE_UPPER}"
+       MATCHES "^(DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL|NONE)\$")
 ENDIF()
 
 # On MacOS, prefer MacPorts libraries to system libraries.
@@ -81,9 +91,21 @@ SET(LIBARCHIVE_VERSION_STRING  "${VERSION}")
 # libarchive 3.1 == interface version 13
 math(EXPR INTERFACE_VERSION  "13 + ${_minor}")
 
-# Set SOVERSION == Interface version
-# ?? Should there be more here ??
-SET(SOVERSION "${INTERFACE_VERSION}")
+# Set SOVERSION so it matches libtool's conventions
+# libtool accepts a string "current:revision:age"; in libarchive, that's set to
+# - current: ${INTERFACE_VERSION} = 13 + ${_minor}
+# - revision: ${_revision}
+# - age: ${_minor}
+# Since libtool computes SOVERSION as "current - age", it's just '13' again
+math(EXPR SOVERSION "${INTERFACE_VERSION} - ${_minor}")
+set(SOVERSION_FULL "${SOVERSION}.${_trimmed_minor}.${_trimmed_revision}")
+
+# Override CMake's default shared library versioning scheme, which uses SOVERSION and VERSION,
+# to match libtool's conventions (see https://github.com/mesonbuild/meson/issues/1451)
+# - compatibility version: current + 1 = ${INTERFACE_VERSION} + 1
+# - current version: ${current + 1}.${revision}
+math(EXPR MACHO_COMPATIBILITY_VERSION "${INTERFACE_VERSION} + 1")
+set(MACHO_CURRENT_VERSION "${MACHO_COMPATIBILITY_VERSION}.${_revision}")
 
 # Enable CMAKE_PUSH_CHECK_STATE() and CMAKE_POP_CHECK_STATE() macros
 # saving and restoring the state of the variables.
@@ -125,7 +147,7 @@ endif ()
 # aggressive about diagnosing build problems; this can get
 # relaxed somewhat in final shipping versions.
 IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
-    CMAKE_C_COMPILER_ID MATCHES "^Clang$")
+    CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
   SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
   #################################################################
   # Set compile flags for all build types.
@@ -148,8 +170,6 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
   # either of the following two, yet neither is supported as of 3.0.2
   # - check_linker_flag - does not exist
   # - try_compile - does not support linker flags
-  #
-  # The CI fails with this on MacOS
   IF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
     # Place the functions and data into separate sections, allowing the linker
     # to garbage collect the unused ones.
@@ -159,9 +179,12 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
     # Printing the discarded section is "too much", so enable on demand.
     #SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections")
     #SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections")
+  ELSE()
+    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip")
+    SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
   ENDIF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
 ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
-       CMAKE_C_COMPILER_ID MATCHES "^Clang$")
+       CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND NOT MSVC)
 IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
   SET(CMAKE_C_COMPILER "xlc_r")
   SET(CMAKE_REQUIRED_FLAGS "-qflag=e:e -qformat=sec")
@@ -241,6 +264,7 @@ OPTION(ENABLE_BZip2 "Enable the use of the system BZip2 library if found" ON)
 OPTION(ENABLE_LIBXML2 "Enable the use of the system libxml2 library if found" ON)
 OPTION(ENABLE_EXPAT "Enable the use of the system EXPAT library if found" ON)
 OPTION(ENABLE_PCREPOSIX "Enable the use of the system PCREPOSIX library if found" ON)
+OPTION(ENABLE_PCRE2POSIX "Enable the use of the system PCRE2POSIX library if found" ON)
 OPTION(ENABLE_LIBGCC "Enable the use of the system LibGCC library if found" ON)
 # CNG is used for encrypt/decrypt Zip archives on Windows.
 OPTION(ENABLE_CNG "Enable the use of CNG(Crypto Next Generation)" ON)
@@ -549,7 +573,7 @@ IF(LIBLZMA_FOUND)
       "#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
       "WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
     CHECK_C_SOURCE_COMPILES(
-      "#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
+      "#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){int ignored __attribute__((unused)); ignored = lzma_stream_encoder_mt(0, 0); return 0;}"
       HAVE_LZMA_STREAM_ENCODER_MT)
     IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
       ADD_DEFINITIONS(-DLZMA_API_STATIC)
@@ -675,13 +699,13 @@ IF(ZSTD_FOUND)
   INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR})
   LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY})
   SET(HAVE_LIBZSTD 1)
-  SET(HAVE_LIBZSTD_COMPRESSOR 1)
+  SET(HAVE_ZSTD_compressStream 1)
   IF(0) # CMake expects the zstd library to work.
   CMAKE_PUSH_CHECK_STATE()
   SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY})
   SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR})
   CHECK_FUNCTION_EXISTS(ZSTD_decompressStream HAVE_LIBZSTD)
-  CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD_COMPRESSOR)
+  CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_ZSTD_compressStream)
   #
   # TODO: test for static library.
   #
@@ -766,7 +790,6 @@ LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
 LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
 LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
 LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
-LA_CHECK_INCLUDE_FILE("sys/queue.h" HAVE_SYS_QUEUE_H)
 LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
 LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
 LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
@@ -1220,7 +1243,7 @@ ENDIF(ENABLE_ICONV)
 #
 # Find Libxml2
 #
-IF(ENABLE_LIBXML2)
+IF(ENABLE_LIBXML2 AND HAVE_ICONV)
   FIND_PACKAGE(LibXml2)
 ELSE()
   SET(LIBXML2_FOUND FALSE)
@@ -1379,6 +1402,68 @@ IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$"
   MARK_AS_ADVANCED(CLEAR LIBGCC_LIBRARIES)
 ENDIF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$")
 
+IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCRE2POSIX)$")
+  #
+  # If requested, try finding library for PCRE2POSIX
+  #
+  IF(ENABLE_LIBGCC)
+    FIND_PACKAGE(LIBGCC)
+  ELSE()
+    MESSAGE(FATAL_ERROR "libgcc not found.")
+    SET(LIBGCC_FOUND FALSE) # Override cached value
+  ENDIF()
+  IF(ENABLE_PCRE2POSIX)
+    FIND_PACKAGE(PCRE2POSIX)
+  ELSE()
+    SET(PCRE2POSIX_FOUND FALSE) # Override cached value
+  ENDIF()
+  IF(PCRE2POSIX_FOUND)
+    INCLUDE_DIRECTORIES(${PCRE2_INCLUDE_DIR})
+    LIST(APPEND ADDITIONAL_LIBS ${PCRE2POSIX_LIBRARIES})
+    # Test if a macro is needed for the library.
+    TRY_MACRO_FOR_LIBRARY(
+      "${PCRE2_INCLUDE_DIR}" "${PCRE2POSIX_LIBRARIES}"
+      COMPILES
+      "#include <pcre2posix.h>\nint main() {regex_t r;return pcre2_regcomp(&r, \"\", 0);}"
+      "WITHOUT_PCRE2_STATIC;PCRE2_STATIC")
+    IF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+      ADD_DEFINITIONS(-DPCRE2_STATIC)
+	ELSEIF(NOT WITHOUT_PCRE2_STATIC AND NOT PCRE2_STATIC AND PCRE2_FOUND)
+	  # Determine if pcre2 static libraries are to be used.
+      LIST(APPEND ADDITIONAL_LIBS ${PCRE2_LIBRARIES})
+      SET(TMP_LIBRARIES ${PCRE2POSIX_LIBRARIES} ${PCRE2_LIBRARIES})
+      MESSAGE(STATUS "trying again with -lpcre2-8 included")
+      TRY_MACRO_FOR_LIBRARY(
+        "${PCRE2_INCLUDE_DIR}" "${TMP_LIBRARIES}"
+        COMPILES
+        "#include <pcre2posix.h>\nint main() {regex_t r;return pcre2_regcomp(&r, \"\", 0);}"
+        "WITHOUT_PCRE2_STATIC;PCRE2_STATIC")
+      IF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+        ADD_DEFINITIONS(-DPCRE2_STATIC)
+      ELSEIF(NOT WITHOUT_PCRE2_STATIC AND NOT PCRE2_STATIC AND MSVC AND LIBGCC_FOUND)
+        # When doing a Visual Studio build using pcre2 static libraries
+        # built using the mingw toolchain, -lgcc is needed to resolve
+        # ___chkstk_ms.
+        MESSAGE(STATUS "Visual Studio build detected, trying again with -lgcc included")
+        LIST(APPEND ADDITIONAL_LIBS ${LIBGCC_LIBRARIES})
+        SET(TMP_LIBRARIES ${PCRE2POSIX_LIBRARIES} ${PCRE2_LIBRARIES} ${LIBGCC_LIBRARIES})
+          TRY_MACRO_FOR_LIBRARY(
+            "${PCRE2_INCLUDE_DIR}" "${TMP_LIBRARIES}"
+            COMPILES
+            "#include <pcre2posix.h>\nint main() {regex_t r;return pcre2_regcomp(&r, \"\", 0);}"
+            "WITHOUT_PCRE2_STATIC;PCRE2_STATIC")
+          IF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+            ADD_DEFINITIONS(-DPCRE2_STATIC)
+          ENDIF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+      ENDIF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+    ENDIF(NOT WITHOUT_PCRE2_STATIC AND PCRE2_STATIC)
+  ENDIF(PCRE2POSIX_FOUND)
+  MARK_AS_ADVANCED(CLEAR PCRE2_INCLUDE_DIR)
+  MARK_AS_ADVANCED(CLEAR PCRE2POSIX_LIBRARIES)
+  MARK_AS_ADVANCED(CLEAR PCRE2_LIBRARIES)
+  MARK_AS_ADVANCED(CLEAR LIBGCC_LIBRARIES)
+ENDIF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCRE2POSIX)$")
+
 #
 # Check functions
 #
@@ -1460,6 +1545,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S)
 CHECK_FUNCTION_EXISTS_GLIBC(strnlen HAVE_STRNLEN)
 CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
 CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
+CHECK_FUNCTION_EXISTS_GLIBC(sysconf HAVE_SYSCONF)
 CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
 CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
 CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT)
@@ -2077,6 +2163,11 @@ IF(APPLE)
   ADD_DEFINITIONS(-Wno-deprecated-declarations)
 ENDIF(APPLE)
 
+OPTION(DONT_FAIL_ON_CRC_ERROR "Ignore CRC errors during parsing (For fuzzing)" OFF)
+IF(DONT_FAIL_ON_CRC_ERROR)
+  ADD_DEFINITIONS(-DDONT_FAIL_ON_CRC_ERROR=1)
+ENDIF(DONT_FAIL_ON_CRC_ERROR)
+
 IF(ENABLE_TEST)
   ADD_CUSTOM_TARGET(run_all_tests)
 ENDIF(ENABLE_TEST)

+ 34 - 0
Utilities/cmlibarchive/build/cmake/FindPCRE2POSIX.cmake

@@ -0,0 +1,34 @@
+# - Find pcre2posix
+# Find the native PCRE2-8 and PCRE2-POSIX include and libraries
+#
+#  PCRE2_INCLUDE_DIR    - where to find pcre2posix.h, etc.
+#  PCRE2POSIX_LIBRARIES - List of libraries when using libpcre2-posix.
+#  PCRE2_LIBRARIES      - List of libraries when using libpcre2-8.
+#  PCRE2POSIX_FOUND     - True if libpcre2-posix found.
+#  PCRE2_FOUND          - True if libpcre2-8 found.
+
+IF (PCRE2_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(PCRE2_FIND_QUIETLY TRUE)
+ENDIF (PCRE2_INCLUDE_DIR)
+
+FIND_PATH(PCRE2_INCLUDE_DIR pcre2posix.h)
+FIND_LIBRARY(PCRE2POSIX_LIBRARY NAMES pcre2-posix libpcre2-posix pcre2-posix-static)
+FIND_LIBRARY(PCRE2_LIBRARY NAMES pcre2-8 libpcre2-8 pcre2-8-static)
+
+# handle the QUIETLY and REQUIRED arguments and set PCRE2POSIX_FOUND to TRUE if 
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2POSIX DEFAULT_MSG PCRE2POSIX_LIBRARY PCRE2_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2 DEFAULT_MSG PCRE2_LIBRARY)
+
+IF(PCRE2POSIX_FOUND)
+  SET(PCRE2POSIX_LIBRARIES ${PCRE2POSIX_LIBRARY})
+  SET(HAVE_LIBPCRE2POSIX 1)
+  SET(HAVE_PCRE2POSIX_H 1)
+ENDIF(PCRE2POSIX_FOUND)
+
+IF(PCRE2_FOUND)
+  SET(PCRE2_LIBRARIES ${PCRE2_LIBRARY})
+  SET(HAVE_LIBPCRE2 1)
+ENDIF(PCRE2_FOUND)

+ 14 - 6
Utilities/cmlibarchive/build/cmake/config.h.in

@@ -537,6 +537,12 @@
 /* Define to 1 if you have the `pcreposix' library (-lpcreposix). */
 #cmakedefine HAVE_LIBPCREPOSIX 1
 
+/* Define to 1 if you have the `pcre2-8' library (-lpcre2-8). */
+#cmakedefine HAVE_LIBPCRE2 1
+
+/* Define to 1 if you have the `pcreposix' library (-lpcre2posix). */
+#cmakedefine HAVE_LIBPCRE2POSIX 1
+
 /* Define to 1 if you have the `xml2' library (-lxml2). */
 #cmakedefine HAVE_LIBXML2 1
 
@@ -552,9 +558,8 @@
 /* Define to 1 if you have the `zstd' library (-lzstd). */
 #cmakedefine HAVE_LIBZSTD 1
 
-/* Define to 1 if you have the `zstd' library (-lzstd) with compression
-   support. */
-#cmakedefine HAVE_LIBZSTD_COMPRESSOR 1
+/* Define to 1 if you have the ZSTD_compressStream function. */
+#cmakedefine HAVE_ZSTD_compressStream 1
 
 /* Define to 1 if you have the <limits.h> header file. */
 #cmakedefine HAVE_LIMITS_H 1
@@ -710,6 +715,9 @@
 /* Define to 1 if you have the <pcreposix.h> header file. */
 #cmakedefine HAVE_PCREPOSIX_H 1
 
+/* Define to 1 if you have the <pcre2posix.h> header file. */
+#cmakedefine HAVE_PCRE2POSIX_H 1
+
 /* Define to 1 if you have the `pipe' function. */
 #cmakedefine HAVE_PIPE 1
 
@@ -867,6 +875,9 @@
 /* Define to 1 if you have the `symlink' function. */
 #cmakedefine HAVE_SYMLINK 1
 
+/* Define to 1 if you have the `sysconf' function. */
+#cmakedefine HAVE_SYSCONF 1
+
 /* Define to 1 if you have the <sys/acl.h> header file. */
 #cmakedefine HAVE_SYS_ACL_H 1
 
@@ -902,9 +913,6 @@
 /* Define to 1 if you have the <sys/poll.h> header file. */
 #cmakedefine HAVE_SYS_POLL_H 1
 
-/* Define to 1 if you have the <sys/queue.h> header file. */
-#cmakedefine HAVE_SYS_QUEUE_H 1
-
 /* Define to 1 if you have the <sys/richacl.h> header file. */
 #cmakedefine HAVE_SYS_RICHACL_H 1
 

+ 0 - 3
Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh

@@ -39,9 +39,6 @@ cat > ${outfile} <<CR_END
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * \$FreeBSD\$
- *
  */
 
 /*

+ 1 - 1
Utilities/cmlibarchive/build/version

@@ -1 +1 @@
-3007002
+3007005

+ 6 - 1
Utilities/cmlibarchive/libarchive/CMakeLists.txt

@@ -256,11 +256,16 @@ IF(BUILD_SHARED_LIBS)
   ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
   TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
   TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
-  SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
+  SET_TARGET_PROPERTIES(archive PROPERTIES 
+                        VERSION ${SOVERSION_FULL}
+                        SOVERSION ${SOVERSION}
+                        MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
+                        MACHO_CURRENT_VERSION ${MACHO_CURRENT_VERSION})
 ENDIF(BUILD_SHARED_LIBS)
 
 # archive_static is a static library
 ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
+TARGET_INCLUDE_DIRECTORIES(archive_static PUBLIC .)
 TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
 SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
   LIBARCHIVE_STATIC)

+ 7 - 5
Utilities/cmlibarchive/libarchive/archive.h

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.50 2008/05/26 17:00:22 kientzle Exp $
  */
 
 #ifndef ARCHIVE_H_INCLUDED
@@ -36,7 +34,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3007002
+#define	ARCHIVE_VERSION_NUMBER 3007005
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -154,7 +152,7 @@ __LA_DECL int		archive_version_number(void);
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.7.2"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.7.5"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
@@ -532,6 +530,10 @@ __LA_DECL int archive_read_open_filenames(struct archive *,
 		     const char **_filenames, size_t _block_size);
 __LA_DECL int archive_read_open_filename_w(struct archive *,
 		     const wchar_t *_filename, size_t _block_size);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+__LA_DECL int archive_read_open_filenames_w(struct archive *,
+		     const wchar_t **_filenames, size_t _block_size);
+#endif
 /* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */
 __LA_DECL int archive_read_open_file(struct archive *,
 		     const char *_filename, size_t _block_size) __LA_DEPRECATED;
@@ -890,7 +892,7 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
 			    const char *opts);
 
 /*
- * Set a encryption passphrase.
+ * Set an encryption passphrase.
  */
 __LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p);
 __LA_DECL int archive_write_set_passphrase_callback(struct archive *,

+ 29 - 23
Utilities/cmlibarchive/libarchive/archive_acl.c

@@ -25,7 +25,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -81,7 +80,7 @@ static int	is_nfs4_flags(const char *start, const char *end,
 		    int *result);
 static int	is_nfs4_perms(const char *start, const char *end,
 		    int *result);
-static void	next_field(const char **p, const char **start,
+static void	next_field(const char **p, size_t *l, const char **start,
 		    const char **end, char *sep);
 static void	append_entry(char **p, const char *prefix, int type,
 		    int tag, int flags, const char *name, int perm, int id);
@@ -1627,6 +1626,13 @@ next_field_w(const wchar_t **wp, const wchar_t **start,
 int
 archive_acl_from_text_l(struct archive_acl *acl, const char *text,
     int want_type, struct archive_string_conv *sc)
+{
+	return archive_acl_from_text_nl(acl, text, strlen(text), want_type, sc);
+}
+
+int
+archive_acl_from_text_nl(struct archive_acl *acl, const char *text,
+    size_t length, int want_type, struct archive_string_conv *sc)
 {
 	struct {
 		const char *start;
@@ -1657,7 +1663,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
 	ret = ARCHIVE_OK;
 	types = 0;
 
-	while (text != NULL &&  *text != '\0') {
+	while (text != NULL && length > 0 && *text != '\0') {
 		/*
 		 * Parse the fields out of the next entry,
 		 * advance 'text' to start of next entry.
@@ -1665,7 +1671,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
 		fields = 0;
 		do {
 			const char *start, *end;
-			next_field(&text, &start, &end, &sep);
+			next_field(&text, &length, &start, &end, &sep);
 			if (fields < numfields) {
 				field[fields].start = start;
 				field[fields].end = end;
@@ -2058,7 +2064,7 @@ is_nfs4_flags(const char *start, const char *end, int *permset)
 }
 
 /*
- * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]".  *wp is updated
+ * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]".  *p is updated
  * to point to just after the separator.  *start points to the first
  * character of the matched text and *end just after the last
  * character of the matched identifier.  In particular *end - *start
@@ -2066,42 +2072,42 @@ is_nfs4_flags(const char *start, const char *end, int *permset)
  * whitespace.
  */
 static void
-next_field(const char **p, const char **start,
+next_field(const char **p, size_t *l, const char **start,
     const char **end, char *sep)
 {
 	/* Skip leading whitespace to find start of field. */
-	while (**p == ' ' || **p == '\t' || **p == '\n') {
+	while (*l > 0 && (**p == ' ' || **p == '\t' || **p == '\n')) {
 		(*p)++;
+		(*l)--;
 	}
 	*start = *p;
 
-	/* Scan for the separator. */
-	while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
-	    **p != '#') {
+	/* Locate end of field, trim trailing whitespace if necessary */
+	while (*l > 0 && **p != ' ' && **p != '\t' && **p != '\n' && **p != ',' && **p != ':' && **p != '#') {
 		(*p)++;
+		(*l)--;
 	}
-	*sep = **p;
+	*end = *p;
 
-	/* Locate end of field, trim trailing whitespace if necessary */
-	if (*p == *start) {
-		*end = *p;
-	} else {
-		*end = *p - 1;
-		while (**end == ' ' || **end == '\t' || **end == '\n') {
-			(*end)--;
-		}
-		(*end)++;
+	/* Scan for the separator. */
+	while (*l > 0 && **p != ',' && **p != ':' && **p != '\n' && **p != '#') {
+		(*p)++;
+		(*l)--;
 	}
+	*sep = **p;
 
 	/* Handle in-field comments */
 	if (*sep == '#') {
-		while (**p != '\0' && **p != ',' && **p != '\n') {
+		while (*l > 0 && **p != ',' && **p != '\n') {
 			(*p)++;
+			(*l)--;
 		}
 		*sep = **p;
 	}
 
-	/* Adjust scanner location. */
-	if (**p != '\0')
+	/* Skip separator. */
+	if (*l > 0) {
 		(*p)++;
+		(*l)--;
+	}
 }

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

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
 #ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
@@ -79,5 +77,7 @@ int archive_acl_from_text_w(struct archive_acl *, const wchar_t * /* wtext */,
     int /* type */);
 int archive_acl_from_text_l(struct archive_acl *, const char * /* text */,
     int /* type */, struct archive_string_conv *);
+int archive_acl_from_text_nl(struct archive_acl *, const char * /* text */,
+    size_t /* size of text */, int /* type */, struct archive_string_conv *);
 
 #endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_check_magic.c 201089 2009-12-28 02:20:23Z kientzle $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -62,7 +61,7 @@ errmsg(const char *m)
 	}
 }
 
-static __LA_DEAD void
+static __LA_NORETURN void
 diediedie(void)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
@@ -99,13 +98,12 @@ archive_handle_type_name(unsigned m)
 	}
 }
 
-
-static char *
+static void
 write_all_states(char *buff, unsigned int states)
 {
 	unsigned int lowbit;
 
-	buff[0] = '\0';
+	*buff = '\0';
 
 	/* A trick for computing the lowest set bit. */
 	while ((lowbit = states & (1 + ~states)) != 0) {
@@ -114,7 +112,6 @@ write_all_states(char *buff, unsigned int states)
 		if (states != 0)
 			strcat(buff, "/");
 	}
-	return buff;
 }
 
 /*
@@ -160,16 +157,19 @@ __archive_check_magic(struct archive *a, unsigned int magic,
 
 	if ((a->state & state) == 0) {
 		/* If we're already FATAL, don't overwrite the error. */
-		if (a->state != ARCHIVE_STATE_FATAL)
+		if (a->state != ARCHIVE_STATE_FATAL) {
+			write_all_states(states1, a->state);
+			write_all_states(states2, state);
 			archive_set_error(a, -1,
 			    "INTERNAL ERROR: Function '%s' invoked with"
 			    " archive structure in state '%s',"
 			    " should be in state '%s'",
 			    function,
-			    write_all_states(states1, a->state),
-			    write_all_states(states2, state));
+			    states1,
+			    states2);
+		}
 		a->state = ARCHIVE_STATE_FATAL;
 		return (ARCHIVE_FATAL);
 	}
-	return ARCHIVE_OK;
+	return (ARCHIVE_OK);
 }

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

@@ -25,8 +25,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
 #ifdef HAVE_STRING_H
 #  include <string.h>
 #endif

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

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
 #ifndef ARCHIVE_CMDLINE_PRIVATE_H

+ 5 - 2
Utilities/cmlibarchive/libarchive/archive_crc32.h

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_crc32.h 201102 2009-12-28 03:11:36Z kientzle $
  */
 
 #ifndef ARCHIVE_CRC32_H
@@ -32,6 +30,8 @@
 #error This header is only to be used internally to libarchive.
 #endif
 
+#include <stddef.h>
+
 /*
  * When zlib is unavailable, we should still be able to validate
  * uncompressed zip archives.  That requires us to be able to compute
@@ -48,6 +48,9 @@ crc32(unsigned long crc, const void *_p, size_t len)
 	static volatile int crc_tbl_inited = 0;
 	static unsigned long crc_tbl[256];
 
+	if (_p == NULL)
+		return (0);
+
 	if (!crc_tbl_inited) {
 		for (b = 0; b < 256; ++b) {
 			crc2 = b;

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

@@ -424,8 +424,8 @@ static int
 aes_ctr_release(archive_crypto_ctx *ctx)
 {
 	EVP_CIPHER_CTX_free(ctx->ctx);
-	memset(ctx->key, 0, ctx->key_len);
-	memset(ctx->nonce, 0, sizeof(ctx->nonce));
+	OPENSSL_cleanse(ctx->key, ctx->key_len);
+	OPENSSL_cleanse(ctx->nonce, sizeof(ctx->nonce));
 	return 0;
 }
 

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

@@ -23,8 +23,6 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/libarchive/archive_endian.h 201085 2009-12-28 02:17:15Z kientzle $
- *
  * Borrowed from FreeBSD's <sys/endian.h>
  */
 

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_entry.3

@@ -23,8 +23,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_ENTRY 3
 .Os

+ 230 - 96
Utilities/cmlibarchive/libarchive/archive_entry.c

@@ -25,7 +25,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:27Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -119,7 +118,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:
 static char *	 ae_fflagstostr(unsigned long bitset, unsigned long bitclear);
 static const wchar_t	*ae_wcstofflags(const wchar_t *stringp,
 		    unsigned long *setp, unsigned long *clrp);
-static const char	*ae_strtofflags(const char *stringp,
+static const char	*ae_strtofflags(const char *stringp, size_t length,
 		    unsigned long *setp, unsigned long *clrp);
 
 #ifndef HAVE_WCSCPY
@@ -158,10 +157,9 @@ archive_entry_clear(struct archive_entry *entry)
 		return (NULL);
 	archive_mstring_clean(&entry->ae_fflags_text);
 	archive_mstring_clean(&entry->ae_gname);
-	archive_mstring_clean(&entry->ae_hardlink);
+	archive_mstring_clean(&entry->ae_linkname);
 	archive_mstring_clean(&entry->ae_pathname);
 	archive_mstring_clean(&entry->ae_sourcepath);
-	archive_mstring_clean(&entry->ae_symlink);
 	archive_mstring_clean(&entry->ae_uname);
 	archive_entry_copy_mac_metadata(entry, NULL, 0);
 	archive_acl_clear(&entry->acl);
@@ -196,10 +194,9 @@ archive_entry_clone(struct archive_entry *entry)
 	 * character sets are different? XXX */
 	archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
 	archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
-	archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
+	archive_mstring_copy(&entry2->ae_linkname, &entry->ae_linkname);
 	archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
 	archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
-	archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
 	entry2->ae_set = entry->ae_set;
 	archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
 
@@ -372,6 +369,12 @@ archive_entry_filetype(struct archive_entry *entry)
 	return (AE_IFMT & entry->acl.mode);
 }
 
+int
+archive_entry_filetype_is_set(struct archive_entry *entry)
+{
+	return (entry->ae_set & AE_SET_FILETYPE);
+}
+
 void
 archive_entry_fflags(struct archive_entry *entry,
     unsigned long *set, unsigned long *clear)
@@ -425,6 +428,12 @@ archive_entry_gid(struct archive_entry *entry)
 	return (entry->ae_stat.aest_gid);
 }
 
+int
+archive_entry_gid_is_set(struct archive_entry *entry)
+{
+	return (entry->ae_set & AE_SET_GID);
+}
+
 const char *
 archive_entry_gname(struct archive_entry *entry)
 {
@@ -466,6 +475,15 @@ _archive_entry_gname_l(struct archive_entry *entry,
 	return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
 }
 
+void
+archive_entry_set_link_to_hardlink(struct archive_entry *entry)
+{
+	if ((entry->ae_set & AE_SET_SYMLINK) != 0) {
+		entry->ae_set &= ~AE_SET_SYMLINK;
+	}
+	entry->ae_set |= AE_SET_HARDLINK;
+}
+
 const char *
 archive_entry_hardlink(struct archive_entry *entry)
 {
@@ -473,7 +491,7 @@ archive_entry_hardlink(struct archive_entry *entry)
 	if ((entry->ae_set & AE_SET_HARDLINK) == 0)
 		return (NULL);
 	if (archive_mstring_get_mbs(
-	    entry->archive, &entry->ae_hardlink, &p) == 0)
+	    entry->archive, &entry->ae_linkname, &p) == 0)
 		return (p);
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
@@ -487,7 +505,7 @@ archive_entry_hardlink_utf8(struct archive_entry *entry)
 	if ((entry->ae_set & AE_SET_HARDLINK) == 0)
 		return (NULL);
 	if (archive_mstring_get_utf8(
-	    entry->archive, &entry->ae_hardlink, &p) == 0)
+	    entry->archive, &entry->ae_linkname, &p) == 0)
 		return (p);
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
@@ -501,13 +519,19 @@ archive_entry_hardlink_w(struct archive_entry *entry)
 	if ((entry->ae_set & AE_SET_HARDLINK) == 0)
 		return (NULL);
 	if (archive_mstring_get_wcs(
-	    entry->archive, &entry->ae_hardlink, &p) == 0)
+	    entry->archive, &entry->ae_linkname, &p) == 0)
 		return (p);
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
 	return (NULL);
 }
 
+int
+archive_entry_hardlink_is_set(struct archive_entry *entry)
+{
+	return (entry->ae_set & AE_SET_HARDLINK) != 0;
+}
+
 int
 _archive_entry_hardlink_l(struct archive_entry *entry,
     const char **p, size_t *len, struct archive_string_conv *sc)
@@ -517,7 +541,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
 		*len = 0;
 		return (0);
 	}
-	return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
+	return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
 }
 
 la_int64_t
@@ -631,32 +655,56 @@ archive_entry_perm(struct archive_entry *entry)
 	return (~AE_IFMT & entry->acl.mode);
 }
 
+int
+archive_entry_perm_is_set(struct archive_entry *entry)
+{
+	return (entry->ae_set & AE_SET_PERM);
+}
+
+int
+archive_entry_rdev_is_set(struct archive_entry *entry)
+{
+	return (entry->ae_set & AE_SET_RDEV);
+}
+
 dev_t
 archive_entry_rdev(struct archive_entry *entry)
 {
-	if (entry->ae_stat.aest_rdev_is_broken_down)
-		return ae_makedev(entry->ae_stat.aest_rdevmajor,
-		    entry->ae_stat.aest_rdevminor);
-	else
-		return (entry->ae_stat.aest_rdev);
+	if (archive_entry_rdev_is_set(entry)) {
+		if (entry->ae_stat.aest_rdev_is_broken_down)
+			return ae_makedev(entry->ae_stat.aest_rdevmajor,
+			    entry->ae_stat.aest_rdevminor);
+		else
+			return (entry->ae_stat.aest_rdev);
+	} else {
+		return 0;
+	}
 }
 
 dev_t
 archive_entry_rdevmajor(struct archive_entry *entry)
 {
-	if (entry->ae_stat.aest_rdev_is_broken_down)
-		return (entry->ae_stat.aest_rdevmajor);
-	else
-		return major(entry->ae_stat.aest_rdev);
+	if (archive_entry_rdev_is_set(entry)) {
+		if (entry->ae_stat.aest_rdev_is_broken_down)
+			return (entry->ae_stat.aest_rdevmajor);
+		else
+			return major(entry->ae_stat.aest_rdev);
+	} else {
+		return 0;
+	}
 }
 
 dev_t
 archive_entry_rdevminor(struct archive_entry *entry)
 {
-	if (entry->ae_stat.aest_rdev_is_broken_down)
-		return (entry->ae_stat.aest_rdevminor);
-	else
-		return minor(entry->ae_stat.aest_rdev);
+	if (archive_entry_rdev_is_set(entry)) {
+		if (entry->ae_stat.aest_rdev_is_broken_down)
+			return (entry->ae_stat.aest_rdevminor);
+		else
+			return minor(entry->ae_stat.aest_rdev);
+	} else {
+		return 0;
+	}
 }
 
 la_int64_t
@@ -700,13 +748,22 @@ archive_entry_symlink(struct archive_entry *entry)
 	if ((entry->ae_set & AE_SET_SYMLINK) == 0)
 		return (NULL);
 	if (archive_mstring_get_mbs(
-	    entry->archive, &entry->ae_symlink, &p) == 0)
+	    entry->archive, &entry->ae_linkname, &p) == 0)
 		return (p);
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
 	return (NULL);
 }
 
+void
+archive_entry_set_link_to_symlink(struct archive_entry *entry)
+{
+	if ((entry->ae_set & AE_SET_HARDLINK) != 0) {
+		entry->ae_set &= ~AE_SET_HARDLINK;
+	}
+	entry->ae_set |= AE_SET_SYMLINK;
+}
+
 int
 archive_entry_symlink_type(struct archive_entry *entry)
 {
@@ -720,7 +777,7 @@ archive_entry_symlink_utf8(struct archive_entry *entry)
 	if ((entry->ae_set & AE_SET_SYMLINK) == 0)
 		return (NULL);
 	if (archive_mstring_get_utf8(
-	    entry->archive, &entry->ae_symlink, &p) == 0)
+	    entry->archive, &entry->ae_linkname, &p) == 0)
 		return (p);
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
@@ -734,7 +791,7 @@ archive_entry_symlink_w(struct archive_entry *entry)
 	if ((entry->ae_set & AE_SET_SYMLINK) == 0)
 		return (NULL);
 	if (archive_mstring_get_wcs(
-	    entry->archive, &entry->ae_symlink, &p) == 0)
+	    entry->archive, &entry->ae_linkname, &p) == 0)
 		return (p);
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
@@ -750,7 +807,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
 		*len = 0;
 		return (0);
 	}
-	return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
+	return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_linkname, p, len, sc));
 }
 
 la_int64_t
@@ -759,6 +816,12 @@ archive_entry_uid(struct archive_entry *entry)
 	return (entry->ae_stat.aest_uid);
 }
 
+int
+archive_entry_uid_is_set(struct archive_entry *entry)
+{
+	return (entry->ae_set & AE_SET_UID);
+}
+
 const char *
 archive_entry_uname(struct archive_entry *entry)
 {
@@ -827,6 +890,7 @@ archive_entry_set_filetype(struct archive_entry *entry, unsigned int type)
 	entry->stat_valid = 0;
 	entry->acl.mode &= ~AE_IFMT;
 	entry->acl.mode |= AE_IFMT & type;
+	entry->ae_set |= AE_SET_FILETYPE;
 }
 
 void
@@ -840,10 +904,17 @@ archive_entry_set_fflags(struct archive_entry *entry,
 
 const char *
 archive_entry_copy_fflags_text(struct archive_entry *entry,
-    const char *flags)
+	const char *flags)
 {
-	archive_mstring_copy_mbs(&entry->ae_fflags_text, flags);
-	return (ae_strtofflags(flags,
+	return archive_entry_copy_fflags_text_len(entry, flags, strlen(flags));
+}
+
+const char *
+archive_entry_copy_fflags_text_len(struct archive_entry *entry,
+    const char *flags, size_t flags_length)
+{
+	archive_mstring_copy_mbs_len(&entry->ae_fflags_text, flags, flags_length);
+	return (ae_strtofflags(flags, flags_length,
 		    &entry->ae_fflags_set, &entry->ae_fflags_clear));
 }
 
@@ -859,8 +930,12 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
 void
 archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
 {
+	if (g < 0) {
+		g = 0;
+	}
 	entry->stat_valid = 0;
 	entry->ae_stat.aest_gid = g;
+	entry->ae_set |= AE_SET_GID;
 }
 
 void
@@ -908,6 +983,9 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
 void
 archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
 {
+	if (ino < 0) {
+		ino = 0;
+	}
 	entry->stat_valid = 0;
 	entry->ae_set |= AE_SET_INO;
 	entry->ae_stat.aest_ino = ino;
@@ -916,6 +994,9 @@ archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
 void
 archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
 {
+	if (ino < 0) {
+		ino = 0;
+	}
 	entry->stat_valid = 0;
 	entry->ae_set |= AE_SET_INO;
 	entry->ae_stat.aest_ino = ino;
@@ -924,17 +1005,24 @@ archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
 void
 archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
 {
-	archive_mstring_copy_mbs(&entry->ae_hardlink, target);
-	if (target != NULL)
-		entry->ae_set |= AE_SET_HARDLINK;
-	else
+	if (target == NULL) {
 		entry->ae_set &= ~AE_SET_HARDLINK;
+		if (entry->ae_set & AE_SET_SYMLINK) {
+			return;
+		}
+	} else {
+		entry->ae_set |= AE_SET_HARDLINK;
+	}
+	entry->ae_set &= ~AE_SET_SYMLINK;
+	archive_mstring_copy_mbs(&entry->ae_linkname, target);
 }
 
 void
 archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
 {
-	archive_mstring_copy_utf8(&entry->ae_hardlink, target);
+	if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+		return;
+	archive_mstring_copy_utf8(&entry->ae_linkname, target);
 	if (target != NULL)
 		entry->ae_set |= AE_SET_HARDLINK;
 	else
@@ -944,7 +1032,9 @@ archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
 void
 archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
 {
-	archive_mstring_copy_mbs(&entry->ae_hardlink, target);
+	if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+		return;
+	archive_mstring_copy_mbs(&entry->ae_linkname, target);
 	if (target != NULL)
 		entry->ae_set |= AE_SET_HARDLINK;
 	else
@@ -954,7 +1044,9 @@ archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
 void
 archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target)
 {
-	archive_mstring_copy_wcs(&entry->ae_hardlink, target);
+	if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+		return;
+	archive_mstring_copy_wcs(&entry->ae_linkname, target);
 	if (target != NULL)
 		entry->ae_set |= AE_SET_HARDLINK;
 	else
@@ -964,12 +1056,14 @@ archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target
 int
 archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target)
 {
+	if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+		return (0);
 	if (target != NULL)
 		entry->ae_set |= AE_SET_HARDLINK;
 	else
 		entry->ae_set &= ~AE_SET_HARDLINK;
 	if (archive_mstring_update_utf8(entry->archive,
-	    &entry->ae_hardlink, target) == 0)
+	    &entry->ae_linkname, target) == 0)
 		return (1);
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
@@ -982,7 +1076,9 @@ _archive_entry_copy_hardlink_l(struct archive_entry *entry,
 {
 	int r;
 
-	r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
+	if (target == NULL && (entry->ae_set & AE_SET_SYMLINK))
+		return (0);
+	r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
 	    target, len, sc);
 	if (target != NULL && r == 0)
 		entry->ae_set |= AE_SET_HARDLINK;
@@ -1073,51 +1169,50 @@ archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
 void
 archive_entry_set_link(struct archive_entry *entry, const char *target)
 {
-	if (entry->ae_set & AE_SET_SYMLINK)
-		archive_mstring_copy_mbs(&entry->ae_symlink, target);
-	else
-		archive_mstring_copy_mbs(&entry->ae_hardlink, target);
+	archive_mstring_copy_mbs(&entry->ae_linkname, target);
+	if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+		entry->ae_set |= AE_SET_HARDLINK;
+	}
 }
 
 void
 archive_entry_set_link_utf8(struct archive_entry *entry, const char *target)
 {
-	if (entry->ae_set & AE_SET_SYMLINK)
-		archive_mstring_copy_utf8(&entry->ae_symlink, target);
-	else
-		archive_mstring_copy_utf8(&entry->ae_hardlink, target);
+	archive_mstring_copy_utf8(&entry->ae_linkname, target);
+	if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+		entry->ae_set |= AE_SET_HARDLINK;
+	}
 }
 
 /* Set symlink if symlink is already set, else set hardlink. */
 void
 archive_entry_copy_link(struct archive_entry *entry, const char *target)
 {
-	if (entry->ae_set & AE_SET_SYMLINK)
-		archive_mstring_copy_mbs(&entry->ae_symlink, target);
-	else
-		archive_mstring_copy_mbs(&entry->ae_hardlink, target);
+	archive_mstring_copy_mbs(&entry->ae_linkname, target);
+	if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+		entry->ae_set |= AE_SET_HARDLINK;
+	}
 }
 
 /* Set symlink if symlink is already set, else set hardlink. */
 void
 archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target)
 {
-	if (entry->ae_set & AE_SET_SYMLINK)
-		archive_mstring_copy_wcs(&entry->ae_symlink, target);
-	else
-		archive_mstring_copy_wcs(&entry->ae_hardlink, target);
+	archive_mstring_copy_wcs(&entry->ae_linkname, target);
+	if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+		entry->ae_set |= AE_SET_HARDLINK;
+	}
 }
 
 int
 archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
 {
 	int r;
-	if (entry->ae_set & AE_SET_SYMLINK)
-		r = archive_mstring_update_utf8(entry->archive,
-		    &entry->ae_symlink, target);
-	else
-		r = archive_mstring_update_utf8(entry->archive,
-		    &entry->ae_hardlink, target);
+	r = archive_mstring_update_utf8(entry->archive,
+		    &entry->ae_linkname, target);
+	if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+		entry->ae_set |= AE_SET_HARDLINK;
+	}
 	if (r == 0)
 		return (1);
 	if (errno == ENOMEM)
@@ -1131,12 +1226,11 @@ _archive_entry_copy_link_l(struct archive_entry *entry,
 {
 	int r;
 
-	if (entry->ae_set & AE_SET_SYMLINK)
-		r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
-		    target, len, sc);
-	else
-		r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
+	r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
 		    target, len, sc);
+	if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+		entry->ae_set |= AE_SET_HARDLINK;
+	}
 	return (r);
 }
 
@@ -1145,6 +1239,7 @@ archive_entry_set_mode(struct archive_entry *entry, mode_t m)
 {
 	entry->stat_valid = 0;
 	entry->acl.mode = m;
+	entry->ae_set |= AE_SET_PERM | AE_SET_FILETYPE;
 }
 
 void
@@ -1220,6 +1315,7 @@ archive_entry_set_perm(struct archive_entry *entry, mode_t p)
 	entry->stat_valid = 0;
 	entry->acl.mode &= AE_IFMT;
 	entry->acl.mode |= ~AE_IFMT & p;
+	entry->ae_set |= AE_SET_PERM;
 }
 
 void
@@ -1228,6 +1324,9 @@ archive_entry_set_rdev(struct archive_entry *entry, dev_t m)
 	entry->stat_valid = 0;
 	entry->ae_stat.aest_rdev = m;
 	entry->ae_stat.aest_rdev_is_broken_down = 0;
+	entry->ae_stat.aest_rdevmajor = 0;
+	entry->ae_stat.aest_rdevminor = 0;
+	entry->ae_set |= AE_SET_RDEV;
 }
 
 void
@@ -1235,7 +1334,9 @@ archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m)
 {
 	entry->stat_valid = 0;
 	entry->ae_stat.aest_rdev_is_broken_down = 1;
+	entry->ae_stat.aest_rdev = 0;
 	entry->ae_stat.aest_rdevmajor = m;
+	entry->ae_set |= AE_SET_RDEV;
 }
 
 void
@@ -1243,12 +1344,17 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
 {
 	entry->stat_valid = 0;
 	entry->ae_stat.aest_rdev_is_broken_down = 1;
+	entry->ae_stat.aest_rdev = 0;
 	entry->ae_stat.aest_rdevminor = m;
+	entry->ae_set |= AE_SET_RDEV;
 }
 
 void
 archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
 {
+	if (s < 0) {
+		s = 0;
+	}
 	entry->stat_valid = 0;
 	entry->ae_stat.aest_size = s;
 	entry->ae_set |= AE_SET_SIZE;
@@ -1276,11 +1382,14 @@ archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path
 void
 archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
 {
-	archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
-	if (linkname != NULL)
-		entry->ae_set |= AE_SET_SYMLINK;
-	else
+	if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+		return;
+	archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
+	entry->ae_set &= ~AE_SET_HARDLINK;
+	if (linkname == NULL)
 		entry->ae_set &= ~AE_SET_SYMLINK;
+	else
+		entry->ae_set |= AE_SET_SYMLINK;
 }
 
 void
@@ -1292,42 +1401,54 @@ archive_entry_set_symlink_type(struct archive_entry *entry, int type)
 void
 archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
 {
-	archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
-	if (linkname != NULL)
-		entry->ae_set |= AE_SET_SYMLINK;
-	else
+	if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+		return;
+	archive_mstring_copy_utf8(&entry->ae_linkname, linkname);
+	entry->ae_set &= ~AE_SET_HARDLINK;
+	if (linkname == NULL)
 		entry->ae_set &= ~AE_SET_SYMLINK;
+	else
+		entry->ae_set |= AE_SET_SYMLINK;
 }
 
 void
 archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
 {
-	archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
-	if (linkname != NULL)
-		entry->ae_set |= AE_SET_SYMLINK;
-	else
+	if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+		return;
+	archive_mstring_copy_mbs(&entry->ae_linkname, linkname);
+	entry->ae_set &= ~AE_SET_HARDLINK;
+	if (linkname == NULL)
 		entry->ae_set &= ~AE_SET_SYMLINK;
+	else
+		entry->ae_set |= AE_SET_SYMLINK;
 }
 
 void
 archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname)
 {
-	archive_mstring_copy_wcs(&entry->ae_symlink, linkname);
-	if (linkname != NULL)
-		entry->ae_set |= AE_SET_SYMLINK;
-	else
+	if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+		return;
+	archive_mstring_copy_wcs(&entry->ae_linkname, linkname);
+	entry->ae_set &= ~AE_SET_HARDLINK;
+	if (linkname == NULL)
 		entry->ae_set &= ~AE_SET_SYMLINK;
+	else
+		entry->ae_set |= AE_SET_SYMLINK;
 }
 
 int
 archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname)
 {
-	if (linkname != NULL)
-		entry->ae_set |= AE_SET_SYMLINK;
-	else
+	if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+		return (0);
+	entry->ae_set &= ~AE_SET_HARDLINK;
+	if (linkname == NULL)
 		entry->ae_set &= ~AE_SET_SYMLINK;
+	else
+		entry->ae_set |= AE_SET_SYMLINK;
 	if (archive_mstring_update_utf8(entry->archive,
-	    &entry->ae_symlink, linkname) == 0)
+	    &entry->ae_linkname, linkname) == 0)
 		return (1);
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
@@ -1340,20 +1461,27 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
 {
 	int r;
 
-	r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
+	if (linkname == NULL && (entry->ae_set & AE_SET_HARDLINK))
+		return (0);
+	entry->ae_set &= ~AE_SET_HARDLINK;
+	r = archive_mstring_copy_mbs_len_l(&entry->ae_linkname,
 	    linkname, len, sc);
-	if (linkname != NULL && r == 0)
-		entry->ae_set |= AE_SET_SYMLINK;
-	else
+	if (linkname == NULL || r != 0)
 		entry->ae_set &= ~AE_SET_SYMLINK;
+	else
+		entry->ae_set |= AE_SET_SYMLINK;
 	return (r);
 }
 
 void
 archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
 {
+	if (u < 0) {
+		u = 0;
+	}
 	entry->stat_valid = 0;
 	entry->ae_stat.aest_uid = u;
+	entry->ae_set |= AE_SET_UID;
 }
 
 void
@@ -2003,7 +2131,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
  *	provided string.
  */
 static const char *
-ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
+ae_strtofflags(const char *s, size_t l, unsigned long *setp, unsigned long *clrp)
 {
 	const char *start, *end;
 	const struct flag *flag;
@@ -2014,15 +2142,19 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
 	start = s;
 	failed = NULL;
 	/* Find start of first token. */
-	while (*start == '\t'  ||  *start == ' '  ||  *start == ',')
+	while (l > 0 && (*start == '\t'  ||  *start == ' '  ||  *start == ',')) {
 		start++;
-	while (*start != '\0') {
+		l--;
+	}
+	while (l > 0) {
 		size_t length;
 		/* Locate end of token. */
 		end = start;
-		while (*end != '\0'  &&  *end != '\t'  &&
-		    *end != ' '  &&  *end != ',')
+		while (l > 0 && *end != '\t'  &&
+		    *end != ' '  &&  *end != ',') {
 			end++;
+			l--;
+		}
 		length = end - start;
 		for (flag = fileflags; flag->name != NULL; flag++) {
 			size_t flag_length = strlen(flag->name);
@@ -2046,8 +2178,10 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
 
 		/* Find start of next token. */
 		start = end;
-		while (*start == '\t'  ||  *start == ' '  ||  *start == ',')
+		while (l > 0 && (*start == '\t'  ||  *start == ' '  ||  *start == ',')) {
 			start++;
+			l--;
+		}
 
 	}
 

+ 11 - 3
Utilities/cmlibarchive/libarchive/archive_entry.h

@@ -22,15 +22,13 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $
  */
 
 #ifndef ARCHIVE_ENTRY_H_INCLUDED
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3007002
+#define	ARCHIVE_VERSION_NUMBER 3007005
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
@@ -248,17 +246,21 @@ __LA_DECL int		 archive_entry_dev_is_set(struct archive_entry *);
 __LA_DECL dev_t		 archive_entry_devmajor(struct archive_entry *);
 __LA_DECL dev_t		 archive_entry_devminor(struct archive_entry *);
 __LA_DECL __LA_MODE_T	 archive_entry_filetype(struct archive_entry *);
+__LA_DECL int		 archive_entry_filetype_is_set(struct archive_entry *);
 __LA_DECL void		 archive_entry_fflags(struct archive_entry *,
 			    unsigned long * /* set */,
 			    unsigned long * /* clear */);
 __LA_DECL const char	*archive_entry_fflags_text(struct archive_entry *);
 __LA_DECL la_int64_t	 archive_entry_gid(struct archive_entry *);
+__LA_DECL int		 archive_entry_gid_is_set(struct archive_entry *);
 __LA_DECL const char	*archive_entry_gname(struct archive_entry *);
 __LA_DECL const char	*archive_entry_gname_utf8(struct archive_entry *);
 __LA_DECL const wchar_t	*archive_entry_gname_w(struct archive_entry *);
+__LA_DECL void		 archive_entry_set_link_to_hardlink(struct archive_entry *);
 __LA_DECL const char	*archive_entry_hardlink(struct archive_entry *);
 __LA_DECL const char	*archive_entry_hardlink_utf8(struct archive_entry *);
 __LA_DECL const wchar_t	*archive_entry_hardlink_w(struct archive_entry *);
+__LA_DECL int		 archive_entry_hardlink_is_set(struct archive_entry *);
 __LA_DECL la_int64_t	 archive_entry_ino(struct archive_entry *);
 __LA_DECL la_int64_t	 archive_entry_ino64(struct archive_entry *);
 __LA_DECL int		 archive_entry_ino_is_set(struct archive_entry *);
@@ -271,6 +273,8 @@ __LA_DECL const char	*archive_entry_pathname(struct archive_entry *);
 __LA_DECL const char	*archive_entry_pathname_utf8(struct archive_entry *);
 __LA_DECL const wchar_t	*archive_entry_pathname_w(struct archive_entry *);
 __LA_DECL __LA_MODE_T	 archive_entry_perm(struct archive_entry *);
+__LA_DECL int		 archive_entry_perm_is_set(struct archive_entry *);
+__LA_DECL int		 archive_entry_rdev_is_set(struct archive_entry *);
 __LA_DECL dev_t		 archive_entry_rdev(struct archive_entry *);
 __LA_DECL dev_t		 archive_entry_rdevmajor(struct archive_entry *);
 __LA_DECL dev_t		 archive_entry_rdevminor(struct archive_entry *);
@@ -279,11 +283,13 @@ __LA_DECL const wchar_t	*archive_entry_sourcepath_w(struct archive_entry *);
 __LA_DECL la_int64_t	 archive_entry_size(struct archive_entry *);
 __LA_DECL int		 archive_entry_size_is_set(struct archive_entry *);
 __LA_DECL const char	*archive_entry_strmode(struct archive_entry *);
+__LA_DECL void		 archive_entry_set_link_to_symlink(struct archive_entry *);
 __LA_DECL const char	*archive_entry_symlink(struct archive_entry *);
 __LA_DECL const char	*archive_entry_symlink_utf8(struct archive_entry *);
 __LA_DECL int		 archive_entry_symlink_type(struct archive_entry *);
 __LA_DECL const wchar_t	*archive_entry_symlink_w(struct archive_entry *);
 __LA_DECL la_int64_t	 archive_entry_uid(struct archive_entry *);
+__LA_DECL int		 archive_entry_uid_is_set(struct archive_entry *);
 __LA_DECL const char	*archive_entry_uname(struct archive_entry *);
 __LA_DECL const char	*archive_entry_uname_utf8(struct archive_entry *);
 __LA_DECL const wchar_t	*archive_entry_uname_w(struct archive_entry *);
@@ -319,6 +325,8 @@ __LA_DECL void	archive_entry_set_fflags(struct archive_entry *,
 /* Note that all recognized tokens are processed, regardless. */
 __LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
 	    const char *);
+__LA_DECL const char *archive_entry_copy_fflags_text_len(struct archive_entry *,
+	    const char *, size_t);
 __LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
 	    const wchar_t *);
 __LA_DECL void	archive_entry_set_gid(struct archive_entry *, la_int64_t);

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

@@ -383,7 +383,7 @@ Prefix each default ACL entry with the word
 The mask and other ACLs don not contain a double colon.
 .El
 .Pp
-The following flags are effecive only on NFSv4 ACL:
+The following flags are effective only on NFSv4 ACL:
 .Bl -tag -offset indent -compact -width ARCHIV
 .It Dv ARCHIVE_ENTRY_ACL_STYLE_COMPACT
 Do not output minus characters for unset permissions and flags in NFSv4 ACL

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #include "archive_private.h"
 #include "archive_entry.h"

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03-07 00:52:02Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>

+ 15 - 1
Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 2009-12-28 03:05:31Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -202,16 +201,26 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
 		le = find_entry(res, *e);
 		if (le != NULL) {
 			archive_entry_unset_size(*e);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+			archive_entry_copy_hardlink_w(*e,
+			    archive_entry_pathname_w(le->canonical));
+#else
 			archive_entry_copy_hardlink(*e,
 			    archive_entry_pathname(le->canonical));
+#endif
 		} else
 			insert_entry(res, *e);
 		return;
 	case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
 		le = find_entry(res, *e);
 		if (le != NULL) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+			archive_entry_copy_hardlink_w(*e,
+			    archive_entry_pathname_w(le->canonical));
+#else
 			archive_entry_copy_hardlink(*e,
 			    archive_entry_pathname(le->canonical));
+#endif
 		} else
 			insert_entry(res, *e);
 		return;
@@ -230,8 +239,13 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
 			le->entry = t;
 			/* Make the old entry into a hardlink. */
 			archive_entry_unset_size(*e);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+			archive_entry_copy_hardlink_w(*e,
+			    archive_entry_pathname_w(le->canonical));
+#else
 			archive_entry_copy_hardlink(*e,
 			    archive_entry_pathname(le->canonical));
+#endif
 			/* If we ran out of links, return the
 			 * final entry as well. */
 			if (le->links == 0) {

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

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
 #ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED

+ 1 - 0
Utilities/cmlibarchive/libarchive/archive_entry_perms.3

@@ -150,6 +150,7 @@ character strings at the same time.
 .Fn archive_entry_set_XXX
 is an alias for
 .Fn archive_entry_copy_XXX .
+The strings are copied, and don't need to outlive the call.
 .Ss File Flags
 File flags are transparently converted between a bitmap
 representation and a textual format.

+ 6 - 4
Utilities/cmlibarchive/libarchive/archive_entry_private.h

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $
  */
 
 #ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
@@ -147,6 +145,11 @@ struct archive_entry {
 #define	AE_SET_SIZE	64
 #define	AE_SET_INO	128
 #define	AE_SET_DEV	256
+#define	AE_SET_PERM	512
+#define	AE_SET_FILETYPE	1024
+#define	AE_SET_UID	2048
+#define	AE_SET_GID	4096
+#define	AE_SET_RDEV	8192
 
 	/*
 	 * Use aes here so that we get transparent mbs<->wcs conversions.
@@ -155,9 +158,8 @@ struct archive_entry {
 	unsigned long ae_fflags_set;		/* Bitmap fflags */
 	unsigned long ae_fflags_clear;
 	struct archive_mstring ae_gname;		/* Name of owning group */
-	struct archive_mstring ae_hardlink;	/* Name of target for hardlink */
+	struct archive_mstring ae_linkname;	/* Name of target for hardlink or symlink */
 	struct archive_mstring ae_pathname;	/* Name of entry */
-	struct archive_mstring ae_symlink;		/* symlink contents */
 	struct archive_mstring ae_uname;		/* Name of owner */
 
 	/* Not used within libarchive; useful for some clients. */

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

@@ -25,7 +25,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #include "archive.h"
 #include "archive_entry.h"

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_stat.c 201100 2009-12-28 03:05:31Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.4 2008/06/15 05:14:01 kientzle Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_entry_time.3

@@ -23,8 +23,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_ENTRY_TIME 3
 .Os

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_xattr.c 201096 2009-12-28 02:41:27Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>

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

@@ -30,10 +30,6 @@
 #ifndef CM_GET_DATE
 #include "archive_platform.h"
 #endif
-#ifdef __FreeBSD__
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
 
 #include <ctype.h>
 #include <stdio.h>

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

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
 #ifndef ARCHIVE_GETDATE_H_INCLUDED

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

@@ -25,7 +25,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -47,7 +46,7 @@ __FBSDID("$FreeBSD$");
 
 struct match {
 	struct match		*next;
-	int			 matches;
+	int			 matched;
 	struct archive_mstring	 pattern;
 };
 
@@ -600,17 +599,14 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
 	int64_t offset;
 	int r;
 
-	ar = archive_read_new(); 
+	ar = archive_read_new();
 	if (ar == NULL) {
 		archive_set_error(&(a->archive), ENOMEM, "No memory");
 		return (ARCHIVE_FATAL);
 	}
 	r = archive_read_support_format_raw(ar);
-#ifdef __clang_analyzer__
-	/* Tolerate deadcode.DeadStores to avoid modifying upstream.  */
-	(void)r;
-#endif
-	r = archive_read_support_format_empty(ar);
+	if (r == ARCHIVE_OK)
+		r = archive_read_support_format_empty(ar);
 	if (r != ARCHIVE_OK) {
 		archive_copy_error(&(a->archive), ar);
 		archive_read_free(ar);
@@ -729,12 +725,12 @@ path_excluded(struct archive_match *a, int mbs, const void *pathname)
 	matched = NULL;
 	for (match = a->inclusions.first; match != NULL;
 	    match = match->next){
-		if (match->matches == 0 &&
+		if (!match->matched &&
 		    (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
 			if (r < 0)
 				return (r);
 			a->inclusions.unmatched_count--;
-			match->matches++;
+			match->matched = 1;
 			matched = match;
 		}
 	}
@@ -757,11 +753,10 @@ path_excluded(struct archive_match *a, int mbs, const void *pathname)
 	for (match = a->inclusions.first; match != NULL;
 	    match = match->next){
 		/* We looked at previously-unmatched inclusions already. */
-		if (match->matches > 0 &&
+		if (match->matched &&
 		    (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
 			if (r < 0)
 				return (r);
-			match->matches++;
 			return (0);
 		}
 	}
@@ -884,7 +879,7 @@ match_list_unmatched_inclusions_next(struct archive_match *a,
 	for (m = list->unmatched_next; m != NULL; m = m->next) {
 		int r;
 
-		if (m->matches)
+		if (m->matched)
 			continue;
 		if (mbs) {
 			const char *p;
@@ -1321,7 +1316,7 @@ cmp_node_mbs(const struct archive_rb_node *n1,
 		return (-1);
 	return (strcmp(p1, p2));
 }
-        
+
 static int
 cmp_key_mbs(const struct archive_rb_node *n, const void *key)
 {
@@ -1350,7 +1345,7 @@ cmp_node_wcs(const struct archive_rb_node *n1,
 		return (-1);
 	return (wcscmp(p1, p2));
 }
-        
+
 static int
 cmp_key_wcs(const struct archive_rb_node *n, const void *key)
 {
@@ -1798,7 +1793,7 @@ match_owner_name_mbs(struct archive_match *a, struct match_list *list,
 		    < 0 && errno == ENOMEM)
 			return (error_nomem(a));
 		if (p != NULL && strcmp(p, name) == 0) {
-			m->matches++;
+			m->matched = 1;
 			return (1);
 		}
 	}
@@ -1819,7 +1814,7 @@ match_owner_name_wcs(struct archive_match *a, struct match_list *list,
 		    < 0 && errno == ENOMEM)
 			return (error_nomem(a));
 		if (p != NULL && wcscmp(p, name) == 0) {
-			m->matches++;
+			m->matched = 1;
 			return (1);
 		}
 	}

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>

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

@@ -27,8 +27,6 @@
 #define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
-
 #include "archive_private.h"
 
 typedef int (*option_handler)(struct archive *a,

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

@@ -33,13 +33,6 @@
 
 #include "archive_platform.h"
 
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-#if !defined(lint)
-__RCSID("$NetBSD$");
-#endif /* not lint */
-
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif

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

@@ -25,7 +25,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_STRING_H
 #include <string.h>

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

@@ -22,8 +22,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
 #ifndef ARCHIVE_PATHMATCH_H

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

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_platform.h 201090 2009-12-28 02:22:04Z kientzle $
  */
 
 /* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
@@ -87,19 +85,6 @@
  * headers as required.
  */
 
-/* Get a real definition for __FBSDID or __RCSID if we can */
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-/* If not, define them so as to avoid dangling semicolons. */
-#ifndef __FBSDID
-#define	__FBSDID(a)     struct _undefined_hack
-#endif
-#ifndef __RCSID
-#define	__RCSID(a)     struct _undefined_hack
-#endif
-
 /* Old glibc mbsnrtowcs fails assertions in our use case.  */
 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1
 # undef HAVE_MBSNRTOWCS

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

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
 /* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */

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

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
  */
 
 /* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */

+ 2 - 3
Utilities/cmlibarchive/libarchive/archive_ppmd8.c

@@ -683,7 +683,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
     upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0)));
   }
 
-  do
+  while (numPs != 0)
   {
     /* Create Child */
     CTX_PTR c1; /* = AllocContext(p); */
@@ -704,8 +704,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
     SetSuccessor(ps[--numPs], REF(c1));
     c = c1;
   }
-  while (numPs != 0);
-  
+
   return c;
 }
 

+ 8 - 6
Utilities/cmlibarchive/libarchive/archive_private.h

@@ -21,16 +21,16 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $
  */
 
 #ifndef ARCHIVE_PRIVATE_H_INCLUDED
 #define ARCHIVE_PRIVATE_H_INCLUDED
 
 #ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST
 #error This header is only to be used internally to libarchive.
 #endif
+#endif
 
 #if HAVE_ICONV_H
 #include <iconv.h>
@@ -40,10 +40,12 @@
 #include "archive_string.h"
 
 #if defined(__GNUC__) && (__GNUC__ > 2 || \
-			  (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
-#define	__LA_DEAD	__attribute__((__noreturn__))
+						  (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
+#define __LA_NORETURN __attribute__((__noreturn__))
+#elif defined(_MSC_VER)
+#define __LA_NORETURN __declspec(noreturn)
 #else
-#define	__LA_DEAD
+#define __LA_NORETURN
 #endif
 
 #if defined(__GNUC__) && (__GNUC__ > 2 || \
@@ -153,7 +155,7 @@ int	__archive_check_magic(struct archive *, unsigned int magic,
 			return ARCHIVE_FATAL; \
 	} while (0)
 
-void	__archive_errx(int retvalue, const char *msg) __LA_DEAD;
+__LA_NORETURN void	__archive_errx(int retvalue, const char *msg);
 
 void	__archive_ensure_cloexec_flag(int fd);
 int	__archive_mktemp(const char *tmpdir);

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_READ 3
 .Os

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

@@ -32,7 +32,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read.c 201157 2009-12-29 05:30:23Z kientzle $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -1383,7 +1382,7 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
 		if (filter->client_avail <= 0) {
 			if (filter->end_of_file) {
 				if (avail != NULL)
-					*avail = 0;
+					*avail = filter->avail;
 				return (NULL);
 			}
 			bytes_read = (filter->vtable->read)(filter,

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd September 14, 2014
 .Dt ARCHIVE_READ_ADD_PASSPHRASE 3
 .Os

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -112,7 +111,7 @@ archive_read_append_filter(struct archive *_a, int code)
     number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
 
     bidder = a->bidders;
-    for (i = 0; i < number_bidders; i++, bidder++)
+    for (i = 1; i < number_bidders; i++, bidder++)
     {
       if (!bidder->name || !strcmp(bidder->name, str))
         break;

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_data.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_READ_DATA 3
 .Os

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/05/23 05:01:29 cperciva Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>

+ 2 - 4
Utilities/cmlibarchive/libarchive/archive_read_disk.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd April 3, 2017
 .Dt ARCHIVE_READ_DISK 3
 .Os
@@ -290,11 +288,11 @@ calls. If matched based on calls to
 .Tn archive_match_time_excluded ,
 or
 .Tn archive_match_owner_excluded ,
-then the callback function specified by the _excluded_func parameter will execute. This function will recieve data provided to the fourth parameter, void *_client_data.
+then the callback function specified by the _excluded_func parameter will execute. This function will receive data provided to the fourth parameter, void *_client_data.
 .It Fn archive_read_disk_set_metadata_filter_callback
 Allows the caller to set a callback function during calls to
 .Xr archive_read_header 3
-to filter out metadata for each entry. The callback function recieves the
+to filter out metadata for each entry. The callback function receives the
 .Tn struct archive
 object, void* custom filter data, and the 
 .Tn struct archive_entry .

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

@@ -26,7 +26,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD");
 
 /* This is the tree-walking code for POSIX systems. */
 #if !defined(_WIN32) || defined(__CYGWIN__)
@@ -521,6 +520,7 @@ setup_xattr(struct archive_read_disk *a,
 	if (size == -1) {
 		archive_set_error(&a->archive, errno,
 		    "Couldn't read extended attribute");
+		free(value);
 		return (ARCHIVE_WARN);
 	}
 

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

@@ -29,7 +29,6 @@
 #if !defined(_WIN32) || defined(__CYGWIN__)
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>

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

@@ -22,8 +22,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $
  */
 
 #ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_set_standard_lookup.c 201109 2009-12-28 03:30:31Z kientzle $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>

+ 3 - 1
Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c

@@ -25,7 +25,6 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
 
@@ -1956,6 +1955,8 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
 				t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
 				return (t->visit_type);
 			}
+			/* Top stack item needs a regular visit. */
+			t->current = t->stack;
 			t->findData = &t->_findData;
 			pattern = NULL;
 		} else if (!FindNextFileW(t->d, &t->_findData)) {
@@ -2439,6 +2440,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
 		return (ARCHIVE_OK);
 	}
 
+	r = ARCHIVE_OK;
 	if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) {
 		r = setup_sparse_from_disk(a, entry, h);
 		if (fd < 0)

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_extract.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_READ_EXTRACT 3
 .Os

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_filter.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd June 9, 2020
 .Dt ARCHIVE_READ_FILTER 3
 .Os

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_format.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_READ_FORMAT 3
 .Os

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_free.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_READ_FREE 3
 .Os

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_header.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_READ_HEADER 3
 .Os

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_new.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_READ_NEW 3
 .Os

+ 0 - 2
Utilities/cmlibarchive/libarchive/archive_read_open.3

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd February 2, 2012
 .Dt ARCHIVE_READ_OPEN 3
 .Os

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28 03:13:49Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_file.c 201093 2009-12-28 02:28:44Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>

+ 71 - 41
Utilities/cmlibarchive/libarchive/archive_read_open_filename.c

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $");
 
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
@@ -155,55 +154,73 @@ no_memory:
 	return (ARCHIVE_FATAL);
 }
 
+/*
+ * This function is an implementation detail of archive_read_open_filename_w,
+ * which is exposed as a separate API on Windows.
+ */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static
+#endif
 int
-archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
+archive_read_open_filenames_w(struct archive *a, const wchar_t **wfilenames,
     size_t block_size)
 {
-	struct read_file_data *mine = (struct read_file_data *)calloc(1,
-		sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
-	if (!mine)
+	struct read_file_data *mine;
+	const wchar_t *wfilename = NULL;
+	if (wfilenames)
+		wfilename = *(wfilenames++);
+
+	archive_clear_error(a);
+	do
 	{
-		archive_set_error(a, ENOMEM, "No memory");
-		return (ARCHIVE_FATAL);
-	}
-	mine->fd = -1;
-	mine->block_size = block_size;
+		if (wfilename == NULL)
+			wfilename = L"";
+		mine = (struct read_file_data *)calloc(1,
+			sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
+		if (mine == NULL)
+			goto no_memory;
+		mine->block_size = block_size;
+		mine->fd = -1;
 
-	if (wfilename == NULL || wfilename[0] == L'\0') {
-		mine->filename_type = FNT_STDIN;
-	} else {
+		if (wfilename == NULL || wfilename[0] == L'\0') {
+			mine->filename_type = FNT_STDIN;
+		} else {
 #if defined(_WIN32) && !defined(__CYGWIN__)
-		mine->filename_type = FNT_WCS;
-		wcscpy(mine->filename.w, wfilename);
+			mine->filename_type = FNT_WCS;
+			wcscpy(mine->filename.w, wfilename);
 #else
-		/*
-		 * POSIX system does not support a wchar_t interface for
-		 * open() system call, so we have to translate a wchar_t
-		 * filename to multi-byte one and use it.
-		 */
-		struct archive_string fn;
-
-		archive_string_init(&fn);
-		if (archive_string_append_from_wcs(&fn, wfilename,
-		    wcslen(wfilename)) != 0) {
-			if (errno == ENOMEM)
-				archive_set_error(a, errno,
-				    "Can't allocate memory");
-			else
-				archive_set_error(a, EINVAL,
-				    "Failed to convert a wide-character"
-				    " filename to a multi-byte filename");
+			/*
+			 * POSIX system does not support a wchar_t interface for
+			 * open() system call, so we have to translate a wchar_t
+			 * filename to multi-byte one and use it.
+			 */
+			struct archive_string fn;
+
+			archive_string_init(&fn);
+			if (archive_string_append_from_wcs(&fn, wfilename,
+			    wcslen(wfilename)) != 0) {
+				if (errno == ENOMEM)
+					archive_set_error(a, errno,
+					    "Can't allocate memory");
+				else
+					archive_set_error(a, EINVAL,
+					    "Failed to convert a wide-character"
+					    " filename to a multi-byte filename");
+				archive_string_free(&fn);
+				free(mine);
+				return (ARCHIVE_FATAL);
+			}
+			mine->filename_type = FNT_MBS;
+			strcpy(mine->filename.m, fn.s);
 			archive_string_free(&fn);
-			free(mine);
-			return (ARCHIVE_FATAL);
-		}
-		mine->filename_type = FNT_MBS;
-		strcpy(mine->filename.m, fn.s);
-		archive_string_free(&fn);
 #endif
-	}
-	if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
-		return (ARCHIVE_FATAL);
+		}
+		if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
+			return (ARCHIVE_FATAL);
+		if (wfilenames == NULL)
+			break;
+		wfilename = *(wfilenames++);
+	} while (wfilename != NULL && wfilename[0] != '\0');
 	archive_read_set_open_callback(a, file_open);
 	archive_read_set_read_callback(a, file_read);
 	archive_read_set_skip_callback(a, file_skip);
@@ -212,6 +229,19 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
 	archive_read_set_seek_callback(a, file_seek);
 
 	return (archive_read_open1(a));
+no_memory:
+	archive_set_error(a, ENOMEM, "No memory");
+	return (ARCHIVE_FATAL);
+}
+
+int
+archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
+    size_t block_size)
+{
+	const wchar_t *wfilenames[2];
+	wfilenames[0] = wfilename;
+	wfilenames[1] = NULL;
+	return archive_read_open_filenames_w(a, wfilenames, block_size);
 }
 
 static int

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/06 15:51:59 kientzle Exp $");
 
 #include <errno.h>
 #include <stdlib.h>

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

@@ -21,8 +21,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $
  */
 
 #ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>

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

@@ -22,8 +22,6 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD$
-.\"
 .Dd January 31, 2020
 .Dt ARCHIVE_READ_OPTIONS 3
 .Os

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #include "archive_read_private.h"
 #include "archive_options_private.h"

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #include "archive.h"
 #include "archive_private.h"

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #include "archive.h"
 #include "archive_private.h"

+ 1 - 3
Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c

@@ -25,8 +25,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -192,7 +190,7 @@ bzip2_reader_init(struct archive_read_filter *self)
 	self->code = ARCHIVE_FILTER_BZIP2;
 	self->name = "bzip2";
 
-	state = (struct private_data *)calloc(sizeof(*state), 1);
+	state = (struct private_data *)calloc(1, sizeof(*state));
 	out_block = (unsigned char *)malloc(out_block_size);
 	if (state == NULL || out_block == NULL) {
 		archive_set_error(&self->archive->archive, ENOMEM,

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

@@ -64,7 +64,6 @@
 
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -218,7 +217,7 @@ compress_bidder_init(struct archive_read_filter *self)
 	self->code = ARCHIVE_FILTER_COMPRESS;
 	self->name = "compress (.Z)";
 
-	state = (struct private_data *)calloc(sizeof(*state), 1);
+	state = (struct private_data *)calloc(1, sizeof(*state));
 	out_block = malloc(out_block_size);
 	if (state == NULL || out_block == NULL) {
 		free(out_block);

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

@@ -25,9 +25,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
-
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif

+ 1 - 4
Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c

@@ -25,9 +25,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
-
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -310,7 +307,7 @@ gzip_bidder_init(struct archive_read_filter *self)
 	self->code = ARCHIVE_FILTER_GZIP;
 	self->name = "gzip";
 
-	state = (struct private_data *)calloc(sizeof(*state), 1);
+	state = (struct private_data *)calloc(1, sizeof(*state));
 	out_block = (unsigned char *)malloc(out_block_size);
 	if (state == NULL || out_block == NULL) {
 		free(out_block);

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

@@ -25,9 +25,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
-
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif

+ 3 - 5
Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c

@@ -25,8 +25,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -225,7 +223,7 @@ lz4_reader_init(struct archive_read_filter *self)
 	self->code = ARCHIVE_FILTER_LZ4;
 	self->name = "lz4";
 
-	state = (struct private_data *)calloc(sizeof(*state), 1);
+	state = (struct private_data *)calloc(1, sizeof(*state));
 	if (state == NULL) {
 		archive_set_error(&self->archive->archive, ENOMEM,
 		    "Can't allocate data for lz4 decompression");
@@ -449,8 +447,8 @@ lz4_filter_read_descriptor(struct archive_read_filter *self)
 	chsum = __archive_xxhash.XXH32(read_buf, (int)descriptor_bytes -1, 0);
 	chsum = (chsum >> 8) & 0xff;
 	chsum_verifier = read_buf[descriptor_bytes-1] & 0xff;
-	if (chsum != chsum_verifier)
 #ifndef DONT_FAIL_ON_CRC_ERROR
+	if (chsum != chsum_verifier)
 		goto malformed_error;
 #endif
 
@@ -522,8 +520,8 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
 			read_buf + 4, (int)compressed_size, 0);
 		unsigned int chsum_block =
 		    archive_le32dec(read_buf + 4 + compressed_size);
-		if (chsum != chsum_block)
 #ifndef DONT_FAIL_ON_CRC_ERROR
+		if (chsum != chsum_block)
 			goto malformed_error;
 #endif
 	}

+ 4 - 5
Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c

@@ -26,8 +26,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -187,7 +185,7 @@ lzop_bidder_init(struct archive_read_filter *self)
 	self->code = ARCHIVE_FILTER_LZOP;
 	self->name = "lzop";
 
-	state = (struct read_lzop *)calloc(sizeof(*state), 1);
+	state = (struct read_lzop *)calloc(1, sizeof(*state));
 	if (state == NULL) {
 		archive_set_error(&self->archive->archive, ENOMEM,
 		    "Can't allocate data for lzop decompression");
@@ -282,8 +280,8 @@ consume_header(struct archive_read_filter *self)
 		checksum = crc32(crc32(0, NULL, 0), p, len);
 	else
 		checksum = adler32(adler32(0, NULL, 0), p, len);
-	if (archive_be32dec(p + len) != checksum)
 #ifndef DONT_FAIL_ON_CRC_ERROR
+	if (archive_be32dec(p + len) != checksum)
 		goto corrupted;
 #endif
 	__archive_read_filter_consume(self->upstream, len + 4);
@@ -293,7 +291,8 @@ consume_header(struct archive_read_filter *self)
 		if (p == NULL)
 			goto truncated;
 		len = archive_be32dec(p);
-		__archive_read_filter_consume(self->upstream, len + 4 + 4);
+		__archive_read_filter_consume(self->upstream,
+		    (int64_t)len + 4 + 4);
 	}
 	state->flags = flags;
 	state->in_stream = 1;

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #include "archive.h"
 #include "archive_private.h"

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

@@ -25,7 +25,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_SYS_WAIT_H
 #  include <sys/wait.h>

+ 26 - 19
Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c

@@ -39,8 +39,8 @@
 
 struct rpm {
 	int64_t		 total_in;
-	size_t		 hpos;
-	size_t		 hlen;
+	uint64_t	 hpos;
+	uint64_t	 hlen;
 	unsigned char	 header[16];
 	enum {
 		ST_LEAD,	/* Skipping 'Lead' section. */
@@ -53,7 +53,8 @@ struct rpm {
 	}		 state;
 	int		 first_header;
 };
-#define RPM_LEAD_SIZE	96	/* Size of 'Lead' section. */
+#define RPM_LEAD_SIZE		96	/* Size of 'Lead' section. */
+#define RPM_MIN_HEAD_SIZE	16	/* Minimum size of 'Head'. */
 
 static int	rpm_bidder_bid(struct archive_read_filter_bidder *,
 		    struct archive_read_filter *);
@@ -63,6 +64,8 @@ static ssize_t	rpm_filter_read(struct archive_read_filter *,
 		    const void **);
 static int	rpm_filter_close(struct archive_read_filter *);
 
+static inline size_t rpm_limit_bytes(uint64_t, size_t);
+
 #if ARCHIVE_VERSION_NUMBER < 4000000
 /* Deprecated; remove in libarchive 4.0 */
 int
@@ -141,7 +144,7 @@ rpm_bidder_init(struct archive_read_filter *self)
 	self->code = ARCHIVE_FILTER_RPM;
 	self->name = "rpm";
 
-	rpm = (struct rpm *)calloc(sizeof(*rpm), 1);
+	rpm = (struct rpm *)calloc(1, sizeof(*rpm));
 	if (rpm == NULL) {
 		archive_set_error(&self->archive->archive, ENOMEM,
 		    "Can't allocate data for rpm");
@@ -155,15 +158,21 @@ rpm_bidder_init(struct archive_read_filter *self)
 	return (ARCHIVE_OK);
 }
 
+static inline size_t
+rpm_limit_bytes(uint64_t bytes, size_t max)
+{
+	return (bytes > max ? max : (size_t)bytes);
+}
+
 static ssize_t
 rpm_filter_read(struct archive_read_filter *self, const void **buff)
 {
 	struct rpm *rpm;
 	const unsigned char *b;
-	ssize_t avail_in, total;
-	size_t used, n;
-	uint32_t section;
-	uint32_t bytes;
+	ssize_t avail_in, total, used;
+	size_t n;
+	uint64_t section;
+	uint64_t bytes;
 
 	rpm = (struct rpm *)self->data;
 	*buff = NULL;
@@ -197,15 +206,14 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
 			}
 			break;
 		case ST_HEADER:
-			n = 16 - rpm->hpos;
-			if (n > avail_in - used)
-				n = avail_in - used;
+			n = rpm_limit_bytes(RPM_MIN_HEAD_SIZE - rpm->hpos,
+			    avail_in - used);
 			memcpy(rpm->header+rpm->hpos, b, n);
 			b += n;
 			used += n;
 			rpm->hpos += n;
 
-			if (rpm->hpos == 16) {
+			if (rpm->hpos == RPM_MIN_HEAD_SIZE) {
 				if (rpm->header[0] != 0x8e ||
 				    rpm->header[1] != 0xad ||
 				    rpm->header[2] != 0xe8 ||
@@ -219,21 +227,20 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
 					}
 					rpm->state = ST_ARCHIVE;
 					*buff = rpm->header;
-					total = rpm->hpos;
+					total = RPM_MIN_HEAD_SIZE;
 					break;
 				}
 				/* Calculate 'Header' length. */
 				section = archive_be32dec(rpm->header+8);
 				bytes = archive_be32dec(rpm->header+12);
-				rpm->hlen = 16 + section * 16 + bytes;
+				rpm->hlen = rpm->hpos + section * 16 + bytes;
 				rpm->state = ST_HEADER_DATA;
 				rpm->first_header = 0;
 			}
 			break;
 		case ST_HEADER_DATA:
-			n = rpm->hlen - rpm->hpos;
-			if (n > avail_in - used)
-				n = avail_in - used;
+			n = rpm_limit_bytes(rpm->hlen - rpm->hpos,
+			    avail_in - used);
 			b += n;
 			used += n;
 			rpm->hpos += n;
@@ -241,7 +248,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
 				rpm->state = ST_PADDING;
 			break;
 		case ST_PADDING:
-			while (used < (size_t)avail_in) {
+			while (used < avail_in) {
 				if (*b != 0) {
 					/* Read next header. */
 					rpm->state = ST_HEADER;
@@ -259,7 +266,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
 			used = avail_in;
 			break;
 		}
-		if (used == (size_t)avail_in) {
+		if (used == avail_in) {
 			rpm->total_in += used;
 			__archive_read_filter_consume(self->upstream, used);
 			b = NULL;

+ 12 - 5
Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -48,11 +47,13 @@ __FBSDID("$FreeBSD$");
 /* Maximum lookahead during bid phase */
 #define UUENCODE_BID_MAX_READ 128*1024 /* in bytes */
 
+#define UUENCODE_MAX_LINE_LENGTH 34*1024 /* in bytes */
+
 struct uudecode {
 	int64_t		 total;
 	unsigned char	*in_buff;
 #define IN_BUFF_SIZE	(1024)
-	int		 in_cnt;
+	ssize_t		 in_cnt;
 	size_t		 in_allocated;
 	unsigned char	*out_buff;
 #define OUT_BUFF_SIZE	(64 * 1024)
@@ -378,7 +379,7 @@ uudecode_bidder_init(struct archive_read_filter *self)
 	self->code = ARCHIVE_FILTER_UU;
 	self->name = "uu";
 
-	uudecode = (struct uudecode *)calloc(sizeof(*uudecode), 1);
+	uudecode = (struct uudecode *)calloc(1, sizeof(*uudecode));
 	out_buff = malloc(OUT_BUFF_SIZE);
 	in_buff = malloc(IN_BUFF_SIZE);
 	if (uudecode == NULL || out_buff == NULL || in_buff == NULL) {
@@ -489,6 +490,12 @@ read_more:
 		goto finish;
 	}
 	if (uudecode->in_cnt) {
+		if (uudecode->in_cnt > UUENCODE_MAX_LINE_LENGTH) {
+			archive_set_error(&self->archive->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Invalid format data");
+			return (ARCHIVE_FATAL);
+		}
 		/*
 		 * If there is remaining data which is saved by
 		 * previous calling, use it first.
@@ -506,7 +513,7 @@ read_more:
 		uudecode->in_cnt = 0;
 	}
 	for (;used < avail_in; d += llen, used += llen) {
-		int64_t l, body;
+		ssize_t l, body;
 
 		b = d;
 		len = get_line(b, avail_in - used, &nl);
@@ -541,7 +548,7 @@ read_more:
 				return (ARCHIVE_FATAL);
 			if (uudecode->in_buff != b)
 				memmove(uudecode->in_buff, b, len);
-			uudecode->in_cnt = (int)len;
+			uudecode->in_cnt = len;
 			if (total == 0) {
 				/* Do not return 0; it means end-of-file.
 				 * We should try to read bytes more. */

+ 15 - 5
Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c

@@ -26,8 +26,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -478,7 +476,7 @@ xz_lzma_bidder_init(struct archive_read_filter *self)
 	struct private_data *state;
 	int ret;
 
-	state = (struct private_data *)calloc(sizeof(*state), 1);
+	state = (struct private_data *)calloc(1, sizeof(*state));
 	out_block = (unsigned char *)malloc(out_block_size);
 	if (state == NULL || out_block == NULL) {
 		archive_set_error(&self->archive->archive, ENOMEM,
@@ -656,13 +654,16 @@ xz_filter_read(struct archive_read_filter *self, const void **p)
 	struct private_data *state;
 	size_t decompressed;
 	ssize_t avail_in;
+	int64_t member_in;
 	int ret;
 
 	state = (struct private_data *)self->data;
 
+	redo:
 	/* Empty our output buffer. */
 	state->stream.next_out = state->out_block;
 	state->stream.avail_out = state->out_block_size;
+	member_in = state->member_in;
 
 	/* Try to fill the output buffer. */
 	while (state->stream.avail_out > 0 && !state->eof) {
@@ -707,9 +708,18 @@ xz_filter_read(struct archive_read_filter *self, const void **p)
 	decompressed = state->stream.next_out - state->out_block;
 	state->total_out += decompressed;
 	state->member_out += decompressed;
-	if (decompressed == 0)
+	if (decompressed == 0) {
+		if (member_in != state->member_in &&
+		    self->code == ARCHIVE_FILTER_LZIP &&
+		    state->eof) {
+			ret = lzip_tail(self);
+			if (ret != ARCHIVE_OK)
+				return (ret);
+			if (!state->eof)
+				goto redo;
+		}
 		*p = NULL;
-	else {
+	} else {
 		*p = state->out_block;
 		if (self->code == ARCHIVE_FILTER_LZIP) {
 			state->crc32 = lzma_crc32(state->out_block,

+ 1 - 3
Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c

@@ -25,8 +25,6 @@
 
 #include "archive_platform.h"
 
-__FBSDID("$FreeBSD$");
-
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -177,7 +175,7 @@ zstd_bidder_init(struct archive_read_filter *self)
 	self->code = ARCHIVE_FILTER_ZSTD;
 	self->name = "zstd";
 
-	state = (struct private_data *)calloc(sizeof(*state), 1);
+	state = (struct private_data *)calloc(1, sizeof(*state));
 	out_block = (unsigned char *)malloc(out_block_size);
 	dstream = ZSTD_createDStream();
 

+ 31 - 12
Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -885,10 +884,9 @@ archive_read_format_7zip_read_data(struct archive_read *a,
 	if (zip->end_of_entry)
 		return (ARCHIVE_EOF);
 
-	const uint64_t max_read_size = 16 * 1024 * 1024;  // Don't try to read more than 16 MB at a time
-	size_t bytes_to_read = max_read_size;
+	size_t bytes_to_read = 16 * 1024 * 1024;  // Don't try to read more than 16 MB at a time
 	if ((uint64_t)bytes_to_read > zip->entry_bytes_remaining) {
-		bytes_to_read = zip->entry_bytes_remaining;
+		bytes_to_read = (size_t)zip->entry_bytes_remaining;
 	}
 	bytes = read_stream(a, buff, bytes_to_read, 0);
 	if (bytes < 0)
@@ -1071,8 +1069,8 @@ ppmd_read(void *p)
 		 */
 		ssize_t bytes_avail = 0;
 		const uint8_t* data = __archive_read_ahead(a,
-		    zip->ppstream.stream_in+1, &bytes_avail);
-		if(bytes_avail < zip->ppstream.stream_in+1) {
+		    (size_t)zip->ppstream.stream_in+1, &bytes_avail);
+		if(data == NULL || bytes_avail < zip->ppstream.stream_in+1) {
 			archive_set_error(&a->archive,
 			    ARCHIVE_ERRNO_FILE_FORMAT,
 			    "Truncated 7z file data");
@@ -1774,6 +1772,10 @@ free_decompression(struct archive_read *a, struct _7zip *zip)
 		}
 		zip->stream_valid = 0;
 	}
+#endif
+#ifdef HAVE_ZSTD_H
+	if (zip->zstdstream_valid)
+		ZSTD_freeDStream(zip->zstd_dstream);
 #endif
 	if (zip->ppmd7_valid) {
 		__archive_ppmd7_functions.Ppmd7_Free(
@@ -2045,6 +2047,8 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
 			if (parse_7zip_uint64(
 			    a, &(f->coders[i].propertiesSize)) < 0)
 				return (-1);
+			if (UMAX_ENTRY < f->coders[i].propertiesSize)
+				return (-1);
 			if ((p = header_bytes(
 			    a, (size_t)f->coders[i].propertiesSize)) == NULL)
 				return (-1);
@@ -2314,7 +2318,7 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
 	usizes = ss->unpackSizes;
 	for (i = 0; i < numFolders; i++) {
 		unsigned pack;
-		uint64_t sum;
+		uint64_t size, sum;
 
 		if (f[i].numUnpackStreams == 0)
 			continue;
@@ -2324,10 +2328,15 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
 			for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
 				if (parse_7zip_uint64(a, usizes) < 0)
 					return (-1);
+				if (*usizes > UINT64_MAX - sum)
+					return (-1);
 				sum += *usizes++;
 			}
 		}
-		*usizes++ = folder_uncompressed_size(&f[i]) - sum;
+		size = folder_uncompressed_size(&f[i]);
+		if (size < sum)
+			return (-1);
+		*usizes++ = size - sum;
 	}
 
 	if (type == kSize) {
@@ -2421,6 +2430,8 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
 		packPos = si->pi.pos;
 		for (i = 0; i < si->pi.numPackStreams; i++) {
 			si->pi.positions[i] = packPos;
+			if (packPos > UINT64_MAX - si->pi.sizes[i])
+				return (-1);
 			packPos += si->pi.sizes[i];
 			if (packPos > zip->header_offset)
 				return (-1);
@@ -2442,6 +2453,10 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
 		f = si->ci.folders;
 		for (i = 0; i < si->ci.numFolders; i++) {
 			f[i].packIndex = packIndex;
+			if (f[i].numPackedStreams > UINT32_MAX)
+				return (-1);
+			if (packIndex > UINT32_MAX - (uint32_t)f[i].numPackedStreams)
+				return (-1);
 			packIndex += (uint32_t)f[i].numPackedStreams;
 			if (packIndex > si->pi.numPackStreams)
 				return (-1);
@@ -3009,7 +3024,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
 	/* CRC check. */
 	if (crc32(0, (const unsigned char *)p + 12, 20)
 	    != archive_le32dec(p + 8)) {
-#ifdef DONT_FAIL_ON_CRC_ERROR
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, -1, "Header CRC error");
 		return (ARCHIVE_FATAL);
 #endif
@@ -3061,8 +3076,8 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
 
 		/* Check the EncodedHeader CRC.*/
 		if (r == 0 && zip->header_crc32 != next_header_crc) {
-			archive_set_error(&a->archive, -1,
 #ifndef DONT_FAIL_ON_CRC_ERROR
+			archive_set_error(&a->archive, -1,
 			    "Damaged 7-Zip archive");
 			r = -1;
 #endif
@@ -3151,7 +3166,7 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
 		/* Copy mode. */
 
 		*buff = __archive_read_ahead(a, minimum, &bytes_avail);
-		if (bytes_avail <= 0) {
+		if (*buff == NULL) {
 			archive_set_error(&a->archive,
 			    ARCHIVE_ERRNO_FILE_FORMAT,
 			    "Truncated 7-Zip file data");
@@ -3457,7 +3472,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
 	/*
 	 * Skip the bytes we already has skipped in skip_stream().
 	 */
-	while (skip_bytes) {
+	while (1) {
 		ssize_t skipped;
 
 		if (zip->uncompressed_buffer_bytes_remaining == 0) {
@@ -3477,6 +3492,10 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
 				return (ARCHIVE_FATAL);
 			}
 		}
+
+		if (!skip_bytes)
+			break;
+
 		skipped = get_uncompressed_data(
 			a, buff, (size_t)skip_bytes, 0);
 		if (skipped < 0)

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_all.c 174991 2007-12-30 04:58:22Z kientzle $");
 
 #include "archive.h"
 #include "archive_private.h"
@@ -68,7 +67,7 @@ archive_read_support_format_all(struct archive *a)
 	 * increase the chance that a high bid from someone else will
 	 * make it unnecessary for these to do anything at all.
 	 */
-	/* These three have potentially large look-ahead. */
+	/* These have potentially large look-ahead. */
 	archive_read_support_format_7zip(a);
 	archive_read_support_format_cab(a);
 	archive_read_support_format_rar(a);

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

@@ -26,7 +26,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_ar.c 201101 2009-12-28 03:06:27Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -271,7 +270,7 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
 		}
 		if (ar->strtab != NULL) {
 			archive_set_error(&a->archive, EINVAL,
-			    "More than one string tables exist");
+			    "More than one string table exists");
 			return (ARCHIVE_FATAL);
 		}
 
@@ -440,9 +439,9 @@ archive_read_format_ar_read_header(struct archive_read *a,
 	if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL)
 		/* Broken header. */
 		return (ARCHIVE_EOF);
-	
+
 	unconsumed = 60;
-	
+
 	ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed);
 
 	if (unconsumed)
@@ -459,7 +458,6 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
 	uint64_t n;
 
 	/* Copy remaining header */
-	archive_entry_set_filetype(entry, AE_IFREG);
 	archive_entry_set_mtime(entry,
 	    (time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
 	archive_entry_set_uid(entry,
@@ -468,6 +466,7 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
 	    (gid_t)ar_atol10(h + AR_gid_offset, AR_gid_size));
 	archive_entry_set_mode(entry,
 	    (mode_t)ar_atol8(h + AR_mode_offset, AR_mode_size));
+	archive_entry_set_filetype(entry, AE_IFREG);
 	n = ar_atol10(h + AR_size_offset, AR_size_size);
 
 	ar->entry_offset = 0;
@@ -516,7 +515,7 @@ archive_read_format_ar_read_data(struct archive_read *a,
 		if (ar->entry_padding) {
 			if (skipped >= 0) {
 				archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-					"Truncated ar archive- failed consuming padding");
+					"Truncated ar archive - failed consuming padding");
 			}
 			return (ARCHIVE_FATAL);
 		}

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>

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

@@ -1682,7 +1682,7 @@ cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
 		    cfdata->uncompressed_size - cab->xstrm.total_out;
 
 		d = __archive_read_ahead(a, 1, &bytes_avail);
-		if (bytes_avail <= 0) {
+		if (d == NULL) {
 			archive_set_error(&a->archive,
 			    ARCHIVE_ERRNO_FILE_FORMAT,
 			    "Truncated CAB file data");

+ 19 - 10
Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c

@@ -25,7 +25,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 201163 2009-12-29 05:50:34Z kientzle $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -835,6 +834,7 @@ static int
 header_afiol(struct archive_read *a, struct cpio *cpio,
     struct archive_entry *entry, size_t *namelength, size_t *name_pad)
 {
+	int64_t t;
 	const void *h;
 	const char *header;
 
@@ -851,7 +851,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
 
 	archive_entry_set_dev(entry, 
 		(dev_t)atol16(header + afiol_dev_offset, afiol_dev_size));
-	archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
+	t = atol16(header + afiol_ino_offset, afiol_ino_size);
+	if (t < 0) {
+		archive_set_error(&a->archive, 0, "Nonsensical ino value");
+		return (ARCHIVE_FATAL);
+	}
+	archive_entry_set_ino(entry, t);
 	archive_entry_set_mode(entry,
 		(mode_t)atol8(header + afiol_mode_offset, afiol_mode_size));
 	archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
@@ -864,8 +869,12 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
 	*namelength = (size_t)atol16(header + afiol_namesize_offset, afiol_namesize_size);
 	*name_pad = 0; /* No padding of filename. */
 
-	cpio->entry_bytes_remaining =
-	    atol16(header + afiol_filesize_offset, afiol_filesize_size);
+	t = atol16(header + afiol_filesize_offset, afiol_filesize_size);
+	if (t < 0) {
+		archive_set_error(&a->archive, 0, "Nonsensical file size");
+		return (ARCHIVE_FATAL);
+	}
+	cpio->entry_bytes_remaining = t;
 	archive_entry_set_size(entry, cpio->entry_bytes_remaining);
 	cpio->entry_padding = 0;
 	__archive_read_consume(a, afiol_header_size);
@@ -1003,7 +1012,7 @@ be4(const unsigned char *p)
 static int64_t
 atol8(const char *p, unsigned char_cnt)
 {
-	int64_t l;
+	uint64_t l;
 	int digit;
 
 	l = 0;
@@ -1011,18 +1020,18 @@ atol8(const char *p, unsigned char_cnt)
 		if (*p >= '0' && *p <= '7')
 			digit = *p - '0';
 		else
-			return (l);
+			return ((int64_t)l);
 		p++;
 		l <<= 3;
 		l |= digit;
 	}
-	return (l);
+	return ((int64_t)l);
 }
 
 static int64_t
 atol16(const char *p, unsigned char_cnt)
 {
-	int64_t l;
+	uint64_t l;
 	int digit;
 
 	l = 0;
@@ -1034,12 +1043,12 @@ atol16(const char *p, unsigned char_cnt)
 		else if (*p >= '0' && *p <= '9')
 			digit = *p - '0';
 		else
-			return (l);
+			return ((int64_t)l);
 		p++;
 		l <<= 4;
 		l |= digit;
 	}
-	return (l);
+	return ((int64_t)l);
 }
 
 static int

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

@@ -24,7 +24,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_empty.c 191524 2009-04-26 18:24:14Z kientzle $");
 
 #include "archive.h"
 #include "archive_entry.h"

+ 112 - 9
Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c

@@ -26,7 +26,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_iso9660.c 201246 2009-12-30 05:30:35Z kientzle $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -403,6 +402,9 @@ static int	isJolietSVD(struct iso9660 *, const unsigned char *);
 static int	isSVD(struct iso9660 *, const unsigned char *);
 static int	isEVD(struct iso9660 *, const unsigned char *);
 static int	isPVD(struct iso9660 *, const unsigned char *);
+static int	isRootDirectoryRecord(const unsigned char *);
+static int	isValid723Integer(const unsigned char *);
+static int	isValid733Integer(const unsigned char *);
 static int	next_cache_entry(struct archive_read *, struct iso9660 *,
 		    struct file_info **);
 static int	next_entry_seek(struct archive_read *, struct iso9660 *,
@@ -774,8 +776,9 @@ isSVD(struct iso9660 *iso9660, const unsigned char *h)
 
 	/* Read Root Directory Record in Volume Descriptor. */
 	p = h + SVD_root_directory_record_offset;
-	if (p[DR_length_offset] != 34)
+	if (!isRootDirectoryRecord(p)) {
 		return (0);
+	}
 
 	return (48);
 }
@@ -852,8 +855,9 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
 
 	/* Read Root Directory Record in Volume Descriptor. */
 	p = h + PVD_root_directory_record_offset;
-	if (p[DR_length_offset] != 34)
+	if (!isRootDirectoryRecord(p)) {
 		return (0);
+	}
 
 	return (48);
 }
@@ -883,21 +887,43 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
 	if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size))
 		return (0);
 
+	/* Volume space size must be encoded according to 7.3.3 */
+	if (!isValid733Integer(h + PVD_volume_space_size_offset)) {
+		return (0);
+	}
+	volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
+	if (volume_block <= SYSTEM_AREA_BLOCK+4)
+		return (0);
+
 	/* Reserved field must be 0. */
 	if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size))
 		return (0);
 
+	/* Volume set size must be encoded according to 7.2.3 */
+	if (!isValid723Integer(h + PVD_volume_set_size_offset)) {
+		return (0);
+	}
+
+	/* Volume sequence number must be encoded according to 7.2.3 */
+	if (!isValid723Integer(h + PVD_volume_sequence_number_offset)) {
+		return (0);
+	}
+
 	/* Logical block size must be > 0. */
 	/* I've looked at Ecma 119 and can't find any stronger
 	 * restriction on this field. */
+	if (!isValid723Integer(h + PVD_logical_block_size_offset)) {
+		return (0);
+	}
 	logical_block_size =
 	    archive_le16dec(h + PVD_logical_block_size_offset);
 	if (logical_block_size <= 0)
 		return (0);
 
-	volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
-	if (volume_block <= SYSTEM_AREA_BLOCK+4)
+	/* Path Table size must be encoded according to 7.3.3 */
+	if (!isValid733Integer(h + PVD_path_table_size_offset)) {
 		return (0);
+	}
 
 	/* File structure version must be 1 for ISO9660/ECMA119. */
 	if (h[PVD_file_structure_version_offset] != 1)
@@ -936,8 +962,9 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
 
 	/* Read Root Directory Record in Volume Descriptor. */
 	p = h + PVD_root_directory_record_offset;
-	if (p[DR_length_offset] != 34)
+	if (!isRootDirectoryRecord(p)) {
 		return (0);
+	}
 
 	if (!iso9660->primary.location) {
 		iso9660->logical_block_size = logical_block_size;
@@ -952,6 +979,51 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
 	return (48);
 }
 
+static int
+isRootDirectoryRecord(const unsigned char *p) {
+	int flags;
+
+	/* ECMA119/ISO9660 requires that the root directory record be _exactly_ 34 bytes.
+	 * However, we've seen images that have root directory records up to 68 bytes. */
+	if (p[DR_length_offset] < 34 || p[DR_length_offset] > 68) {
+		return (0);
+	}
+
+	/* The root directory location must be a 7.3.3 32-bit integer. */
+	if (!isValid733Integer(p + DR_extent_offset)) {
+		return (0);
+	}
+
+	/* The root directory size must be a 7.3.3 integer. */
+	if (!isValid733Integer(p + DR_size_offset)) {
+		return (0);
+	}
+
+	/* According to the standard, certain bits must be one or zero:
+	 * Bit 1: must be 1 (this is a directory)
+	 * Bit 2: must be 0 (not an associated file)
+	 * Bit 3: must be 0 (doesn't use extended attribute record)
+	 * Bit 7: must be 0 (final directory record for this file)
+	 */
+	flags = p[DR_flags_offset];
+	if ((flags & 0x8E) != 0x02) {
+		return (0);
+	}
+
+	/* Volume sequence number must be a 7.2.3 integer. */
+	if (!isValid723Integer(p + DR_volume_sequence_number_offset)) {
+		return (0);
+	}
+
+	/* Root directory name is a single zero byte... */
+	if (p[DR_name_len_offset] != 1 || p[DR_name_offset] != 0) {
+		return (0);
+	}
+
+	/* Nothing looked wrong, so let's accept it. */
+	return (1);
+}
+
 static int
 read_children(struct archive_read *a, struct file_info *parent)
 {
@@ -1213,7 +1285,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
 			}
 		}
 		if (iso9660->utf16be_previous_path == NULL) {
-			iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX);
+			iso9660->utf16be_previous_path = calloc(1, UTF16_NAME_MAX);
 			if (iso9660->utf16be_previous_path == NULL) {
 				archive_set_error(&a->archive, ENOMEM,
 				    "No memory");
@@ -3015,6 +3087,11 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
 	uint64_t file_key, parent_key;
 	int hole, parent;
 
+	/* Reserve 16 bits for possible key collisions (needed for linked items) */
+	/* For ISO files with more than 65535 entries, reordering will still occur */
+	key <<= 16;
+	key += heap->used & 0xFFFF;
+
 #ifndef __clang_analyzer__ /* It cannot see heap->files remains populated.  */
 	/* Expand our pending files list as necessary. */
 	if (heap->used >= heap->allocated) {
@@ -3030,7 +3107,7 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
 			return (ARCHIVE_FATAL);
 		}
 		new_pending_files = (struct file_info **)
-		    malloc(new_size * sizeof(new_pending_files[0]));
+		    calloc(new_size, sizeof(new_pending_files[0]));
 		if (new_pending_files == NULL) {
 			archive_set_error(&a->archive,
 			    ENOMEM, "Out of memory");
@@ -3125,6 +3202,32 @@ toi(const void *p, int n)
 	return (0);
 }
 
+/*
+ * ECMA119/ISO9660 stores multi-byte integers in one of
+ * three different formats:
+ *  * Little-endian (specified in section 7.2.1 and 7.3.1)
+ *  * Big-endian (specified in section 7.2.2 and 7.3.2)
+ *  * Both (specified in section 7.2.3 and 7.3.3)
+ *
+ * For values that follow section 7.2.3 (16-bit) or 7.3.3 (32-bit), we
+ * can check that the little-endian and big-endian forms agree with
+ * each other.  This helps us avoid trying to decode files that are
+ * not really ISO images.
+ */
+static int
+isValid723Integer(const unsigned char *p) {
+	return (p[0] == p[3] && p[1] == p[2]);
+}
+
+static int
+isValid733Integer(const unsigned char *p)
+{
+	return (p[0] == p[7]
+		&& p[1] == p[6]
+		&& p[2] == p[5]
+		&& p[3] == p[4]);
+}
+
 static time_t
 isodate7(const unsigned char *v)
 {
@@ -3162,7 +3265,7 @@ isodate17(const unsigned char *v)
 	tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
 	    + (v[2] - '0') * 10 + (v[3] - '0')
 	    - 1900;
-	tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0');
+	tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0') - 1;
 	tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0');
 	tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0');
 	tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0');

+ 8 - 7
Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c

@@ -227,7 +227,7 @@ static int	lha_read_file_header_1(struct archive_read *, struct lha *);
 static int	lha_read_file_header_2(struct archive_read *, struct lha *);
 static int	lha_read_file_header_3(struct archive_read *, struct lha *);
 static int	lha_read_file_extended_header(struct archive_read *,
-		    struct lha *, uint16_t *, int, size_t, size_t *);
+		    struct lha *, uint16_t *, int, uint64_t, size_t *);
 static size_t	lha_check_header_format(const void *);
 static int	lha_skip_sfx(struct archive_read *);
 static time_t	lha_dos_time(const unsigned char *);
@@ -945,7 +945,7 @@ lha_read_file_header_1(struct archive_read *a, struct lha *lha)
 
 	/* Read extended headers */
 	err2 = lha_read_file_extended_header(a, lha, NULL, 2,
-	    (size_t)(lha->compsize + 2), &extdsize);
+	    (uint64_t)(lha->compsize + 2), &extdsize);
 	if (err2 < ARCHIVE_WARN)
 		return (err2);
 	if (err2 < err)
@@ -1138,7 +1138,7 @@ invalid:
  */
 static int
 lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
-    uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
+    uint16_t *crc, int sizefield_length, uint64_t limitsize, size_t *total_size)
 {
 	const void *h;
 	const unsigned char *extdheader;
@@ -1187,8 +1187,7 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
 		}
 
 		/* Sanity check to the extended header size. */
-		if (((uint64_t)*total_size + extdsize) >
-				    (uint64_t)limitsize ||
+		if (((uint64_t)*total_size + extdsize) > limitsize ||
 		    extdsize <= (size_t)sizefield_length)
 			goto invalid;
 
@@ -1347,6 +1346,8 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
 				lha->compsize = archive_le64dec(extdheader);
 				extdheader += sizeof(uint64_t);
 				lha->origsize = archive_le64dec(extdheader);
+				if (lha->compsize < 0 || lha->origsize < 0)
+					goto invalid;
 			}
 			break;
 		case EXT_CODEPAGE:
@@ -1693,7 +1694,7 @@ archive_read_format_lha_cleanup(struct archive_read *a)
  * example.
  *   1. a symbolic-name is 'aaa/bb/cc'
  *   2. a filename is 'xxx/bbb'
- *  then a archived pathname is 'xxx/bbb|aaa/bb/cc'
+ *  then an archived pathname is 'xxx/bbb|aaa/bb/cc'
  */
 static int
 lha_parse_linkname(struct archive_wstring *linkname,
@@ -2385,7 +2386,7 @@ lzh_decode_blocks(struct lzh_stream *strm, int last)
 					return (100);
 				}
 
-				/* lzh_br_read_ahead() always try to fill the
+				/* lzh_br_read_ahead() always tries to fill the
 				 * cache buffer up. In specific situation we
 				 * are close to the end of the data, the cache
 				 * buffer will not be full and thus we have to

+ 4 - 5
Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c

@@ -26,7 +26,6 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 201165 2009-12-29 05:52:13Z kientzle $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -417,8 +416,8 @@ next_line(struct archive_read *a,
 }
 
 /*
- * Compare characters with a mtree keyword.
- * Returns the length of a mtree keyword if matched.
+ * Compare characters with an mtree keyword.
+ * Returns the length of an mtree keyword if matched.
  * Returns 0 if not matched.
  */
 static int
@@ -516,7 +515,7 @@ bid_keyword(const char *p,  ssize_t len)
 
 /*
  * Test whether there is a set of mtree keywords.
- * Returns the number of keyword.
+ * Returns the number of keywords.
  * Returns -1 if we got incorrect sequence.
  * This function expects a set of "<space characters>keyword=value".
  * When "unset" is specified, expects a set of "<space characters>keyword".
@@ -761,7 +760,7 @@ detect_form(struct archive_read *a, int *is_form_d)
 					multiline = 1;
 				else {
 					/* We've got plenty of correct lines
-					 * to assume that this file is a mtree
+					 * to assume that this file is an mtree
 					 * format. */
 					if (++entry_cnt >= MAX_BID_ENTRY)
 						break;

+ 111 - 34
Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c

@@ -434,7 +434,7 @@ static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
                               struct huffman_table_entry *, int, int);
 static int expand(struct archive_read *, int64_t *);
 static int copy_from_lzss_window_to_unp(struct archive_read *, const void **,
-                                        int64_t, int);
+                                        int64_t, size_t);
 static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
 static int parse_filter(struct archive_read *, const uint8_t *, uint16_t,
                         uint8_t);
@@ -736,7 +736,7 @@ archive_read_support_format_rar(struct archive *_a)
   archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
                       "archive_read_support_format_rar");
 
-  rar = (struct rar *)calloc(sizeof(*rar), 1);
+  rar = (struct rar *)calloc(1, sizeof(*rar));
   if (rar == NULL)
   {
     archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data");
@@ -1375,6 +1375,8 @@ read_header(struct archive_read *a, struct archive_entry *entry,
   struct archive_string_conv *sconv, *fn_sconv;
   unsigned long crc32_val;
   int ret = (ARCHIVE_OK), ret2;
+  char *newptr;
+  size_t newsize;
 
   rar = (struct rar *)(a->format->data);
 
@@ -1471,6 +1473,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
 
   if (rar->file_flags & FHD_LARGE)
   {
+    if (p + 8 > endp) {
+      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+                        "Invalid header size");
+      return (ARCHIVE_FATAL);
+    }
     memcpy(packed_size, file_header.pack_size, 4);
     memcpy(packed_size + 4, p, 4); /* High pack size */
     p += 4;
@@ -1516,8 +1523,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
     return (ARCHIVE_FATAL);
   }
   if (rar->filename_allocated < filename_size * 2 + 2) {
-    char *newptr;
-    size_t newsize = filename_size * 2 + 2;
+    newsize = filename_size * 2 + 2;
     newptr = realloc(rar->filename, newsize);
     if (newptr == NULL) {
       archive_set_error(&a->archive, ENOMEM,
@@ -1541,7 +1547,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
       fn_end = filename_size * 2;
       filename_size = 0;
       offset = (unsigned)strlen(filename) + 1;
-      highbyte = *(p + offset++);
+      highbyte = offset >= end ? 0 : *(p + offset++);
       flagbits = 0;
       flagbyte = 0;
       while (offset < end && filename_size < fn_end)
@@ -1556,14 +1562,22 @@ read_header(struct archive_read *a, struct archive_entry *entry,
         switch((flagbyte >> flagbits) & 3)
         {
           case 0:
+            if (offset >= end)
+              continue;
             filename[filename_size++] = '\0';
             filename[filename_size++] = *(p + offset++);
             break;
           case 1:
+            if (offset >= end)
+              continue;
             filename[filename_size++] = highbyte;
             filename[filename_size++] = *(p + offset++);
             break;
           case 2:
+            if (offset >= end - 1) {
+              offset = end;
+              continue;
+            }
             filename[filename_size++] = *(p + offset + 1);
             filename[filename_size++] = *(p + offset);
             offset += 2;
@@ -1571,9 +1585,15 @@ read_header(struct archive_read *a, struct archive_entry *entry,
           case 3:
           {
             char extra, high;
-            uint8_t length = *(p + offset++);
+            uint8_t length;
+
+            if (offset >= end)
+              continue;
 
+            length = *(p + offset++);
             if (length & 0x80) {
+              if (offset >= end)
+                continue;
               extra = *(p + offset++);
               high = (char)highbyte;
             } else
@@ -1654,13 +1674,16 @@ read_header(struct archive_read *a, struct archive_entry *entry,
     rar->cursor++;
     if (rar->cursor >= rar->nodes)
     {
-      rar->nodes++;
-      if ((rar->dbo =
-        realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL)
+      struct data_block_offsets *newdbo;
+
+      newsize = sizeof(*rar->dbo) * (rar->nodes + 1);
+      if ((newdbo = realloc(rar->dbo, newsize)) == NULL)
       {
         archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
         return (ARCHIVE_FATAL);
       }
+      rar->dbo = newdbo;
+      rar->nodes++;
       rar->dbo[rar->cursor].header_size = header_size;
       rar->dbo[rar->cursor].start_offset = -1;
       rar->dbo[rar->cursor].end_offset = -1;
@@ -1680,9 +1703,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
     return (ARCHIVE_FATAL);
   }
 
-  rar->filename_save = (char*)realloc(rar->filename_save,
-                                      filename_size + 1);
-  memcpy(rar->filename_save, rar->filename, filename_size + 1);
+  newsize = filename_size + 1;
+  if ((newptr = realloc(rar->filename_save, newsize)) == NULL)
+  {
+    archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
+    return (ARCHIVE_FATAL);
+  }
+  rar->filename_save = newptr;
+  memcpy(rar->filename_save, rar->filename, newsize);
   rar->filename_save_size = filename_size;
 
   /* Set info for seeking */
@@ -2062,7 +2090,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
         bs = rar->unp_buffer_size - rar->unp_offset;
       else
         bs = (size_t)rar->bytes_uncopied;
-      ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
+      ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
       if (ret != ARCHIVE_OK)
         return (ret);
       rar->offset += bs;
@@ -2178,6 +2206,19 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
     {
       start = rar->offset;
       end = start + rar->dictionary_size;
+
+      /* We don't want to overflow the window and overwrite data that we write
+       * at 'start'. Therefore, reduce the end length by the maximum match size,
+       * which is 260 bytes. You can compute this maximum by looking at the
+       * definition of 'expand', in particular when 'symbol >= 271'. */
+      /* NOTE: It's possible for 'dictionary_size' to be less than this 260
+       * value, however that will only be the case when 'unp_size' is small,
+       * which should only happen when the entry size is small and there's no
+       * risk of overflowing the buffer */
+      if (rar->dictionary_size > 260) {
+        end -= 260;
+      }
+
       if (rar->filters.filterstart < end) {
         end = rar->filters.filterstart;
       }
@@ -2202,7 +2243,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
       bs = rar->unp_buffer_size - rar->unp_offset;
     else
       bs = (size_t)rar->bytes_uncopied;
-    ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
+    ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
     if (ret != ARCHIVE_OK)
       return (ret);
     rar->offset += bs;
@@ -2568,8 +2609,7 @@ read_next_symbol(struct archive_read *a, struct huffman_code *code)
   rar_br_consume(br, code->tablesize);
 
   node = value;
-  while (!(code->tree[node].branches[0] ==
-    code->tree[node].branches[1]))
+  while (code->tree[node].branches[0] != code->tree[node].branches[1])
   {
     if (!rar_br_read_ahead(a, br, 1)) {
       archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@@ -2944,7 +2984,7 @@ expand(struct archive_read *a, int64_t *end)
 
       if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
         goto bad_data;
-      if (lensymbol > lengthb_min)
+      if (lensymbol >= lengthb_min)
         goto bad_data;
       len = lengthbases[lensymbol] + 2;
       if (lengthbits[lensymbol] > 0) {
@@ -2976,7 +3016,7 @@ expand(struct archive_read *a, int64_t *end)
     }
     else
     {
-      if (symbol-271 > lengthb_min)
+      if (symbol-271 >= lengthb_min)
         goto bad_data;
       len = lengthbases[symbol-271]+3;
       if(lengthbits[symbol-271] > 0) {
@@ -2988,7 +3028,7 @@ expand(struct archive_read *a, int64_t *end)
 
       if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
         goto bad_data;
-      if (offssymbol > offsetb_min)
+      if (offssymbol >= offsetb_min)
         goto bad_data;
       offs = offsetbases[offssymbol]+1;
       if(offsetbits[offssymbol] > 0)
@@ -3083,11 +3123,16 @@ copy_from_lzss_window(struct archive_read *a, void *buffer,
 
 static int
 copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
-                             int64_t startpos, int length)
+                             int64_t startpos, size_t length)
 {
   int windowoffs, firstpart;
   struct rar *rar = (struct rar *)(a->format->data);
 
+  if (length > rar->unp_buffer_size)
+  {
+    goto fatal;
+  }
+
   if (!rar->unp_buffer)
   {
     if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
@@ -3099,17 +3144,17 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
   }
 
   windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
-  if(windowoffs + length <= lzss_size(&rar->lzss)) {
+  if(windowoffs + length <= (size_t)lzss_size(&rar->lzss)) {
     memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
            length);
-  } else if (length <= lzss_size(&rar->lzss)) {
+  } else if (length <= (size_t)lzss_size(&rar->lzss)) {
     firstpart = lzss_size(&rar->lzss) - windowoffs;
     if (firstpart < 0) {
       archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                         "Bad RAR file data");
       return (ARCHIVE_FATAL);
     }
-    if (firstpart < length) {
+    if ((size_t)firstpart < length) {
       memcpy(&rar->unp_buffer[rar->unp_offset],
              &rar->lzss.window[windowoffs], firstpart);
       memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
@@ -3119,16 +3164,19 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
              &rar->lzss.window[windowoffs], length);
     }
   } else {
-      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-                        "Bad RAR file data");
-      return (ARCHIVE_FATAL);
+      goto fatal;
   }
-  rar->unp_offset += length;
+  rar->unp_offset += (unsigned int) length;
   if (rar->unp_offset >= rar->unp_buffer_size)
     *buffer = rar->unp_buffer;
   else
     *buffer = NULL;
   return (ARCHIVE_OK);
+
+fatal:
+  archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+                    "Bad RAR file data");
+  return (ARCHIVE_FATAL);
 }
 
 static const void *
@@ -3314,7 +3362,8 @@ create_filter(struct rar_program_code *prog, const uint8_t *globaldata, uint32_t
   filter->prog = prog;
   filter->globaldatalen = globaldatalen > PROGRAM_SYSTEM_GLOBAL_SIZE ? globaldatalen : PROGRAM_SYSTEM_GLOBAL_SIZE;
   filter->globaldata = calloc(1, filter->globaldatalen);
-  if (!filter->globaldata) {
+  if (!filter->globaldata)
+  {
     free(filter);
     return NULL;
   }
@@ -3344,7 +3393,7 @@ run_filters(struct archive_read *a)
   if (filters == NULL || filter == NULL)
     return (0);
 
-  start = filters->filterstart;
+  start = (size_t)filters->filterstart;
   end = start + filter->blocklength;
 
   filters->filterstart = INT64_MAX;
@@ -3381,10 +3430,16 @@ run_filters(struct archive_read *a)
       return 0;
   }
 
+  if (filter->blocklength > VM_MEMORY_SIZE)
+  {
+    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Bad RAR file data");
+    return 0;
+  }
+
   ret = copy_from_lzss_window(a, filters->vm->memory, start, filter->blocklength);
   if (ret != ARCHIVE_OK)
     return 0;
-  if (!execute_filter(a, filter, filters->vm, rar->offset))
+  if (!execute_filter(a, filter, filters->vm, (size_t)rar->offset))
     return 0;
 
   lastfilteraddress = filter->filteredblockaddress;
@@ -3396,7 +3451,7 @@ run_filters(struct archive_read *a)
   while ((filter = filters->stack) != NULL && (int64_t)filter->blockstartpos == filters->filterstart && filter->blocklength == lastfilterlength)
   {
     memmove(&filters->vm->memory[0], &filters->vm->memory[lastfilteraddress], lastfilterlength);
-    if (!execute_filter(a, filter, filters->vm, rar->offset))
+    if (!execute_filter(a, filter, filters->vm, (size_t)rar->offset))
       return 0;
 
     lastfilteraddress = filter->filteredblockaddress;
@@ -3604,7 +3659,15 @@ execute_filter_delta(struct rar_filter *filter, struct rar_virtual_machine *vm)
   {
     uint8_t lastbyte = 0;
     for (idx = i; idx < length; idx += numchannels)
+    {
+      /*
+       * The src block should not overlap with the dst block.
+       * If so it would be better to consider this archive is broken.
+       */
+      if (src >= dst)
+        return 0;
       lastbyte = dst[idx] = lastbyte - *src++;
+    }
   }
 
   filter->filteredblockaddress = length;
@@ -3620,7 +3683,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
   uint32_t filesize = 0x1000000;
   uint32_t i;
 
-  if (length > PROGRAM_WORK_SIZE || length < 4)
+  if (length > PROGRAM_WORK_SIZE || length <= 4)
     return 0;
 
   for (i = 0; i <= length - 5; i++)
@@ -3629,7 +3692,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
     {
       uint32_t currpos = (uint32_t)pos + i + 1;
       int32_t address = (int32_t)vm_read_32(vm, i + 1);
-      if (address < 0 && currpos >= (uint32_t)-address)
+      if (address < 0 && currpos >= (~(uint32_t)address + 1))
         vm_write_32(vm, i + 1, address + filesize);
       else if (address >= 0 && (uint32_t)address < filesize)
         vm_write_32(vm, i + 1, address - currpos);
@@ -3652,7 +3715,7 @@ execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
   uint8_t *src, *dst;
   uint32_t i, j;
 
-  if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength)
+  if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength || blocklength < 3 || byteoffset > 2)
     return 0;
 
   src = &vm->memory[0];
@@ -3662,6 +3725,13 @@ execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm)
     uint8_t *prev = dst + i - stride;
     for (j = i; j < blocklength; j += 3)
     {
+      /*
+       * The src block should not overlap with the dst block.
+       * If so it would be better to consider this archive is broken.
+       */
+      if (src >= dst)
+        return 0;
+
       if (prev >= dst)
       {
         uint32_t delta1 = abs(prev[3] - prev[0]);
@@ -3706,6 +3776,13 @@ execute_filter_audio(struct rar_filter *filter, struct rar_virtual_machine *vm)
     memset(&state, 0, sizeof(state));
     for (j = i; j < length; j += numchannels)
     {
+      /*
+       * The src block should not overlap with the dst block.
+       * If so it would be better to consider this archive is broken.
+       */
+      if (src >= dst)
+        return 0;
+
       int8_t delta = (int8_t)*src++;
       uint8_t predbyte, byte;
       int prederror;

Some files were not shown because too many files changed in this diff