WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 0586388

Browse files
authored
fix: detect more for-each loops (also prevent issues with missing generics types) (PR #2689)
1 parent 3e20850 commit 0586388

File tree

3 files changed

+146
-1
lines changed

3 files changed

+146
-1
lines changed

jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ private static boolean checkInvoke(InsnNode insn, String declClsFullName, String
396396
if (insn.getType() == InsnType.INVOKE) {
397397
InvokeNode inv = (InvokeNode) insn;
398398
MethodInfo callMth = inv.getCallMth();
399-
if (inv.getInvokeType() == InvokeType.INTERFACE
399+
if ((inv.getInvokeType() == InvokeType.INTERFACE || inv.getInvokeType() == InvokeType.VIRTUAL)
400400
&& callMth.getShortId().equals(mthId)) {
401401
if (declClsFullName == null) {
402402
return true;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package jadx.tests.integration.generics;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import jadx.tests.api.SmaliTest;
6+
7+
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
8+
9+
public class TestMissingGenericsTypes2 extends SmaliTest {
10+
// @formatter:off
11+
/*
12+
package generics;
13+
14+
import java.util.Iterator;
15+
16+
public class TestMissingGenericsTypes2<T> implements Iterable<T> {
17+
18+
@Override
19+
public Iterator<T> iterator() {
20+
return null;
21+
}
22+
23+
public void test(TestMissingGenericsTypes2<String> l) {
24+
Iterator<String> i = l.iterator(); // <-- This generics type was removed in smali
25+
while (i.hasNext()) {
26+
String s = i.next();
27+
doSomething(s);
28+
}
29+
}
30+
31+
private void doSomething(String s) {
32+
}
33+
}
34+
*/
35+
// @formatter:on
36+
37+
@Test
38+
public void test() {
39+
assertThat(getClassNodeFromSmali())
40+
.code()
41+
.contains("for (String s : l) {")
42+
.doesNotContain("Iterator i");
43+
}
44+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
.class public Lgenerics/TestMissingGenericsTypes2;
2+
.super Ljava/lang/Object;
3+
.source "TestMissingGenericsTypes2.java"
4+
5+
# interfaces
6+
.implements Ljava/lang/Iterable;
7+
8+
9+
# annotations
10+
.annotation system Ldalvik/annotation/Signature;
11+
value = {
12+
"<T:",
13+
"Ljava/lang/Object;",
14+
">",
15+
"Ljava/lang/Object;",
16+
"Ljava/lang/Iterable<",
17+
"TT;>;"
18+
}
19+
.end annotation
20+
21+
22+
# direct methods
23+
.method public constructor <init>()V
24+
.registers 1
25+
26+
.local p0, "this":Lgenerics/TestMissingGenericsTypes2;, "Lgenerics/TestMissingGenericsTypes2<TT;>;"
27+
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
28+
29+
return-void
30+
.end method
31+
32+
.method private doSomething(Ljava/lang/String;)V
33+
.registers 2
34+
.param p1, "s" # Ljava/lang/String;
35+
36+
.local p0, "this":Lgenerics/TestMissingGenericsTypes2;, "Lgenerics/TestMissingGenericsTypes2<TT;>;"
37+
return-void
38+
.end method
39+
40+
41+
# virtual methods
42+
.method public iterator()Ljava/util/Iterator;
43+
.registers 2
44+
.annotation system Ldalvik/annotation/Signature;
45+
value = {
46+
"()",
47+
"Ljava/util/Iterator<",
48+
"TT;>;"
49+
}
50+
.end annotation
51+
52+
.local p0, "this":Lgenerics/TestMissingGenericsTypes2;, "Lgenerics/TestMissingGenericsTypes2<TT;>;"
53+
const/4 v0, 0x0
54+
55+
return-object v0
56+
.end method
57+
58+
.method public test(Lgenerics/TestMissingGenericsTypes2;)V
59+
.registers 4
60+
.annotation system Ldalvik/annotation/Signature;
61+
value = {
62+
"(",
63+
"Lgenerics/TestMissingGenericsTypes2<",
64+
"Ljava/lang/String;",
65+
">;)V"
66+
}
67+
.end annotation
68+
69+
.local p0, "this":Lgenerics/TestMissingGenericsTypes2;, "Lgenerics/TestMissingGenericsTypes2<TT;>;"
70+
.local p1, "l":Lgenerics/TestMissingGenericsTypes2;, "Lgenerics/TestMissingGenericsTypes2<Ljava/lang/String;>;"
71+
invoke-virtual {p1}, Lgenerics/TestMissingGenericsTypes2;->iterator()Ljava/util/Iterator;
72+
73+
move-result-object v0
74+
75+
# original:
76+
# .local v0, "i":Ljava/util/Iterator;, "Ljava/util/Iterator<Ljava/lang/String;>;"
77+
# manipulated: removed generic type
78+
.local v0, "i":Ljava/util/Iterator;
79+
80+
:goto_4
81+
invoke-interface {v0}, Ljava/util/Iterator;->hasNext()Z
82+
83+
move-result v1
84+
85+
if-eqz v1, :cond_14
86+
87+
invoke-interface {v0}, Ljava/util/Iterator;->next()Ljava/lang/Object;
88+
89+
move-result-object v1
90+
91+
check-cast v1, Ljava/lang/String;
92+
93+
.local v1, "s":Ljava/lang/String;
94+
invoke-direct {p0, v1}, Lgenerics/TestMissingGenericsTypes2;->doSomething(Ljava/lang/String;)V
95+
96+
.end local v1 # "s":Ljava/lang/String;
97+
goto :goto_4
98+
99+
:cond_14
100+
return-void
101+
.end method

0 commit comments

Comments
 (0)