Skip to content

Commit 02dba8a

Browse files
authored
Merge pull request #791 from t1mlange/sink-ret-parse
Add support for CallType.Return in the XML Parser and add subclass check
2 parents 8f818c0 + 6e45a32 commit 02dba8a

File tree

7 files changed

+74
-3
lines changed

7 files changed

+74
-3
lines changed

soot-infoflow-android/schema/SourcesAndSinks.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
<xs:restriction base="xs:string">
5151
<xs:enumeration value="methodCall" />
5252
<xs:enumeration value="callback" />
53+
<xs:enumeration value="return" />
5354
</xs:restriction>
5455
</xs:simpleType>
5556

soot-infoflow-android/src/soot/jimple/infoflow/android/source/parsers/xml/AbstractXMLSourceSinkParser.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ protected void handleStarttagMeethod(Attributes attributes) {
223223
callType = CallType.MethodCall;
224224
else if (strCallType.equalsIgnoreCase("Callback"))
225225
callType = CallType.Callback;
226+
else if (strCallType.equalsIgnoreCase("Return"))
227+
callType = CallType.Return;
226228
}
227229
}
228230
}

soot-infoflow-android/src/soot/jimple/infoflow/android/source/parsers/xml/XMLSourceSinkParser.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,18 @@ protected void buildSourceSinkLists() {
123123
if (sourceDef != null && !sourceDef.isEmpty()) {
124124
if (sourceDef instanceof MethodSourceSinkDefinition) {
125125
MethodSourceSinkDefinition methodSrc = (MethodSourceSinkDefinition) sourceDef;
126-
if (methodSrc.getMethod() instanceof AndroidMethod) {
126+
if (methodSrc.getCallType() == CallType.Return) {
127+
String mname = methodSrc.getMethod().getMethodName();
128+
logger.error(String.format("Error while building sources for %s: CallType Return is not " +
129+
"supported for Source Definitions. The invalid definition is ignored.", mname));
130+
sourceDef = null;
131+
} else if (methodSrc.getMethod() instanceof AndroidMethod) {
127132
AndroidMethod am = (AndroidMethod) methodSrc.getMethod();
128133
am.setSourceSinkType(am.getSourceSinkType().addType(SourceSinkType.Source));
129134
}
130135
}
131-
sources.add(sourceDef);
136+
if (sourceDef != null)
137+
sources.add(sourceDef);
132138
}
133139

134140
ISourceSinkDefinition sinkDef = def.getSinkOnlyDefinition();

soot-infoflow-android/test/soot/jimple/infoflow/android/test/xmlParser/XmlParserTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,4 +282,31 @@ public void additionalFlowsXMLTest() throws IOException {
282282
}
283283
Assert.assertTrue(foundStrSig && foundStrOffsetSig && foundIntSig && foundByteSig);
284284
}
285+
286+
@Test
287+
public void returnCallTypeTest() throws IOException {
288+
File xmlFile = new File(getInfoflowAndroidRoot(), "testXmlParser/returnCallType.xml");
289+
XMLSourceSinkParser parser = XMLSourceSinkParser.fromFile(xmlFile);
290+
Set<ISourceSinkDefinition> sinkSet = parser.getSinks();
291+
292+
final String expectedSig = "<android.content.ContentProvider: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)>";
293+
294+
Assert.assertEquals(0, parser.getSources().size());
295+
Assert.assertEquals(1, sinkSet.size());
296+
ISourceSinkDefinition sink = sinkSet.iterator().next();
297+
Assert.assertTrue(sink instanceof MethodSourceSinkDefinition);
298+
MethodSourceSinkDefinition methodSink = (MethodSourceSinkDefinition) sink;
299+
String methodSig = methodSink.getMethod().getSignature();
300+
Assert.assertEquals(expectedSig, methodSig);
301+
Assert.assertEquals(methodSink.getCallType(), MethodSourceSinkDefinition.CallType.Return);
302+
Assert.assertEquals(1, methodSink.getReturnValues().size());
303+
}
304+
305+
@Test
306+
public void invalidReturnCallTypeTest() throws IOException {
307+
File xmlFile = new File(getInfoflowAndroidRoot(), "testXmlParser/invalidReturnCallType.xml");
308+
XMLSourceSinkParser parser = XMLSourceSinkParser.fromFile(xmlFile);
309+
Assert.assertEquals(0, parser.getSinks().size());
310+
Assert.assertEquals(0, parser.getSources().size());
311+
}
285312
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<sinkSources>
2+
<category id="NO_CATEGORY">
3+
<method callType="return" signature="android.content.ContentProvider: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)">
4+
<return>
5+
<accessPath isSource="true" isSink="false" />
6+
</return>
7+
</method>
8+
</category>
9+
</sinkSources>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<sinkSources>
2+
<category id="NO_CATEGORY">
3+
<method callType="return" signature="android.content.ContentProvider: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)">
4+
<return>
5+
<accessPath isSource="false" isSink="true" />
6+
</return>
7+
</method>
8+
</category>
9+
</sinkSources>

soot-infoflow/src/soot/jimple/infoflow/sourcesSinks/manager/BaseSourceSinkManager.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,24 @@ protected Collection<ISourceSinkDefinition> getSinkDefinitions(Stmt sCallSite, I
320320
return def;
321321
}
322322
} else if (sCallSite instanceof ReturnStmt) {
323-
return sinkReturnMethods.get(manager.getICFG().getMethodOf(sCallSite));
323+
SootMethod sm = manager.getICFG().getMethodOf(sCallSite);
324+
// Do we have a direct hit?
325+
{
326+
Collection<ISourceSinkDefinition> def = this.sinkReturnMethods.get(sm);
327+
if (!def.isEmpty())
328+
return def;
329+
}
330+
331+
final String subSig = sm.getSubSignature();
332+
333+
// Check whether we have any of the interfaces on the list
334+
for (SootClass i : parentClassesAndInterfaces.getUnchecked(sm.getDeclaringClass())) {
335+
if (i.declaresMethod(subSig)) {
336+
Collection<ISourceSinkDefinition> def = this.sinkReturnMethods.get(i.getMethod(subSig));
337+
if (!def.isEmpty())
338+
return def;
339+
}
340+
}
324341
}
325342

326343
// nothing found

0 commit comments

Comments
 (0)