-
Notifications
You must be signed in to change notification settings - Fork 63
Open
Description
Environment
- Repository: java-utils
- File:
JavaUtils/src/id/ac/ub/filkom/rendicahya/utils/matrix/operators/HorizontalStacker.java - Method:
operate(int[][ a, int[][] b)(line 66)
Bug Description
The HorizontalStacker.operate() method assumes input matrices have exactly 2 rows and throws ArrayIndexOutOfBoundsException when given matrices with different row counts.
Reproducing HorizontalStacker.operate() Bug
Create an instance of HorizontalStacker
Call operate() with matrices having non-2 row counts
Observe the exception
HorizontalStacker stacker = new HorizontalStacker();
int[][] oneRow = {{1, 2, 3}}; // 1 row
int[][] anotherMatrix = {{4, 5}}; // 1 row
stacker.operate(oneRow, anotherMatrix); // Throws ArrayIndexOutOfBoundsExceptionExpected vs Actual Behavior
Expected Behavior:
The method should either:
- Support matrices with any number of rows (generalized horizontal stacking), OR
- Validate input and throw a descriptive error for unsupported dimensions
Actual Behavior:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
Root Cause
The method hardcodes array access to indices [0] and [1] without checking matrix dimensions:
public int[][] operate(int[][] a, int[][] b) {
int[][] c = new int[2][a[0].length + b[0].length]; // ← Line 67: Assumes 2 rows
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if (i == 0) {
c[0][j] = a[0][j];
} else {
c[0][j + a[i].length] = b[0][j];
}
}
}
// Second loop also accesses a[1] and assumes exactly 2 rows
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if (i == 0) {
c[1][j] = a[1][j]; // ← Line 81: Will fail if a has < 2 rows
} else {
c[1][j + a[i].length] = b[1][j]; // ← Will fail if b has < 2 rows
}
}
}
return c;
}Additional Issues & Suggested Fix
Additional Issues:
- Logic error in index calculation:
c[0][j + a[i].length]should usea[0].length - No validation of input matrix dimensions
- Code duplication in the two loops
Suggested Fix:
Option 1: Add validation for 2-row requirement
public int[][] operate(int[][] a, int[][] b) {
if (a.length != 2 || b.length != 2) {
throw new IllegalArgumentException("Both matrices must have exactly 2 rows. " +
"Got: a=" + a.length + " rows, b=" + b.length + " rows");
}
if (a[0].length != a[1].length || b[0].length != b[1].length) {
throw new IllegalArgumentException("Matrix rows must have consistent lengths");
}
int[][] c = new int[2][a[0].length + b[0].length];
// First row: concatenate a[0] and b[0]
System.arraycopy(a[0], 0, c[0], 0, a[0].length);
System.arraycopy(b[0], 0, c[0], a[0].length, b[0].length);
// Second row: concatenate a[1] and b[1]
System.arraycopy(a[1], 0, c[1], 0, a[1].length);
System.arraycopy(b[1], 0, c[1], a[1].length, b[1].length);
return c;
}**Option 2: Generalize for any number of rows
public int[][] operate(int[][] a, int[][] b) {
if (a.length != b.length) {
throw new IllegalArgumentException("Matrices must have same number of rows");
}
int rows = a.length;
int[][] c = new int[rows][a[0].length + b[0].length];
for (int i = 0; i < rows; i++) {
System.arraycopy(a[i], 0, c[i], 0, a[i].length);
System.arraycopy(b[i], 0, c[i], a[i].length, b[i].length);
}
return c;
}public int[][] operate(int[][] a, int[][] b) {
if (a.length != b.length) {
throw new IllegalArgumentException("Matrices must have same number of rows");
}
int rows = a.length;
int[][] c = new int[rows][a[0].length + b[0].length];
for (int i = 0; i < rows; i++) {
System.arraycopy(a[i], 0, c[i], 0, a[i].length);
System.arraycopy(b[i], 0, c[i], a[i].length, b[i].length);
}
return c;
}Impact & Test Cases to Add
Impact:
- Severity: High
- Affected Methods: All
operate()overloads inHorizontalStacker - Use Cases: Matrix operations, image processing, data table manipulation
Test Cases to Add:
// Should fail with descriptive error
assertThrows(IllegalArgumentException.class, () ->
stacker.operate(new int[][]{{1,2,3}}, new int[][]{{4,5}}));
// Should work for valid 2x2 matrices
int[][] a = {{1, 2}, {3, 4}};
int[][] b = {{5, 6}, {7, 8}};
int[][] result = stacker.operate(a, b);
assertArrayEquals(new int[]{1, 2, 5, 6}, result[0]);
assertArrayEquals(new int[]{3, 4, 7, 8}, result[1]);Metadata
Metadata
Assignees
Labels
No labels