fix: don't add region on exit block (#1040)
This commit is contained in:
@@ -30,6 +30,7 @@ import jadx.core.dex.nodes.Edge;
|
||||
import jadx.core.dex.nodes.IBlock;
|
||||
import jadx.core.dex.nodes.IContainer;
|
||||
import jadx.core.dex.nodes.IRegion;
|
||||
import jadx.core.dex.nodes.InsnContainer;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.dex.regions.Region;
|
||||
@@ -76,6 +77,10 @@ public class RegionMaker {
|
||||
if (startBlock == null) {
|
||||
return r;
|
||||
}
|
||||
if (stack.containsExit(startBlock)) {
|
||||
insertEdgeInsns(r, startBlock);
|
||||
return r;
|
||||
}
|
||||
|
||||
int startBlockId = startBlock.getId();
|
||||
if (processedBlocks.get(startBlockId)) {
|
||||
@@ -95,6 +100,27 @@ public class RegionMaker {
|
||||
return r;
|
||||
}
|
||||
|
||||
private void insertEdgeInsns(Region region, BlockNode exitBlock) {
|
||||
List<EdgeInsnAttr> edgeInsns = exitBlock.getAll(AType.EDGE_INSN);
|
||||
if (edgeInsns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<InsnNode> insns = new ArrayList<>(edgeInsns.size());
|
||||
addOneInsnOfType(insns, edgeInsns, InsnType.BREAK);
|
||||
addOneInsnOfType(insns, edgeInsns, InsnType.CONTINUE);
|
||||
region.add(new InsnContainer(insns));
|
||||
}
|
||||
|
||||
private void addOneInsnOfType(List<InsnNode> insns, List<EdgeInsnAttr> edgeInsns, InsnType insnType) {
|
||||
for (EdgeInsnAttr edgeInsn : edgeInsns) {
|
||||
InsnNode insn = edgeInsn.getInsn();
|
||||
if (insn.getType() == insnType) {
|
||||
insns.add(insn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively traverse all blocks from 'block' until block from 'exits'
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package jadx.tests.integration.trycatch;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestLoopInTryCatch extends SmaliTest {
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(getClassNodeFromSmali())
|
||||
.code()
|
||||
.containsLines(2,
|
||||
"int i;",
|
||||
"while (true) {",
|
||||
" try {",
|
||||
" i = getI();",
|
||||
" } catch (RuntimeException unused) {",
|
||||
" return;",
|
||||
" }",
|
||||
" if (i == 1 || i == 2) {",
|
||||
" break;",
|
||||
" }",
|
||||
"}",
|
||||
"if (i == 1) {",
|
||||
"}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
.class public Ltrycatch/TestLoopInTryCatch;
|
||||
.super Ljava/lang/Object;
|
||||
.source "SourceFile"
|
||||
|
||||
.method public static test()V
|
||||
.registers 6
|
||||
|
||||
:try_start
|
||||
|
||||
:loop
|
||||
|
||||
invoke-static {}, Ltrycatch/TestLoopInTryCatch;->getI()I
|
||||
move-result v1
|
||||
|
||||
const/4 v2, 0x1
|
||||
|
||||
if-eq v1, v2, :cond
|
||||
|
||||
const/4 v3, 0x2
|
||||
|
||||
if-eq v1, v3, :cond
|
||||
|
||||
goto :loop
|
||||
|
||||
:cond
|
||||
if-eq v1, v2, :end
|
||||
|
||||
return-void
|
||||
|
||||
:try_end
|
||||
.catch Ljava/lang/RuntimeException; {:try_start .. :try_end} :end
|
||||
|
||||
:end
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public static getI()I
|
||||
.locals 2
|
||||
|
||||
const/4 v1, 0x1
|
||||
return v1
|
||||
.end method
|
||||
Reference in New Issue
Block a user