From 272e0d3754ad243d15b290ec392fb67ea75e38ae Mon Sep 17 00:00:00 2001 From: "13.beta2" Date: Tue, 26 Nov 2013 23:56:17 +0400 Subject: [PATCH] core: fix missing code after 'if' inside loop --- .../core/dex/visitors/BlockMakerVisitor.java | 1 - .../dex/visitors/regions/RegionMaker.java | 42 ++++++++++++++++--- .../tests/internal/TestLoopCondition.java | 12 ++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java index 220bdbb1d..de1f42559 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java @@ -353,7 +353,6 @@ public class BlockMakerVisitor extends AbstractVisitor { // splice return block if several predecessors presents for (BlockNode block : mth.getExitBlocks()) { if (block.getInstructions().size() == 1 - && block.getInstructions().get(0).getArgsCount() > 0 && !block.getInstructions().get(0).getAttributes().contains(AttributeType.CATCH_BLOCK) && !block.getAttributes().contains(AttributeFlag.SYNTHETIC)) { List preds = new ArrayList(block.getPredecessors()); 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 dbe80836d..03ef833c0 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 @@ -265,10 +265,10 @@ public class RegionMaker { && r.getInstructions().size() > 0 && r.getInstructions().get(0).getType() == InsnType.RETURN) { next.getAttributes().add(new ForceReturnAttr(r.getInstructions().get(0))); - } else { + } /*/ else { next.getAttributes().add(AttributeFlag.BREAK); stack.addExit(r); - } + } /**/ } else { stack.addExit(next); } @@ -492,8 +492,10 @@ public class RegionMaker { IfCondition nestedCondition = IfCondition.fromIfNode(nestedIfInsn); if (isPathExists(bElse, nestedIfBlock)) { // else branch - if (bThen != nbThen) { - if (bThen != nbElse) { + if (bThen != nbThen + && !isEqualReturns(bThen, nbThen)) { + if (bThen != nbElse + && !isEqualReturns(bThen, nbElse)) { // not connected conditions break; } @@ -503,8 +505,10 @@ public class RegionMaker { condition = IfCondition.merge(Mode.OR, condition, nestedCondition); } else { // then branch - if (bElse != nbElse) { - if (bElse != nbThen) { + if (bElse != nbElse + && !isEqualReturns(bElse, nbElse)) { + if (bElse != nbThen + && !isEqualReturns(bElse, nbThen)) { // not connected conditions break; } @@ -516,6 +520,8 @@ public class RegionMaker { result = new IfInfo(); result.setCondition(condition); nestedIfBlock.getAttributes().add(AttributeFlag.SKIP); + bThen.getAttributes().add(AttributeFlag.SKIP); + if (merged != null) { merged.add(nestedIfBlock); } @@ -683,4 +689,28 @@ public class RegionMaker { handler.getHandlerRegion().getAttributes().add(excHandlerAttr); } + private boolean isEqualReturns(BlockNode b1, BlockNode b2) { + if (b1 == b2) { + return true; + } + if (b1 == null + || b2 == null) { + return false; + } + if (b1.getInstructions().size() + + b2.getInstructions().size() != 2) { + return false; + } + if (!b1.getAttributes().contains(AttributeFlag.RETURN) + || !b2.getAttributes().contains(AttributeFlag.RETURN)) { + return false; + } + if (b1.getInstructions().get(0).getArgsCount() > 0) { + if (b1.getInstructions().get(0).getArg(0) + != b2.getInstructions().get(0).getArg(0)) { + return false; + } + } + return true; + } } diff --git a/jadx-core/src/test/java/jadx/tests/internal/TestLoopCondition.java b/jadx-core/src/test/java/jadx/tests/internal/TestLoopCondition.java index c53b141b0..6d16f4d77 100644 --- a/jadx-core/src/test/java/jadx/tests/internal/TestLoopCondition.java +++ b/jadx-core/src/test/java/jadx/tests/internal/TestLoopCondition.java @@ -39,6 +39,16 @@ public class TestLoopCondition extends InternalJadxTest { } return i; } + + private void testMoreComplexIfInLoop(java.util.ArrayList list) throws Exception { + for (int i = 0; i != 16 && i < 255; i++) { + list.set(i, "ABC"); + if (i == 128) { + return; + } + list.set(i, "DEF"); + } + } } @Test @@ -50,5 +60,7 @@ public class TestLoopCondition extends InternalJadxTest { assertThat(code, containsString("i < f.length()")); assertThat(code, containsString("while (a && i < 10) {")); + assertThat(code, containsString("list.set(i, \"ABC\")")); + assertThat(code, containsString("list.set(i, \"DEF\")")); } }