Skip to content

Commit

Permalink
fix: keep types on duplicate cast remove (#1527)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Jun 12, 2022
1 parent a2cd8e1 commit 1533b7f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 5 deletions.
20 changes: 15 additions & 5 deletions jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -362,31 +362,41 @@ private static boolean checkArrSizes(MethodNode mth, NewArrayNode newArrInsn, Fi
private static void removeCheckCast(MethodNode mth, BlockNode block, int i, IndexInsnNode insn) {
InsnArg castArg = insn.getArg(0);
ArgType castType = (ArgType) insn.getIndex();
if (!ArgType.isCastNeeded(mth.root(), castArg.getType(), castType)
|| isCastDuplicate(insn)) {
if (!ArgType.isCastNeeded(mth.root(), castArg.getType(), castType)) {
RegisterArg result = insn.getResult();
result.setType(castArg.getType());

InsnNode move = new InsnNode(InsnType.MOVE, 1);
move.setResult(result);
move.addArg(castArg);
replaceInsn(mth, block, i, move);
return;
}
InsnNode prevCast = isCastDuplicate(insn);
if (prevCast != null) {
// replace previous cast with move
InsnNode move = new InsnNode(InsnType.MOVE, 1);
move.setResult(prevCast.getResult());
move.addArg(prevCast.getArg(0));
replaceInsn(mth, block, prevCast, move);
}
}

private static boolean isCastDuplicate(IndexInsnNode castInsn) {
private static @Nullable InsnNode isCastDuplicate(IndexInsnNode castInsn) {
InsnArg arg = castInsn.getArg(0);
if (arg.isRegister()) {
SSAVar sVar = ((RegisterArg) arg).getSVar();
if (sVar != null && sVar.getUseCount() == 1 && !sVar.isUsedInPhi()) {
InsnNode assignInsn = sVar.getAssign().getParentInsn();
if (assignInsn != null && assignInsn.getType() == InsnType.CHECK_CAST) {
ArgType assignCastType = (ArgType) ((IndexInsnNode) assignInsn).getIndex();
return assignCastType.equals(castInsn.getIndex());
if (assignCastType.equals(castInsn.getIndex())) {
return assignInsn;
}
}
}
}
return false;
return null;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package jadx.tests.integration.types;

import org.junit.jupiter.api.Test;

import jadx.tests.api.SmaliTest;

import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;

/**
* Issue 1527
*/
@SuppressWarnings("CommentedOutCode")
public class TestTypeResolver21 extends SmaliTest {
// @formatter:off
/*
public Number test(Object objectArray) {
Object[] arr = (Object[]) objectArray;
return (Number) arr[0];
}
*/
// @formatter:on

@Test
public void test() {
assertThat(getClassNodeFromSmali())
.code()
.containsOne("Object[] arr = (Object[]) objectArray;");
}
}
23 changes: 23 additions & 0 deletions jadx-core/src/test/smali/types/TestTypeResolver21.smali
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.class public Ltypes/TestTypeResolver21;
.super Ljava/lang/Object;
.source "TestTypeResolver21.java"


.method public test(Ljava/lang/Object;)Ljava/lang/Number;
.registers 4
.param p1, "objectArray" # Ljava/lang/Object;

.prologue
.line 16
check-cast p1, [Ljava/lang/Object;
.end local p1 # "objectArray":Ljava/lang/Object;
move-object v0, p1
check-cast v0, [Ljava/lang/Object;

.line 17
.local v0, "arr":[Ljava/lang/Object;
const/4 v1, 0x0
aget-object v1, v0, v1
check-cast v1, Ljava/lang/Number;
return-object v1
.end method

0 comments on commit 1533b7f

Please sign in to comment.