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);