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/10/02 16:01:34 UTC

(commons-compress) 01/01: Use `IOUtils.checkIndexFromSize` for argument validation

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

pkarwasz pushed a commit to branch fix/read-argument-validation
in repository https://gitbox.apache.org/repos/asf/commons-compress.git

commit 57ebbedcd5498cacc45d9455ae35c2db6f3d6585
Author: Piotr P. Karwasz <pk...@apache.org>
AuthorDate: Thu Oct 2 18:01:04 2025 +0200

    Use `IOUtils.checkIndexFromSize` for argument validation
    
    This change replaces custom argument checks in all `InputStream` and `OutputStream` implementations with the common utility method `IOUtils.checkIndexFromSize`.
    This ensures consistent validation logic across the codebase.
    
    Some implementations are intentionally left unchanged: cases where the arguments are immediately delegated to methods such as `InputStream#read`, `OutputStream#write`, or `ByteBuffer#wrap`, which already perform equivalent checks internally.
---
 .../compress/archivers/ar/ArArchiveInputStream.java  |  6 +-----
 .../archivers/arj/ArjArchiveInputStream.java         |  1 +
 .../archivers/cpio/CpioArchiveInputStream.java       |  6 ++----
 .../archivers/cpio/CpioArchiveOutputStream.java      |  7 +++----
 .../archivers/dump/DumpArchiveInputStream.java       | 11 +++--------
 .../compress/archivers/dump/TapeInputStream.java     |  2 +-
 .../archivers/sevenz/AES256SHA256Decoder.java        |  2 ++
 .../BoundedSeekableByteChannelInputStream.java       | 11 +++++++++++
 .../compress/archivers/sevenz/SevenZOutputFile.java  |  2 ++
 .../archivers/tar/TarArchiveInputStream.java         |  1 +
 .../archivers/tar/TarArchiveOutputStream.java        |  2 ++
 .../tar/TarArchiveSparseZeroInputStream.java         | 14 ++++++++++++++
 .../archivers/zip/ZipArchiveInputStream.java         |  1 +
 .../archivers/zip/ZipArchiveOutputStream.java        |  2 ++
 .../compress/archivers/zip/ZipSplitOutputStream.java |  2 ++
 .../bzip2/BZip2CompressorInputStream.java            | 20 ++++----------------
 .../bzip2/BZip2CompressorOutputStream.java           | 11 ++---------
 .../deflate/DeflateCompressorInputStream.java        |  4 ----
 .../deflate64/Deflate64CompressorInputStream.java    |  4 +---
 .../compressors/gzip/GzipCompressorInputStream.java  |  1 +
 .../compressors/gzip/GzipCompressorOutputStream.java |  2 ++
 .../lz4/BlockLZ4CompressorInputStream.java           |  5 ++---
 .../lz4/FramedLZ4CompressorInputStream.java          |  2 +-
 .../lz4/FramedLZ4CompressorOutputStream.java         |  2 ++
 .../compressors/lz77support/LZ77Compressor.java      |  4 ++++
 .../compress/compressors/lzw/LZWInputStream.java     |  2 ++
 .../snappy/FramedSnappyCompressorInputStream.java    |  2 +-
 .../snappy/FramedSnappyCompressorOutputStream.java   |  2 ++
 .../snappy/SnappyCompressorInputStream.java          |  5 ++---
 .../compressors/xz/XZCompressorInputStream.java      |  3 ---
 .../zstandard/ZstdCompressorInputStream.java         |  3 ---
 .../compress/utils/BoundedArchiveInputStream.java    |  6 ++++++
 .../compress/utils/FixedLengthBlockOutputStream.java |  1 +
 33 files changed, 81 insertions(+), 68 deletions(-)

diff --git a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
index 9423d8a64..a109a5388 100644
--- a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
@@ -435,13 +435,9 @@ private ArArchiveEntry parseEntry(final byte[] headerBuf) throws IOException {
         }
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see InputStream#read(byte[], int, int)
-     */
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        org.apache.commons.io.IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/arj/ArjArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/arj/ArjArchiveInputStream.java
index 44aca3759..de81ffbed 100644
--- a/src/main/java/org/apache/commons/compress/archivers/arj/ArjArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/arj/ArjArchiveInputStream.java
@@ -211,6 +211,7 @@ public ArjArchiveEntry getNextEntry() throws IOException {
 
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        org.apache.commons.io.IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
index d99695407..1bb7d5f96 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
@@ -375,13 +375,11 @@ public CpioArchiveEntry getNextEntry() throws IOException {
      */
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
-        checkOpen();
-        if (off < 0 || len < 0 || off > b.length - len) {
-            throw new IndexOutOfBoundsException();
-        }
+        org.apache.commons.io.IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
+        checkOpen();
         if (entry == null || entryEOF) {
             return -1;
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
index e0e7d2361..447786f7d 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java
@@ -31,6 +31,7 @@
 import org.apache.commons.compress.archivers.ArchiveOutputStream;
 import org.apache.commons.compress.archivers.zip.ZipEncoding;
 import org.apache.commons.compress.archivers.zip.ZipEncodingHelper;
+import org.apache.commons.io.IOUtils;
 
 /**
  * CpioArchiveOutputStream is a stream for writing CPIO streams. All formats of CPIO are supported (old ASCII, old binary, new portable format and the new
@@ -317,13 +318,11 @@ public void putArchiveEntry(final CpioArchiveEntry entry) throws IOException {
      */
     @Override
     public void write(final byte[] b, final int off, final int len) throws IOException {
-        checkOpen();
-        if (off < 0 || len < 0 || off > b.length - len) {
-            throw new IndexOutOfBoundsException();
-        }
+        IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return;
         }
+        checkOpen();
         if (this.entry == null) {
             throw new ArchiveException("No current CPIO entry");
         }
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 be4aba459..38b9ba846 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
@@ -390,18 +390,13 @@ public DumpArchiveSummary getSummary() {
     }
 
     /**
-     * Reads bytes from the current dump archive entry.
+     * {@inheritDoc}
      *
-     * This method is aware of the boundaries of the current entry in the archive and will deal with them as if they were this stream's start and EOF.
-     *
-     * @param buf The buffer into which to place bytes read.
-     * @param off The offset at which to place bytes read.
-     * @param len The number of bytes to read.
-     * @return The number of bytes read, or -1 at EOF.
-     * @throws IOException on error
+     * <p>This method is aware of the boundaries of the current entry in the archive and will deal with them as if they were this stream's start and EOF.</p>
      */
     @Override
     public int read(final byte[] buf, int off, int len) throws IOException {
+        org.apache.commons.io.IOUtils.checkFromIndexSize(buf, off, len);
         if (len == 0) {
             return 0;
         }
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 3aeb8e8a5..48ed69d59 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
@@ -127,10 +127,10 @@ public int read() throws IOException {
      * </p>
      *
      * @param len length to read, must be a multiple of the stream's record size.
-     * @throws IOException Thrown if an I/O error occurs.
      */
     @Override
     public int read(final byte[] b, int off, final int len) throws IOException {
+        org.apache.commons.io.IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java
index 14a233157..8618577a0 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java
@@ -37,6 +37,7 @@
 
 import org.apache.commons.compress.PasswordRequiredException;
 import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.io.IOUtils;
 
 final class AES256SHA256Decoder extends AbstractCoder {
 
@@ -169,6 +170,7 @@ private void flushBuffer() throws IOException {
 
         @Override
         public void write(final byte[] b, final int off, final int len) throws IOException {
+            IOUtils.checkFromIndexSize(b, off, len);
             int gap = len + count > cipherBlockSize ? cipherBlockSize - count : len;
             System.arraycopy(b, off, cipherBlockBuffer, count, gap);
             count += gap;
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/BoundedSeekableByteChannelInputStream.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/BoundedSeekableByteChannelInputStream.java
index 083364c41..14076c784 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/BoundedSeekableByteChannelInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/BoundedSeekableByteChannelInputStream.java
@@ -23,6 +23,8 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.SeekableByteChannel;
 
+import org.apache.commons.io.IOUtils;
+
 final class BoundedSeekableByteChannelInputStream extends InputStream {
     private static final int MAX_BUF_LEN = 8192;
     private final ByteBuffer buffer;
@@ -63,9 +65,18 @@ public int read() throws IOException {
      * <p>
      * This implementation may return 0 if the underlying {@link SeekableByteChannel} is non-blocking and currently hasn't got any bytes available.
      * </p>
+     *
+     * @param b   the buffer into which the data is read.
+     * @param off the start offset in array b at which the data is written.
+     * @param len the maximum number of bytes to read.
+     * @return the total number of bytes read into the buffer, or -1 if EOF is reached.
+     * @throws NullPointerException      if b is null.
+     * @throws IndexOutOfBoundsException if {@code off} or {@code len} are negative, or if {@code off + len} is greater than {@code b.length}.
+     * @throws IOException               if an I/O error occurs.
      */
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFile.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFile.java
index 5a35824c1..5db75811c 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFile.java
@@ -55,6 +55,7 @@
 
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.file.attribute.FileTimes;
 import org.apache.commons.io.output.CountingOutputStream;
 
@@ -87,6 +88,7 @@ public void write(final byte[] b) throws IOException {
 
         @Override
         public void write(final byte[] b, final int off, final int len) throws IOException {
+            IOUtils.checkFromIndexSize(b, off, len);
             if (len > BUF_SIZE) {
                 channel.write(ByteBuffer.wrap(b, off, len));
             } else {
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java
index 80dd6859f..517bb52d5 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java
@@ -638,6 +638,7 @@ public boolean markSupported() {
      */
     @Override
     public int read(final byte[] buf, final int offset, int numToRead) throws IOException {
+        org.apache.commons.io.IOUtils.checkFromIndexSize(buf, offset, numToRead);
         if (numToRead == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
index 4ab04832a..d9d4849b5 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java
@@ -39,6 +39,7 @@
 import org.apache.commons.compress.archivers.zip.ZipEncodingHelper;
 import org.apache.commons.compress.utils.FixedLengthBlockOutputStream;
 import org.apache.commons.io.Charsets;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.file.attribute.FileTimes;
 import org.apache.commons.io.output.CountingOutputStream;
 import org.apache.commons.lang3.ArrayFill;
@@ -631,6 +632,7 @@ private void transferModTime(final TarArchiveEntry from, final TarArchiveEntry t
      */
     @Override
     public void write(final byte[] wBuf, final int wOffset, final int numToWrite) throws IOException {
+        IOUtils.checkFromIndexSize(wBuf, wOffset, numToWrite);
         if (!haveUnclosedEntry) {
             throw new IllegalStateException("No current tar entry");
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseZeroInputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseZeroInputStream.java
index 513ed0722..263619a2a 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseZeroInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveSparseZeroInputStream.java
@@ -18,7 +18,11 @@
  */
 package org.apache.commons.compress.archivers.tar;
 
+import java.io.IOException;
 import java.io.InputStream;
+import java.util.Arrays;
+
+import org.apache.commons.io.IOUtils;
 
 /**
  * This is an InputStream that always return 0, this is used when reading the "holes" of a sparse file
@@ -35,6 +39,16 @@ public int read() {
         return 0;
     }
 
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
+        if (len == 0) {
+            return 0;
+        }
+        Arrays.fill(b, off, off + len, (byte) 0);
+        return len;
+    }
+
     /**
      * Returns the input.
      *
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
index d02e62568..1ea753abf 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
@@ -1033,6 +1033,7 @@ private void pushback(final byte[] buf, final int offset, final int length) thro
 
     @Override
     public int read(final byte[] buffer, final int offset, final int length) throws IOException {
+        org.apache.commons.io.IOUtils.checkFromIndexSize(buffer, offset, length);
         if (length == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
index 07d3492c5..309e7eead 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
@@ -41,6 +41,7 @@
 import org.apache.commons.compress.archivers.ArchiveException;
 import org.apache.commons.compress.archivers.ArchiveOutputStream;
 import org.apache.commons.io.Charsets;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.ArrayUtils;
 
 /**
@@ -1572,6 +1573,7 @@ private int versionNeededToExtractMethod(final int zipMethod) {
      */
     @Override
     public void write(final byte[] b, final int offset, final int length) throws IOException {
+        IOUtils.checkFromIndexSize(b, offset, length);
         if (entry == null) {
             throw new IllegalStateException("No current entry");
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipSplitOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipSplitOutputStream.java
index accc0b8a0..59bae8ff6 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipSplitOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipSplitOutputStream.java
@@ -33,6 +33,7 @@
 import java.util.TreeMap;
 
 import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.file.PathUtils;
 
 /**
@@ -256,6 +257,7 @@ public void write(final byte[] b) throws IOException {
      */
     @Override
     public void write(final byte[] b, final int off, final int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
         if (len <= 0) {
             return;
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java
index 40110dbdb..2f3784bc5 100644
--- a/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java
@@ -33,6 +33,7 @@
 import org.apache.commons.compress.compressors.CompressorInputStream;
 import org.apache.commons.compress.utils.BitInputStream;
 import org.apache.commons.compress.utils.InputStreamStatistics;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.input.CloseShieldInputStream;
 
 /**
@@ -712,28 +713,15 @@ public int read() throws IOException {
         throw new CompressorException("Stream closed");
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see InputStream#read(byte[], int, int)
-     */
     @Override
     public int read(final byte[] dest, final int offs, final int len) throws IOException {
-        if (offs < 0) {
-            throw new IndexOutOfBoundsException("offs(" + offs + ") < 0.");
-        }
-        if (len < 0) {
-            throw new IndexOutOfBoundsException("len(" + len + ") < 0.");
-        }
-        if (offs + len > dest.length) {
-            throw new IndexOutOfBoundsException("offs(" + offs + ") + len(" + len + ") > dest.length(" + dest.length + ").");
+        IOUtils.checkFromIndexSize(dest, offs, len);
+        if (len == 0) {
+            return 0;
         }
         if (this.bin == null) {
             throw new CompressorException("Stream closed");
         }
-        if (len == 0) {
-            return 0;
-        }
 
         final int hi = offs + len;
         int destOffs = offs;
diff --git a/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java b/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java
index d3a9fd908..fb48afbb5 100644
--- a/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.java
@@ -23,6 +23,7 @@
 import java.util.Arrays;
 
 import org.apache.commons.compress.compressors.CompressorOutputStream;
+import org.apache.commons.io.IOUtils;
 
 /**
  * An output stream that compresses into the BZip2 format into another stream.
@@ -1149,15 +1150,7 @@ private void sendMTFValues7() throws IOException {
 
     @Override
     public void write(final byte[] buf, int offs, final int len) throws IOException {
-        if (offs < 0) {
-            throw new IndexOutOfBoundsException("offs(" + offs + ") < 0.");
-        }
-        if (len < 0) {
-            throw new IndexOutOfBoundsException("len(" + len + ") < 0.");
-        }
-        if (offs + len > buf.length) {
-            throw new IndexOutOfBoundsException("offs(" + offs + ") + len(" + len + ") > buf.length(" + buf.length + ").");
-        }
+        IOUtils.checkFromIndexSize(buf, offs, len);
         checkOpen();
         for (final int hi = offs + len; offs < hi;) {
             write0(buf[offs++]);
diff --git a/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateCompressorInputStream.java
index 9a0974da9..274c8ef44 100644
--- a/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateCompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateCompressorInputStream.java
@@ -110,12 +110,8 @@ public int read() throws IOException {
         return ret;
     }
 
-    /** {@inheritDoc} */
     @Override
     public int read(final byte[] buf, final int off, final int len) throws IOException {
-        if (len == 0) {
-            return 0;
-        }
         final int ret = in.read(buf, off, len);
         count(ret);
         return ret;
diff --git a/src/main/java/org/apache/commons/compress/compressors/deflate64/Deflate64CompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/deflate64/Deflate64CompressorInputStream.java
index 0b5623b79..d0f35c515 100644
--- a/src/main/java/org/apache/commons/compress/compressors/deflate64/Deflate64CompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/deflate64/Deflate64CompressorInputStream.java
@@ -102,11 +102,9 @@ public int read() throws IOException {
         }
     }
 
-    /**
-     * @throws java.io.EOFException if the underlying stream is exhausted before the end of deflated data was reached.
-     */
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java
index 916f76720..681d79616 100644
--- a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorInputStream.java
@@ -445,6 +445,7 @@ public int read() throws IOException {
      */
     @Override
     public int read(final byte[] b, int off, int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorOutputStream.java b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorOutputStream.java
index a62cee244..e36b4cb70 100644
--- a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipCompressorOutputStream.java
@@ -29,6 +29,7 @@
 
 import org.apache.commons.compress.compressors.CompressorException;
 import org.apache.commons.compress.compressors.CompressorOutputStream;
+import org.apache.commons.io.IOUtils;
 
 /**
  * Compressed output stream using the gzip format. This implementation improves over the standard {@link GZIPOutputStream} class by allowing the configuration
@@ -127,6 +128,7 @@ public void write(final byte[] buffer) throws IOException {
      */
     @Override
     public void write(final byte[] buffer, final int offset, final int length) throws IOException {
+        IOUtils.checkFromIndexSize(buffer, offset, length);
         checkOpen();
         if (deflater.finished()) {
             throw new CompressorException("Cannot write more data, the end of the compressed data stream has been reached.");
diff --git a/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorInputStream.java
index cb8d13364..5dffa27cc 100644
--- a/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/lz4/BlockLZ4CompressorInputStream.java
@@ -24,6 +24,7 @@
 import org.apache.commons.compress.compressors.CompressorException;
 import org.apache.commons.compress.compressors.lz77support.AbstractLZ77CompressorInputStream;
 import org.apache.commons.compress.utils.ByteUtils;
+import org.apache.commons.io.IOUtils;
 
 /**
  * CompressorInputStream for the LZ4 block format.
@@ -89,11 +90,9 @@ private boolean initializeBackReference() throws IOException {
         return true;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/lz4/FramedLZ4CompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/lz4/FramedLZ4CompressorInputStream.java
index 9128e534e..243fc5d2e 100644
--- a/src/main/java/org/apache/commons/compress/compressors/lz4/FramedLZ4CompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/lz4/FramedLZ4CompressorInputStream.java
@@ -235,9 +235,9 @@ public int read() throws IOException {
         return read(oneByte, 0, 1) == -1 ? -1 : oneByte[0] & 0xFF;
     }
 
-    /** {@inheritDoc} */
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        org.apache.commons.io.IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/lz4/FramedLZ4CompressorOutputStream.java b/src/main/java/org/apache/commons/compress/compressors/lz4/FramedLZ4CompressorOutputStream.java
index d53088dde..f9f2c5b7a 100644
--- a/src/main/java/org/apache/commons/compress/compressors/lz4/FramedLZ4CompressorOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/lz4/FramedLZ4CompressorOutputStream.java
@@ -24,6 +24,7 @@
 
 import org.apache.commons.compress.compressors.CompressorOutputStream;
 import org.apache.commons.compress.utils.ByteUtils;
+import org.apache.commons.io.IOUtils;
 
 /**
  * CompressorOutputStream for the LZ4 frame format.
@@ -271,6 +272,7 @@ private void flushBlock() throws IOException {
 
     @Override
     public void write(final byte[] data, int off, int len) throws IOException {
+        IOUtils.checkFromIndexSize(data, off, len);
         if (params.withContentChecksum) {
             contentHash.update(data, off, len);
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/lz77support/LZ77Compressor.java b/src/main/java/org/apache/commons/compress/compressors/lz77support/LZ77Compressor.java
index 9105187ac..07e197664 100644
--- a/src/main/java/org/apache/commons/compress/compressors/lz77support/LZ77Compressor.java
+++ b/src/main/java/org/apache/commons/compress/compressors/lz77support/LZ77Compressor.java
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.util.Objects;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.ArrayFill;
 
 /**
@@ -414,9 +415,12 @@ public void compress(final byte[] data) throws IOException {
      * @param data the data to compress - must not be null
      * @param off  the start offset of the data
      * @param len  the number of bytes to compress
+     * @throws NullPointerException if data is {@code null}
+     * @throws IndexOutOfBoundsException if {@code off} or {@code len} are negative, or if {@code off + len} is bigger than {@code data.length}.
      * @throws IOException if the callback throws an exception
      */
     public void compress(final byte[] data, int off, int len) throws IOException {
+        IOUtils.checkFromIndexSize(data, off, len);
         final int wSize = params.getWindowSize();
         while (len > wSize) { // chop into windowSize sized chunks
             doCompress(data, off, wSize);
diff --git a/src/main/java/org/apache/commons/compress/compressors/lzw/LZWInputStream.java b/src/main/java/org/apache/commons/compress/compressors/lzw/LZWInputStream.java
index 2015b96de..54bd88411 100644
--- a/src/main/java/org/apache/commons/compress/compressors/lzw/LZWInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/lzw/LZWInputStream.java
@@ -27,6 +27,7 @@
 import org.apache.commons.compress.compressors.CompressorInputStream;
 import org.apache.commons.compress.utils.BitInputStream;
 import org.apache.commons.compress.utils.InputStreamStatistics;
+import org.apache.commons.io.IOUtils;
 
 /**
  * <p>
@@ -276,6 +277,7 @@ public int read() throws IOException {
 
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/snappy/FramedSnappyCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/snappy/FramedSnappyCompressorInputStream.java
index f83f5251e..733be9582 100644
--- a/src/main/java/org/apache/commons/compress/compressors/snappy/FramedSnappyCompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/snappy/FramedSnappyCompressorInputStream.java
@@ -198,9 +198,9 @@ public int read() throws IOException {
         return read(oneByte, 0, 1) == -1 ? -1 : oneByte[0] & 0xFF;
     }
 
-    /** {@inheritDoc} */
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        org.apache.commons.io.IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/snappy/FramedSnappyCompressorOutputStream.java b/src/main/java/org/apache/commons/compress/compressors/snappy/FramedSnappyCompressorOutputStream.java
index ce3be3c3c..b5e733b7e 100644
--- a/src/main/java/org/apache/commons/compress/compressors/snappy/FramedSnappyCompressorOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/snappy/FramedSnappyCompressorOutputStream.java
@@ -26,6 +26,7 @@
 import org.apache.commons.compress.compressors.CompressorOutputStream;
 import org.apache.commons.compress.compressors.lz77support.Parameters;
 import org.apache.commons.compress.utils.ByteUtils;
+import org.apache.commons.io.IOUtils;
 
 /**
  * CompressorOutputStream for the framing Snappy format.
@@ -125,6 +126,7 @@ private void flushBuffer() throws IOException {
 
     @Override
     public void write(final byte[] data, int off, int len) throws IOException {
+        IOUtils.checkFromIndexSize(data, off, len);
         int blockDataRemaining = buffer.length - currentIndex;
         while (len > 0) {
             final int copyLen = Math.min(len, blockDataRemaining);
diff --git a/src/main/java/org/apache/commons/compress/compressors/snappy/SnappyCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/snappy/SnappyCompressorInputStream.java
index 037903314..ec9b31fbc 100644
--- a/src/main/java/org/apache/commons/compress/compressors/snappy/SnappyCompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/snappy/SnappyCompressorInputStream.java
@@ -24,6 +24,7 @@
 import org.apache.commons.compress.compressors.CompressorException;
 import org.apache.commons.compress.compressors.lz77support.AbstractLZ77CompressorInputStream;
 import org.apache.commons.compress.utils.ByteUtils;
+import org.apache.commons.io.IOUtils;
 
 /**
  * CompressorInputStream for the raw Snappy format.
@@ -192,11 +193,9 @@ public long getUncompressedSize() {
         return uncompressedSize;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
         if (len == 0) {
             return 0;
         }
diff --git a/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java
index 9f8e2356e..bc97d0f2d 100644
--- a/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/xz/XZCompressorInputStream.java
@@ -240,9 +240,6 @@ public int read() throws IOException {
 
     @Override
     public int read(final byte[] buf, final int off, final int len) throws IOException {
-        if (len == 0) {
-            return 0;
-        }
         try {
             final int ret = in.read(buf, off, len);
             count(ret);
diff --git a/src/main/java/org/apache/commons/compress/compressors/zstandard/ZstdCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/zstandard/ZstdCompressorInputStream.java
index 8b2187389..32b934568 100644
--- a/src/main/java/org/apache/commons/compress/compressors/zstandard/ZstdCompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/zstandard/ZstdCompressorInputStream.java
@@ -113,9 +113,6 @@ public int read(final byte[] b) throws IOException {
 
     @Override
     public int read(final byte[] buf, final int off, final int len) throws IOException {
-        if (len == 0) {
-            return 0;
-        }
         final int ret = decIS.read(buf, off, len);
         count(ret);
         return ret;
diff --git a/src/main/java/org/apache/commons/compress/utils/BoundedArchiveInputStream.java b/src/main/java/org/apache/commons/compress/utils/BoundedArchiveInputStream.java
index 2808964d9..c66b24a1c 100644
--- a/src/main/java/org/apache/commons/compress/utils/BoundedArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/utils/BoundedArchiveInputStream.java
@@ -22,6 +22,8 @@
 import java.io.InputStream;
 import java.nio.ByteBuffer;
 
+import org.apache.commons.io.IOUtils;
+
 /**
  * NIO backed bounded input stream for reading a predefined amount of data.
  *
@@ -69,6 +71,10 @@ public synchronized int read() throws IOException {
 
     @Override
     public synchronized int read(final byte[] b, final int off, final int len) throws IOException {
+        IOUtils.checkFromIndexSize(b, off, len);
+        if (len == 0) {
+            return 0;
+        }
         if (loc >= end) {
             return -1;
         }
diff --git a/src/main/java/org/apache/commons/compress/utils/FixedLengthBlockOutputStream.java b/src/main/java/org/apache/commons/compress/utils/FixedLengthBlockOutputStream.java
index 805b61413..ce7d341d1 100644
--- a/src/main/java/org/apache/commons/compress/utils/FixedLengthBlockOutputStream.java
+++ b/src/main/java/org/apache/commons/compress/utils/FixedLengthBlockOutputStream.java
@@ -201,6 +201,7 @@ private void padBlock() {
 
     @Override
     public void write(final byte[] b, final int offset, final int length) throws IOException {
+        IOUtils.checkFromIndexSize(b, offset, length);
         if (!isOpen()) {
             throw new ClosedChannelException();
         }