]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
unzip: mark bsdunzip as long-path aware on Windows 3167/head
authorReyad Attiyat <reyad.attiyat@siemens-healthineers.com>
Tue, 23 Jun 2026 20:38:11 +0000 (15:38 -0500)
committerTobias Stoeckmann <tobias@stoeckmann.org>
Wed, 24 Jun 2026 16:02:20 +0000 (18:02 +0200)
Signed-off-by: God-damnit-all <53661808+God-damnit-all@users.noreply.github.com>
Makefile.am
unzip/CMakeLists.txt
unzip/bsdunzip.exe.manifest [new file with mode: 0644]
unzip/bsdunzip.rc [new file with mode: 0644]

index 3e5c4a02aa48b39247fe83d51abd52929d9d28e7..dff2b32e72e9d41ebf71752eabfda965de0e58ed 100644 (file)
@@ -1690,9 +1690,20 @@ bsdunzip_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV)
 bsdunzip_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdunzip_ccstatic) $(PLATFORMCPPFLAGS)
 bsdunzip_LDFLAGS= $(bsdunzip_ldstatic) $(DEAD_CODE_REMOVAL)
 
+if INC_WINDOWS_FILES
+# Embed an application manifest marking bsdunzip as long-path aware.
+unzip/bsdunzip_rc.$(OBJEXT): $(top_srcdir)/unzip/bsdunzip.rc $(top_srcdir)/unzip/bsdunzip.exe.manifest
+       $(AM_V_GEN)$(WINDRES) -I $(top_srcdir)/unzip -i $(top_srcdir)/unzip/bsdunzip.rc -o $@
+bsdunzip_LDADD += unzip/bsdunzip_rc.$(OBJEXT)
+bsdunzip_DEPENDENCIES += unzip/bsdunzip_rc.$(OBJEXT)
+CLEANFILES += unzip/bsdunzip_rc.$(OBJEXT)
+endif
+
 bsdunzip_EXTRA_DIST= \
        unzip/bsdunzip_windows.h \
        unzip/bsdunzip_windows.c \
+       unzip/bsdunzip.rc \
+       unzip/bsdunzip.exe.manifest \
        unzip/bsdunzip.1 \
        unzip/CMakeLists.txt
 
index eb9c28f0acd826500b88d194cff4390e585dea05..496b9b36881060522a18b3e4991a1b3da056b20d 100644 (file)
@@ -28,6 +28,15 @@ IF(ENABLE_UNZIP)
   IF(WIN32 AND NOT CYGWIN)
     LIST(APPEND bsdunzip_SOURCES bsdunzip_windows.c)
     LIST(APPEND bsdunzip_SOURCES bsdunzip_windows.h)
+    IF(NOT MSVC)
+      # The GNU toolchains (MinGW/Clang) do not generate an application
+      # manifest, so we embed one through a resource script.
+      ENABLE_LANGUAGE(RC)
+      INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+      LIST(APPEND bsdunzip_SOURCES bsdunzip.rc)
+      SET_SOURCE_FILES_PROPERTIES(bsdunzip.rc PROPERTIES
+        OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bsdunzip.exe.manifest)
+    ENDIF(NOT MSVC)
   ENDIF(WIN32 AND NOT CYGWIN)
 
   # bsdunzip documentation
@@ -42,6 +51,10 @@ IF(ENABLE_UNZIP)
     SET_TARGET_PROPERTIES(bsdunzip PROPERTIES COMPILE_DEFINITIONS
                                  LIBARCHIVE_STATIC)
   ENDIF(ENABLE_UNZIP_SHARED)
+  IF(WIN32 AND NOT CYGWIN AND MSVC)
+    # MSVC merges .manifest sources into the linker's default manifest
+    TARGET_SOURCES(bsdunzip PRIVATE bsdunzip.exe.manifest)
+  ENDIF(WIN32 AND NOT CYGWIN AND MSVC)
 
   # Installation rules
   IF(ENABLE_INSTALL)
diff --git a/unzip/bsdunzip.exe.manifest b/unzip/bsdunzip.exe.manifest
new file mode 100644 (file)
index 0000000..32142e9
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+    <security>
+      <requestedPrivileges>
+        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <application xmlns="urn:schemas-microsoft-com:asm.v3">
+    <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
+      <ws2:longPathAware>true</ws2:longPathAware>
+    </windowsSettings>
+  </application>
+</assembly>
diff --git a/unzip/bsdunzip.rc b/unzip/bsdunzip.rc
new file mode 100644 (file)
index 0000000..6b4d9b5
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Embed an application manifest that marks bsdunzip as long-path aware.
+ *
+ * bsdunzip's file name handling is limited to MAX_PATH (260) characters unless
+ * the process opts in to long paths via a "longPathAware" manifest.
+ * A system-wide LongPathsEnabled registry value is not sufficient on its own;
+ * the executable must also carry this manifest.  Without it, extracting into
+ * deeply nested destination directories fails.
+ *
+ * See:
+ * https://learn.microsoft.com/windows/win32/fileio/maximum-file-path-limitation
+ */
+
+#define RT_MANIFEST 24
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "bsdunzip.exe.manifest"