core: fix loop detection
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package jadx.tests.internal;
|
||||
package jadx.tests.internal.loops;
|
||||
|
||||
import jadx.api.InternalJadxTest;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
@@ -0,0 +1,37 @@
|
||||
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) {"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user