Skip to content

Commit a99931b

Browse files
Copilotslachiewicz
andauthored
Fix AbstractArchiver.getFiles() to return forward slashes for ZIP-based archivers (#392)
* Override getFiles() in AbstractZipArchiver to normalize paths to forward slashes Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com>
1 parent 59f8800 commit a99931b

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,23 @@ private static void closeQuietlyIfCloseable(Object resource) {
616616
}
617617
}
618618

619+
/**
620+
* Returns a map of the files that have been added to the archive.
621+
* <p>
622+
* Note: The entry names in the map use platform-specific path separators
623+
* (e.g., backslashes on Windows, forward slashes on Unix). For ZIP archivers,
624+
* the actual archive entries will use forward slashes as required by the ZIP
625+
* specification, but this map returns names as they were added.
626+
* </p>
627+
* <p>
628+
* For ZIP-based archivers (ZipArchiver, JarArchiver, etc.), use the overridden
629+
* implementation which normalizes paths to forward slashes to match the actual
630+
* ZIP entry names.
631+
* </p>
632+
*
633+
* @return A map where keys are entry names and values are the corresponding ArchiveEntry objects.
634+
* @deprecated Use {@link #getResources()} instead.
635+
*/
619636
@Override
620637
@Deprecated
621638
public Map<String, ArchiveEntry> getFiles() {

src/main/java/org/codehaus/plexus/archiver/Archiver.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,16 @@ void addArchivedFileSet(@Nonnull File archiveFile, String prefix, String[] inclu
260260
ResourceIterator getResources() throws ArchiverException;
261261

262262
/**
263+
* Returns a map of the files that have been added to the archive.
264+
* <p>
265+
* Note: The entry names in the map may use platform-specific path separators
266+
* in the base implementation. However, archive format-specific implementations
267+
* (such as ZIP-based archivers) should normalize paths according to their format
268+
* requirements. For example, ZIP archivers normalize to forward slashes as required
269+
* by the ZIP file specification.
270+
* </p>
271+
*
272+
* @return A map where keys are entry names and values are the corresponding ArchiveEntry objects.
263273
* @deprecated Use {@link #getResources()}
264274
*/
265275
@Deprecated

src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
import java.nio.file.attribute.FileTime;
2828
import java.util.Calendar;
2929
import java.util.Deque;
30+
import java.util.HashMap;
3031
import java.util.Hashtable;
3132
import java.util.Locale;
33+
import java.util.Map;
3234
import java.util.TimeZone;
3335
import java.util.concurrent.ExecutionException;
3436
import java.util.zip.CRC32;
@@ -564,6 +566,29 @@ protected boolean createEmptyZip(File zipFile) throws ArchiverException {
564566
return true;
565567
}
566568

569+
/**
570+
* Returns a map of the files that have been added to the archive.
571+
* This method is overridden to normalize path separators to forward slashes,
572+
* as required by the ZIP file format specification.
573+
*
574+
* @return A map where keys are entry names with forward slashes as separators,
575+
* and values are the corresponding ArchiveEntry objects.
576+
* @deprecated Use {@link #getResources()} instead.
577+
*/
578+
@Override
579+
@Deprecated
580+
public Map<String, ArchiveEntry> getFiles() {
581+
Map<String, ArchiveEntry> files = super.getFiles();
582+
Map<String, ArchiveEntry> normalizedFiles = new HashMap<>();
583+
584+
for (Map.Entry<String, ArchiveEntry> entry : files.entrySet()) {
585+
String normalizedPath = entry.getKey().replace(File.separatorChar, '/');
586+
normalizedFiles.put(normalizedPath, entry.getValue());
587+
}
588+
589+
return normalizedFiles;
590+
}
591+
567592
/**
568593
* Do any clean up necessary to allow this instance to be used again.
569594
* <p>

src/test/java/org/codehaus/plexus/archiver/zip/ZipArchiverTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.apache.commons.compress.archivers.zip.ZipExtraField;
5353
import org.apache.commons.compress.archivers.zip.ZipFile;
5454
import org.apache.commons.io.input.BoundedInputStream;
55+
import org.codehaus.plexus.archiver.ArchiveEntry;
5556
import org.codehaus.plexus.archiver.Archiver;
5657
import org.codehaus.plexus.archiver.ArchiverException;
5758
import org.codehaus.plexus.archiver.BasePlexusArchiverTest;
@@ -857,4 +858,38 @@ private long toLocalTimeZone(long timestamp) {
857858
return 0L;
858859
}
859860
}
861+
862+
/**
863+
* Test that getFiles() returns entry names with forward slashes (not platform-specific separators)
864+
* as required by the ZIP file specification.
865+
*/
866+
@Test
867+
void testGetFilesReturnsForwardSlashes() throws Exception {
868+
File zipFile = getTestFile("target/output/test-getfiles-slashes.zip");
869+
ZipArchiver archiver = getZipArchiver(zipFile);
870+
871+
// Add files with nested directory structure
872+
File pomFile = new File("pom.xml");
873+
archiver.addFile(pomFile, "dir1/dir2/pom.xml");
874+
archiver.addFile(pomFile, "another/nested/path/file.xml");
875+
876+
// Get the files map BEFORE creating the archive
877+
Map<String, ArchiveEntry> files = archiver.getFiles();
878+
879+
// Verify all entry names use forward slashes
880+
for (String entryName : files.keySet()) {
881+
assertFalse(entryName.contains("\\"), "Entry name should not contain backslashes, but got: " + entryName);
882+
assertTrue(
883+
entryName.contains("/") || !entryName.contains(File.separator),
884+
"Entry name should use forward slashes as separator: " + entryName);
885+
}
886+
887+
// Verify specific entries exist with correct format
888+
assertTrue(files.containsKey("dir1/dir2/pom.xml"), "Should contain dir1/dir2/pom.xml");
889+
assertTrue(files.containsKey("another/nested/path/file.xml"), "Should contain another/nested/path/file.xml");
890+
891+
// Create the archive to ensure it's valid
892+
archiver.createArchive();
893+
assertTrue(zipFile.exists());
894+
}
860895
}

0 commit comments

Comments
 (0)