Commit 2cf28eb2 authored by Skylot's avatar Skylot

core: fix loop detection

parent 2b300341
......@@ -244,7 +244,6 @@ public class RegionMaker {
}
}
stack.push(loopRegion);
curRegion.getSubBlocks().add(loopRegion);
exitBlocks.remove(condBlock);
......@@ -290,9 +289,12 @@ public class RegionMaker {
out = (bThen == loopStart ? bElse : bThen);
loopStart.getAttributes().remove(AttributeType.LOOP);
stack.push(loopRegion);
stack.addExit(loop.getEnd());
loopRegion.setBody(makeRegion(loopStart, stack));
loopStart.getAttributes().add(loop);
stack.pop();
} else {
Set<BlockNode> loopBlocks = loop.getLoopBlocks();
BlockNode loopBody = null;
......@@ -308,14 +310,18 @@ public class RegionMaker {
out = selectOther(loopBody, condBlock.getSuccessors());
AttributesList outAttrs = out.getAttributes();
if (outAttrs.contains(AttributeFlag.LOOP_START)
&& outAttrs.get(AttributeType.LOOP) != loop) {
&& outAttrs.get(AttributeType.LOOP) != loop
&& stack.peekRegion() instanceof LoopRegion
&& RegionUtils.isRegionContainsBlock(stack.peekRegion(), out)) {
// exit to outer loop which already processed
out = null;
}
stack.push(loopRegion);
stack.addExit(out);
loopRegion.setBody(makeRegion(loopBody, stack));
stack.pop();
}
stack.pop();
return out;
}
......
package jadx.tests.internal;
package jadx.tests.internal.loops;
import jadx.api.InternalJadxTest;
import jadx.core.dex.nodes.ClassNode;
......
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 TestLoopDetection extends InternalJadxTest {
public static class TestCls {
private void test(int[] a, int b) {
int i = 0;
while (i < a.length && i < b) {
a[i]++;
i++;
}
while (i < a.length) {
a[i]--;
i++;
}
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
System.out.println(code);
assertThat(code, containsString("while (i < a.length && i < b) {"));
assertThat(code, containsString("while (i < a.length) {"));
}
}
package jadx.tests.internal.loops;
import jadx.api.InternalJadxTest;
import jadx.core.dex.nodes.ClassNode;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
public class TestNestedLoops extends InternalJadxTest {
public static class TestCls {
private void test(List<String> l1, List<String> l2) {
Iterator<String> it1 = l1.iterator();
while (it1.hasNext()) {
String s1 = it1.next();
Iterator<String> it2 = l2.iterator();
while (it2.hasNext()) {
String s2 = it2.next();
if (s1.equals(s2)) {
if (s1.length() == 5) {
l2.add(s1);
} else {
l1.remove(s2);
}
}
}
}
if (l2.size() > 0) {
l1.clear();
}
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
System.out.println(code);
assertThat(code, containsString("while (it1.hasNext()) {"));
assertThat(code, containsString("while (it2.hasNext()) {"));
assertThat(code, containsString("if (s1.equals(s2)) {"));
assertThat(code, containsString("l2.add(s1);"));
}
}
......@@ -87,6 +87,23 @@ public class TestCF3 extends AbstractTest {
return j > 10;
}
private int testLoops(int[] a, int b) {
int i = 0;
while (i < a.length && i < b) {
a[i]++;
i++;
}
while (i < a.length) {
a[i]--;
i++;
}
int sum = 0;
for (int e : a) {
sum += e;
}
return sum;
}
public static boolean testLabeledBreakContinue() {
String searchMe = "Look for a substring in me";
String substring = "sub";
......@@ -227,6 +244,8 @@ public class TestCF3 extends AbstractTest {
assertEquals(testComplexIfInLoop3(6), 6);
assertEquals(testComplexIfInLoop3(8), 24);
assertEquals(testLoops(new int[]{1, 2, 3, 4, 5, 6}, 2), 19);
assertTrue(testInline() > 20);
assertTrue(testInline2());
return true;
......
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