Skip to content

Commit c675028

Browse files
committed
Add Fragment and Activity edge case
1 parent 9ae1f1c commit c675028

File tree

2 files changed

+75
-5
lines changed

2 files changed

+75
-5
lines changed

java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,26 @@ class OnActivityResultIncomingIntent extends DataFlow::Node {
2828
* Intent to `onActivityResult`.
2929
*/
3030
predicate isRemoteSource() {
31-
exists(ImplicitStartActivityForResultConf conf, DataFlow::Node sink |
31+
exists(ImplicitStartActivityForResultConf conf, RefType startingType, DataFlow::Node sink |
3232
conf.hasFlowTo(sink) and
33-
DataFlow::getInstanceArgument(sink.asExpr().(Argument).getCall()).getType() =
34-
this.getEnclosingCallable().getDeclaringType()
33+
startingType = sink.asExpr().(Argument).getCall().getEnclosingCallable().getDeclaringType()
34+
|
35+
startingType = this.getEnclosingCallable().getDeclaringType()
36+
or
37+
// A fragment calls `startActivityForResult`
38+
// and the activity it belongs to defines `onActivityResult`.
39+
exists(MethodAccess ma |
40+
ma.getMethod().hasName(["add", "attach", "replace"]) and
41+
ma.getMethod().getDeclaringType().hasName("FragmentTransaction") and
42+
any(Argument arg | arg = ma.getAnArgument()).getType() = startingType
43+
or
44+
ma.getMethod().hasName("show") and
45+
ma.getMethod().getDeclaringType().getASupertype*().hasName("DialogFragment") and
46+
startingType = ma.getQualifier().getType()
47+
|
48+
ma.getEnclosingCallable().getDeclaringType() =
49+
this.getEnclosingCallable().getDeclaringType()
50+
)
3551
)
3652
}
3753
}
@@ -49,16 +65,38 @@ private class ImplicitStartActivityForResultConf extends DataFlow5::Configuratio
4965
}
5066

5167
override predicate isSink(DataFlow::Node sink) {
52-
exists(ActivityOrFragment actOrFrag, MethodAccess startActivityForResult |
68+
exists(MethodAccess startActivityForResult |
5369
startActivityForResult.getMethod().hasName("startActivityForResult") and
54-
startActivityForResult.getEnclosingCallable() = actOrFrag.getACallable() and
70+
startActivityForResult.getMethod().getDeclaringType().getASupertype*() instanceof
71+
ActivityOrFragment and
5572
sink.asExpr() = startActivityForResult.getArgument(0)
5673
)
5774
}
5875

5976
override predicate isBarrier(DataFlow::Node barrier) {
6077
barrier instanceof ExplicitIntentSanitizer
6178
}
79+
80+
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
81+
// Wrapping the Intent in a chooser
82+
exists(MethodAccess ma, Method m |
83+
ma.getMethod() = m and
84+
m.hasName("createChooser") and
85+
m.getDeclaringType() instanceof TypeIntent
86+
|
87+
node1.asExpr() = ma.getArgument(0) and
88+
node2.asExpr() = ma
89+
)
90+
or
91+
// Using the copy constructor
92+
exists(ClassInstanceExpr cie |
93+
cie.getConstructedType() instanceof TypeIntent and
94+
cie.getArgument(0).getType() instanceof TypeIntent
95+
|
96+
node1.asExpr() = cie.getArgument(0) and
97+
node2.asExpr() = cie
98+
)
99+
}
62100
}
63101

64102
/** An Android Activity or Fragment. */
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import android.app.Activity;
2+
import android.app.Fragment;
3+
import android.content.Intent;
4+
import android.os.Bundle;
5+
import androidx.fragment.app.FragmentTransaction;
6+
7+
public class TestActivityAndFragment extends Activity {
8+
9+
private TestFragment frag;
10+
11+
void sink(Object o) {}
12+
13+
public void onCreate(Bundle saved) {
14+
FragmentTransaction ft = null;
15+
ft.add(0, frag);
16+
17+
}
18+
19+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
20+
sink(requestCode); // safe
21+
sink(resultCode); // safe
22+
sink(data); // $ hasValueFlow
23+
}
24+
25+
private class TestFragment extends Fragment {
26+
public void onCreate(Bundle savedInstance) {
27+
Intent implicitIntent = new Intent("SOME_ACTION");
28+
startActivityForResult(implicitIntent, 0);
29+
}
30+
31+
}
32+
}

0 commit comments

Comments
 (0)