Commit 7492889f authored by Skylot's avatar Skylot

core: prevent endless region processing (#340)

parent 0c041120
package jadx.core.dex.instructions; package jadx.core.dex.instructions;
import java.util.List;
import com.android.dx.io.instructions.DecodedInstruction; import com.android.dx.io.instructions.DecodedInstruction;
import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.ArgType;
...@@ -57,11 +59,12 @@ public class IfNode extends GotoNode { ...@@ -57,11 +59,12 @@ public class IfNode extends GotoNode {
@Override @Override
public void initBlocks(BlockNode curBlock) { public void initBlocks(BlockNode curBlock) {
thenBlock = getBlockByOffset(target, curBlock.getSuccessors()); List<BlockNode> successors = curBlock.getSuccessors();
if (curBlock.getSuccessors().size() == 1) { thenBlock = getBlockByOffset(target, successors);
if (successors.size() == 1) {
elseBlock = thenBlock; elseBlock = thenBlock;
} else { } else {
elseBlock = selectOther(thenBlock, curBlock.getSuccessors()); elseBlock = selectOther(thenBlock, successors);
} }
} }
......
...@@ -2,6 +2,7 @@ package jadx.core.dex.visitors.regions; ...@@ -2,6 +2,7 @@ package jadx.core.dex.visitors.regions;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -52,6 +53,12 @@ public class IfMakerHelper { ...@@ -52,6 +53,12 @@ public class IfMakerHelper {
BlockNode thenBlock = info.getThenBlock(); BlockNode thenBlock = info.getThenBlock();
BlockNode elseBlock = info.getElseBlock(); 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 // select 'then', 'else' and 'exit' blocks
if (thenBlock.contains(AFlag.RETURN) && elseBlock.contains(AFlag.RETURN)) { if (thenBlock.contains(AFlag.RETURN) && elseBlock.contains(AFlag.RETURN)) {
info.setOutBlock(null); info.setOutBlock(null);
......
...@@ -60,21 +60,26 @@ public class RegionMaker { ...@@ -60,21 +60,26 @@ public class RegionMaker {
private final MethodNode mth; private final MethodNode mth;
private int regionsCount; private int regionsCount;
private Region[] regionByBlock; private BitSet processedBlocks;
public RegionMaker(MethodNode mth) { public RegionMaker(MethodNode mth) {
this.mth = 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) { public Region makeRegion(BlockNode startBlock, RegionStack stack) {
Region r = new Region(stack.peekRegion());
if (startBlock == null) {
return r;
}
int startBlockId = startBlock.getId(); int startBlockId = startBlock.getId();
Region region = regionByBlock[startBlockId]; if (processedBlocks.get(startBlockId)) {
if (region != null) { mth.addWarn("Removed duplicated region for block: " + startBlock + " " + startBlock.getAttributesString());
return region; return r;
} }
processedBlocks.set(startBlockId);
Region r = new Region(stack.peekRegion());
BlockNode next = startBlock; BlockNode next = startBlock;
while (next != null) { while (next != null) {
next = traverse(r, next, stack); next = traverse(r, next, stack);
...@@ -83,7 +88,6 @@ public class RegionMaker { ...@@ -83,7 +88,6 @@ public class RegionMaker {
throw new JadxRuntimeException("Regions count limit reached"); throw new JadxRuntimeException("Regions count limit reached");
} }
} }
regionByBlock[startBlockId] = r;
return r; return r;
} }
...@@ -201,6 +205,7 @@ public class RegionMaker { ...@@ -201,6 +205,7 @@ public class RegionMaker {
loopStart.remove(AType.LOOP); loopStart.remove(AType.LOOP);
loop.getEnd().add(AFlag.SKIP); loop.getEnd().add(AFlag.SKIP);
stack.addExit(loop.getEnd()); stack.addExit(loop.getEnd());
processedBlocks.clear(loopStart.getId());
Region body = makeRegion(loopStart, stack); Region body = makeRegion(loopStart, stack);
loopRegion.setBody(body); loopRegion.setBody(body);
loopStart.addAttr(AType.LOOP, loop); loopStart.addAttr(AType.LOOP, loop);
...@@ -296,6 +301,7 @@ public class RegionMaker { ...@@ -296,6 +301,7 @@ public class RegionMaker {
curRegion.getSubBlocks().add(loopRegion); curRegion.getSubBlocks().add(loopRegion);
loopStart.remove(AType.LOOP); loopStart.remove(AType.LOOP);
processedBlocks.clear(loopStart.getId());
stack.push(loopRegion); stack.push(loopRegion);
BlockNode out = null; BlockNode out = null;
......
...@@ -5,6 +5,7 @@ import org.junit.Test; ...@@ -5,6 +5,7 @@ import org.junit.Test;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest; import jadx.tests.api.IntegrationTest;
import static jadx.tests.api.utils.JadxMatchers.containsLines;
import static jadx.tests.api.utils.JadxMatchers.containsOne; import static jadx.tests.api.utils.JadxMatchers.containsOne;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.not;
...@@ -18,10 +19,8 @@ public class TestWrongCode extends IntegrationTest { ...@@ -18,10 +19,8 @@ public class TestWrongCode extends IntegrationTest {
return a.length; return a.length;
} }
@SuppressWarnings("empty")
private int test2(int a) { private int test2(int a) {
if (a == 0) { if (a == 0) {
;
} }
return a; return a;
} }
...@@ -36,7 +35,11 @@ public class TestWrongCode extends IntegrationTest { ...@@ -36,7 +35,11 @@ public class TestWrongCode extends IntegrationTest {
assertThat(code, containsOne("int[] a = null;")); assertThat(code, containsOne("int[] a = null;"));
assertThat(code, containsOne("return a.length;")); assertThat(code, containsOne("return a.length;"));
assertThat(code, containsString("return a == 0 ? a : a;")); assertThat(code, containsLines(2,
"if (a == 0) {",
"}",
"return a;"
));
} }
@Test @Test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment