From 85a18e6d7502e62b72b2437176b0ab856b17b08b Mon Sep 17 00:00:00 2001 From: Skylot Date: Sat, 2 May 2015 20:29:15 +0300 Subject: [PATCH] core: don't insert break in method exit blocks (fix #60) --- .../dex/visitors/regions/RegionMaker.java | 9 ++-- .../integration/loops/TestBreakInLoop2.java | 51 +++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/loops/TestBreakInLoop2.java diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java index 42e64bfaa..df5e6fca7 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java @@ -353,9 +353,12 @@ public class RegionMaker { return false; } List simplePath = BlockUtils.buildSimplePath(exit); - if (!simplePath.isEmpty() - && simplePath.get(simplePath.size() - 1).contains(AFlag.RETURN)) { - return false; + if (!simplePath.isEmpty()) { + BlockNode lastBlock = simplePath.get(simplePath.size() - 1); + if (lastBlock.contains(AFlag.RETURN) + || lastBlock.getSuccessors().isEmpty()) { + return false; + } } // check if there no outer switch (TODO: very expensive check) Set paths = BlockUtils.getAllPathsBlocks(mth.getEnterBlock(), exit); diff --git a/jadx-core/src/test/java/jadx/tests/integration/loops/TestBreakInLoop2.java b/jadx-core/src/test/java/jadx/tests/integration/loops/TestBreakInLoop2.java new file mode 100644 index 000000000..a5add027b --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/loops/TestBreakInLoop2.java @@ -0,0 +1,51 @@ +package jadx.tests.integration.loops; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.IntegrationTest; + +import java.util.List; + +import org.junit.Test; + +import static jadx.tests.api.utils.JadxMatchers.containsOne; +import static org.junit.Assert.assertThat; + +public class TestBreakInLoop2 extends IntegrationTest { + + public static class TestCls { + public void test(List data) throws Exception { + for (; ; ) { + try { + funcB(data); + break; + } catch (Exception ex) { + if (funcC()) { + throw ex; + } + data.clear(); + } + Thread.sleep(100); + } + } + + private boolean funcB(List data) { + return false; + } + + private boolean funcC() { + return true; + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + + assertThat(code, containsOne("while (true) {")); + assertThat(code, containsOne("break;")); + assertThat(code, containsOne("throw ex;")); + assertThat(code, containsOne("data.clear();")); + assertThat(code, containsOne("Thread.sleep(100);")); + } +}