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

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


The following commit(s) were added to refs/heads/master by this push:
     new 649638b7c Reject unknown file type in CPIO entry mode (#790)
649638b7c is described below

commit 649638b7c945da9fd7d409502e853e72aa4b826e
Author: Gary Gregory <[email protected]>
AuthorDate: Sat Aug 22 16:32:18 2026 -0400

    Reject unknown file type in CPIO entry mode (#790)
    
    Add tests, main changes no longer needed.
---
 src/changes/changes.xml                            |   1 +
 .../org/apache/commons/compress/AbstractTest.java  |  10 ++
 .../archivers/cpio/CpioArchiveInputStreamTest.java | 101 +++++++++++++++++++++
 3 files changed, 112 insertions(+)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 52138667e..56ecac9df 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -147,6 +147,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="fix" dev="ggregory" due-to="Gary Gregory">[Cpio] 
CpioArchiveEntry now throws ArchiveException instead of 
IllegalArgumetException/IllegalStateException.</action>
       <action type="fix" dev="ggregory" due-to="Gary Gregory">[Cpio] 
CpioArchiveInputStream now throws ArchiveException instead of 
IllegalArgumetException/IllegalStateException.</action>
       <action type="fix" dev="ggregory" due-to="Gary Gregory">[Cpio] 
CpioArchiveOutputStream now throws ArchiveException instead of 
IllegalArgumetException/IllegalStateException.</action>
+      <action type="fix" dev="ggregory" due-to="Gary Gregory, KALI 
834X">[Cpio] Reject unknown file type in CPIO entry mode (#790); add 
tests.</action>
       <!-- FIX gzip -->
       <action type="fix" dev="ggregory" due-to="Gary Gregory">[GZip] 
GzipParameters.setOperatingSystem(int) now throws CompressorException on 
illegal input.</action>
       <action type="fix" issue="COMPRESS-705" dev="ggregory" due-to="Mario 
Fredenhagen, Gary Gregory">[GZip] GZip IOException: Extra subfield length 
exceeds remaining bytes in extra field; use new option 
GzipCompressorInputStream.Builder.setIgnoreExtraField(boolean).</action>
diff --git a/src/test/java/org/apache/commons/compress/AbstractTest.java 
b/src/test/java/org/apache/commons/compress/AbstractTest.java
index a386d3317..cf6b8e793 100644
--- a/src/test/java/org/apache/commons/compress/AbstractTest.java
+++ b/src/test/java/org/apache/commons/compress/AbstractTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.commons.compress;
 
+import static org.junit.Assert.assertNull;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.fail;
@@ -53,6 +54,15 @@ protected interface StreamWrapper<I extends InputStream> {
         I wrap(InputStream inputStream) throws Exception;
     }
 
+    /**
+     * Asserts that the cause of the given Throwable is null.
+     *
+     * @param e the Throwable to check.
+     */
+    public static void assertNullCause(final Throwable e) {
+        assertNull(e.getCause());
+    }
+
     /**
      * Deletes a file or directory. For a directory, delete it and all 
subdirectories.
      *
diff --git 
a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
 
b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
index 829fa4501..a2a2b2a4b 100644
--- 
a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
+++ 
b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
@@ -175,6 +175,79 @@ void testEndOfFileInEntry_c_namesize_0xFFFFFFFF() throws 
Exception {
         }
     }
 
+    @Test
+    void testInvalidFileTypeInMode() throws Exception {
+        // c_mode declares file type 0170000, which CPIO does not define
+        // @formatter:off
+        final String header =
+                "070701" + // c_magic
+                "00000001" + // c_ino
+                "0000F000" + // c_mode
+                "00000000" + // c_uid
+                "00000000" + // c_gid
+                "00000001" + // c_nlink
+                "00000000" + // c_mtime
+                "00000000" + // c_filesize
+                "00000000" + // c_devmajor
+                "00000000" + // c_devminor
+                "00000000" + // c_rdevmajor
+                "00000000" + // c_rdevminor
+                "00000002" + // c_namesize
+                "00000000" + // c_check
+                "a\0";
+        // @formatter:on
+        try (CpioArchiveInputStream cpio = CpioArchiveInputStream.builder()
+                .setByteArray(header.getBytes(StandardCharsets.US_ASCII))
+                .get()) {
+            assertNullCause(assertThrows(ArchiveException.class, 
cpio::getNextEntry));
+        }
+    }
+
+    @Test
+    void testInvalidFileTypeInModeMagicOldAscii() throws Exception {
+        // c_mode declares file type 0170000, which CPIO does not define
+        // @formatter:off
+        final String header =
+                "070707" + // c_magic
+                "000000" + // c_dev
+                "000001" + // c_ino
+                "170000" + // c_mode
+                "000000" + // c_uid
+                "000000" + // c_gid
+                "000001" + // c_nlink
+                "000000" + // c_rdev
+                "00000000000" + // c_mtime
+                "000002" + // c_namesize
+                "00000000000" + // c_filesize
+                "a\0";
+        // @formatter:on
+        try (CpioArchiveInputStream cpio = CpioArchiveInputStream.builder()
+                .setByteArray(header.getBytes(StandardCharsets.US_ASCII))
+                .get()) {
+            assertThrows(ArchiveException.class, cpio::getNextEntry);
+        }
+    }
+
+    @Test
+    void testInvalidFileTypeInModeMagicOldBinary() throws Exception {
+        // c_mode declares file type 0170000, which CPIO does not define
+        // c_magic, c_dev, c_ino, c_mode, c_uid, c_gid, c_nlink, c_rdev as 
little endian half words
+        final int[] halfWords = { 070707, 0, 1, 0170000, 0, 0, 1, 0 };
+        final byte[] data = new byte[halfWords.length * 2 + 10 + 2];
+        int off = 0;
+        for (final int halfWord : halfWords) {
+            data[off++] = (byte) halfWord;
+            data[off++] = (byte) (halfWord >> 8);
+        }
+        off += 4; // c_mtime
+        data[off] = 2; // c_namesize
+        off += 6; // c_namesize and c_filesize
+        data[off] = 'a';
+        try (CpioArchiveInputStream cpio = 
CpioArchiveInputStream.builder().setByteArray(data).get()) {
+            assertThrows(ArchiveException.class, cpio::getNextEntry);
+        }
+    }
+
     @Test
     void testInvalidLongValueInMetadata() throws Exception {
         try (CpioArchiveInputStream archive = CpioArchiveInputStream.builder()
@@ -196,6 +269,34 @@ void testMultiByteReadConsistentlyReturnsMinusOneAtEof() 
throws Exception {
         }
     }
 
+    @Test
+    void testNegativeSizeInHeader() throws Exception {
+        // c_filesize parses to -1, making CpioArchiveEntry.setSize throw 
IllegalArgumentException
+        // @formatter:off
+        final String header =
+                "070701" + // c_magic
+                "00000001" + // c_ino
+                "000081A4" + // c_mode
+                "00000000" + // c_uid
+                "00000000" + // c_gid
+                "00000001" + // c_nlink
+                "00000000" + // c_mtime
+                "-0000001" + // c_filesize
+                "00000000" + // c_devmajor
+                "00000000" + // c_devminor
+                "00000000" + // c_rdevmajor
+                "00000000" + // c_rdevminor
+                "00000002" + // c_namesize
+                "00000000" + // c_check
+                "a\0";
+        // @formatter:on
+        try (CpioArchiveInputStream cpio = CpioArchiveInputStream.builder()
+                .setByteArray(header.getBytes(StandardCharsets.US_ASCII))
+                .get()) {
+            assertNullCause(assertThrows(ArchiveException.class, 
cpio::getNextEntry));
+        }
+    }
+
     @Test
     void testSingleArgumentConstructor() throws Exception {
         final InputStream inputStream = mock(InputStream.class);

Reply via email to