Merge topic 'fix-short-path'

a368a59467 Windows: Tolerate GetShortPathNameW failure

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !8432
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b26172d..ac8e168 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -664,6 +664,13 @@
         CMAKE_CI_BUILD_NAME: intel2021.8.0_makefiles
         CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2023.0.0-el8
 
+t:intel2021.9.0-makefiles:
+    extends:
+        - .cmake_test_linux_intelclassic_makefiles
+    variables:
+        CMAKE_CI_BUILD_NAME: intel2021.9.0_makefiles
+        CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2023.1.0-el8
+
 t:oneapi2021.1.1-makefiles:
     extends:
         - .cmake_test_linux_inteloneapi_makefiles
@@ -727,6 +734,13 @@
         CMAKE_CI_BUILD_NAME: oneapi2023.0.0_makefiles
         CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2023.0.0-el8
 
+t:oneapi2023.1.0-makefiles:
+    extends:
+        - .cmake_test_linux_inteloneapi_makefiles
+    variables:
+        CMAKE_CI_BUILD_NAME: oneapi2023.1.0_makefiles
+        CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2023.1.0-el8
+
 b:linux-x86_64-package:
     extends:
         - .linux_package
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst
index 7aea8e6..e2366da 100644
--- a/Help/manual/cmake-presets.7.rst
+++ b/Help/manual/cmake-presets.7.rst
@@ -133,6 +133,9 @@
 guaranteed to be provided by the project. ``CMakeUserPresets.json`` may
 include files from anywhere.
 
+Starting from version ``7``, the ``include`` field supports
+`macro expansion`_, but only ``$penv{}`` macro expansion.
+
 Configure Preset
 ^^^^^^^^^^^^^^^^
 
diff --git a/Help/release/dev/preset-includes-macro-expansion.rst b/Help/release/dev/preset-includes-macro-expansion.rst
new file mode 100644
index 0000000..e1f0030
--- /dev/null
+++ b/Help/release/dev/preset-includes-macro-expansion.rst
@@ -0,0 +1,7 @@
+preset-includes-macro-expansion
+-------------------------------
+
+* :manual:`cmake-presets(7)` files now support schema version ``7``.
+
+* :manual:`cmake-presets(7)` now supports ``$penv{}`` macro expansion
+  in ``include`` fields.
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 67044fb..403766e 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -345,6 +345,7 @@
     set(id_platform ${CMAKE_VS_PLATFORM_NAME})
     set(id_lang "${lang}")
     set(id_PostBuildEvent_Command "")
+    set(id_api_level "")
     if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$")
       set(id_cl_var "ClangClExecutable")
     elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg]([Cc][Ll]$|_[0-9])")
@@ -430,9 +431,10 @@
       set(id_system "")
     endif()
     if(id_keyword STREQUAL "Android")
+      set(id_api_level "<AndroidAPILevel>android-${CMAKE_SYSTEM_VERSION}</AndroidAPILevel>")
       if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
         set(id_system_version "<ApplicationTypeRevision>2.0</ApplicationTypeRevision>")
-      elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+      elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[567]")
         set(id_system_version "<ApplicationTypeRevision>3.0</ApplicationTypeRevision>")
       else()
         set(id_system_version "")
diff --git a/Modules/Compiler/NVHPC-Fortran.cmake b/Modules/Compiler/NVHPC-Fortran.cmake
index 5c06457..879c140 100644
--- a/Modules/Compiler/NVHPC-Fortran.cmake
+++ b/Modules/Compiler/NVHPC-Fortran.cmake
@@ -1,4 +1,4 @@
 include(Compiler/PGI-Fortran)
 include(Compiler/NVHPC)
 __compiler_nvhpc(Fortran)
-set(CMAKE_Fortran_PREPROCESS_SOURCE_EXCLUDE_FLAGS_REGEX "(^| )-Werror +[a-z][a-z-]+( |$)")
+set(CMAKE_Fortran_PREPROCESS_SOURCE_EXCLUDE_FLAGS_REGEX "(^| )-Werror([=,][a-z][a-z-]+)?( |$)")
diff --git a/Modules/Compiler/NVHPC.cmake b/Modules/Compiler/NVHPC.cmake
index 474ac80..0593456 100644
--- a/Modules/Compiler/NVHPC.cmake
+++ b/Modules/Compiler/NVHPC.cmake
@@ -13,5 +13,5 @@
 macro(__compiler_nvhpc lang)
   # Logic specific to NVHPC.
   set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
-  set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror" "all-warnings")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror")
 endmacro()
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index 3598fc7..fa324d8 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -26,6 +26,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration">
     <ConfigurationType>@id_config_type@</ConfigurationType>
     @id_toolset@
+    @id_api_level@
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -44,7 +45,7 @@
       <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>false</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(ApplicationType)'!='Android'">MultiThreadedDebugDLL</RuntimeLibrary>
       <PrecompiledHeader>
       </PrecompiledHeader>
       <WarningLevel>TurnOffAllWarnings</WarningLevel>
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index 4423ebb..06457d9 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -1042,7 +1042,11 @@
   endif()
 
   _CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library
-  foreach (cuda_lib cublasLt cufft curand nppc nvjpeg)
+  foreach (cuda_lib cublasLt cufft nvjpeg)
+    _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
+    _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS cudart_static_deps culibos)
+  endforeach()
+  foreach (cuda_lib curand nppc)
     _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
     _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos)
   endforeach()
@@ -1146,7 +1150,12 @@
   _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS nvrtc_builtins nvJitLink)
   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.5.0)
     _CUDAToolkit_find_and_add_import_lib(nvrtc_builtins_static ALT nvrtc-builtins_static DEPS cuda_driver)
-    _CUDAToolkit_find_and_add_import_lib(nvrtc_static DEPS nvrtc_builtins_static nvptxcompiler_static nvJitLink_static)
+    if(NOT TARGET CUDA::nvrtc_static)
+      _CUDAToolkit_find_and_add_import_lib(nvrtc_static DEPS nvrtc_builtins_static nvptxcompiler_static nvJitLink_static)
+      if(TARGET CUDA::nvrtc_static AND WIN32 AND NOT (BORLAND OR MINGW OR CYGWIN))
+        target_link_libraries(CUDA::nvrtc_static INTERFACE Ws2_32.lib)
+      endif()
+    endif()
   endif()
 
   _CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml)
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index 715f68b..bc60222 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -34,18 +34,13 @@
 cmake_policy(SET CMP0057 NEW) # if IN_LIST
 
 # If using Android tools for Visual Studio, compile a sample project to get the
-# sysroot.
+# NDK path
 if(CMAKE_GENERATOR MATCHES "Visual Studio")
-  if(NOT CMAKE_SYSROOT)
+  if(NOT CMAKE_ANDROID_NDK)
     set(vcx_platform ${CMAKE_GENERATOR_PLATFORM})
-    if(CMAKE_GENERATOR MATCHES "Visual Studio 1[45]")
-      set(vcx_sysroot_var "Sysroot")
-    else()
-      set(vcx_sysroot_var "SysrootLink")
-    endif()
     if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
       set(vcx_revision "2.0")
-    elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+    elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[567]")
       set(vcx_revision "3.0")
     else()
       set(vcx_revision "")
@@ -62,16 +57,16 @@
       RESULT_VARIABLE VCXPROJ_INSPECT_RESULT
       )
     unset(_msbuild)
-    if(NOT CMAKE_SYSROOT AND VCXPROJ_INSPECT_OUTPUT MATCHES "CMAKE_SYSROOT=([^%\r\n]+)[\r\n]")
+    if(VCXPROJ_INSPECT_OUTPUT MATCHES "CMAKE_ANDROID_NDK=([^%\r\n]+)[\r\n]")
       # Strip VS diagnostic output from the end of the line.
-      string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _sysroot "${CMAKE_MATCH_1}")
-      if(EXISTS "${_sysroot}")
-        file(TO_CMAKE_PATH "${_sysroot}" CMAKE_SYSROOT)
+      string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _ndk "${CMAKE_MATCH_1}")
+      if(EXISTS "${_ndk}")
+        file(TO_CMAKE_PATH "${_ndk}" CMAKE_ANDROID_NDK)
       endif()
     endif()
     if(VCXPROJ_INSPECT_RESULT)
       message(CONFIGURE_LOG
-        "Determining the sysroot for the Android NDK failed.
+        "Determining the Android NDK failed from msbuild failed.
 The output was:
 ${VCXPROJ_INSPECT_RESULT}
 ${VCXPROJ_INSPECT_OUTPUT}
@@ -79,7 +74,7 @@
 ")
     else()
       message(CONFIGURE_LOG
-        "Determining the sysroot for the Android NDK succeeded.
+        "Determining the Android NDK succeeded.
 The output was:
 ${VCXPROJ_INSPECT_RESULT}
 ${VCXPROJ_INSPECT_OUTPUT}
diff --git a/Modules/Platform/Android/VCXProjInspect.vcxproj.in b/Modules/Platform/Android/VCXProjInspect.vcxproj.in
index 6919d2c..f87d59b 100644
--- a/Modules/Platform/Android/VCXProjInspect.vcxproj.in
+++ b/Modules/Platform/Android/VCXProjInspect.vcxproj.in
@@ -19,6 +19,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <CharacterSet>MultiByte</CharacterSet>
+    <AndroidAPILevel>android-21</AndroidAPILevel>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
@@ -29,7 +30,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">
     <PostBuildEvent>
-      <Command>%40echo CMAKE_SYSROOT=$(@vcx_sysroot_var@)</Command>
+      <Command>%40echo CMAKE_ANDROID_NDK=$(VS_NdkRoot)</Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index b512f5d..832d93c 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 26)
-set(CMake_VERSION_PATCH 20230425)
+set(CMake_VERSION_PATCH 20230427)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/Modules/CMakeBuildUtilities.cmake b/Source/Modules/CMakeBuildUtilities.cmake
index 3dc099f..d6e3e88 100644
--- a/Source/Modules/CMakeBuildUtilities.cmake
+++ b/Source/Modules/CMakeBuildUtilities.cmake
@@ -279,7 +279,7 @@
   set(ENABLE_LIBXML2 OFF)
   set(ENABLE_EXPAT OFF)
   set(ENABLE_PCREPOSIX OFF)
-  set(ENABLE_LibGCC OFF)
+  set(ENABLE_LIBGCC OFF)
   set(ENABLE_CNG OFF)
   set(ENABLE_TAR OFF)
   set(ENABLE_TAR_SHARED OFF)
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index 13e8bad..13eddbe 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -4,7 +4,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cstdlib>
 #include <functional>
 #include <iostream>
 #include <iterator>
@@ -49,6 +48,7 @@
 using PresetPair = cmCMakePresetsGraph::PresetPair<T>;
 using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult;
 using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
+using cmCMakePresetsGraphInternal::ExpandMacros;
 
 void InheritString(std::string& child, const std::string& parent)
 {
@@ -204,14 +204,6 @@
 ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status,
                            const std::vector<MacroExpander>& macroExpanders,
                            int version);
-ExpandMacroResult ExpandMacros(
-  std::string& out, const std::vector<MacroExpander>& macroExpanders,
-  int version);
-ExpandMacroResult ExpandMacro(std::string& out,
-                              const std::string& macroNamespace,
-                              const std::string& macroName,
-                              const std::vector<MacroExpander>& macroExpanders,
-                              int version);
 
 bool ExpandMacros(const cmCMakePresetsGraph& graph,
                   const ConfigurePreset& preset,
@@ -448,9 +440,9 @@
       if (macroName.empty()) {
         return ExpandMacroResult::Error;
       }
-      const char* value = std::getenv(macroName.c_str());
-      if (value) {
-        result += value;
+      if (cm::optional<std::string> value =
+            cmSystemTools::GetEnvVar(macroName)) {
+        result += *value;
       }
       return ExpandMacroResult::Ok;
     }
@@ -515,8 +507,9 @@
   status = CycleStatus::Verified;
   return ExpandMacroResult::Ok;
 }
+}
 
-ExpandMacroResult ExpandMacros(
+ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacros(
   std::string& out, const std::vector<MacroExpander>& macroExpanders,
   int version)
 {
@@ -595,11 +588,10 @@
   return ExpandMacroResult::Ok;
 }
 
-ExpandMacroResult ExpandMacro(std::string& out,
-                              const std::string& macroNamespace,
-                              const std::string& macroName,
-                              const std::vector<MacroExpander>& macroExpanders,
-                              int version)
+ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacro(
+  std::string& out, const std::string& macroNamespace,
+  const std::string& macroName,
+  const std::vector<MacroExpander>& macroExpanders, int version)
 {
   for (auto const& macroExpander : macroExpanders) {
     auto result = macroExpander(macroNamespace, macroName, out, version);
@@ -615,6 +607,7 @@
   return ExpandMacroResult::Error;
 }
 
+namespace {
 template <typename T>
 bool SetupWorkflowConfigurePreset(const T& preset,
                                   const ConfigurePreset*& configurePreset,
diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h
index db784c3..f133efb 100644
--- a/Source/cmCMakePresetsGraphInternal.h
+++ b/Source/cmCMakePresetsGraphInternal.h
@@ -28,6 +28,16 @@
 
 using MacroExpander = std::function<ExpandMacroResult(
   const std::string&, const std::string&, std::string&, int version)>;
+
+ExpandMacroResult ExpandMacros(
+  std::string& out, const std::vector<MacroExpander>& macroExpanders,
+  int version);
+
+ExpandMacroResult ExpandMacro(std::string& out,
+                              const std::string& macroNamespace,
+                              const std::string& macroName,
+                              const std::vector<MacroExpander>& macroExpanders,
+                              int version);
 }
 
 class cmCMakePresetsGraph::Condition
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index bc829f3..54fea40 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -33,6 +33,9 @@
 using WorkflowPreset = cmCMakePresetsGraph::WorkflowPreset;
 using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
 using JSONHelperBuilder = cmJSONHelperBuilder;
+using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult;
+using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
+using cmCMakePresetsGraphInternal::ExpandMacros;
 
 constexpr int MIN_VERSION = 1;
 constexpr int MAX_VERSION = 7;
@@ -688,7 +691,39 @@
     return true;
   };
 
-  for (auto include : presets.Include) {
+  std::vector<MacroExpander> macroExpanders;
+
+  MacroExpander environmentMacroExpander =
+    [](const std::string& macroNamespace, const std::string& macroName,
+       std::string& expanded, int /*version*/) -> ExpandMacroResult {
+    if (macroNamespace == "penv") {
+      if (macroName.empty()) {
+        return ExpandMacroResult::Error;
+      }
+      if (cm::optional<std::string> value =
+            cmSystemTools::GetEnvVar(macroName)) {
+        expanded += *value;
+      }
+      return ExpandMacroResult::Ok;
+    }
+
+    return ExpandMacroResult::Ignore;
+  };
+
+  macroExpanders.push_back(environmentMacroExpander);
+
+  for (Json::ArrayIndex i = 0; i < presets.Include.size(); ++i) {
+    auto include = presets.Include[i];
+
+    // Support for macro expansion in includes added in version 7
+    if (v >= 7) {
+      if (ExpandMacros(include, macroExpanders, v) != ExpandMacroResult::Ok) {
+        cmCMakePresetErrors::INVALID_INCLUDE(&root["include"][i],
+                                             &this->parseState);
+        return false;
+      }
+    }
+
     if (!cmSystemTools::FileIsFullPath(include)) {
       auto directory = cmSystemTools::GetFilenamePath(filename);
       include = cmStrCat(directory, '/', include);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 036ddc6..f4d17f8 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -3,6 +3,7 @@
 #include "cmcmd.h"
 
 #include <functional>
+#include <iterator>
 
 #include <cm/optional>
 #include <cmext/algorithm>
@@ -346,7 +347,6 @@
   cmList iwyu_cmd{ runCmd, cmList::EmptyElements::Yes };
   cm::append(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
   // Run the iwyu command line.  Capture its stderr and hide its stdout.
-  // Ignore its return code because the tool always returns non-zero.
   std::string stdErr;
   int ret;
   if (!cmSystemTools::RunSingleCommand(iwyu_cmd, nullptr, &stdErr, &ret,
@@ -360,8 +360,15 @@
     std::cerr << "Warning: include-what-you-use reported diagnostics:\n"
               << stdErr << "\n";
   }
-  // always return 0 we don't want to break the compile
-  return 0;
+  // Older versions of iwyu always returned a non-zero exit code,
+  // so ignore it unless the user has enabled errors.
+  auto has_error_opt = std::find_if(
+    iwyu_cmd.cbegin(), iwyu_cmd.cend(),
+    [](std::string const& opt) { return cmHasLiteralPrefix(opt, "--error"); });
+  bool errors_enabled = has_error_opt != iwyu_cmd.cend() &&
+    has_error_opt != iwyu_cmd.cbegin() &&
+    *std::prev(has_error_opt) == "-Xiwyu";
+  return errors_enabled ? ret : 0;
 }
 
 int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in
index c47266a..3bb2fd6 100644
--- a/Templates/TestDriver.cxx.in
+++ b/Templates/TestDriver.cxx.in
@@ -20,11 +20,19 @@
 #  else
 #    define CM_NULL NULL
 #  endif
+#  define CM_NAMESPACE_BEGIN namespace {
+#  define CM_NAMESPACE_END }
+#  define CM_LOCAL
 #else
 #  define CM_CAST(TYPE, EXPR) (TYPE)(EXPR)
 #  define CM_NULL NULL
+#  define CM_NAMESPACE_BEGIN
+#  define CM_NAMESPACE_END
+#  define CM_LOCAL static
 #endif
 
+CM_NAMESPACE_BEGIN
+
 /* Create map.  */
 
 typedef int (*MainFuncPointer)(int, char* []); /* NOLINT */
@@ -34,17 +42,17 @@
   MainFuncPointer func;
 } functionMapEntry;
 
-static functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
+CM_LOCAL const functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
   @CMAKE_FUNCTION_TABLE_ENTRIES@
   { CM_NULL, CM_NULL } /* NOLINT */
 };
 
-static const int NumTests = CM_CAST(int,
+CM_LOCAL const int NumTests = CM_CAST(int,
   sizeof(cmakeGeneratedFunctionMapEntries) / sizeof(functionMapEntry)) - 1;
 
 /* Allocate and create a lowercased copy of string
    (note that it has to be free'd manually) */
-static char* lowercase(const char* string)
+CM_LOCAL char* lowercase(const char* string)
 {
   char *new_string;
   char *p;
@@ -63,7 +71,7 @@
   return new_string;
 }
 
-static int isTestSkipped(const char *name, int n_skipped_tests, char *skipped_tests[]) {
+CM_LOCAL int isTestSkipped(const char *name, int n_skipped_tests, char *skipped_tests[]) {
   int i;
   for (i = 0; i < n_skipped_tests; i++) {
     if (strcmp(name, skipped_tests[i]) == 0) {
@@ -74,6 +82,8 @@
   return 0;
 }
 
+CM_NAMESPACE_END
+
 int main(int ac, char* av[])
 {
   int i;
diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt
new file mode 100644
index 0000000..e0f858a
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/EmptyPenvInInclude:
+Error: @3,15: Invalid "include" field
+  "include": \["\$penv\{\}"\],
+              \^$
diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in
new file mode 100644
index 0000000..651b0de
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in
@@ -0,0 +1,11 @@
+{
+  "version": 7,
+  "include": ["$penv{}"],
+  "configurePresets": [
+    {
+      "name": "EmptyPenvInInclude",
+      "generator": "@RunCMake_GENERATOR@",
+      "binaryDir": "${sourceDir}/build"
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt b/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt
new file mode 100644
index 0000000..d3f1afc
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt
@@ -0,0 +1,5 @@
+^Not searching for unused variables given on the command line\.
+Available configure presets:
+
+  "Include"
+  "IncludeCommon"$
diff --git a/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in b/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in
new file mode 100644
index 0000000..b4f8292
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in
@@ -0,0 +1,10 @@
+{
+  "version": 7,
+  "include": ["$penv{TEST_ENV_INCLUDE_DIR}/IncludeCommon.json"],
+  "configurePresets": [
+    {
+      "name": "Include",
+      "inherits": ["IncludeCommon"]
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
index d67e8b1..c4a8b3f 100644
--- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
@@ -146,6 +146,7 @@
 run_cmake_presets(EnvCycle)
 run_cmake_presets(EmptyEnv)
 run_cmake_presets(EmptyPenv)
+run_cmake_presets(EmptyPenvInInclude)
 run_cmake_presets(InvalidRegex)
 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
 run_cmake_presets(ConditionFuture)
@@ -393,6 +394,12 @@
   "${RunCMake_SOURCE_DIR}/subdir/CMakePresets.json.in"
   )
 run_cmake_presets(Include --list-presets)
+set(CMakePresets_EXTRA_FILES
+  "${RunCMake_SOURCE_DIR}/IncludeCommon.json.in"
+  )
+set(ENV{TEST_ENV_INCLUDE_DIR} ${RunCMake_BINARY_DIR}/IncludeExpansion)
+run_cmake_presets(IncludeExpansion --list-presets)
+unset(ENV{TEST_ENV_INCLUDE_DIR})
 unset(CMakePresets_EXTRA_FILES)
 run_cmake_presets(IncludeNotFound)
 run_cmake_presets(IncludeCycle)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-result.txt b/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-stdout.txt b/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-stdout.txt
new file mode 100644
index 0000000..cb74677
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-stdout.txt
@@ -0,0 +1,4 @@
+Warning: include-what-you-use reported diagnostics:
+should add these lines:
+*
+#include <\.\.\.>
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-error.cmake b/Tests/RunCMake/IncludeWhatYouUse/C-error.cmake
new file mode 100644
index 0000000..d5230bb
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-error.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -Xiwyu --error)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-result.txt b/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-stdout.txt b/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-stdout.txt
new file mode 100644
index 0000000..cb74677
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-stdout.txt
@@ -0,0 +1,4 @@
+Warning: include-what-you-use reported diagnostics:
+should add these lines:
+*
+#include <\.\.\.>
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-error.cmake b/Tests/RunCMake/IncludeWhatYouUse/CXX-error.cmake
new file mode 100644
index 0000000..1d10a55
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-error.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -Xiwyu --error)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake b/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake
index 8f99eb1..8ec24be 100644
--- a/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake
+++ b/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake
@@ -16,6 +16,8 @@
 
 run_iwyu(C)
 run_iwyu(CXX)
+run_iwyu(C-error)
+run_iwyu(CXX-error)
 if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
   run_iwyu(C-launch)
   run_iwyu(CXX-launch)
diff --git a/Utilities/Scripts/update-libarchive.bash b/Utilities/Scripts/update-libarchive.bash
index 856a6ea..5a4f11a 100755
--- a/Utilities/Scripts/update-libarchive.bash
+++ b/Utilities/Scripts/update-libarchive.bash
@@ -8,7 +8,7 @@
 readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
 readonly subtree="Utilities/cmlibarchive"
 readonly repo="https://github.com/libarchive/libarchive.git"
-readonly tag="v3.6.0"
+readonly tag="v3.6.2"
 readonly shortlog=false
 readonly paths="
   CMakeLists.txt
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index b38e653..027de5c 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -238,7 +238,7 @@
 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_LibGCC "Enable the use of the system LibGCC 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)
 
@@ -257,7 +257,7 @@
 
 SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
 SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
-SET(WINDOWS_VERSION "WIN7" CACHE STRING "Set Windows version to use (Windows only)")
+SET(WINDOWS_VERSION "WIN10" CACHE STRING "Set Windows version to use (Windows only)")
 
 IF(ENABLE_COVERAGE)
        include(LibarchiveCodeCoverage)
@@ -268,7 +268,11 @@
 ENDIF(ENABLE_TEST)
 
 IF(WIN32)
-  IF(WINDOWS_VERSION STREQUAL "WIN8")
+  IF(WINDOWS_VERSION STREQUAL "WIN10")
+    SET(NTDDI_VERSION 0x0A000000)
+    SET(_WIN32_WINNT 0x0A00)
+    SET(WINVER 0x0A00)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WIN8")
     SET(NTDDI_VERSION 0x06020000)
     SET(_WIN32_WINNT 0x0602)
     SET(WINVER 0x0602)
@@ -292,12 +296,12 @@
     SET(NTDDI_VERSION 0x05010000)
     SET(_WIN32_WINNT 0x0501)
     SET(WINVER 0x0501)
-  ELSE(WINDOWS_VERSION STREQUAL "WIN8")
+  ELSE(WINDOWS_VERSION STREQUAL "WIN10")
     # Default to Windows Server 2003 API if we don't recognize the specifier
     SET(NTDDI_VERSION 0x05020000)
     SET(_WIN32_WINNT 0x0502)
     SET(WINVER 0x0502)
-  ENDIF(WINDOWS_VERSION STREQUAL "WIN8")
+  ENDIF(WINDOWS_VERSION STREQUAL "WIN10")
 ENDIF(WIN32)
 
 IF(MSVC)
@@ -632,8 +636,15 @@
     SET(ZSTD_FIND_QUIETLY TRUE)
   ENDIF (ZSTD_INCLUDE_DIR)
 
-  FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
-  FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
+  IF(0) # CMake does not let pkg-config override its search paths.
+  IF(UNIX)
+    FIND_PACKAGE(PkgConfig QUIET)
+    PKG_SEARCH_MODULE(PC_ZSTD libzstd)
+  ENDIF()
+  ENDIF()
+
+  FIND_PATH(ZSTD_INCLUDE_DIR zstd.h HINTS ${PC_ZSTD_INCLUDEDIR} ${PC_ZSTD_INCLUDE_DIRS})
+  FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd HINTS ${PC_ZSTD_LIBDIR} ${PC_ZSTD_LIBRARY_DIRS})
   INCLUDE(FindPackageHandleStandardArgs)
   FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
 ELSE(ENABLE_ZSTD)
@@ -1284,9 +1295,10 @@
   #
   # If requested, try finding library for PCREPOSIX
   #
-  IF(ENABLE_LibGCC)
-    FIND_PACKAGE(LibGCC)
+  IF(ENABLE_LIBGCC)
+    FIND_PACKAGE(LIBGCC)
   ELSE()
+    MESSAGE(FATAL_ERROR "libgcc not found.")
     SET(LIBGCC_FOUND FALSE) # Override cached value
   ENDIF()
   IF(ENABLE_PCREPOSIX)
@@ -1996,6 +2008,19 @@
 
 CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
 
+IF(0) # CMake does not build libarchive's shared library.
+# Check visibility annotations
+SET(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fvisibility=hidden -Werror")
+CHECK_C_SOURCE_COMPILES("void __attribute__((visibility(\"default\"))) foo(void);
+int main() { return 0; }" HAVE_VISIBILITY_ATTR)
+IF (HAVE_VISIBILITY_ATTR)
+  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
+  ADD_DEFINITIONS(-D__LIBARCHIVE_ENABLE_VISIBILITY)
+ENDIF(HAVE_VISIBILITY_ATTR)
+SET(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
+ENDIF()
+
 # Generate "config.h" from "build/cmake/config.h.in"
 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
 	${CMAKE_CURRENT_BINARY_DIR}/config.h)
diff --git a/Utilities/cmlibarchive/build/cmake/FindLibGCC.cmake b/Utilities/cmlibarchive/build/cmake/FindLIBGCC.cmake
similarity index 100%
rename from Utilities/cmlibarchive/build/cmake/FindLibGCC.cmake
rename to Utilities/cmlibarchive/build/cmake/FindLIBGCC.cmake
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index 72467a5..e44a514 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -147,13 +147,13 @@
 #cmakedefine ARCHIVE_XATTR_LINUX 1
 
 /* Version number of bsdcpio */
-#cmakedefine BSDCPIO_VERSION_STRING "${BSDCPIO_VERSION_STRING}"
+#cmakedefine BSDCPIO_VERSION_STRING "@BSDCPIO_VERSION_STRING@"
 
 /* Version number of bsdtar */
-#cmakedefine BSDTAR_VERSION_STRING "${BSDTAR_VERSION_STRING}"
+#cmakedefine BSDTAR_VERSION_STRING "@BSDTAR_VERSION_STRING@"
 
 /* Version number of bsdcat */
-#cmakedefine BSDCAT_VERSION_STRING "${BSDCAT_VERSION_STRING}"
+#cmakedefine BSDCAT_VERSION_STRING "@BSDCAT_VERSION_STRING@"
 
 /* Define to 1 if you have the `acl_create_entry' function. */
 #cmakedefine HAVE_ACL_CREATE_ENTRY 1
@@ -1012,13 +1012,13 @@
 #cmakedefine HAVE__MKGMTIME64 1
 
 /* Define as const if the declaration of iconv() needs const. */
-#define ICONV_CONST ${ICONV_CONST}
+#define ICONV_CONST @ICONV_CONST@
 
 /* Version number of libarchive as a single integer */
-#cmakedefine LIBARCHIVE_VERSION_NUMBER "${LIBARCHIVE_VERSION_NUMBER}"
+#cmakedefine LIBARCHIVE_VERSION_NUMBER "@LIBARCHIVE_VERSION_NUMBER@"
 
 /* Version number of libarchive */
-#cmakedefine LIBARCHIVE_VERSION_STRING "${LIBARCHIVE_VERSION_STRING}"
+#cmakedefine LIBARCHIVE_VERSION_STRING "@LIBARCHIVE_VERSION_STRING@"
 
 /* Define to 1 if `lstat' dereferences a symlink specified with a trailing
    slash. */
@@ -1036,7 +1036,7 @@
 #cmakedefine NO_MINUS_C_MINUS_O 1
 
 /* The size of `wchar_t', as computed by sizeof. */
-#cmakedefine SIZEOF_WCHAR_T ${SIZEOF_WCHAR_T}
+#cmakedefine SIZEOF_WCHAR_T @SIZEOF_WCHAR_T@
 
 /* Define to 1 if strerror_r returns char *. */
 #cmakedefine STRERROR_R_CHAR_P 1
@@ -1072,56 +1072,56 @@
 #endif /* SAFE_TO_DEFINE_EXTENSIONS */
 
 /* Version number of package */
-#cmakedefine VERSION "${VERSION}"
+#cmakedefine VERSION "@VERSION@"
 
 /* Number of bits in a file offset, on hosts where this is settable. */
-#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
+#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@
 
 /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
 #cmakedefine _LARGEFILE_SOURCE 1
 
 /* Define for large files, on AIX-style hosts. */
-#cmakedefine _LARGE_FILES ${_LARGE_FILES}
+#cmakedefine _LARGE_FILES @_LARGE_FILES@
 
 /* Define to control Windows SDK version */
 #ifndef NTDDI_VERSION
-#cmakedefine NTDDI_VERSION ${NTDDI_VERSION}
+#cmakedefine NTDDI_VERSION @NTDDI_VERSION@
 #endif // NTDDI_VERSION
 
 #ifndef _WIN32_WINNT
-#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
+#cmakedefine _WIN32_WINNT @_WIN32_WINNT@
 #endif // _WIN32_WINNT
 
 #ifndef WINVER
-#cmakedefine WINVER ${WINVER}
+#cmakedefine WINVER @WINVER@
 #endif // WINVER
 
 /* Define to empty if `const' does not conform to ANSI C. */
-#cmakedefine const ${const}
+#cmakedefine const @const@
 
 /* Define to `int' if <sys/types.h> doesn't define. */
-#cmakedefine gid_t ${gid_t}
+#cmakedefine gid_t @gid_t@
 
 /* Define to `unsigned long' if <sys/types.h> does not define. */
-#cmakedefine id_t ${id_t}
+#cmakedefine id_t @id_t@
 
 /* Define to `int' if <sys/types.h> does not define. */
-#cmakedefine mode_t ${mode_t}
+#cmakedefine mode_t @mode_t@
 
 /* Define to `long long' if <sys/types.h> does not define. */
-#cmakedefine off_t ${off_t}
+#cmakedefine off_t @off_t@
 
 /* Define to `int' if <sys/types.h> doesn't define. */
-#cmakedefine pid_t ${pid_t}
+#cmakedefine pid_t @pid_t@
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
-#cmakedefine size_t ${size_t}
+#cmakedefine size_t @size_t@
 
 /* Define to `int' if <sys/types.h> does not define. */
-#cmakedefine ssize_t ${ssize_t}
+#cmakedefine ssize_t @ssize_t@
 
 /* Define to `int' if <sys/types.h> doesn't define. */
-#cmakedefine uid_t ${uid_t}
+#cmakedefine uid_t @uid_t@
 
 #include <cm3p/kwiml/int.h>
 
diff --git a/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in b/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
index 4b631e6..1f51e77 100644
--- a/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
+++ b/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
@@ -10,3 +10,4 @@
 Cflags.private: -DLIBARCHIVE_STATIC
 Libs: -L${libdir} -larchive
 Libs.private: @LIBS@
+Requires.private: @LIBSREQUIRED@
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
index 102ec29..1af1bec 100644
--- a/Utilities/cmlibarchive/build/version
+++ b/Utilities/cmlibarchive/build/version
@@ -1 +1 @@
-3006000
+3006002
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index feb8697..bee69c2 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -5,6 +5,10 @@
 #
 ############################################
 
+if (ANDROID)
+  include_directories(${PROJECT_SOURCE_DIR}/contrib/android/include)
+endif()
+
 # Public headers
 SET(include_HEADERS
   archive.h
@@ -78,6 +82,7 @@
   archive_read_set_format.c
   archive_read_set_options.c
   archive_read_support_filter_all.c
+  archive_read_support_filter_by_code.c
   archive_read_support_filter_bzip2.c
   archive_read_support_filter_compress.c
   archive_read_support_filter_gzip.c
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index ac01738..180f3e4 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006000
+#define	ARCHIVE_VERSION_NUMBER 3006002
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -120,6 +120,8 @@
 #   define __LA_DECL	__declspec(dllimport)
 #  endif
 # endif
+#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
+#  define __LA_DECL __attribute__((visibility("default")))
 #else
 /* Static libraries or non-Windows needs no special declaration. */
 # define __LA_DECL
@@ -152,7 +154,7 @@
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.6.0"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.6.2"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest.c b/Utilities/cmlibarchive/libarchive/archive_digest.c
index 410df01..3361b19 100644
--- a/Utilities/cmlibarchive/libarchive/archive_digest.c
+++ b/Utilities/cmlibarchive/libarchive/archive_digest.c
@@ -49,16 +49,16 @@
  * Initialize a Message digest.
  */
 static int
-win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
+win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
 {
 
 	ctx->valid = 0;
 	if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
-	    PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+	    prov, CRYPT_VERIFYCONTEXT)) {
 		if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
 			return (ARCHIVE_FAILED);
 		if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
-		    PROV_RSA_FULL, CRYPT_NEWKEYSET))
+		    prov, CRYPT_NEWKEYSET))
 			return (ARCHIVE_FAILED);
 	}
 
@@ -243,7 +243,8 @@
 {
   if ((*ctx = EVP_MD_CTX_new()) == NULL)
 	return (ARCHIVE_FAILED);
-  EVP_DigestInit(*ctx, EVP_md5());
+  if (!EVP_DigestInit(*ctx, EVP_md5()))
+	return (ARCHIVE_FAILED);
   return (ARCHIVE_OK);
 }
 
@@ -275,7 +276,7 @@
 static int
 __archive_md5init(archive_md5_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_MD5));
+  return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
 }
 
 static int
@@ -434,7 +435,8 @@
 {
   if ((*ctx = EVP_MD_CTX_new()) == NULL)
 	return (ARCHIVE_FAILED);
-  EVP_DigestInit(*ctx, EVP_ripemd160());
+  if (!EVP_DigestInit(*ctx, EVP_ripemd160()))
+	return (ARCHIVE_FAILED);
   return (ARCHIVE_OK);
 }
 
@@ -624,7 +626,8 @@
 {
   if ((*ctx = EVP_MD_CTX_new()) == NULL)
 	return (ARCHIVE_FAILED);
-  EVP_DigestInit(*ctx, EVP_sha1());
+  if (!EVP_DigestInit(*ctx, EVP_sha1()))
+	return (ARCHIVE_FAILED);
   return (ARCHIVE_OK);
 }
 
@@ -656,7 +659,7 @@
 static int
 __archive_sha1init(archive_sha1_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_SHA1));
+  return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
 }
 
 static int
@@ -887,7 +890,8 @@
 {
   if ((*ctx = EVP_MD_CTX_new()) == NULL)
 	return (ARCHIVE_FAILED);
-  EVP_DigestInit(*ctx, EVP_sha256());
+  if (!EVP_DigestInit(*ctx, EVP_sha256()))
+	return (ARCHIVE_FAILED);
   return (ARCHIVE_OK);
 }
 
@@ -915,7 +919,7 @@
 static int
 __archive_sha256init(archive_sha256_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_SHA_256));
+  return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
 }
 
 static int
@@ -1122,7 +1126,8 @@
 {
   if ((*ctx = EVP_MD_CTX_new()) == NULL)
 	return (ARCHIVE_FAILED);
-  EVP_DigestInit(*ctx, EVP_sha384());
+  if (!EVP_DigestInit(*ctx, EVP_sha384()))
+	return (ARCHIVE_FAILED);
   return (ARCHIVE_OK);
 }
 
@@ -1150,7 +1155,7 @@
 static int
 __archive_sha384init(archive_sha384_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_SHA_384));
+  return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
 }
 
 static int
@@ -1381,7 +1386,8 @@
 {
   if ((*ctx = EVP_MD_CTX_new()) == NULL)
 	return (ARCHIVE_FAILED);
-  EVP_DigestInit(*ctx, EVP_sha512());
+  if (!EVP_DigestInit(*ctx, EVP_sha512()))
+	return (ARCHIVE_FAILED);
   return (ARCHIVE_OK);
 }
 
@@ -1409,7 +1415,7 @@
 static int
 __archive_sha512init(archive_sha512_ctx *ctx)
 {
-  return (win_crypto_init(ctx, CALG_SHA_512));
+  return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.c b/Utilities/cmlibarchive/libarchive/archive_entry.c
index ca7a4bd..ae6dc33 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.c
@@ -568,6 +568,13 @@
 	return (entry->ae_stat.aest_nlink);
 }
 
+/* Instead, our caller could have chosen a specific encoding
+ * (archive_mstring_get_mbs, archive_mstring_get_utf8,
+ * archive_mstring_get_wcs).  So we should try multiple
+ * encodings.  Try mbs first because of history, even though
+ * utf8 might be better for pathname portability.
+ * Also omit wcs because of type mismatch (char * versus wchar *)
+ */
 const char *
 archive_entry_pathname(struct archive_entry *entry)
 {
@@ -575,6 +582,13 @@
 	if (archive_mstring_get_mbs(
 	    entry->archive, &entry->ae_pathname, &p) == 0)
 		return (p);
+#if HAVE_EILSEQ  /*{*/
+    if (errno == EILSEQ) {
+	    if (archive_mstring_get_utf8(
+	        entry->archive, &entry->ae_pathname, &p) == 0)
+		    return (p);
+    }
+#endif  /*}*/
 	if (errno == ENOMEM)
 		__archive_errx(1, "No memory");
 	return (NULL);
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index 221ef80..91ef0c9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3006000
+#define	ARCHIVE_VERSION_NUMBER 3006002
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
@@ -122,6 +122,8 @@
 #   define __LA_DECL	__declspec(dllimport)
 #  endif
 # endif
+#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
+#  define __LA_DECL __attribute__((visibility("default")))
 #else
 /* Static libraries on all platforms and shared libraries on non-Windows. */
 # define __LA_DECL
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac.c b/Utilities/cmlibarchive/libarchive/archive_hmac.c
index 2a9d04c..012fe15 100644
--- a/Utilities/cmlibarchive/libarchive/archive_hmac.c
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac.c
@@ -230,10 +230,23 @@
 static int
 __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	OSSL_PARAM params[2];
+
+	EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+	*ctx = EVP_MAC_CTX_new(mac);
+	if (*ctx == NULL)
+		return -1;
+	EVP_MAC_free(mac);
+	params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
+	params[1] = OSSL_PARAM_construct_end();
+	EVP_MAC_init(*ctx, key, key_len, params);
+#else
 	*ctx = HMAC_CTX_new();
 	if (*ctx == NULL)
 		return -1;
 	HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL);
+#endif
 	return 0;
 }
 
@@ -241,22 +254,38 @@
 __hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
     size_t data_len)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	EVP_MAC_update(*ctx, data, data_len);
+#else
 	HMAC_Update(*ctx, data, data_len);
+#endif
 }
 
 static void
 __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	size_t len = *out_len;
+#else
 	unsigned int len = (unsigned int)*out_len;
+#endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	EVP_MAC_final(*ctx, out, &len, *out_len);
+#else
 	HMAC_Final(*ctx, out, &len);
+#endif
 	*out_len = len;
 }
 
 static void
 __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	EVP_MAC_CTX_free(*ctx);
+#else
 	HMAC_CTX_free(*ctx);
+#endif
 	*ctx = NULL;
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
index 13a67d4..50044a0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
@@ -74,9 +74,16 @@
 typedef	struct hmac_sha1_ctx archive_hmac_sha1_ctx;
 
 #elif defined(HAVE_LIBCRYPTO)
+#include <openssl/opensslv.h>
+#include <openssl/hmac.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
+
+#else
 #include "archive_openssl_hmac_private.h"
 
 typedef	HMAC_CTX* archive_hmac_sha1_ctx;
+#endif
 
 #else
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
index f87b423..63b255e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -188,8 +188,9 @@
 
 /*
  * glibc 2.24 deprecates readdir_r
+ * bionic c deprecates readdir_r too
  */
-#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24))
+#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__))
 #define	USE_READDIR_R	1
 #else
 #undef	USE_READDIR_R
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
index d0e1f35..5a94ec5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -34,9 +34,6 @@
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
-#ifdef HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
@@ -54,6 +51,8 @@
 #endif
 #ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>
+#elif HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
 #endif
 /*
  * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
@@ -109,6 +108,11 @@
 #define O_CLOEXEC	0
 #endif
 
+#if defined(__hpux) && !defined(HAVE_DIRFD)
+#define dirfd(x) ((x)->__dd_fd)
+#define HAVE_DIRFD
+#endif
+
 /*-
  * This is a new directory-walking system that addresses a number
  * of problems I've had with fts(3).  In particular, it has no
@@ -2098,6 +2102,8 @@
 	struct tree_entry *te;
 
 	te = calloc(1, sizeof(*te));
+	if (te == NULL)
+		__archive_errx(1, "Out of memory");
 	te->next = t->stack;
 	te->parent = t->current;
 	if (te->parent)
@@ -2428,7 +2434,7 @@
 #else /* HAVE_FDOPENDIR */
 		if (tree_enter_working_dir(t) == 0) {
 			t->d = opendir(".");
-#if HAVE_DIRFD || defined(dirfd)
+#ifdef HAVE_DIRFD
 			__archive_ensure_cloexec_flag(dirfd(t->d));
 #endif
 		}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
index ea32e2a..f9d1395 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
@@ -418,8 +418,9 @@
 	    FILE_FLAG_OPEN_REPARSE_POINT;
 	int ret;
 
-	h = CreateFileW(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, flag,
-	    NULL);
+	h = CreateFileW(path, 0,
+	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+	    OPEN_EXISTING, flag, NULL);
 	if (h == INVALID_HANDLE_VALUE) {
 		la_dosmaperr(GetLastError());
 		return (-1);
@@ -1073,7 +1074,9 @@
 		else
 			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
 		t->entry_fh = CreateFileW(tree_current_access_path(t),
-		    GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
+		    GENERIC_READ,
+		    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+		    NULL, OPEN_EXISTING, flags, NULL);
 		if (t->entry_fh == INVALID_HANDLE_VALUE) {
 			la_dosmaperr(GetLastError());
 			archive_set_error(&a->archive, errno,
@@ -2046,7 +2049,8 @@
 	
 	if (sim_lstat && tree_current_is_physical_link(t))
 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
-	h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
+	h = CreateFileW(tree_current_access_path(t), 0,
+	    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 	    OPEN_EXISTING, flag, NULL);
 	if (h == INVALID_HANDLE_VALUE) {
 		la_dosmaperr(GetLastError());
@@ -2275,7 +2279,8 @@
 			} else
 				desiredAccess = GENERIC_READ;
 
-			h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
+			h = CreateFileW(path, desiredAccess,
+			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 			    OPEN_EXISTING, flag, NULL);
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
@@ -2337,7 +2342,8 @@
 		if (fd >= 0) {
 			h = (HANDLE)_get_osfhandle(fd);
 		} else {
-			h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
+			h = CreateFileW(path, GENERIC_READ,
+			    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
 			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
index ae0b080..1e99542 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
@@ -450,7 +450,9 @@
 	chsum = (chsum >> 8) & 0xff;
 	chsum_verifier = read_buf[descriptor_bytes-1] & 0xff;
 	if (chsum != chsum_verifier)
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		goto malformed_error;
+#endif
 
 	__archive_read_filter_consume(self->upstream, descriptor_bytes);
 
@@ -521,7 +523,9 @@
 		unsigned int chsum_block =
 		    archive_le32dec(read_buf + 4 + compressed_size);
 		if (chsum != chsum_block)
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			goto malformed_error;
+#endif
 	}
 
 
@@ -652,10 +656,12 @@
 			    state->xxh32_state);
 			state->xxh32_state = NULL;
 			if (checksum != checksum_stream) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 				archive_set_error(&self->archive->archive,
 				    ARCHIVE_ERRNO_MISC,
 				    "lz4 stream checksum error");
 				return (ARCHIVE_FATAL);
+#endif
 			}
 		} else if (ret > 0)
 			__archive_xxhash.XXH32_update(state->xxh32_state,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
index 42e2636..cc1572f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
@@ -283,7 +283,9 @@
 	else
 		checksum = adler32(adler32(0, NULL, 0), p, len);
 	if (archive_be32dec(p + len) != checksum)
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		goto corrupted;
+#endif
 	__archive_read_filter_consume(self->upstream, len + 4);
 	if (flags & EXTRA_FIELD) {
 		/* Skip extra field */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
index b978eb0..90b0da2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
@@ -612,9 +612,11 @@
 	/* Check the crc32 value of the uncompressed data of the current
 	 * member */
 	if (state->crc32 != archive_le32dec(f)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
 		    "Lzip: CRC32 error");
 		return (ARCHIVE_FAILED);
+#endif
 	}
 
 	/* Check the uncompressed size of the current member */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
index 7d7e702..722edf1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -287,6 +287,7 @@
 		const unsigned char	*next_in;
 		int64_t			 avail_in;
 		int64_t			 total_in;
+		int64_t			 stream_in;
 		unsigned char		*next_out;
 		int64_t			 avail_out;
 		int64_t			 total_out;
@@ -775,7 +776,7 @@
 	}
 
 	/* Set up a more descriptive format name. */
-	sprintf(zip->format_name, "7-Zip");
+	snprintf(zip->format_name, sizeof(zip->format_name), "7-Zip");
 	a->archive.archive_format_name = zip->format_name;
 
 	return (ret);
@@ -986,15 +987,30 @@
 	struct _7zip *zip = (struct _7zip *)(a->format->data);
 	Byte b;
 
-	if (zip->ppstream.avail_in == 0) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-		    "Truncated RAR file data");
-		zip->ppstream.overconsumed = 1;
-		return (0);
+	if (zip->ppstream.avail_in <= 0) {
+		/*
+		 * Ppmd7_DecodeSymbol might require reading multiple bytes
+		 * and we are on boundary;
+		 * last resort to read using __archive_read_ahead.
+		 */
+		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) {
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Truncated 7z file data");
+			zip->ppstream.overconsumed = 1;
+			return (0);
+		}
+		zip->ppstream.next_in++;
+		b = data[zip->ppstream.stream_in];
+	} else {
+		b = *zip->ppstream.next_in++;
 	}
-	b = *zip->ppstream.next_in++;
 	zip->ppstream.avail_in--;
 	zip->ppstream.total_in++;
+	zip->ppstream.stream_in++;
 	return (b);
 }
 
@@ -1485,6 +1501,7 @@
 		}
 		zip->ppstream.next_in = t_next_in;
 		zip->ppstream.avail_in = t_avail_in;
+		zip->ppstream.stream_in = 0;
 		zip->ppstream.next_out = t_next_out;
 		zip->ppstream.avail_out = t_avail_out;
 		if (zip->ppmd7_stat == 0) {
@@ -2840,8 +2857,10 @@
 	/* CRC check. */
 	if (crc32(0, (const unsigned char *)p + 12, 20)
 	    != archive_le32dec(p + 8)) {
+#ifdef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, -1, "Header CRC error");
 		return (ARCHIVE_FATAL);
+#endif
 	}
 
 	next_header_offset = archive_le64dec(p + 12);
@@ -2891,8 +2910,10 @@
 		/* 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
 			    "Damaged 7-Zip archive");
 			r = -1;
+#endif
 		}
 		if (r == 0) {
 			if (zip->si.ci.folders[0].digest_defined)
@@ -2943,9 +2964,11 @@
 
 		/* Check the Header CRC.*/
 		if (check_header_crc && zip->header_crc32 != next_header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			archive_set_error(&a->archive, -1,
 			    "Malformed 7-Zip archive");
 			return (ARCHIVE_FATAL);
+#endif
 		}
 		break;
 	default:
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
index 8742378..6fcfbfc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -996,7 +996,7 @@
 		cab->end_of_entry_cleanup = cab->end_of_entry = 1;
 
 	/* Set up a more descriptive format name. */
-	sprintf(cab->format_name, "CAB %d.%d (%s)",
+	snprintf(cab->format_name, sizeof(cab->format_name), "CAB %d.%d (%s)",
 	    hd->major, hd->minor, cab->entry_cffolder->compname);
 	a->archive.archive_format_name = cab->format_name;
 
@@ -1134,7 +1134,7 @@
 	}
 	if (sumbytes) {
 		int odd = sumbytes & 3;
-		if (sumbytes - odd > 0)
+		if ((int)(sumbytes - odd) > 0)
 			cfdata->sum_calculated = cab_checksum_cfdata_4(
 			    p, sumbytes - odd, cfdata->sum_calculated);
 		if (odd)
@@ -1171,12 +1171,14 @@
 	cfdata->sum_calculated = cab_checksum_cfdata(
 	    cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
 	if (cfdata->sum_calculated != cfdata->sum) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes",
 		    cab->entry_cffolder->cfdata_index -1,
 		    cfdata->sum, cfdata->sum_calculated,
 		    cfdata->compressed_size);
 		return (ARCHIVE_FAILED);
+#endif
 	}
 	return (ARCHIVE_OK);
 }
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
index 9121166..380cbb8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -1007,7 +1007,8 @@
 		p = b;
 		b += iso9660->logical_block_size;
 		step -= iso9660->logical_block_size;
-		for (; *p != 0 && p < b && p + *p <= b; p += *p) {
+		for (; *p != 0 && p + DR_name_offset < b && p + *p <= b;
+			p += *p) {
 			struct file_info *child;
 
 			/* N.B.: these special directory identifiers
@@ -1756,7 +1757,7 @@
 	size_t name_len;
 	const unsigned char *rr_start, *rr_end;
 	const unsigned char *p;
-	size_t dr_len;
+	size_t dr_len = 0;
 	uint64_t fsize, offset;
 	int32_t location;
 	int flags;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
index 1357f9a..8b7bf66 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
@@ -739,7 +739,7 @@
 	if (lha->directory || lha->compsize == 0)
 		lha->end_of_entry = 1;
 
-	sprintf(lha->format_name, "lha -%c%c%c-",
+	snprintf(lha->format_name, sizeof(lha->format_name), "lha -%c%c%c-",
 	    lha->method[0], lha->method[1], lha->method[2]);
 	a->archive.archive_format_name = lha->format_name;
 
@@ -1039,9 +1039,11 @@
 	}
 
 	if (header_crc != lha->header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "LHa header CRC error");
 		return (ARCHIVE_FATAL);
+#endif
 	}
 	return (err);
 }
@@ -1107,9 +1109,11 @@
 		return (err);
 
 	if (header_crc != lha->header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "LHa header CRC error");
 		return (ARCHIVE_FATAL);
+#endif
 	}
 	return (err);
 invalid:
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index 88bca76..2bc3ba0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -692,7 +692,7 @@
 {
 	const char *p;
 	ssize_t avail, ravail;
-	ssize_t detected_bytes = 0, len, nl;
+	ssize_t len, nl;
 	int entry_cnt = 0, multiline = 0;
 	int form_D = 0;/* The archive is generated by `NetBSD mtree -D'
 			* (In this source we call it `form D') . */
@@ -728,8 +728,6 @@
 			 * character of previous line was '\' character. */
 			if (bid_keyword_list(p, len, 0, 0) <= 0)
 				break;
-			if (multiline == 1)
-				detected_bytes += len;
 			if (p[len-nl-1] != '\\') {
 				if (multiline == 1 &&
 				    ++entry_cnt >= MAX_BID_ENTRY)
@@ -745,7 +743,6 @@
 
 			keywords = bid_entry(p, len, nl, &last_is_path);
 			if (keywords >= 0) {
-				detected_bytes += len;
 				if (form_D == 0) {
 					if (last_is_path)
 						form_D = 1;
@@ -997,9 +994,11 @@
 			struct mtree_entry *alt;
 			alt = (struct mtree_entry *)__archive_rb_tree_find_node(
 			    &mtree->rbtree, entry->name);
-			while (alt->next_dup)
-				alt = alt->next_dup;
-			alt->next_dup = entry;
+			if (alt != NULL) {
+				while (alt->next_dup)
+					alt = alt->next_dup;
+				alt->next_dup = entry;
+			}
 		}
 	}
 
@@ -1074,7 +1073,7 @@
 			continue;
 		/* Non-printable characters are not allowed */
 		for (s = p;s < p + len - 1; s++) {
-			if (!isprint((unsigned char)*s)) {
+			if (!isprint((unsigned char)*s) && *s != '\t') {
 				r = ARCHIVE_FATAL;
 				break;
 			}
@@ -1253,9 +1252,17 @@
 				archive_entry_filetype(entry) == AE_IFDIR) {
 			mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
 			__archive_ensure_cloexec_flag(mtree->fd);
-			if (mtree->fd == -1 &&
-				(errno != ENOENT ||
-				 archive_strlen(&mtree->contents_name) > 0)) {
+			if (mtree->fd == -1 && (
+#if defined(_WIN32) && !defined(__CYGWIN__)
+        /*
+         * On Windows, attempting to open a file with an
+         * invalid name result in EINVAL (Error 22)
+         */
+				(errno != ENOENT && errno != EINVAL)
+#else
+				errno != ENOENT
+#endif
+        || archive_strlen(&mtree->contents_name) > 0)) {
 				archive_set_error(&a->archive, errno,
 						"Can't open %s", path);
 				r = ARCHIVE_WARN;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index 5c02a25..1c9a057 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -430,7 +430,7 @@
 static int make_table(struct archive_read *, struct huffman_code *);
 static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
                               struct huffman_table_entry *, int, int);
-static int64_t expand(struct archive_read *, int64_t);
+static int expand(struct archive_read *, int64_t *);
 static int copy_from_lzss_window_to_unp(struct archive_read *, const void **,
                                         int64_t, int);
 static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
@@ -1007,9 +1007,11 @@
 
       crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
       if ((crc32_val & 0xffff) != archive_le16dec(p)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
           "Header CRC error");
         return (ARCHIVE_FATAL);
+#endif
       }
       __archive_read_consume(a, skip);
       break;
@@ -1065,9 +1067,11 @@
 	      skip -= to_read;
       }
       if ((crc32_val & 0xffff) != crc32_expected) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 	      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		  "Header CRC error");
 	      return (ARCHIVE_FATAL);
+#endif
       }
       if (head_type == ENDARC_HEAD)
 	      return (ARCHIVE_EOF);
@@ -1432,9 +1436,11 @@
   /* File Header CRC check. */
   crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7));
   if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
     archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
       "Header CRC error");
     return (ARCHIVE_FATAL);
+#endif
   }
   /* If no CRC error, Go on parsing File Header. */
   p = h;
@@ -1952,9 +1958,11 @@
     *size = 0;
     *offset = rar->offset;
     if (rar->file_crc != rar->crc_calculated) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
       archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                         "File CRC error");
       return (ARCHIVE_FATAL);
+#endif
     }
     rar->entry_eof = 1;
     return (ARCHIVE_EOF);
@@ -1988,7 +1996,7 @@
     return (ARCHIVE_FATAL);
 
   struct rar *rar;
-  int64_t start, end, actualend;
+  int64_t start, end;
   size_t bs;
   int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
 
@@ -2045,9 +2053,11 @@
       *size = 0;
       *offset = rar->offset;
       if (rar->file_crc != rar->crc_calculated) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                           "File CRC error");
         return (ARCHIVE_FATAL);
+#endif
       }
       rar->entry_eof = 1;
       return (ARCHIVE_EOF);
@@ -2179,11 +2189,12 @@
         end = rar->filters.filterstart;
       }
 
-      if ((actualend = expand(a, end)) < 0)
-        return ((int)actualend);
+      ret = expand(a, &end);
+      if (ret != ARCHIVE_OK)
+	      return (ret);
 
-      rar->bytes_uncopied = actualend - start;
-      rar->filters.lastend = actualend;
+      rar->bytes_uncopied = end - start;
+      rar->filters.lastend = end;
       if (rar->filters.lastend != rar->filters.filterstart && rar->bytes_uncopied == 0) {
           /* Broken RAR files cause this case.
           * NOTE: If this case were possible on a normal RAR file
@@ -2825,8 +2836,8 @@
   return ret;
 }
 
-static int64_t
-expand(struct archive_read *a, int64_t end)
+static int
+expand(struct archive_read *a, int64_t *end)
 {
   static const unsigned char lengthbases[] =
     {   0,   1,   2,   3,   4,   5,   6,
@@ -2873,16 +2884,19 @@
   struct rar *rar = (struct rar *)(a->format->data);
   struct rar_br *br = &(rar->br);
 
-  if (rar->filters.filterstart < end)
-    end = rar->filters.filterstart;
+  if (rar->filters.filterstart < *end)
+    *end = rar->filters.filterstart;
 
   while (1)
   {
-    if(lzss_position(&rar->lzss) >= end)
-      return end;
+    if(lzss_position(&rar->lzss) >= *end) {
+      return (ARCHIVE_OK);
+    }
 
-    if(rar->is_ppmd_block)
-      return lzss_position(&rar->lzss);
+    if(rar->is_ppmd_block) {
+      *end = lzss_position(&rar->lzss);
+      return (ARCHIVE_OK);
+    }
 
     if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
       return (ARCHIVE_FATAL);
@@ -2906,7 +2920,8 @@
           goto truncated_data;
         rar->start_new_table = rar_br_bits(br, 1);
         rar_br_consume(br, 1);
-        return lzss_position(&rar->lzss);
+        *end = lzss_position(&rar->lzss);
+        return (ARCHIVE_OK);
       }
       else
       {
@@ -2917,7 +2932,7 @@
     }
     else if(symbol==257)
     {
-      if (!read_filter(a, &end))
+      if (!read_filter(a, end))
           return (ARCHIVE_FATAL);
       continue;
     }
@@ -3323,14 +3338,43 @@
   struct rar *rar = (struct rar *)(a->format->data);
   struct rar_filters *filters = &rar->filters;
   struct rar_filter *filter = filters->stack;
-  size_t start = filters->filterstart;
-  size_t end = start + filter->blocklength;
+  struct rar_filter *f;
+  size_t start, end;
+  int64_t tend;
   uint32_t lastfilteraddress;
   uint32_t lastfilterlength;
   int ret;
 
+  if (filters == NULL || filter == NULL)
+    return (0);
+
+  start = filters->filterstart;
+  end = start + filter->blocklength;
+
   filters->filterstart = INT64_MAX;
-  end = (size_t)expand(a, end);
+  tend = (int64_t)end;
+  ret = expand(a, &tend);
+  if (ret != ARCHIVE_OK)
+    return 0;
+
+  /* Check if filter stack was modified in expand() */
+  ret = ARCHIVE_FATAL;
+  f = filters->stack;
+  while (f)
+  {
+    if (f == filter)
+    {
+      ret = ARCHIVE_OK;
+      break;
+    }
+    f = f->next;
+  }
+  if (ret != ARCHIVE_OK)
+    return 0;
+
+  if (tend < 0)
+    return 0;
+  end = (size_t)tend;
   if (end != start + filter->blocklength)
     return 0;
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
index 8850c93..548da4e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
@@ -2821,11 +2821,13 @@
 	    ^ (uint8_t) (*block_size >> 16);
 
 	if(calculated_cksum != hdr->block_cksum) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Block checksum error: got 0x%x, expected 0x%x",
 		    hdr->block_cksum, calculated_cksum);
 
 		return ARCHIVE_FATAL;
+#endif
 	}
 
 	return ARCHIVE_OK;
@@ -3911,6 +3913,13 @@
 			case GOOD:
 				/* fallthrough */
 			case BEST:
+				/* No data is returned here. But because a sparse-file aware
+				 * caller (like archive_read_data_into_fd) may treat zero-size
+				 * as a sparse file block, we need to update the offset
+				 * accordingly. At this point the decoder doesn't have any
+				 * pending uncompressed data blocks, so the current position in
+				 * the output file should be last_write_ptr. */
+				if (offset) *offset = rar->cstate.last_write_ptr;
 				return uncompress_file(a);
 			default:
 				archive_set_error(&a->archive,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
index bfdad7f..93c3fd5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -407,14 +407,13 @@
 	/*
 	 * Check format of mode/uid/gid/mtime/size/rdevmajor/rdevminor fields.
 	 */
-	if (bid > 0 && (
-	    validate_number_field(header->mode, sizeof(header->mode)) == 0
+	if (validate_number_field(header->mode, sizeof(header->mode)) == 0
 	    || validate_number_field(header->uid, sizeof(header->uid)) == 0
 	    || validate_number_field(header->gid, sizeof(header->gid)) == 0
 	    || validate_number_field(header->mtime, sizeof(header->mtime)) == 0
 	    || validate_number_field(header->size, sizeof(header->size)) == 0
 	    || validate_number_field(header->rdevmajor, sizeof(header->rdevmajor)) == 0
-	    || validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0)) {
+	    || validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0) {
 		bid = 0;
 	}
 
@@ -2108,6 +2107,21 @@
 			/* "size" is the size of the data in the entry. */
 			tar->entry_bytes_remaining
 			    = tar_atol10(value, strlen(value));
+			if (tar->entry_bytes_remaining < 0) {
+				tar->entry_bytes_remaining = 0;
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Tar size attribute is negative");
+				return (ARCHIVE_FATAL);
+			}
+			if (tar->entry_bytes_remaining == INT64_MAX) {
+				/* Note: tar_atol returns INT64_MAX on overflow */
+				tar->entry_bytes_remaining = 0;
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "Tar size attribute overflow");
+				return (ARCHIVE_FATAL);
+			}
 			/*
 			 * The "size" pax header keyword always overrides the
 			 * "size" field in the tar header.
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
index 2e60cf7..330df58 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -624,7 +624,9 @@
 		__archive_read_consume(a, xar->toc_chksum_size);
 		xar->offset += xar->toc_chksum_size;
 		if (r != ARCHIVE_OK)
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			return (ARCHIVE_FATAL);
+#endif
 	}
 
 	/*
@@ -827,10 +829,12 @@
 		    xattr->a_sum.val, xattr->a_sum.len,
 		    xattr->e_sum.val, xattr->e_sum.len);
 		if (r != ARCHIVE_OK) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
 			archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
 			    "Xattr checksum error");
 			r = ARCHIVE_WARN;
 			break;
+#endif
 		}
 		if (xattr->name.s == NULL) {
 			archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index 8ad73b6..e126ae3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -1667,7 +1667,7 @@
 	 */
 
 	/* Read magic1,magic2,lzma_params from the ZIPX stream. */
-	if((p = __archive_read_ahead(a, 9, NULL)) == NULL) {
+	if(zip->entry_bytes_remaining < 9 || (p = __archive_read_ahead(a, 9, NULL)) == NULL) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Truncated lzma data");
 		return (ARCHIVE_FATAL);
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index d7f2c46..69458e1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -3988,10 +3988,10 @@
 archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes,
     const char **p, size_t *length, struct archive_string_conv *sc)
 {
-	int r, ret = 0;
-
-	(void)r; /* UNUSED */
+	int ret = 0;
 #if defined(_WIN32) && !defined(__CYGWIN__)
+	int r;
+
 	/*
 	 * Internationalization programming on Windows must use Wide
 	 * characters because Windows platform cannot make locale UTF-8.
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index 66592e8..27626b5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -201,6 +201,10 @@
 	struct archive_write_filter *f;
 
 	f = calloc(1, sizeof(*f));
+
+	if (f == NULL)
+		return (NULL);
+
 	f->archive = _a;
 	f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
 	if (a->filter_first == NULL)
@@ -548,6 +552,10 @@
 	a->client_data = client_data;
 
 	client_filter = __archive_write_allocate_filter(_a);
+
+	if (client_filter == NULL)
+		return (ARCHIVE_FATAL);
+
 	client_filter->open = archive_write_client_open;
 	client_filter->write = archive_write_client_write;
 	client_filter->close = archive_write_client_close;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index b6d3d0a..bd5180e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -1996,6 +1996,8 @@
 		free(a);
 		return (NULL);
 	}
+	a->path_safe.s[0] = 0;
+
 #ifdef HAVE_ZLIB_H
 	a->decmpfs_compression_level = 5;
 #endif
@@ -2793,7 +2795,7 @@
 	char *tail;
 	char *head;
 	int last;
-	char c;
+	char c = '\0';
 	int r;
 	struct stat st;
 	int chdir_fd;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 1b12a29..88df3ce 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -1370,6 +1370,7 @@
 		free(a);
 		return (NULL);
 	}
+	a->path_safe.s[0] = 0;
 	return (&a->archive);
 }
 
@@ -2154,6 +2155,8 @@
 				return (ARCHIVE_FAILED);
 			}
 		}
+		if (!c)
+			break;
 		pn[0] = c;
 		pn++;
 	}
@@ -2258,6 +2261,9 @@
 			return (ARCHIVE_FAILED);
 		} else
 			p += 4;
+    /* Network drive path like "\\<server-name>\<share-name>\file" */
+    } else if (p[0] == L'\\' && p[1] == L'\\') {
+        p += 2;
 	}
 
 	/* Skip leading drive letter from archives created
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open.3 b/Utilities/cmlibarchive/libarchive/archive_write_open.3
index 29bffe4..6bceb96 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open.3
@@ -218,6 +218,7 @@
 .Fn archive_set_error
 to register an error code and message and
 return
+.Cm ARCHIVE_FATAL .
 .Bl -item -offset indent
 .It
 .Ft typedef int
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
index 5291149..cf1f477 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
@@ -1717,7 +1717,7 @@
 	 * to having clients override it.
 	 */
 #if HAVE_GETPID && 0  /* Disable this for now; see above comment. */
-	sprintf(buff, "PaxHeader.%d", getpid());
+	snprintf(buff, sizeof(buff), "PaxHeader.%d", getpid());
 #else
 	/* If the platform can't fetch the pid, don't include it. */
 	strcpy(buff, "PaxHeader");
diff --git a/Utilities/cmlibarchive/libarchive/cpio.5 b/Utilities/cmlibarchive/libarchive/cpio.5
index 837a456..c71018b 100644
--- a/Utilities/cmlibarchive/libarchive/cpio.5
+++ b/Utilities/cmlibarchive/libarchive/cpio.5
@@ -354,7 +354,7 @@
 It appeared in 1977 as part of PWB/UNIX 1.0, the
 .Dq Programmer's Work Bench
 derived from
-.At 6th Edition UNIX
+.At v6
 that was used internally at AT&T.
 Both the new binary and old character formats were in use
 by 1980, according to the System III source released
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
index ac255c4..62085a7 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
@@ -76,7 +76,7 @@
 __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
 		pid_t *out_child)
 {
-	pid_t child;
+	pid_t child = -1;
 	int stdin_pipe[2], stdout_pipe[2], tmp;
 #if HAVE_POSIX_SPAWNP
 	posix_spawn_file_actions_t actions;