Commit 343bddc6 authored by Skylot's avatar Skylot

core: fix 'break' detection in loop

parent 632a742e
......@@ -181,7 +181,6 @@ public final class Decompiler {
}
void processClass(ClassNode cls) {
LOG.debug("processing class {} ...", cls);
ProcessClass.process(cls, passes);
}
......
......@@ -104,7 +104,8 @@ public class ClassNode extends LineAttrNode implements ILoadable {
int sfIdx = cls.getSourceFileIndex();
if (sfIdx != DexNode.NO_INDEX) {
String fileName = dex.getString(sfIdx);
if (!this.getFullName().contains(fileName.replace(".java", ""))) {
if (!this.getFullName().contains(fileName.replace(".java", ""))
&& !fileName.equals("SourceFile")) {
this.getAttributes().add(new SourceFileAttr(fileName));
LOG.debug("Class '{}' compiled from '{}'", this, fileName);
}
......
......@@ -238,13 +238,15 @@ public class RegionMaker {
exitBlocks.remove(condBlock);
if (exitBlocks.size() > 0) {
// add 'break' instruction before path cross between main loop exit and subexit
BlockNode loopExit = BlockUtils.selectOther(loopBody, condBlock.getCleanSuccessors());
for (Edge exitEdge : loop.getExitEdges()) {
if (!exitBlocks.contains(exitEdge.getSource())) {
continue;
BlockNode loopExit = BlockUtils.selectOtherSafe(loopBody, condBlock.getCleanSuccessors());
if (loopExit != null) {
// add 'break' instruction before path cross between main loop exit and subexit
for (Edge exitEdge : loop.getExitEdges()) {
if (!exitBlocks.contains(exitEdge.getSource())) {
continue;
}
insertBreak(stack, loopExit, exitEdge);
}
insertBreak(stack, loopExit, exitEdge);
}
}
......
......@@ -45,6 +45,18 @@ public class BlockUtils {
}
}
public static BlockNode selectOtherSafe(BlockNode node, List<BlockNode> blocks) {
int size = blocks.size();
if (size == 1) {
BlockNode first = blocks.get(0);
return first != node ? first : null;
} else if (size == 2) {
BlockNode first = blocks.get(0);
return first != node ? first : blocks.get(1);
}
return null;
}
private static List<BlockNode> cleanBlockList(List<BlockNode> list) {
List<BlockNode> ret = new ArrayList<BlockNode>(list.size());
for (BlockNode block : list) {
......
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 TestLoopDetection3 extends InternalJadxTest {
public static class TestCls {
private void test(TestCls parent, int pos) {
Object item;
while (--pos >= 0) {
item = parent.get(pos);
if (item instanceof String) {
func((String) item);
return;
}
}
}
private Object get(int pos) {
return null;
}
private void func(String item) {
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
System.out.println(code);
assertThat(code, containsString("while"));
// TODO
// assertThat(code, containsString("while (--pos >= 0) {"));
}
}
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