core: fix field initialization extract from try/catch block (fix #78)
This commit is contained in:
@@ -205,6 +205,21 @@ public class InsnNode extends LineAttrNode {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canReorderRecursive() {
|
||||
if (!canReorder()) {
|
||||
return false;
|
||||
}
|
||||
for (InsnArg arg : this.getArguments()) {
|
||||
if (arg.isInsnWrap()) {
|
||||
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
|
||||
if (!wrapInsn.canReorderRecursive()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return InsnUtils.formatOffset(offset) + ": "
|
||||
|
||||
@@ -6,6 +6,8 @@ import jadx.core.dex.info.AccessInfo;
|
||||
import jadx.core.dex.info.FieldInfo;
|
||||
import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
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.nodes.BlockNode;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
@@ -189,14 +191,22 @@ public class ExtractFieldInit extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private static boolean checkInsn(InsnNode insn) {
|
||||
InsnArg arg = insn.getArg(0);
|
||||
if (arg.isInsnWrap()) {
|
||||
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
|
||||
if (!wrapInsn.canReorderRecursive() && insn.contains(AType.CATCH_BLOCK)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return arg.isLiteral() || arg.isThis();
|
||||
}
|
||||
Set<RegisterArg> regs = new HashSet<RegisterArg>();
|
||||
insn.getRegisterArgs(regs);
|
||||
if (regs.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (RegisterArg reg : regs) {
|
||||
if (!reg.isThis()) {
|
||||
return false;
|
||||
if (!regs.isEmpty()) {
|
||||
for (RegisterArg reg : regs) {
|
||||
if (!reg.isThis()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package jadx.tests.integration.others;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static jadx.tests.api.utils.JadxMatchers.containsLines;
|
||||
import static jadx.tests.api.utils.JadxMatchers.containsOne;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestFieldInitInTryCatch extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
private static final URL a;
|
||||
|
||||
static {
|
||||
try {
|
||||
a = new URL("http://www.example.com/");
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestCls2 {
|
||||
private static final URL[] a;
|
||||
|
||||
static {
|
||||
try {
|
||||
a = new URL[]{new URL("http://www.example.com/")};
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestCls3 {
|
||||
private static final String[] a;
|
||||
|
||||
static {
|
||||
try {
|
||||
a = new String[]{"a"};
|
||||
// Note: follow code will not be extracted:
|
||||
// a = new String[]{new String("a")};
|
||||
new URL("http://www.example.com/");
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("private static final URL a;"));
|
||||
assertThat(code, containsOne("a = new URL(\"http://www.example.com/\");"));
|
||||
assertThat(code, containsLines(2,
|
||||
"try {",
|
||||
indent(1) + "a = new URL(\"http://www.example.com/\");",
|
||||
"} catch (MalformedURLException e) {"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
ClassNode cls = getClassNode(TestCls2.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsLines(2,
|
||||
"try {",
|
||||
indent(1) + "a = new URL[]{new URL(\"http://www.example.com/\")};",
|
||||
"} catch (MalformedURLException e) {"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
ClassNode cls = getClassNode(TestCls3.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("private static final String[] a = new String[]{\"a\"};"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user