1616 * To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files.
1717 * Example of the corresponding test file, e.g. Test.java
1818 * ```swift
19- * func source() -> Any { return nil }
20- * func taint() -> Any { return nil }
19+ * func source(_ label: String ) -> Any { return nil }
20+ * func taint(_ label: String ) -> Any { return nil }
2121 * func sink(_ o: Any) { }
2222 *
2323 * func test() {
24- * let s = source()
25- * sink(s) // $ hasValueFlow
26- * let t = "foo" + taint()
27- * sink(t); // $ hasTaintFlow
24+ * let s = source("mySource" )
25+ * sink(s) // $ hasValueFlow=mySource
26+ * let t = "foo" + taint("myTaint" )
27+ * sink(t); // $ hasTaintFlow=myTaint
2828 * }
2929 * ```
3030 *
@@ -42,11 +42,17 @@ import codeql.swift.dataflow.TaintTracking
4242import TestUtilities.InlineExpectationsTest
4343
4444private predicate defaultSource ( DataFlow:: Node source ) {
45- source .asExpr ( ) .( CallExpr ) .getStaticTarget ( ) .( Function ) .getShortName ( ) = [ "source" , "taint" ]
45+ source
46+ .asExpr ( )
47+ .( CallExpr )
48+ .getStaticTarget ( )
49+ .( Function )
50+ .getShortName ( )
51+ .matches ( [ "source%" , "taint" ] )
4652}
4753
4854private predicate defaultSink ( DataFlow:: Node sink ) {
49- exists ( CallExpr ca | ca .getStaticTarget ( ) .( Function ) .getShortName ( ) = "sink" |
55+ exists ( CallExpr ca | ca .getStaticTarget ( ) .( Function ) .getShortName ( ) . matches ( "sink%" ) |
5056 sink .asExpr ( ) = ca .getAnArgument ( ) .getExpr ( )
5157 )
5258}
@@ -59,40 +65,55 @@ module DefaultFlowConfig implements DataFlow::ConfigSig {
5965 int fieldFlowBranchLimit ( ) { result = 1000 }
6066}
6167
62- private module NoFlowConfig implements DataFlow:: ConfigSig {
68+ module NoFlowConfig implements DataFlow:: ConfigSig {
6369 predicate isSource ( DataFlow:: Node source ) { none ( ) }
6470
6571 predicate isSink ( DataFlow:: Node sink ) { none ( ) }
6672}
6773
74+ private signature string valueFlowTagSig ( ) ;
75+
76+ private signature string taintFlowTagSig ( ) ;
77+
78+ string defaultValueFlowTag ( ) { result = "hasValueFlow" }
79+
80+ string defaultTaintFlowTag ( ) { result = "hasTaintFlow" }
81+
6882private string getSourceArgString ( DataFlow:: Node src ) {
6983 defaultSource ( src ) and
7084 src .asExpr ( ) .( CallExpr ) .getAnArgument ( ) .getExpr ( ) .( StringLiteralExpr ) .getValue ( ) = result
7185}
7286
73- module FlowTest< DataFlow:: ConfigSig ValueFlowConfig, DataFlow:: ConfigSig TaintFlowConfig> {
87+ module FlowTest<
88+ DataFlow:: ConfigSig ValueFlowConfig, DataFlow:: ConfigSig TaintFlowConfig,
89+ valueFlowTagSig / 0 valueFlowTag, taintFlowTagSig / 0 taintFlowTag>
90+ {
7491 module ValueFlow = DataFlow:: Global< ValueFlowConfig > ;
7592
7693 module TaintFlow = TaintTracking:: Global< TaintFlowConfig > ;
7794
7895 private module InlineTest implements TestSig {
79- string getARelevantTag ( ) { result = [ "hasValueFlow" , "hasTaintFlow" ] }
96+ string getARelevantTag ( ) { result = [ valueFlowTag ( ) , taintFlowTag ( ) ] }
8097
8198 predicate hasActualResult ( Location location , string element , string tag , string value ) {
82- tag = "hasValueFlow" and
99+ tag = valueFlowTag ( ) and
83100 exists ( DataFlow:: Node src , DataFlow:: Node sink | ValueFlow:: flow ( src , sink ) |
84101 sink .getLocation ( ) = location and
85102 element = sink .toString ( ) and
86- if exists ( getSourceArgString ( src ) ) then value = getSourceArgString ( src ) else value = ""
103+ if exists ( getSourceArgString ( src ) )
104+ then value = getSourceArgString ( src )
105+ else value = src .getLocation ( ) .getStartLine ( ) .toString ( )
87106 )
88107 or
89- tag = "hasTaintFlow" and
108+ tag = taintFlowTag ( ) and
90109 exists ( DataFlow:: Node src , DataFlow:: Node sink |
91110 TaintFlow:: flow ( src , sink ) and not ValueFlow:: flow ( src , sink )
92111 |
93112 sink .getLocation ( ) = location and
94113 element = sink .toString ( ) and
95- if exists ( getSourceArgString ( src ) ) then value = getSourceArgString ( src ) else value = ""
114+ if exists ( getSourceArgString ( src ) )
115+ then value = getSourceArgString ( src )
116+ else value = src .getLocation ( ) .getStartLine ( ) .toString ( )
96117 )
97118 }
98119 }
@@ -106,12 +127,13 @@ module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFl
106127 }
107128}
108129
109- module DefaultFlowTest = FlowTest< DefaultFlowConfig , DefaultFlowConfig > ;
130+ module DefaultFlowTest =
131+ FlowTest< DefaultFlowConfig , DefaultFlowConfig , defaultValueFlowTag / 0 , defaultTaintFlowTag / 0 > ;
110132
111133module ValueFlowTest< DataFlow:: ConfigSig ValueFlowConfig> {
112- import FlowTest< ValueFlowConfig , NoFlowConfig >
134+ import FlowTest< ValueFlowConfig , NoFlowConfig , defaultValueFlowTag / 0 , defaultTaintFlowTag / 0 >
113135}
114136
115137module TaintFlowTest< DataFlow:: ConfigSig TaintFlowConfig> {
116- import FlowTest< NoFlowConfig , TaintFlowConfig >
138+ import FlowTest< NoFlowConfig , TaintFlowConfig , defaultValueFlowTag / 0 , defaultTaintFlowTag / 0 >
117139}
0 commit comments