fix: make correct replacement for synthetic constructor (#808)
This commit is contained in:
@@ -2,6 +2,8 @@ package jadx.core.dex.visitors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.core.codegen.TypeGen;
|
||||
import jadx.core.dex.info.MethodInfo;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
@@ -105,8 +107,12 @@ public class ConstructorVisitor extends AbstractVisitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace call of synthetic constructor
|
||||
* Replace call of synthetic constructor with all 'null' args
|
||||
* to a non-synthetic or default constructor if possible.
|
||||
*
|
||||
* @return insn for replacement or null if replace not needed or not possible.
|
||||
*/
|
||||
@Nullable
|
||||
private static ConstructorInsn processConstructor(MethodNode mth, ConstructorInsn co) {
|
||||
MethodNode callMth = mth.dex().resolveMethod(co.getCallMth());
|
||||
if (callMth == null
|
||||
@@ -125,11 +131,11 @@ public class ConstructorVisitor extends AbstractVisitor {
|
||||
boolean passThis = instanceArg.isThis();
|
||||
String ctrId = "<init>(" + (passThis ? TypeGen.signature(instanceArg.getInitType()) : "") + ")V";
|
||||
MethodNode defCtr = classNode.searchMethodByShortId(ctrId);
|
||||
if (defCtr == null) {
|
||||
if (defCtr == null || defCtr.equals(callMth) || defCtr.getAccessFlags().isSynthetic()) {
|
||||
return null;
|
||||
}
|
||||
ConstructorInsn newInsn = new ConstructorInsn(defCtr.getMethodInfo(), co.getCallType());
|
||||
newInsn.setResult(co.getResult());
|
||||
newInsn.setResult(co.getResult().duplicate());
|
||||
return newInsn;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
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;
|
||||
|
||||
public class TestSyntheticConstructor extends SmaliTest {
|
||||
// @formatter:off
|
||||
/*
|
||||
public class Test {
|
||||
static {
|
||||
new BuggyConstructor();
|
||||
}
|
||||
}
|
||||
*/
|
||||
// @formatter:on
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
disableCompilation();
|
||||
assertThat(getClassNodeFromSmaliFiles("Test"))
|
||||
.code()
|
||||
.containsLine(2, "new BuggyConstructor();");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
.class public LBuggyConstructor;
|
||||
.super Ljava/lang/Object;
|
||||
.source "BuggyConstructor.java"
|
||||
|
||||
#.implements LInterfaceClass;
|
||||
|
||||
.method public synthetic constructor <init>()V
|
||||
.locals 0
|
||||
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
||||
return-void
|
||||
.end method
|
||||
@@ -0,0 +1,11 @@
|
||||
.class public Lothers/Test;
|
||||
.super Ljava/lang/Object;
|
||||
.source "Test.java"
|
||||
|
||||
.field public static final A00:Ljava/lang/Object;
|
||||
|
||||
.method public static constructor <clinit>()V
|
||||
.locals 1
|
||||
new-instance v0, LBuggyConstructor;
|
||||
invoke-direct {v0}, LBuggyConstructor;-><init>()V
|
||||
.end method
|
||||
Reference in New Issue
Block a user