mirror of
https://github.com/skylot/jadx.git
synced 2024-11-26 22:20:50 +00:00
fix: use type from new-instance
if differ from constructor call (#2285)
This commit is contained in:
parent
efa2f5d172
commit
23696d3971
@ -25,8 +25,12 @@ public final class ConstructorInsn extends BaseInvokeNode {
|
||||
}
|
||||
|
||||
public ConstructorInsn(MethodNode mth, InvokeNode invoke) {
|
||||
this(mth, invoke, invoke.getCallMth());
|
||||
}
|
||||
|
||||
public ConstructorInsn(MethodNode mth, InvokeNode invoke, MethodInfo callMth) {
|
||||
super(InsnType.CONSTRUCTOR, invoke.getArgsCount() - 1);
|
||||
this.callMth = invoke.getCallMth();
|
||||
this.callMth = callMth;
|
||||
this.callType = getCallType(mth, callMth.getDeclClass(), invoke.getArg(0));
|
||||
int argsCount = invoke.getArgsCount();
|
||||
for (int i = 1; i < argsCount; i++) {
|
||||
|
@ -6,9 +6,13 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.core.codegen.TypeGen;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.info.ClassInfo;
|
||||
import jadx.core.dex.info.MethodInfo;
|
||||
import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
import jadx.core.dex.instructions.InvokeNode;
|
||||
import jadx.core.dex.instructions.PhiInsn;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
@ -59,10 +63,17 @@ public class ConstructorVisitor extends AbstractVisitor {
|
||||
|
||||
private static boolean processInvoke(MethodNode mth, BlockNode block, int indexInBlock, InsnRemover remover) {
|
||||
InvokeNode inv = (InvokeNode) block.getInstructions().get(indexInBlock);
|
||||
if (!inv.getCallMth().isConstructor()) {
|
||||
MethodInfo callMth = inv.getCallMth();
|
||||
if (!callMth.isConstructor()) {
|
||||
return false;
|
||||
}
|
||||
ConstructorInsn co = new ConstructorInsn(mth, inv);
|
||||
ArgType instType = searchInstanceType(inv);
|
||||
if (instType != null && !instType.equals(callMth.getDeclClass().getType())) {
|
||||
ClassInfo instCls = ClassInfo.fromType(mth.root(), instType);
|
||||
callMth = MethodInfo.fromDetails(mth.root(), instCls, callMth.getName(),
|
||||
callMth.getArgumentsTypes(), callMth.getReturnType());
|
||||
}
|
||||
ConstructorInsn co = new ConstructorInsn(mth, inv, callMth);
|
||||
if (canRemoveConstructor(mth, co)) {
|
||||
remover.addAndUnbind(inv);
|
||||
return false;
|
||||
@ -101,6 +112,18 @@ public class ConstructorVisitor extends AbstractVisitor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static @Nullable ArgType searchInstanceType(InvokeNode inv) {
|
||||
InsnArg instanceArg = inv.getInstanceArg();
|
||||
if (instanceArg == null || !instanceArg.isRegister()) {
|
||||
return null;
|
||||
}
|
||||
InsnNode assignInsn = ((RegisterArg) instanceArg).getSVar().getAssignInsn();
|
||||
if (assignInsn == null || assignInsn.getType() != InsnType.NEW_INSTANCE) {
|
||||
return null;
|
||||
}
|
||||
return ((IndexInsnNode) assignInsn).getIndexAsType();
|
||||
}
|
||||
|
||||
private static RegisterArg insertPhiInsn(MethodNode mth, BlockNode curBlock,
|
||||
RegisterArg instArg, ConstructorInsn otherCtr) {
|
||||
BlockNode otherBlock = BlockUtils.getBlockByInsn(mth, otherCtr);
|
||||
|
@ -0,0 +1,20 @@
|
||||
package jadx.tests.integration.others;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
/**
|
||||
* Constructor called on object instance is from Object not instance type
|
||||
*/
|
||||
public class TestConstructor2 extends SmaliTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(getClassNodeFromSmaliFiles())
|
||||
.code()
|
||||
.containsOne("A a = new A();");
|
||||
}
|
||||
}
|
5
jadx-core/src/test/smali/others/TestConstructor2/A.smali
Normal file
5
jadx-core/src/test/smali/others/TestConstructor2/A.smali
Normal file
@ -0,0 +1,5 @@
|
||||
.class public final Lothers/TestConstructor2$A;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.field public a:I
|
||||
.field public b:Ljava/util/ArrayDeque;
|
@ -0,0 +1,79 @@
|
||||
.class public Lothers/TestConstructor2;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
.field public a:Ljava/util/HashMap;
|
||||
|
||||
.method public final a(III)V
|
||||
.registers 6
|
||||
|
||||
.line 1
|
||||
.line 2
|
||||
new-instance v0, Lothers/TestConstructor2$A;
|
||||
|
||||
.line 3
|
||||
.line 4
|
||||
.line 5
|
||||
invoke-direct {v0}, Ljava/lang/Object;-><init>()V
|
||||
|
||||
.line 6
|
||||
.line 7
|
||||
if-gt p2, p3, :cond_1c
|
||||
|
||||
.line 8
|
||||
.line 9
|
||||
new-instance p2, Ljava/util/ArrayDeque;
|
||||
|
||||
.line 10
|
||||
.line 11
|
||||
iget v1, v0, Lothers/TestConstructor2$A;->a:I
|
||||
|
||||
.line 12
|
||||
.line 13
|
||||
.line 14
|
||||
invoke-direct {p2, v1}, Ljava/util/ArrayDeque;-><init>(I)V
|
||||
|
||||
.line 15
|
||||
.line 16
|
||||
iput-object p2, v0, Lothers/TestConstructor2$A;->b:Ljava/util/ArrayDeque;
|
||||
|
||||
.line 17
|
||||
.line 18
|
||||
iput p3, v0, Lothers/TestConstructor2$A;->a:I
|
||||
|
||||
.line 19
|
||||
.line 20
|
||||
iget-object p2, p0, Lothers/TestConstructor2;->a:Ljava/util/HashMap;
|
||||
|
||||
.line 21
|
||||
.line 22
|
||||
.line 23
|
||||
invoke-static {p1}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
|
||||
|
||||
.line 24
|
||||
move-result-object p1
|
||||
|
||||
.line 25
|
||||
.line 26
|
||||
.line 27
|
||||
invoke-virtual {p2, p1, v0}, Ljava/util/HashMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
|
||||
.line 28
|
||||
return-void
|
||||
|
||||
.line 29
|
||||
.line 30
|
||||
:cond_1c
|
||||
new-instance p1, Ljava/lang/IllegalArgumentException;
|
||||
|
||||
.line 31
|
||||
.line 32
|
||||
const-string/jumbo p2, "error"
|
||||
|
||||
.line 33
|
||||
.line 34
|
||||
.line 35
|
||||
invoke-direct {p1, p2}, Ljava/lang/IllegalArgumentException;-><init>(Ljava/lang/String;)V
|
||||
|
||||
.line 36
|
||||
throw p1
|
||||
.end method
|
Loading…
Reference in New Issue
Block a user