fix: keep all dimensions for anewarray of an array element type (PR #2887)

This commit is contained in:
Ananya
2026-06-14 22:50:06 +02:00
committed by GitHub
parent 8c28a8530e
commit 9d4babcdce
3 changed files with 45 additions and 12 deletions
@@ -528,18 +528,10 @@ public class InsnDecoder {
private InsnNode makeNewArray(InsnData insn) {
ArgType indexType = ArgType.parse(insn.getIndexAsType());
// NEW_ARRAY literal = dimensions to wrap the operand by: 0 if it is already the full array type
// (dalvik new-array, java multianewarray), 1 for newarray/anewarray (operand is the element type)
int dim = (int) insn.getLiteral();
ArgType arrType;
if (dim == 0) {
arrType = indexType;
} else {
if (indexType.isArray()) {
// java bytecode can pass array as a base type
arrType = indexType;
} else {
arrType = ArgType.array(indexType, dim);
}
}
ArgType arrType = dim == 0 ? indexType : ArgType.array(indexType, dim);
int regsCount = insn.getRegsCount();
NewArrayNode newArr = new NewArrayNode(arrType, regsCount - 1);
newArr.setResult(InsnArg.reg(insn, 0, arrType));
@@ -0,0 +1,39 @@
package jadx.tests.integration.arrays;
import org.junit.jupiter.api.Test;
import jadx.tests.api.IntegrationTest;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestNewArrayOfArrays extends IntegrationTest {
public static class TestCls {
public static long[][] anewarrayOfArray(int n) {
return new long[n][]; // anewarray [J
}
public static String[][] anewarrayOfObjectArray(int n) {
return new String[n][]; // anewarray [Ljava/lang/String;
}
public static int[][][] anewarrayDeep(int n) {
return new int[n][][]; // anewarray [[I
}
public static int[][] multiAnewarray(int a, int b) {
return new int[a][b]; // multianewarray [[I
}
}
@Test
public void test() {
useJavaInput();
assertThat(getClassNode(TestCls.class))
.code()
.containsOne("new long[n][]")
.containsOne("new String[n][]")
.containsOne("new int[n][][]")
.containsOne("new int[a][b]");
}
}
@@ -342,7 +342,9 @@ public class JavaInsnsRegister {
s.idx(s.u2());
int dim = s.u1();
JavaInsnData insn = s.insn();
insn.setLiteral(dim);
// operand is already the full array type (like new-array): literal 0 = no wrapping; the
// dimension count is carried by regsCount
insn.setLiteral(0);
insn.setRegsCount(dim + 1);
for (int i = dim; i > 0; i--) {
s.pop(i);