This is an automated email from the ASF dual-hosted git repository.
olamy pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/maven-build-cache-extension.git
The following commit(s) were added to refs/heads/master by this push:
new 697f01e fix for issue #450 - fixed CacheUtils.unzip to properly
restore unix permissions on file systems that support it (#451)
697f01e is described below
commit 697f01eba273a245fc8e5ad24963a54facbb1f97
Author: Andrei Karneyenka <[email protected]>
AuthorDate: Thu Feb 12 17:18:02 2026 -0500
fix for issue #450 - fixed CacheUtils.unzip to properly restore unix
permissions on file systems that support it (#451)
* fix for issue #450 - fixed CacheUtils.unzip to properly restore unix
permissions on file systems that support it
CacheUtils.unzip() is using ZipArchiveInputStream which is not properly
reading unix permissions. Apparently, it's a known shortcoming documented in
commons-compress javadocs. Switched to using ZipFile and permissions are now
extracted correctly.
* fix for issue #450 - updated test description for better clarity
* addressed code review feedback from @olamy
---
.../org/apache/maven/buildcache/CacheUtils.java | 17 ++++++++------
.../buildcache/CacheUtilsPermissionsTest.java | 27 ++++++++++++++++++++++
2 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/src/main/java/org/apache/maven/buildcache/CacheUtils.java
b/src/main/java/org/apache/maven/buildcache/CacheUtils.java
index df3bb49..1265d0d 100644
--- a/src/main/java/org/apache/maven/buildcache/CacheUtils.java
+++ b/src/main/java/org/apache/maven/buildcache/CacheUtils.java
@@ -20,6 +20,7 @@
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
@@ -32,6 +33,7 @@
import java.nio.file.attribute.PosixFilePermission;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
@@ -39,8 +41,8 @@
import java.util.stream.Stream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
-import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
+import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.mutable.MutableBoolean;
@@ -210,9 +212,10 @@ public static void unzip(Path zip, Path out, boolean
preservePermissions) throws
final boolean supportsPosix = preservePermissions
&&
out.getFileSystem().supportedFileAttributeViews().contains("posix");
- try (ZipArchiveInputStream zis = new
ZipArchiveInputStream(Files.newInputStream(zip))) {
- ZipArchiveEntry entry = zis.getNextEntry();
- while (entry != null) {
+ try (ZipFile zipFile = ZipFile.builder().setFile(zip.toFile()).get()) {
+ Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
+ while (entries.hasMoreElements()) {
+ ZipArchiveEntry entry = entries.nextElement();
Path file = out.resolve(entry.getName());
if (!file.normalize().startsWith(out.normalize())) {
throw new RuntimeException("Bad zip entry");
@@ -222,7 +225,9 @@ public static void unzip(Path zip, Path out, boolean
preservePermissions) throws
} else {
Path parent = file.getParent();
Files.createDirectories(parent);
- Files.copy(zis, file, StandardCopyOption.REPLACE_EXISTING);
+ try (InputStream is = zipFile.getInputStream(entry)) {
+ Files.copy(is, file,
StandardCopyOption.REPLACE_EXISTING);
+ }
}
Files.setLastModifiedTime(file,
FileTime.fromMillis(entry.getTime()));
@@ -234,8 +239,6 @@ public static void unzip(Path zip, Path out, boolean
preservePermissions) throws
Files.setPosixFilePermissions(file, permissions);
}
}
-
- entry = zis.getNextEntry();
}
}
}
diff --git
a/src/test/java/org/apache/maven/buildcache/CacheUtilsPermissionsTest.java
b/src/test/java/org/apache/maven/buildcache/CacheUtilsPermissionsTest.java
index fe2a6ec..0ce8685 100644
--- a/src/test/java/org/apache/maven/buildcache/CacheUtilsPermissionsTest.java
+++ b/src/test/java/org/apache/maven/buildcache/CacheUtilsPermissionsTest.java
@@ -149,6 +149,33 @@ void testPermissionsDoNotAffectHashWhenDisabled() throws
IOException {
+ "Files should use system default permissions
(umask).");
}
+ @Test
+ @DisabledOnOs(OS.WINDOWS)
+ void testPermissionsAreRestoredOnUnzip() throws Exception {
+ // Given: a source directory with a file that has "execute" permission
+ Path source = tempDir.resolve("source");
+ Files.createDirectories(source);
+
+ Path script = source.resolve("script.sh");
+ writeString(script, "#!/bin/bash\necho hello");
+ Set<PosixFilePermission> execPermissions =
PosixFilePermissions.fromString("rwxr-xr-x");
+ Files.setPosixFilePermissions(script, execPermissions);
+
+ // When: ZIP file is created from that directory with
"preservePermissions=true"
+ Path zippedFile = tempDir.resolve("target.zip");
+ CacheUtils.zip(source, zippedFile, "*", true);
+
+ // And: ZIP file is extracted with "preservePermissions=true"
+ Path unzippedDir = tempDir.resolve("target-unzipped");
+ Files.createDirectories(unzippedDir);
+ CacheUtils.unzip(zippedFile, unzippedDir, true);
+
+ // Then: extracted file should have executable permissions
+ Path extractedScript = unzippedDir.resolve("script.sh");
+ assertTrue(Files.exists(extractedScript), "Extracted script should
exist.");
+ assertTrue(Files.isExecutable(extractedScript), "Permissions should be
restored when the file is extracted");
+ }
+
/**
* Java 8 compatible version of Files.writeString().
*/