From 185d88288baa6eaec6528c58b957d50a7f3cdb71 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Oct 2025 13:03:12 +0000 Subject: [PATCH 1/2] Initial plan From 8d3df212f2c8210955a5774d4f42f5aaf253da77 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Oct 2025 13:12:48 +0000 Subject: [PATCH 2/2] Override getFiles() in AbstractZipArchiver to normalize paths to forward slashes Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --- .../plexus/archiver/AbstractArchiver.java | 17 +++++++++ .../codehaus/plexus/archiver/Archiver.java | 10 ++++++ .../archiver/zip/AbstractZipArchiver.java | 25 +++++++++++++ .../plexus/archiver/zip/ZipArchiverTest.java | 35 +++++++++++++++++++ 4 files changed, 87 insertions(+) diff --git a/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java b/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java index 673eda8a..734e1cd5 100755 --- a/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java +++ b/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java @@ -616,6 +616,23 @@ private static void closeQuietlyIfCloseable(Object resource) { } } + /** + * Returns a map of the files that have been added to the archive. + *

+ * Note: The entry names in the map use platform-specific path separators + * (e.g., backslashes on Windows, forward slashes on Unix). For ZIP archivers, + * the actual archive entries will use forward slashes as required by the ZIP + * specification, but this map returns names as they were added. + *

+ *

+ * For ZIP-based archivers (ZipArchiver, JarArchiver, etc.), use the overridden + * implementation which normalizes paths to forward slashes to match the actual + * ZIP entry names. + *

+ * + * @return A map where keys are entry names and values are the corresponding ArchiveEntry objects. + * @deprecated Use {@link #getResources()} instead. + */ @Override @Deprecated public Map getFiles() { diff --git a/src/main/java/org/codehaus/plexus/archiver/Archiver.java b/src/main/java/org/codehaus/plexus/archiver/Archiver.java index 578a668d..7ff08ae5 100644 --- a/src/main/java/org/codehaus/plexus/archiver/Archiver.java +++ b/src/main/java/org/codehaus/plexus/archiver/Archiver.java @@ -260,6 +260,16 @@ void addArchivedFileSet(@Nonnull File archiveFile, String prefix, String[] inclu ResourceIterator getResources() throws ArchiverException; /** + * Returns a map of the files that have been added to the archive. + *

+ * Note: The entry names in the map may use platform-specific path separators + * in the base implementation. However, archive format-specific implementations + * (such as ZIP-based archivers) should normalize paths according to their format + * requirements. For example, ZIP archivers normalize to forward slashes as required + * by the ZIP file specification. + *

+ * + * @return A map where keys are entry names and values are the corresponding ArchiveEntry objects. * @deprecated Use {@link #getResources()} */ @Deprecated diff --git a/src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java b/src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java index dccb7edc..04e56c21 100755 --- a/src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java +++ b/src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java @@ -27,8 +27,10 @@ import java.nio.file.attribute.FileTime; import java.util.Calendar; import java.util.Deque; +import java.util.HashMap; import java.util.Hashtable; import java.util.Locale; +import java.util.Map; import java.util.TimeZone; import java.util.concurrent.ExecutionException; import java.util.zip.CRC32; @@ -564,6 +566,29 @@ protected boolean createEmptyZip(File zipFile) throws ArchiverException { return true; } + /** + * Returns a map of the files that have been added to the archive. + * This method is overridden to normalize path separators to forward slashes, + * as required by the ZIP file format specification. + * + * @return A map where keys are entry names with forward slashes as separators, + * and values are the corresponding ArchiveEntry objects. + * @deprecated Use {@link #getResources()} instead. + */ + @Override + @Deprecated + public Map getFiles() { + Map files = super.getFiles(); + Map normalizedFiles = new HashMap<>(); + + for (Map.Entry entry : files.entrySet()) { + String normalizedPath = entry.getKey().replace(File.separatorChar, '/'); + normalizedFiles.put(normalizedPath, entry.getValue()); + } + + return normalizedFiles; + } + /** * Do any clean up necessary to allow this instance to be used again. *

diff --git a/src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java b/src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java index 4323aad7..68f8b2ad 100644 --- a/src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java +++ b/src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java @@ -52,6 +52,7 @@ import org.apache.commons.compress.archivers.zip.ZipExtraField; import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.io.input.BoundedInputStream; +import org.codehaus.plexus.archiver.ArchiveEntry; import org.codehaus.plexus.archiver.Archiver; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.BasePlexusArchiverTest; @@ -857,4 +858,38 @@ private long toLocalTimeZone(long timestamp) { return 0L; } } + + /** + * Test that getFiles() returns entry names with forward slashes (not platform-specific separators) + * as required by the ZIP file specification. + */ + @Test + void testGetFilesReturnsForwardSlashes() throws Exception { + File zipFile = getTestFile("target/output/test-getfiles-slashes.zip"); + ZipArchiver archiver = getZipArchiver(zipFile); + + // Add files with nested directory structure + File pomFile = new File("pom.xml"); + archiver.addFile(pomFile, "dir1/dir2/pom.xml"); + archiver.addFile(pomFile, "another/nested/path/file.xml"); + + // Get the files map BEFORE creating the archive + Map files = archiver.getFiles(); + + // Verify all entry names use forward slashes + for (String entryName : files.keySet()) { + assertFalse(entryName.contains("\\"), "Entry name should not contain backslashes, but got: " + entryName); + assertTrue( + entryName.contains("/") || !entryName.contains(File.separator), + "Entry name should use forward slashes as separator: " + entryName); + } + + // Verify specific entries exist with correct format + assertTrue(files.containsKey("dir1/dir2/pom.xml"), "Should contain dir1/dir2/pom.xml"); + assertTrue(files.containsKey("another/nested/path/file.xml"), "Should contain another/nested/path/file.xml"); + + // Create the archive to ensure it's valid + archiver.createArchive(); + assertTrue(zipFile.exists()); + } }