Skip to content

Commit ab609b7

Browse files
committed
Check for too many or no leaf nodes
1 parent fad7c2c commit ab609b7

2 files changed

Lines changed: 35 additions & 6 deletions

File tree

src/main/java/org/apache/commons/compress/compressors/lha/BinaryTree.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ class BinaryTree {
5454
* be read from the bit stream when the read method is called, as there are no children to traverse.
5555
*
5656
* @param array the array to build the binary tree from
57+
* @throws CompressorException if the tree is invalid
5758
*/
58-
BinaryTree(final int... array) {
59+
BinaryTree(final int... array) throws CompressorException {
5960
if (array.length == 1) {
6061
// Tree only contains a single value, which is the root node value
6162
this.tree = new int[] { array[0] };
@@ -64,6 +65,9 @@ class BinaryTree {
6465

6566
// Determine the maximum depth of the tree from the input array
6667
final int maxDepth = Arrays.stream(array).max().getAsInt();
68+
if (maxDepth == 0) {
69+
throw new CompressorException("Tree contains no leaf nodes");
70+
}
6771

6872
// Allocate binary tree with enough space for all nodes
6973
this.tree = initTree(maxDepth);
@@ -82,6 +86,10 @@ class BinaryTree {
8286
// Add leaf nodes for values with the current depth
8387
for (int value = 0; value < array.length; value++) {
8488
if (array[value] == currentDepth) {
89+
if (numNodesAtCurrentDepth == maxNodesAtCurrentDepth) {
90+
throw new CompressorException("Tree contains too many leaf nodes for depth %d", currentDepth);
91+
}
92+
8593
this.tree[treePos++] = value; // Add leaf (value) node
8694
numNodesAtCurrentDepth++;
8795
}
@@ -109,10 +117,11 @@ class BinaryTree {
109117
*
110118
* @param depth the depth of the tree, must be between 0 and 16 (inclusive)
111119
* @return an array representing the binary tree, initialized with UNDEFINED values
120+
* @throws CompressorException for invalid depth
112121
*/
113-
private int[] initTree(final int depth) {
122+
private int[] initTree(final int depth) throws CompressorException {
114123
if (depth < 0 || depth > 16) {
115-
throw new IllegalArgumentException("Depth must not be negative and not bigger than 16 but is " + depth);
124+
throw new CompressorException("Tree depth must not be negative and not bigger than 16 but is " + depth);
116125
}
117126

118127
final int arraySize = depth == 0 ? 1 : (int) ((1L << depth + 1) - 1); // Depth 0 has only a single node (the root)

src/test/java/org/apache/commons/compress/compressors/lha/BinaryTreeTest.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,29 @@ void testInvalidBitstream() throws Exception {
228228
void testCheckMaxDepth() throws Exception {
229229
try {
230230
new BinaryTree(1, 17);
231-
fail("Expected IllegalArgumentException for depth > 16");
232-
} catch (IllegalArgumentException e) {
233-
assertEquals("Depth must not be negative and not bigger than 16 but is 17", e.getMessage());
231+
fail("Expected CompressorException for depth > 16");
232+
} catch (CompressorException e) {
233+
assertEquals("Tree depth must not be negative and not bigger than 16 but is 17", e.getMessage());
234+
}
235+
}
236+
237+
@Test
238+
void testTooManyLeafNodes() throws Exception {
239+
try {
240+
new BinaryTree(0, 2, 1, 2, 2);
241+
fail("Expected CompressorException for too many leaf nodes");
242+
} catch (CompressorException e) {
243+
assertEquals("Tree contains too many leaf nodes for depth 2", e.getMessage());
244+
}
245+
}
246+
247+
@Test
248+
void testNoLeafNodes() throws Exception {
249+
try {
250+
new BinaryTree(0, 0, 0, 0, 0);
251+
fail("Expected CompressorException for no leaf nodes");
252+
} catch (CompressorException e) {
253+
assertEquals("Tree contains no leaf nodes", e.getMessage());
234254
}
235255
}
236256

0 commit comments

Comments
 (0)