|
3 | 3 | import org.junit.Assert; |
4 | 4 | import org.junit.Test; |
5 | 5 | import org.xmlpull.v1.XmlPullParserException; |
| 6 | +import soot.SootMethod; |
6 | 7 | import soot.jimple.infoflow.InfoflowConfiguration; |
7 | 8 | import soot.jimple.infoflow.android.SetupApplication; |
| 9 | +import soot.jimple.infoflow.android.data.parsers.PermissionMethodParser; |
8 | 10 | import soot.jimple.infoflow.methodSummary.taintWrappers.TaintWrapperFactory; |
| 11 | +import soot.jimple.infoflow.results.DataFlowResult; |
9 | 12 | import soot.jimple.infoflow.results.InfoflowResults; |
10 | 13 | import soot.jimple.infoflow.taintWrappers.ITaintPropagationWrapper; |
11 | | -import soot.jimple.infoflow.util.DebugFlowFunctionTaintPropagationHandler; |
12 | 14 |
|
13 | 15 | import javax.xml.stream.XMLStreamException; |
14 | 16 | import java.io.IOException; |
15 | 17 | import java.util.Collections; |
| 18 | +import java.util.*; |
16 | 19 |
|
17 | 20 | /** |
18 | 21 | * Tests that uncovered a bug. |
@@ -42,17 +45,47 @@ public void testFlowSensitivityWithOverwrite() throws XmlPullParserException, IO |
42 | 45 | Assert.assertEquals(2, results.getResultSet().size()); |
43 | 46 | } |
44 | 47 |
|
45 | | - |
46 | 48 | /** |
47 | 49 | * Tests that StubDroid correctly narrows the type when the summary is in a superclass. |
48 | 50 | * See also the comment in SummaryTaintWrapper#getSummaryDeclaringClass(). |
49 | 51 | */ |
50 | 52 | @Test |
51 | 53 | public void testTypeHierarchyFromSummary() throws XmlPullParserException, IOException { |
52 | 54 | SetupApplication app = initApplication("testAPKs/TypeHierarchyTest.apk"); |
53 | | - app.setTaintPropagationHandler(new DebugFlowFunctionTaintPropagationHandler()); |
54 | 55 | InfoflowResults results = app.runInfoflow("../soot-infoflow-android/SourcesAndSinks.txt"); |
55 | 56 | Assert.assertEquals(1, results.size()); |
56 | 57 | Assert.assertEquals(1, results.getResultSet().size()); |
57 | 58 | } |
| 59 | + |
| 60 | + /** |
| 61 | + * Tests an app that uses the kotlin collections. |
| 62 | + * Expects four leaks: |
| 63 | + * * From getDeviceId() in onCreate() to Log.d(String, String) |
| 64 | + * in listFlow(String), mapFlow(String) and setFlow(String). |
| 65 | + * * From new File in fileFlow() to Log.d(String, String) in fileFlow(String). |
| 66 | + */ |
| 67 | + @Test |
| 68 | + public void testKotlinAppWithCollections() throws IOException { |
| 69 | + SetupApplication app = initApplication("testAPKs/KotlinCollectionApp.apk"); |
| 70 | + |
| 71 | + // Make sure we find only one flow per method |
| 72 | + app.addResultsAvailableHandler((cfg, results) -> { |
| 73 | + Set<SootMethod> seenSet = new HashSet<>(); |
| 74 | + for (DataFlowResult res : results.getResultSet()) { |
| 75 | + SootMethod sm = cfg.getMethodOf(res.getSink().getStmt()); |
| 76 | + Assert.assertFalse(seenSet.contains(sm)); |
| 77 | + seenSet.add(sm); |
| 78 | + } |
| 79 | + }); |
| 80 | + |
| 81 | + // Add the sources and sinks |
| 82 | + List<String> ssinks = new ArrayList<>(); |
| 83 | + ssinks.add("<android.telephony.TelephonyManager: java.lang.String getDeviceId()> android.permission.READ_PHONE_STATE -> _SOURCE_"); |
| 84 | + ssinks.add("<android.util.Log: int d(java.lang.String,java.lang.String)> -> _SINK_"); |
| 85 | + ssinks.add("<kotlin.io.TextStreamsKt: java.util.List readLines(java.io.Reader)> -> _SOURCE_"); |
| 86 | + |
| 87 | + InfoflowResults results = app.runInfoflow(PermissionMethodParser.fromStringList(ssinks)); |
| 88 | + Assert.assertEquals(4, results.size()); |
| 89 | + Assert.assertEquals(4, results.getResultSet().size()); |
| 90 | + } |
58 | 91 | } |
0 commit comments