This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git


The following commit(s) were added to refs/heads/master by this push:
     new b95421c7c [IO-872] PathUtils.directoryAndFileContentEquals doesn't 
work across FileSystems
b95421c7c is described below

commit b95421c7cbc03bd60a11975f6203e59d15f3786b
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Fri Apr 4 09:57:44 2025 -0400

    [IO-872] PathUtils.directoryAndFileContentEquals doesn't work across
    FileSystems
    
    Add tests and fix NPE
---
 .../java/org/apache/commons/io/file/PathUtils.java |   4 +-
 .../io/file/PathUtilsContentEqualsTest.java        |  56 ++++++++++++++++++++-
 src/test/resources/org/apache/commons/io/empty.zip | Bin 0 -> 8972 bytes
 3 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/commons/io/file/PathUtils.java 
b/src/main/java/org/apache/commons/io/file/PathUtils.java
index a9f6bea2e..c2be28788 100644
--- a/src/main/java/org/apache/commons/io/file/PathUtils.java
+++ b/src/main/java/org/apache/commons/io/file/PathUtils.java
@@ -1739,8 +1739,8 @@ public static BigInteger 
sizeOfDirectoryAsBigInteger(final Path directory) throw
     private static Path stripTrailingSeparator(final Path cdir) {
         final Path dir = cdir.normalize();
         final String separator = dir.getFileSystem().getSeparator();
-        final String fileName = dir.getFileName().toString();
-        return fileName.endsWith(separator) ? 
dir.resolveSibling(fileName.substring(0, fileName.length() - 1)) : dir;
+        final String fileName = Objects.toString(dir.getFileName(), null);
+        return fileName != null && fileName.endsWith(separator) ? 
dir.resolveSibling(fileName.substring(0, fileName.length() - 1)) : dir;
     }
 
     /**
diff --git 
a/src/test/java/org/apache/commons/io/file/PathUtilsContentEqualsTest.java 
b/src/test/java/org/apache/commons/io/file/PathUtilsContentEqualsTest.java
index 45be9d739..71c3adb05 100644
--- a/src/test/java/org/apache/commons/io/file/PathUtilsContentEqualsTest.java
+++ b/src/test/java/org/apache/commons/io/file/PathUtilsContentEqualsTest.java
@@ -28,6 +28,7 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
 
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.io.TempDir;
@@ -106,7 +107,7 @@ public void testDirectoryAndFileContentEquals() throws 
Exception {
      * @throws Exception on test failure.
      */
     @Test
-    public void testDirectoryAndFileContentEqualsDifferentFileSystems() throws 
Exception {
+    public void 
testDirectoryAndFileContentEqualsDifferentFileSystemsFileVsZip() throws 
Exception {
         final Path dir1 = Paths.get("src/test/resources/dir-equals-tests");
         try (FileSystem fileSystem = 
FileSystems.newFileSystem(dir1.resolveSibling(dir1.getFileName() + ".zip"), 
null)) {
             final Path dir2 = fileSystem.getPath("/dir-equals-tests");
@@ -115,6 +116,59 @@ public void 
testDirectoryAndFileContentEqualsDifferentFileSystems() throws Excep
         }
     }
 
+    /**
+     * Tests IO-872 PathUtils.directoryAndFileContentEquals doesn't work 
across FileSystems.
+     *
+     * @throws Exception on test failure.
+     */
+    @Test
+    public void 
testDirectoryAndFileContentEqualsDifferentFileSystemsZipVsZip() throws 
Exception {
+        final Path zipPath = 
Paths.get("src/test/resources/dir-equals-tests.zip");
+        final Path zipCopy = temporaryFolder.toPath().resolve("copy.zip");
+        Files.copy(zipPath, zipCopy, StandardCopyOption.REPLACE_EXISTING);
+        try (FileSystem fileSystem1 = FileSystems.newFileSystem(zipPath, null);
+                FileSystem fileSystem2 = FileSystems.newFileSystem(zipCopy, 
null)) {
+            final Path dir1 = fileSystem1.getPath("/dir-equals-tests");
+            final Path dir2 = fileSystem2.getPath("/dir-equals-tests");
+            // WindowsPath, UnixPath, and ZipPath equals() methods always 
return false if the argument is not of the same instance as itself.
+            assertTrue(PathUtils.directoryAndFileContentEquals(dir1, dir2));
+        }
+    }
+
+    /**
+     * Tests IO-872 PathUtils.directoryAndFileContentEquals doesn't work 
across FileSystems.
+     *
+     * @throws Exception on test failure.
+     */
+    @Test
+    public void 
testDirectoryAndFileContentEqualsDifferentFileSystemsZipVsZipEmpty() throws 
Exception {
+        final Path zipPath = 
Paths.get("src/test/resources/dir-equals-tests.zip");
+        final Path emptyZip = 
Paths.get("src/test/resources/org/apache/commons/io/empty.zip");
+        Files.copy(zipPath, emptyZip, StandardCopyOption.REPLACE_EXISTING);
+        try (FileSystem fileSystem1 = FileSystems.newFileSystem(zipPath, null);
+                FileSystem fileSystem2 = FileSystems.newFileSystem(emptyZip, 
null)) {
+            final Path dir1 = fileSystem1.getPath("/dir-equals-tests");
+            final Path dir2 = fileSystem2.getPath("/");
+            // WindowsPath, UnixPath, and ZipPath equals() methods always 
return false if the argument is not of the same instance as itself.
+            assertFalse(PathUtils.directoryAndFileContentEquals(dir1, dir2));
+        }
+        try (FileSystem fileSystem1 = FileSystems.newFileSystem(zipPath, null);
+                FileSystem fileSystem2 = FileSystems.newFileSystem(emptyZip, 
null)) {
+            final Path dir1 = fileSystem1.getPath("/dir-equals-tests");
+            final Path dir2 = 
fileSystem2.getRootDirectories().iterator().next();
+            // WindowsPath, UnixPath, and ZipPath equals() methods always 
return false if the argument is not of the same instance as itself.
+            assertFalse(PathUtils.directoryAndFileContentEquals(dir1, dir2));
+        }
+        final Path zipCopy = temporaryFolder.toPath().resolve("copy.zip");
+        Files.copy(emptyZip, zipCopy, StandardCopyOption.REPLACE_EXISTING);
+        try (FileSystem fileSystem1 = FileSystems.newFileSystem(emptyZip, 
null);
+                FileSystem fileSystem2 = FileSystems.newFileSystem(zipCopy, 
null)) {
+            final Path dir1 = fileSystem1.getPath("");
+            final Path dir2 = fileSystem2.getPath("");
+            // WindowsPath, UnixPath, and ZipPath equals() methods always 
return false if the argument is not of the same instance as itself.
+            assertTrue(PathUtils.directoryAndFileContentEquals(dir1, dir2));
+        }
+    }
 
     @Test
     public void testDirectoryContentEquals() throws Exception {
diff --git a/src/test/resources/org/apache/commons/io/empty.zip 
b/src/test/resources/org/apache/commons/io/empty.zip
new file mode 100644
index 000000000..7eb7ce09c
Binary files /dev/null and b/src/test/resources/org/apache/commons/io/empty.zip 
differ

Reply via email to