core: fix class cast exception
This commit is contained in:
@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
|
||||
/**
|
||||
* Jadx API usage example:
|
||||
* <pre><code>
|
||||
* Decompiler jadx = new Decompiler();
|
||||
* JadxDecompiler jadx = new JadxDecompiler();
|
||||
* jadx.loadFile(new File("classes.dex"));
|
||||
* jadx.setOutputDir(new File("out"));
|
||||
* jadx.save();
|
||||
|
||||
@@ -101,7 +101,7 @@ public class InsnGen {
|
||||
if (f.isStatic()) {
|
||||
staticField(code, f.getField());
|
||||
} else {
|
||||
instanceField(code, f.getField(), f.getRegisterArg());
|
||||
instanceField(code, f.getField(), f.getInstanceArg());
|
||||
}
|
||||
} else {
|
||||
throw new CodegenException("Unknown arg type " + arg);
|
||||
|
||||
@@ -6,12 +6,12 @@ import jadx.core.dex.info.FieldInfo;
|
||||
public final class FieldArg extends RegisterArg {
|
||||
|
||||
private final FieldInfo field;
|
||||
// regArg equal 'null' for static fields
|
||||
private final RegisterArg regArg;
|
||||
// instArg equal 'null' for static fields
|
||||
private final InsnArg instArg;
|
||||
|
||||
public FieldArg(FieldInfo field, RegisterArg reg) {
|
||||
public FieldArg(FieldInfo field, InsnArg reg) {
|
||||
super(-1);
|
||||
this.regArg = reg;
|
||||
this.instArg = reg;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ public final class FieldArg extends RegisterArg {
|
||||
return field;
|
||||
}
|
||||
|
||||
public RegisterArg getRegisterArg() {
|
||||
return regArg;
|
||||
public InsnArg getInstanceArg() {
|
||||
return instArg;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return regArg == null;
|
||||
return instArg == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,7 +54,7 @@ public final class FieldArg extends RegisterArg {
|
||||
if (!field.equals(fieldArg.field)) {
|
||||
return false;
|
||||
}
|
||||
if (regArg != null ? !regArg.equals(fieldArg.regArg) : fieldArg.regArg != null) {
|
||||
if (instArg != null ? !instArg.equals(fieldArg.instArg) : fieldArg.instArg != null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -64,7 +64,7 @@ public final class FieldArg extends RegisterArg {
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + field.hashCode();
|
||||
result = 31 * result + (regArg != null ? regArg.hashCode() : 0);
|
||||
result = 31 * result + (instArg != null ? instArg.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import jadx.core.dex.instructions.args.FieldArg;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
import jadx.core.dex.instructions.args.InsnWrapArg;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
import jadx.core.dex.instructions.mods.ConstructorInsn;
|
||||
import jadx.core.dex.nodes.BlockNode;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
@@ -186,9 +185,9 @@ public class SimplifyVisitor extends AbstractVisitor {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
RegisterArg reg = null;
|
||||
InsnArg reg = null;
|
||||
if (getType == InsnType.IGET) {
|
||||
reg = ((RegisterArg) get.getArg(0));
|
||||
reg = get.getArg(0);
|
||||
}
|
||||
FieldArg fArg = new FieldArg(field, reg);
|
||||
if (reg != null) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package jadx.core.utils;
|
||||
import jadx.core.Consts;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
import jadx.core.dex.instructions.args.InsnWrapArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
import jadx.core.dex.instructions.args.SSAVar;
|
||||
import jadx.core.dex.nodes.BlockNode;
|
||||
@@ -65,17 +66,24 @@ public class InstructionRemover {
|
||||
mth.removeSVar(r.getSVar());
|
||||
}
|
||||
for (InsnArg arg : insn.getArguments()) {
|
||||
if (arg instanceof RegisterArg) {
|
||||
RegisterArg reg = (RegisterArg) arg;
|
||||
SSAVar sVar = reg.getSVar();
|
||||
if (sVar != null) {
|
||||
sVar.removeUse(reg);
|
||||
}
|
||||
}
|
||||
unbindArgUsage(mth, arg);
|
||||
}
|
||||
insn.add(AFlag.INCONSISTENT_CODE);
|
||||
}
|
||||
|
||||
public static void unbindArgUsage(MethodNode mth, InsnArg arg) {
|
||||
if (arg instanceof RegisterArg) {
|
||||
RegisterArg reg = (RegisterArg) arg;
|
||||
SSAVar sVar = reg.getSVar();
|
||||
if (sVar != null) {
|
||||
sVar.removeUse(reg);
|
||||
}
|
||||
} else if (arg instanceof InsnWrapArg) {
|
||||
InsnWrapArg wrap = (InsnWrapArg) arg;
|
||||
unbindInsn(mth, wrap.getWrapInsn());
|
||||
}
|
||||
}
|
||||
|
||||
// Don't use 'insns.removeAll(toRemove)' because it will remove instructions by content
|
||||
// and here can be several instructions with same content
|
||||
private void removeAll(List<InsnNode> insns, List<InsnNode> toRemove) {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package jadx.tests.internal;
|
||||
package jadx.tests.internal.arith;
|
||||
|
||||
import jadx.api.InternalJadxTest;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
@@ -0,0 +1,40 @@
|
||||
package jadx.tests.internal.arith;
|
||||
|
||||
import jadx.api.InternalJadxTest;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestFieldIncrement2 extends InternalJadxTest {
|
||||
|
||||
class A {
|
||||
int f = 5;
|
||||
}
|
||||
|
||||
public static class TestCls {
|
||||
public A a;
|
||||
|
||||
public void test1(int n) {
|
||||
this.a.f = this.a.f + n;
|
||||
}
|
||||
|
||||
public void test2(int n) {
|
||||
this.a.f *= n;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
System.out.println(code);
|
||||
|
||||
assertThat(code, containsString("this.a.f += n;"));
|
||||
assertThat(code, containsString("a.f *= n;"));
|
||||
// TODO
|
||||
// assertThat(code, containsString("this.a.f *= n;"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user