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 530420923 Throw CompressorException when all code lengths are zero 
(#806)
530420923 is described below

commit 530420923d1c3d616ba0dc93f37ae40d6705e43a
Author: Fredrik Kjellberg <[email protected]>
AuthorDate: Sun Aug 23 20:47:54 2026 +0200

    Throw CompressorException when all code lengths are zero (#806)
---
 .../apache/commons/compress/huffman/HuffmanDecoder.java  |  15 +++++++++------
 .../bzip2/BZip2CompressorInputStreamTest.java            |   7 +++++++
 .../commons/compress/huffman/HuffmanDecoderTest.java     |  15 +++++++--------
 src/test/resources/empty.txt.bz2                         | Bin 0 -> 14 bytes
 4 files changed, 23 insertions(+), 14 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/compress/huffman/HuffmanDecoder.java 
b/src/main/java/org/apache/commons/compress/huffman/HuffmanDecoder.java
index 3f444e88e..a4ac52012 100644
--- a/src/main/java/org/apache/commons/compress/huffman/HuffmanDecoder.java
+++ b/src/main/java/org/apache/commons/compress/huffman/HuffmanDecoder.java
@@ -160,8 +160,8 @@ private static int readBitsFully(final BitInputStream in, 
final int numBits) thr
      *
      * @param codeLengths code length per symbol; {@code 0} means the symbol 
is not used; not {@code null}.
      * @throws NullPointerException     if {@code codeLengths} is {@code null}.
-     * @throws CompressorException      if {@code codeLengths} size is out of 
range or if any code length is out of range or if the code lengths violate
-     *                                  Kraft's inequality.
+     * @throws CompressorException      if {@code codeLengths} size is out of 
range, if any code length is out of range, if all code lengths are zero,
+     *                                  or if the code lengths violate Kraft's 
inequality.
      */
     public HuffmanDecoder(final int[] codeLengths) throws CompressorException {
         this(codeLengths, 0, MAX_SUPPORTED_CODE_LENGTH);
@@ -180,8 +180,8 @@ public HuffmanDecoder(final int[] codeLengths) throws 
CompressorException {
      * @throws NullPointerException     if {@code codeLengths} is {@code null}.
      * @throws IllegalArgumentException if {@code maxCodeLength} exceeds the 
implementation limit (30) or if {@code minCodeLength}
      *                                  is not in the range 0-{@code 
maxCodeLength}].
-     * @throws CompressorException      if {@code codeLengths} size is out of 
range or if any code length is out of range or if the code lengths violate
-     *                                  Kraft's inequality.
+     * @throws CompressorException      if {@code codeLengths} size is out of 
range, if any code length is out of range, if all code lengths are zero,
+     *                                  or if the code lengths violate Kraft's 
inequality.
      */
     public HuffmanDecoder(final int[] codeLengths, final int minCodeLength, 
final int maxCodeLength) throws CompressorException {
         Objects.requireNonNull(codeLengths, "codeLengths");
@@ -192,11 +192,11 @@ public HuffmanDecoder(final int[] codeLengths, final int 
minCodeLength, final in
             throw new IllegalArgumentException(String.format("minCodeLength 
(%d) not within range [0, %d)", minCodeLength, maxCodeLength));
         }
         if (codeLengths.length == 0) {
-            throw new CompressorException(String.format("Empty code length 
list"));
+            throw new CompressorException("Empty code length list");
         }
         // Validate and find min/max lengths
         int min = maxCodeLength;
-        int max = minCodeLength;
+        int max = 0;
         for (int i = 0; i < codeLengths.length; i++) {
             final int len = codeLengths[i];
             if (len < minCodeLength || len > maxCodeLength) {
@@ -213,6 +213,9 @@ public HuffmanDecoder(final int[] codeLengths, final int 
minCodeLength, final in
                 max = len;
             }
         }
+        if (max == 0) {
+            throw new CompressorException("All code lengths are zero");
+        }
         this.minLength = min;
         this.maxLength = max;
         // Allocate outputs; we reuse them as scratch inside fillCodeTable
diff --git 
a/src/test/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStreamTest.java
 
b/src/test/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStreamTest.java
index 5fb25169d..fd498f5d3 100644
--- 
a/src/test/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStreamTest.java
+++ 
b/src/test/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStreamTest.java
@@ -280,4 +280,11 @@ void testSingleByteReadConsistentlyReturnsMinusOneAtEof() 
throws IOException {
         }
     }
 
+    @Test
+    void testEmpty() throws IOException {
+        try (BZip2CompressorInputStream in = new 
BZip2CompressorInputStream(newInputStream("empty.txt.bz2"))) {
+            final byte[] data = IOUtils.toByteArray(in);
+            assertEquals(0, data.length);
+        }
+    }
 }
diff --git 
a/src/test/java/org/apache/commons/compress/huffman/HuffmanDecoderTest.java 
b/src/test/java/org/apache/commons/compress/huffman/HuffmanDecoderTest.java
index 3a989c140..6ba6d1ef0 100644
--- a/src/test/java/org/apache/commons/compress/huffman/HuffmanDecoderTest.java
+++ b/src/test/java/org/apache/commons/compress/huffman/HuffmanDecoderTest.java
@@ -150,6 +150,13 @@ private int decodeSymbol(final HuffmanDecoder decoder, 
final int... data) throws
         }
     }
 
+    @Test
+    void testAllCodeLengthsAreZero() {
+        final CompressorException e = assertThrows(CompressorException.class, 
() -> new HuffmanDecoder(new int[] {0, 0, 0, 0, 0}),
+                "Expected CompressorException when all code lengths are zero");
+        assertEquals("All code lengths are zero", e.getMessage());
+    }
+
     @Test
     void testCodeLengthBelowMinCodeLength() throws Exception {
         final int[] codeLengths = new int[] {4, 2, 3, 0, 5, 5, 1};
@@ -252,14 +259,6 @@ void testNoCodeLengths() {
         assertEquals("Empty code length list", e.getMessage());
     }
 
-    @Test
-    void testNoLeafNodes() throws Exception {
-        final HuffmanDecoder decoder = new HuffmanDecoder(new int[] { 0, 0, 0, 
0, 0 });
-        final CompressorException e = assertThrows(CompressorException.class, 
() -> decodeSymbol(decoder, 0, 0, 0, 0),
-                "Expected CompressorException when decoding symbols for tree 
with no leaf nodes");
-        assertEquals("Invalid Huffman code: 0", e.getMessage());
-    }
-
     @Test
     void testReadEof() throws Exception {
         final int[] length = { 4, 2, 3, 0, 5, 5, 1 };
diff --git a/src/test/resources/empty.txt.bz2 b/src/test/resources/empty.txt.bz2
new file mode 100644
index 000000000..b56f3b974
Binary files /dev/null and b/src/test/resources/empty.txt.bz2 differ

Reply via email to