diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java index 9b1e170c468..e41c4f8c0a1 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java @@ -256,6 +256,13 @@ private static boolean checkIterableForEach(MethodNode mth, LoopRegion loopRegio if (iterVar == null) { return false; } + if (!usedOnlyInLoop(mth, loopRegion, iterVar)) { + return false; + } + if (!assignOnlyInLoop(mth, loopRegion, iterVar)) { + return false; + } + if (nextCall.contains(AFlag.WRAPPED)) { InsnArg wrapArg = BlockUtils.searchWrappedInsnParent(mth, nextCall); if (wrapArg != null && wrapArg.getParentInsn() != null) { diff --git a/jadx-core/src/test/java/jadx/tests/integration/loops/TestLoopDetection5.java b/jadx-core/src/test/java/jadx/tests/integration/loops/TestLoopDetection5.java new file mode 100644 index 00000000000..4329d9af73d --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/loops/TestLoopDetection5.java @@ -0,0 +1,52 @@ +package jadx.tests.integration.loops; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.IntegrationTest; + +import static jadx.tests.api.utils.JadxMatchers.containsOne; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + +public class TestLoopDetection5 extends IntegrationTest { + + public static class TestCls { + + public String test(String str) { + Iterator it = getStrings().iterator(); + String otherStr = null; + while (it.hasNext()) { + otherStr = it.next(); + if (otherStr.equalsIgnoreCase(str)) { + break; + } + } + return otherStr; + } + + private List getStrings() { + return Arrays.asList("str", "otherStr", "STR", "OTHERSTR"); + } + + public void check() { + assertThat(test("OTHERSTR"), is("otherStr")); + } + } + + @Test + public void test() { + noDebugInfo(); + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + + assertThat(code, not(containsString("for ("))); + assertThat(code, containsOne("it.next();")); + } +}