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-compress.git


The following commit(s) were added to refs/heads/master by this push:
     new 8a9a5847c COMPRESS-632: Fixes for dump file parsing (#442)
8a9a5847c is described below

commit 8a9a5847c04ae39a1d45b365f8bb82022466067d
Author: Yakov Shafranovich <yako...@amazon.com>
AuthorDate: Tue Nov 28 07:49:07 2023 -0500

    COMPRESS-632: Fixes for dump file parsing (#442)
    
    * Added check for negative blocksize
    
    * more dump tests
    
    * removing unused imports
    
    * fixing checkstyle violations
    
    * moved null check to DumpArchiveUtil
    
    * Trim whitespace
    
    * Format and normalize tests declarations
    
    * fix exception message to match unit test
    
    ---------
    
    Co-authored-by: Gary Gregory <garydgreg...@users.noreply.github.com>
---
 .../archivers/dump/DumpArchiveConstants.java       |   4 +--
 .../compress/archivers/dump/DumpArchiveUtil.java   |  13 ++++-----
 .../compress/archivers/dump/TapeInputStream.java   |   3 +++
 .../archivers/dump/DumpArchiveInputStreamTest.java |  16 ++++++++++++
 .../archivers/dump/DumpArchiveUtilTest.java        |  21 +++++++++++++++
 ...chiveUtilTest.java => TapeInputStreamTest.java} |  29 +++++++++------------
 .../compress/dump/directory_null_bytes.dump        | Bin 0 -> 78903 bytes
 .../compress/dump/invalid_compression_type.dump    | Bin 0 -> 11904 bytes
 8 files changed, 62 insertions(+), 24 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveConstants.java
 
b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveConstants.java
index 47d9d34cc..6c266d43a 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveConstants.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveConstants.java
@@ -26,7 +26,7 @@ public final class DumpArchiveConstants {
      * The type of compression.
      */
     public enum COMPRESSION_TYPE {
-        ZLIB(0), BZLIB(1), LZO(2);
+        UNKNOWN(-1), ZLIB(0), BZLIB(1), LZO(2);
 
         public static COMPRESSION_TYPE find(final int code) {
             for (final COMPRESSION_TYPE t : values()) {
@@ -35,7 +35,7 @@ public final class DumpArchiveConstants {
                 }
             }
 
-            return null;
+            return UNKNOWN;
         }
 
         final int code;
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtil.java 
b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtil.java
index 223039dff..ec26377f8 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtil.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtil.java
@@ -37,11 +37,9 @@ final class DumpArchiveUtil {
      */
     public static int calculateChecksum(final byte[] buffer) {
         int calc = 0;
-
         for (int i = 0; i < 256; i++) {
             calc += DumpArchiveUtil.convert32(buffer, 4 * i);
         }
-
         return DumpArchiveConstants.CHECKSUM - (calc - 
DumpArchiveUtil.convert32(buffer, 28));
     }
 
@@ -82,7 +80,10 @@ final class DumpArchiveUtil {
      * Decodes a byte array to a string.
      */
     static String decode(final ZipEncoding encoding, final byte[] b, final int 
offset, final int len) throws IOException {
-        return encoding.decode(Arrays.copyOfRange(b, offset, offset + len));
+            if (offset > offset + len) {
+                throw new IOException("Invalid offset/length combination");
+            }
+            return encoding.decode(Arrays.copyOfRange(b, offset, offset + 
len));
     }
 
     /**
@@ -102,16 +103,16 @@ final class DumpArchiveUtil {
      * @return Whether the buffer contains a tape segment header.
      */
     public static boolean verify(final byte[] buffer) {
+        if (buffer == null) {
+            return false;
+        }
         // verify magic. for now only accept NFS_MAGIC.
         final int magic = convert32(buffer, 24);
-
         if (magic != DumpArchiveConstants.NFS_MAGIC) {
             return false;
         }
-
         // verify checksum...
         final int checksum = convert32(buffer, 28);
-
         return checksum == calculateChecksum(buffer);
     }
 
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/dump/TapeInputStream.java 
b/src/main/java/org/apache/commons/compress/archivers/dump/TapeInputStream.java
index 46d1cc6ff..27c8a89cf 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/dump/TapeInputStream.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/dump/TapeInputStream.java
@@ -294,6 +294,9 @@ final class TapeInputStream extends FilterInputStream {
             throw new IOException("Block with " + recsPerBlock + " records 
found, must be at least 1");
         }
         blockSize = RECORD_SIZE * recsPerBlock;
+        if (blockSize < 1) {
+            throw new IOException("Block size cannot be less than or equal to 
0: " + blockSize);
+        }
 
         // save first block in case we need it again
         final byte[] oldBuffer = blockBuffer;
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 bb6e41d8b..4b4c2396a 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
@@ -87,4 +87,20 @@ public class DumpArchiveInputStreamTest extends AbstractTest 
{
         }
     }
 
+    @Test
+    public void testDirectoryNullBytes() throws Exception {
+        try (InputStream is = 
newInputStream("org/apache/commons/compress/dump/directory_null_bytes.dump");
+             DumpArchiveInputStream archive = new DumpArchiveInputStream(is)) {
+            assertThrows(InvalidFormatException.class, archive::getNextEntry);
+        }
+    }
+
+    @Test
+    public void testInvalidCompressType() throws Exception {
+        try (InputStream is = 
newInputStream("org/apache/commons/compress/dump/invalid_compression_type.dump"))
 {
+            final ArchiveException ex = assertThrows(ArchiveException.class, 
() -> new DumpArchiveInputStream(is).close());
+            assertInstanceOf(UnsupportedCompressionAlgorithmException.class, 
ex.getCause());
+        }
+    }
+
 }
diff --git 
a/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtilTest.java
 
b/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtilTest.java
index 7559a535d..ae829059d 100644
--- 
a/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtilTest.java
+++ 
b/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtilTest.java
@@ -18,7 +18,11 @@
  */
 package org.apache.commons.compress.archivers.dump;
 
+import static org.junit.Assert.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.io.IOException;
 
 import org.junit.jupiter.api.Test;
 
@@ -38,4 +42,21 @@ public class DumpArchiveUtilTest {
     public void testConvert64() {
         assertEquals(0xABCDEF0123456780L, DumpArchiveUtil.convert64(new byte[] 
{ (byte) 0x80, 0x67, 0x45, 0x23, 1, (byte) 0xEF, (byte) 0xCD, (byte) 0xAB }, 
0));
     }
+
+    @Test
+    public void testDecodeInvalidArguments() {
+        assertThrows(IOException.class, () -> DumpArchiveUtil.decode(null, new 
byte[10], 10, -1));
+    }
+
+    @Test
+    public void testVerifyNullArgument() {
+        assertFalse(DumpArchiveUtil.verify(null));
+    }
+
+    @Test
+    public void testVerifyNoMagic() {
+        assertFalse(DumpArchiveUtil.verify(new byte[32]));
+    }
+
 }
+
diff --git 
a/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtilTest.java
 
b/src/test/java/org/apache/commons/compress/archivers/dump/TapeInputStreamTest.java
similarity index 53%
copy from 
src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtilTest.java
copy to 
src/test/java/org/apache/commons/compress/archivers/dump/TapeInputStreamTest.java
index 7559a535d..775bb66bc 100644
--- 
a/src/test/java/org/apache/commons/compress/archivers/dump/DumpArchiveUtilTest.java
+++ 
b/src/test/java/org/apache/commons/compress/archivers/dump/TapeInputStreamTest.java
@@ -18,24 +18,21 @@
  */
 package org.apache.commons.compress.archivers.dump;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
-import org.junit.jupiter.api.Test;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
 
-public class DumpArchiveUtilTest {
+import org.apache.commons.compress.AbstractTest;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
-    @Test
-    public void testConvert16() {
-        assertEquals(0xABCD, DumpArchiveUtil.convert16(new byte[] { (byte) 
0xCD, (byte) 0xAB }, 0));
-    }
-
-    @Test
-    public void testConvert32() {
-        assertEquals(0xABCDEF01, DumpArchiveUtil.convert32(new byte[] { 1, 
(byte) 0xEF, (byte) 0xCD, (byte) 0xAB }, 0));
-    }
-
-    @Test
-    public void testConvert64() {
-        assertEquals(0xABCDEF0123456780L, DumpArchiveUtil.convert64(new byte[] 
{ (byte) 0x80, 0x67, 0x45, 0x23, 1, (byte) 0xEF, (byte) 0xCD, (byte) 0xAB }, 
0));
+public class TapeInputStreamTest extends AbstractTest {
+    @ParameterizedTest
+    @ValueSource(ints = {-1, 0, Integer.MAX_VALUE / 1000, Integer.MAX_VALUE})
+    public void testResetBlockSizeWithInvalidValues(final int recsPerBlock) 
throws Exception {
+        try (TapeInputStream tapeInputStream = new TapeInputStream(new 
ByteArrayInputStream(new byte[1]))) {
+            assertThrows(IOException.class, () -> 
tapeInputStream.resetBlockSize(recsPerBlock, true));
+        }
     }
 }
diff --git 
a/src/test/resources/org/apache/commons/compress/dump/directory_null_bytes.dump 
b/src/test/resources/org/apache/commons/compress/dump/directory_null_bytes.dump
new file mode 100644
index 000000000..66f62049f
Binary files /dev/null and 
b/src/test/resources/org/apache/commons/compress/dump/directory_null_bytes.dump 
differ
diff --git 
a/src/test/resources/org/apache/commons/compress/dump/invalid_compression_type.dump
 
b/src/test/resources/org/apache/commons/compress/dump/invalid_compression_type.dump
new file mode 100644
index 000000000..77b5ebfe2
Binary files /dev/null and 
b/src/test/resources/org/apache/commons/compress/dump/invalid_compression_type.dump
 differ

Reply via email to