You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by pk...@apache.org on 2025/09/25 09:01:17 UTC

(commons-compress) branch fix/dump-max-length created (now fae43953c)

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

pkarwasz pushed a change to branch fix/dump-max-length
in repository https://gitbox.apache.org/repos/asf/commons-compress.git


      at fae43953c fix: Handling of long file names in `DumpArchiveInputStream`

This branch includes the following new commits:

     new fae43953c fix: Handling of long file names in `DumpArchiveInputStream`

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(commons-compress) 01/01: fix: Handling of long file names in `DumpArchiveInputStream`

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch fix/dump-max-length
in repository https://gitbox.apache.org/repos/asf/commons-compress.git

commit fae43953cc896e65e3cc8be767916dbeee9ea7e8
Author: Piotr P. Karwasz <pk...@apache.org>
AuthorDate: Thu Sep 25 10:58:26 2025 +0200

    fix: Handling of long file names in `DumpArchiveInputStream`
    
    `DumpArchiveInputStream` previously failed to handle file names longer than `Byte.MAX_VALUE` (127) due to an incorrect type conversion.
    
    This change fixes the interpretation of the file name length field so that it is treated as an *unsigned* 8-bit integer, allowing file names up to 255 bytes as specified by the dump format.
---
 src/changes/changes.xml                            |   1 +
 .../archivers/dump/DumpArchiveInputStream.java     |   3 ++-
 .../archivers/dump/DumpArchiveInputStreamTest.java |  26 +++++++++++++++++++++
 src/test/resources/dump/max-segment-length.dump    | Bin 0 -> 7168 bytes
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index b23dc64dc..9a037a8a1 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -62,6 +62,7 @@ The <action> type attribute can be add,update,fix,remove.
       <!-- FIX dump -->      
       <action type="fix" dev="pkarwasz" due-to="Tyler Nighswander">Align DUMP archive block size with Linux `dump` utility.</action>
       <action type="fix" dev="ggregory" due-to="Tyler Nighswander, Gary Gregory">DumpArchiveInputStream.getNextEntry() throws an ArchiveException instead of ArrayIndexOutOfBoundsException.</action>
+      <action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">Fixed DumpArchiveInputStream to correctly handle file names up to 255 bytes.</action>
       <!-- FIX zip -->      
       <action type="fix" dev="ggregory" due-to="Dominik Stadler, Gary Gregory" issue="COMPRESS-598">ZipArchiveInputStream.read(byte[], int, int) now throws an IOException instead of a NullPointerException.</action>
       <action type="fix" dev="ggregory" due-to="Tyler Nighswander, Gary Gregory">ZipFile.createBoundedInputStream(long, long) now throws an ArchiveException instead of IllegalArgumentException.</action>
diff --git a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStream.java
index 5bf0b1202..1f3c2c182 100644
--- a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStream.java
@@ -547,7 +547,8 @@ private void readDirectoryEntry(DumpArchiveEntry entry) throws IOException {
 
                 final byte type = blockBuffer[i + 6];
 
-                final String name = DumpArchiveUtil.decode(zipEncoding, blockBuffer, i + 8, blockBuffer[i + 7]);
+                final String name =
+                        DumpArchiveUtil.decode(zipEncoding, blockBuffer, i + 8, Byte.toUnsignedInt(blockBuffer[i + 7]));
 
                 if (CURRENT_PATH_SEGMENT.equals(name) || PARENT_PATH_SEGMENT.equals(name)) {
                     // do nothing...
diff --git a/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStreamTest.java b/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStreamTest.java
index b5efb7535..a42b66cce 100644
--- a/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStreamTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveInputStreamTest.java
@@ -22,6 +22,7 @@
 import static org.apache.commons.compress.archivers.dump.DumpArchiveTestFactory.createSegment;
 import static org.apache.commons.compress.archivers.dump.DumpArchiveTestFactory.createSummary;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -37,8 +38,10 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.compress.AbstractTest;
+import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.ArchiveException;
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.api.Timeout.ThreadMode;
@@ -137,6 +140,29 @@ void testLoopingInodes() throws Exception {
         }
     }
 
+    @Test
+    void testMaxSegmentLength() throws Exception {
+        try (DumpArchiveInputStream archive = DumpArchiveInputStream.builder()
+                .setURI(getURI("dump/max-segment-length.dump"))
+                .get()) {
+            // Verify that the archive correctly handles file names up to the maximum
+            // supported length of 255 bytes.
+            //
+            // The first entry is the root directory (name = ""), followed by a file
+            // whose name is exactly 255 characters long ("aaaa...a"). This ensures
+            // the implementation can read and preserve file names at the boundary
+            // of the allowed length.
+            ArchiveEntry entry = assertDoesNotThrow(archive::getNextEntry);
+            String entryName = entry.getName();
+            assertEquals("", entryName);
+
+            entry = assertDoesNotThrow(archive::getNextEntry);
+            entryName = entry.getName();
+            assertEquals(255, entryName.length());
+            assertEquals(StringUtils.repeat("a", 255), entryName);
+        }
+    }
+
     @Test
     void testMultiByteReadConsistentlyReturnsMinusOneAtEof() throws Exception {
         final byte[] buf = new byte[2];
diff --git a/src/test/resources/dump/max-segment-length.dump b/src/test/resources/dump/max-segment-length.dump
new file mode 100644
index 000000000..9beae1269
Binary files /dev/null and b/src/test/resources/dump/max-segment-length.dump differ