diff --git a/jadx-core/src/main/java/jadx/api/Decompiler.java b/jadx-core/src/main/java/jadx/api/Decompiler.java index 2615b1c72..3709040fc 100644 --- a/jadx-core/src/main/java/jadx/api/Decompiler.java +++ b/jadx-core/src/main/java/jadx/api/Decompiler.java @@ -181,7 +181,6 @@ public final class Decompiler { } void processClass(ClassNode cls) { - LOG.debug("processing class {} ...", cls); ProcessClass.process(cls, passes); } diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java index 8e5c9db76..042061117 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java @@ -104,7 +104,8 @@ public class ClassNode extends LineAttrNode implements ILoadable { int sfIdx = cls.getSourceFileIndex(); if (sfIdx != DexNode.NO_INDEX) { String fileName = dex.getString(sfIdx); - if (!this.getFullName().contains(fileName.replace(".java", ""))) { + if (!this.getFullName().contains(fileName.replace(".java", "")) + && !fileName.equals("SourceFile")) { this.getAttributes().add(new SourceFileAttr(fileName)); LOG.debug("Class '{}' compiled from '{}'", this, fileName); } 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 f211d2f87..621f9cdda 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 @@ -238,13 +238,15 @@ public class RegionMaker { exitBlocks.remove(condBlock); if (exitBlocks.size() > 0) { - // add 'break' instruction before path cross between main loop exit and subexit - BlockNode loopExit = BlockUtils.selectOther(loopBody, condBlock.getCleanSuccessors()); - for (Edge exitEdge : loop.getExitEdges()) { - if (!exitBlocks.contains(exitEdge.getSource())) { - continue; + BlockNode loopExit = BlockUtils.selectOtherSafe(loopBody, condBlock.getCleanSuccessors()); + if (loopExit != null) { + // add 'break' instruction before path cross between main loop exit and subexit + for (Edge exitEdge : loop.getExitEdges()) { + if (!exitBlocks.contains(exitEdge.getSource())) { + continue; + } + insertBreak(stack, loopExit, exitEdge); } - insertBreak(stack, loopExit, exitEdge); } } diff --git a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java index 6bbce0d4c..0f25a1c6d 100644 --- a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java @@ -45,6 +45,18 @@ public class BlockUtils { } } + public static BlockNode selectOtherSafe(BlockNode node, List blocks) { + int size = blocks.size(); + if (size == 1) { + BlockNode first = blocks.get(0); + return first != node ? first : null; + } else if (size == 2) { + BlockNode first = blocks.get(0); + return first != node ? first : blocks.get(1); + } + return null; + } + private static List cleanBlockList(List list) { List ret = new ArrayList(list.size()); for (BlockNode block : list) { diff --git a/jadx-core/src/test/java/jadx/tests/internal/loops/TestLoopDetection3.java b/jadx-core/src/test/java/jadx/tests/internal/loops/TestLoopDetection3.java new file mode 100644 index 000000000..444b90814 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/internal/loops/TestLoopDetection3.java @@ -0,0 +1,44 @@ +package jadx.tests.internal.loops; + +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 TestLoopDetection3 extends InternalJadxTest { + + public static class TestCls { + + private void test(TestCls parent, int pos) { + Object item; + while (--pos >= 0) { + item = parent.get(pos); + if (item instanceof String) { + func((String) item); + return; + } + } + } + + private Object get(int pos) { + return null; + } + + private void func(String item) { + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + System.out.println(code); + + assertThat(code, containsString("while")); + // TODO + // assertThat(code, containsString("while (--pos >= 0) {")); + } +}