diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/IfNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/IfNode.java index a14ace1df..be953902e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/IfNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/IfNode.java @@ -1,5 +1,7 @@ package jadx.core.dex.instructions; +import java.util.List; + import com.android.dx.io.instructions.DecodedInstruction; import jadx.core.dex.instructions.args.ArgType; @@ -57,11 +59,12 @@ public class IfNode extends GotoNode { @Override public void initBlocks(BlockNode curBlock) { - thenBlock = getBlockByOffset(target, curBlock.getSuccessors()); - if (curBlock.getSuccessors().size() == 1) { + List successors = curBlock.getSuccessors(); + thenBlock = getBlockByOffset(target, successors); + if (successors.size() == 1) { elseBlock = thenBlock; } else { - elseBlock = selectOther(thenBlock, curBlock.getSuccessors()); + elseBlock = selectOther(thenBlock, successors); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java index 4ef80c231..38d947258 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java @@ -2,6 +2,7 @@ package jadx.core.dex.visitors.regions; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Set; import org.slf4j.Logger; @@ -52,6 +53,12 @@ public class IfMakerHelper { BlockNode thenBlock = info.getThenBlock(); BlockNode elseBlock = info.getElseBlock(); + if (Objects.equals(thenBlock, elseBlock)) { + IfInfo ifInfo = new IfInfo(info, null, null); + ifInfo.setOutBlock(thenBlock); + return ifInfo; + } + // select 'then', 'else' and 'exit' blocks if (thenBlock.contains(AFlag.RETURN) && elseBlock.contains(AFlag.RETURN)) { info.setOutBlock(null); 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 8334da4ea..ad807a5b7 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 @@ -60,21 +60,26 @@ public class RegionMaker { private final MethodNode mth; private int regionsCount; - private Region[] regionByBlock; + private BitSet processedBlocks; public RegionMaker(MethodNode mth) { this.mth = mth; - this.regionByBlock = new Region[mth.getBasicBlocks().size()]; + this.processedBlocks = new BitSet(mth.getBasicBlocks().size()); } public Region makeRegion(BlockNode startBlock, RegionStack stack) { - int startBlockId = startBlock.getId(); - Region region = regionByBlock[startBlockId]; - if (region != null) { - return region; + Region r = new Region(stack.peekRegion()); + if (startBlock == null) { + return r; } - Region r = new Region(stack.peekRegion()); + int startBlockId = startBlock.getId(); + if (processedBlocks.get(startBlockId)) { + mth.addWarn("Removed duplicated region for block: " + startBlock + " " + startBlock.getAttributesString()); + return r; + } + processedBlocks.set(startBlockId); + BlockNode next = startBlock; while (next != null) { next = traverse(r, next, stack); @@ -83,7 +88,6 @@ public class RegionMaker { throw new JadxRuntimeException("Regions count limit reached"); } } - regionByBlock[startBlockId] = r; return r; } @@ -201,6 +205,7 @@ public class RegionMaker { loopStart.remove(AType.LOOP); loop.getEnd().add(AFlag.SKIP); stack.addExit(loop.getEnd()); + processedBlocks.clear(loopStart.getId()); Region body = makeRegion(loopStart, stack); loopRegion.setBody(body); loopStart.addAttr(AType.LOOP, loop); @@ -296,6 +301,7 @@ public class RegionMaker { curRegion.getSubBlocks().add(loopRegion); loopStart.remove(AType.LOOP); + processedBlocks.clear(loopStart.getId()); stack.push(loopRegion); BlockNode out = null; @@ -850,7 +856,7 @@ public class RegionMaker { } private Map> reOrderSwitchCases(Map> blocksMap, - Map fallThroughCases) { + Map fallThroughCases) { List list = new ArrayList<>(blocksMap.size()); list.addAll(blocksMap.keySet()); list.sort((a, b) -> { diff --git a/jadx-core/src/test/java/jadx/tests/integration/TestWrongCode.java b/jadx-core/src/test/java/jadx/tests/integration/TestWrongCode.java index 894f0c248..c175f851b 100644 --- a/jadx-core/src/test/java/jadx/tests/integration/TestWrongCode.java +++ b/jadx-core/src/test/java/jadx/tests/integration/TestWrongCode.java @@ -5,6 +5,7 @@ import org.junit.Test; import jadx.core.dex.nodes.ClassNode; import jadx.tests.api.IntegrationTest; +import static jadx.tests.api.utils.JadxMatchers.containsLines; import static jadx.tests.api.utils.JadxMatchers.containsOne; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.not; @@ -18,10 +19,8 @@ public class TestWrongCode extends IntegrationTest { return a.length; } - @SuppressWarnings("empty") private int test2(int a) { if (a == 0) { - ; } return a; } @@ -36,7 +35,11 @@ public class TestWrongCode extends IntegrationTest { assertThat(code, containsOne("int[] a = null;")); assertThat(code, containsOne("return a.length;")); - assertThat(code, containsString("return a == 0 ? a : a;")); + assertThat(code, containsLines(2, + "if (a == 0) {", + "}", + "return a;" + )); } @Test