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

commit 571208f7b594b95c9c7680ac6dfc5799b5232084
Author: Gary Gregory <[email protected]>
AuthorDate: Mon Aug 10 18:39:44 2026 -0400

    TarUtils now throws ArchiveException instead of
    IllegalArgumentException.
---
 src/changes/changes.xml                            |  1 +
 .../compress/archivers/tar/TarArchiveEntry.java    |  4 ++--
 .../commons/compress/archivers/tar/TarUtils.java   | 28 ++++++++++++----------
 .../apache/commons/compress/archivers/TarTest.java | 14 +++++------
 .../compress/archivers/tar/TarUtilsTest.java       | 26 ++++++++++----------
 5 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 328054d3a..34c494af4 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -106,6 +106,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="fix" dev="ggregory" due-to="Gary Gregory">TAR ParsingUtils 
now throws the IOException subclass CompressException.</action>
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">TarArchiveOutputStream now throws ArchiveException instead of 
IllegalArgumentException.</action>
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">TarArchiveInputStream now throws ArchiveException instead of 
IllegalArgumentException.</action>
+      <action type="fix" dev="ggregory" due-to="Gary Gregory">TarUtils now 
throws ArchiveException instead of IllegalArgumentException.</action>
       <!-- FIX ar -->
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">ArArchiveInputStream.readGNUStringTable(byte[], int, int) now provides 
a better exception message, wrapping the underlying exception.</action>
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">ArArchiveInputStream.read(byte[], int, int) now throws 
ArchiveException instead of ArithmeticException.</action>
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java 
b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
index 8a8114551..5d7442eb2 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java
@@ -298,11 +298,11 @@ private static Instant 
parseInstantFromDecimalSeconds(final String value) throws
         }
     }
 
-    private static long parseOctalOrBinary(final byte[] header, final int 
offset, final int length, final boolean lenient) {
+    private static long parseOctalOrBinary(final byte[] header, final int 
offset, final int length, final boolean lenient) throws ArchiveException {
         if (lenient) {
             try {
                 return TarUtils.parseOctalOrBinary(header, offset, length);
-            } catch (final IllegalArgumentException ex) { // NOSONAR
+            } catch (final ArchiveException ex) { // NOSONAR
                 return UNKNOWN;
             }
         }
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java 
b/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
index 6d329c00e..78132cc90 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
@@ -420,7 +420,7 @@ static boolean isSpecialTarRecord(final TarArchiveEntry 
entry) {
         return entry.isGNULongLinkEntry() || entry.isGNULongNameEntry() || 
entry.isGlobalPaxHeader() || entry.isPaxHeader();
     }
 
-    private static long parseBinaryBigInteger(final byte[] buffer, final int 
offset, final int length, final boolean negative) {
+    private static long parseBinaryBigInteger(final byte[] buffer, final int 
offset, final int length, final boolean negative) throws ArchiveException {
         final byte[] remainder = new byte[length - 1];
         System.arraycopy(buffer, offset + 1, remainder, 0, length - 1);
         BigInteger val = new BigInteger(remainder);
@@ -429,14 +429,14 @@ private static long parseBinaryBigInteger(final byte[] 
buffer, final int offset,
             val = val.add(NEG_1_BIG_INT).not();
         }
         if (val.bitLength() > 63) {
-            throw new IllegalArgumentException("At offset " + offset + ", " + 
length + " byte binary number exceeds maximum signed long value");
+            throw new ArchiveException("At offset " + offset + ", " + length + 
" byte binary number exceeds maximum signed long value");
         }
         return negative ? -val.longValue() : val.longValue();
     }
 
-    private static long parseBinaryLong(final byte[] buffer, final int offset, 
final int length, final boolean negative) {
+    private static long parseBinaryLong(final byte[] buffer, final int offset, 
final int length, final boolean negative) throws ArchiveException {
         if (length >= 9) {
-            throw new IllegalArgumentException("At offset " + offset + ", " + 
length + " byte binary number exceeds maximum signed long value");
+            throw new ArchiveException("At offset " + offset + ", " + length + 
" byte binary number exceeds maximum signed long value");
         }
         long val = 0;
         for (int i = 1; i < length; i++) {
@@ -548,18 +548,18 @@ public static String parseName(final byte[] buffer, final 
int offset, final int
      * @param offset The offset into the buffer from which to parse.
      * @param length The maximum number of bytes to parse - must be at least 2 
bytes.
      * @return The long value of the octal string.
-     * @throws IllegalArgumentException if the trailing space/NUL is missing 
or if an invalid byte is detected.
+     * @throws ArchiveException if the trailing space/NUL is missing or if an 
invalid byte is detected.
      */
-    public static long parseOctal(final byte[] buffer, final int offset, final 
int length) {
+    public static long parseOctal(final byte[] buffer, final int offset, final 
int length) throws ArchiveException {
         return parseOctal(buffer, offset, length, "parseOctal()", false);
     }
 
-    static long parseOctal(final byte[] buffer, final int offset, final int 
length, final String context, final boolean lenient) {
+    static long parseOctal(final byte[] buffer, final int offset, final int 
length, final String context, final boolean lenient) throws ArchiveException {
         long result = 0;
         int end = offset + length;
         int start = offset;
         if (length < 2) {
-            throw new IllegalArgumentException(context + ": Length " + length 
+ " must be at least 2");
+            throw new ArchiveException(context + ": Length " + length + " must 
be at least 2");
         }
         if (buffer[start] == 0) {
             return 0L;
@@ -587,7 +587,7 @@ static long parseOctal(final byte[] buffer, final int 
offset, final int length,
                     // When lenient, an early NUL ends the parsing 
(COMPRESS-707).
                     return result;
                 }
-                throw new IllegalArgumentException(context + ": " + 
exceptionMessage(buffer, offset, length, start, currentByte));
+                throw new ArchiveException(context + ": " + 
exceptionMessage(buffer, offset, length, start, currentByte));
             }
             result = (result << 3) + (currentByte - '0'); // convert from ASCII
         }
@@ -602,11 +602,11 @@ static long parseOctal(final byte[] buffer, final int 
offset, final int length,
      * @param offset The offset into the buffer from which to parse.
      * @param length The maximum number of bytes to parse.
      * @return The long value of the octal or binary string.
-     * @throws IllegalArgumentException if the trailing space/NUL is missing 
or an invalid byte is detected in an octal number, or if a binary number would
+     * @throws ArchiveException if the trailing space/NUL is missing or an 
invalid byte is detected in an octal number, or if a binary number would
      *                                  exceed the size of a signed long 
64-bit integer.
      * @since 1.4
      */
-    public static long parseOctalOrBinary(final byte[] buffer, final int 
offset, final int length) {
+    public static long parseOctalOrBinary(final byte[] buffer, final int 
offset, final int length) throws ArchiveException {
         if ((buffer[offset] & 0x80) == 0) {
             return parseOctal(buffer, offset, length, "parseOctalOrBinary()", 
false);
         }
@@ -886,11 +886,12 @@ static List<TarArchiveStructSparse> 
readSparseStructs(final byte[] buffer, final
      *
      * @param header tar header.
      * @return whether the checksum is reasonably good.
+     * @throws ArchiveException Thrown on invalid input.
      * @see <a 
href="https://en.wikipedia.org/wiki/Tar_(computing)#File_header">TAR header</a>
      * @see <a 
href="https://issues.apache.org/jira/browse/COMPRESS-191";>COMPRESS-191</a>
      * @since 1.5
      */
-    public static boolean verifyCheckSum(final byte[] header) {
+    public static boolean verifyCheckSum(final byte[] header) throws 
ArchiveException {
         return verifyCheckSum(header, false);
     }
 
@@ -909,11 +910,12 @@ public static boolean verifyCheckSum(final byte[] header) 
{
      * @param header tar header.
      * @param lenient Whether to allow out-of-spec formatting.
      * @return whether the checksum is reasonably good.
+     * @throws ArchiveException Thrown on invalid input.
      * @see <a 
href="https://en.wikipedia.org/wiki/Tar_(computing)#File_header">TAR header</a>
      * @see <a 
href="https://issues.apache.org/jira/browse/COMPRESS-191";>COMPRESS-191</a>
      * @see <a 
href="https://issues.apache.org/jira/browse/COMPRESS-707";>COMPRESS-707</a>
      */
-    static boolean verifyCheckSum(final byte[] header, final boolean lenient) {
+    static boolean verifyCheckSum(final byte[] header, final boolean lenient) 
throws ArchiveException {
         final long storedSum = parseOctal(header, TarConstants.CHKSUM_OFFSET, 
TarConstants.CHKSUMLEN, "verifyCheckSum()", lenient);
         long unsignedSum = 0;
         long signedSum = 0;
diff --git a/src/test/java/org/apache/commons/compress/archivers/TarTest.java 
b/src/test/java/org/apache/commons/compress/archivers/TarTest.java
index f80b05f32..1d6861d87 100644
--- a/src/test/java/org/apache/commons/compress/archivers/TarTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/TarTest.java
@@ -19,10 +19,10 @@
 package org.apache.commons.compress.archivers;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assert.assertNull;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -86,9 +86,8 @@ void testCOMPRESS178() throws Exception {
         final File input = getFile("COMPRESS-178-fail.tar");
         try (InputStream is = Files.newInputStream(input.toPath());
                 ArchiveInputStream<?> in = 
ArchiveStreamFactory.DEFAULT.createArchiveInputStream("tar", is)) {
-            final IOException e = assertThrows(ArchiveException.class, 
in::getNextEntry, "Expected IOException");
-            final Throwable t = e.getCause();
-            assertInstanceOf(IllegalArgumentException.class, t, "Expected 
cause = IllegalArgumentException");
+            final ArchiveException e = assertThrows(ArchiveException.class, 
in::getNextEntry, "Expected IOException");
+            assertNull(e.getCause());
         }
     }
 
@@ -303,13 +302,12 @@ void testTarFileCOMPRESS114() throws Exception {
     @Test
     void testTarFileCOMPRESS178() throws Exception {
         final File input = getFile("COMPRESS-178-fail.tar");
-        final IOException e = assertThrows(ArchiveException.class, () -> {
+        final ArchiveException e = assertThrows(ArchiveException.class, () -> {
             try (TarFile tarFile = TarFile.builder().setFile(input).get()) {
                 // Compared to the TarArchiveInputStream all entries are read 
when instantiating the tar file
             }
-        }, "Expected IOException");
-        final Throwable t = e.getCause();
-        assertInstanceOf(IllegalArgumentException.class, t, "Expected cause = 
IllegalArgumentException");
+        });
+        assertNull(e.getCause());
     }
 
     @Test
diff --git 
a/src/test/java/org/apache/commons/compress/archivers/tar/TarUtilsTest.java 
b/src/test/java/org/apache/commons/compress/archivers/tar/TarUtilsTest.java
index 351d0586b..326e406a0 100644
--- a/src/test/java/org/apache/commons/compress/archivers/tar/TarUtilsTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/tar/TarUtilsTest.java
@@ -278,7 +278,7 @@ void 
testParseFromPAX01SparseHeadersRejectsOddNumberOfEntries() throws Exception
     }
 
     @Test
-    void testParseOctal() {
+    void testParseOctal() throws ArchiveException {
         long value;
         byte[] buffer;
         final long MAX_OCTAL = 077777777777L; // Allowed 11 digits
@@ -305,7 +305,7 @@ void testParseOctal() {
     }
 
     @Test
-    void testParseOctalCompress330() {
+    void testParseOctalCompress330() throws ArchiveException {
         final long expected = 0100000;
         final byte[] buffer = { 32, 32, 32, 32, 32, 49, 48, 48, 48, 48, 48, 32 
};
         assertEquals(expected, TarUtils.parseOctalOrBinary(buffer, 0, 
buffer.length));
@@ -314,25 +314,25 @@ void testParseOctalCompress330() {
     @Test
     void testParseOctalEmbeddedSpace() {
         final byte[] buffer4 = " 0 07 ".getBytes(UTF_8); // Invalid - embedded 
space
-        assertThrows(IllegalArgumentException.class, () -> 
TarUtils.parseOctal(buffer4, 0, buffer4.length),
+        assertThrows(ArchiveException.class, () -> 
TarUtils.parseOctal(buffer4, 0, buffer4.length),
                 "Expected IllegalArgumentException - embedded space");
     }
 
     @Test
     void testParseOctalInvalid() {
         final byte[] buffer1 = ArrayUtils.EMPTY_BYTE_ARRAY;
-        assertThrows(IllegalArgumentException.class, () -> 
TarUtils.parseOctal(buffer1, 0, buffer1.length),
-                "Expected IllegalArgumentException - should be at least 2 
bytes long");
+        assertThrows(ArchiveException.class, () -> 
TarUtils.parseOctal(buffer1, 0, buffer1.length),
+                "Expected ArchiveException - should be at least 2 bytes long");
 
         final byte[] buffer2 = { 0 }; // 1-byte array
-        assertThrows(IllegalArgumentException.class, () -> 
TarUtils.parseOctal(buffer2, 0, buffer2.length),
-                "Expected IllegalArgumentException - should be at least 2 
bytes long");
+        assertThrows(ArchiveException.class, () -> 
TarUtils.parseOctal(buffer2, 0, buffer2.length),
+                "Expected ArchiveException - should be at least 2 bytes long");
 
         final byte[] buffer3 = "abcdef ".getBytes(UTF_8); // Invalid input
-        assertThrows(IllegalArgumentException.class, () -> 
TarUtils.parseOctal(buffer3, 0, buffer3.length), "Expected 
IllegalArgumentException");
+        assertThrows(ArchiveException.class, () -> 
TarUtils.parseOctal(buffer3, 0, buffer3.length), "Expected 
IllegalArgumentException");
 
         final byte[] buffer5 = " 0\00007 ".getBytes(UTF_8); // Invalid - 
embedded NUL
-        assertThrows(IllegalArgumentException.class, () -> 
TarUtils.parseOctal(buffer5, 0, buffer5.length), "Expected 
IllegalArgumentException - embedded NUL");
+        assertThrows(ArchiveException.class, () -> 
TarUtils.parseOctal(buffer5, 0, buffer5.length), "Expected 
IllegalArgumentException - embedded NUL");
     }
 
     @Test
@@ -502,14 +502,14 @@ void testReadLongNameThrowsOnTruncation(final long size) 
throws IOException {
     }
 
     @Test
-    void testReadNegativeBinary12Byte() {
+    void testReadNegativeBinary12Byte() throws ArchiveException {
         final byte[] b = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 
(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
                 (byte) 0xf1, (byte) 0xef, };
         assertEquals(-3601L, TarUtils.parseOctalOrBinary(b, 0, 12));
     }
 
     @Test
-    void testReadNegativeBinary8Byte() {
+    void testReadNegativeBinary8Byte() throws ArchiveException {
         final byte[] b = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 
(byte) 0xff, (byte) 0xff, (byte) 0xf1, (byte) 0xef, };
         assertEquals(-3601L, TarUtils.parseOctalOrBinary(b, 0, 8));
     }
@@ -707,7 +707,7 @@ void testTrailers() throws ArchiveException {
 
     // https://issues.apache.org/jira/browse/COMPRESS-191
     @Test
-    void testVerifyHeaderCheckSum() {
+    void testVerifyHeaderCheckSum() throws ArchiveException {
         final byte[] valid = { // from bla.tar
                 116, 101, 115, 116, 49, 46, 120, 109, 108, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -759,7 +759,7 @@ void testVerifyHeaderCheckSum() {
     }
 
     @Test
-    void testWriteNegativeBinary8Byte() {
+    void testWriteNegativeBinary8Byte() throws ArchiveException {
         final byte[] b = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 
(byte) 0xff, (byte) 0xff, (byte) 0xf1, (byte) 0xef, };
         assertEquals(-3601L, TarUtils.parseOctalOrBinary(b, 0, 8));
     }

Reply via email to