Skip to content

Commit 853bf2a

Browse files
committed
C#: Rewrite InlineFlowTest as a parameterized module
1 parent eb62df6 commit 853bf2a

File tree

9 files changed

+73
-50
lines changed

9 files changed

+73
-50
lines changed

csharp/ql/test/TestUtilities/InlineFlowTest.qll

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
* Example for a test.ql:
55
* ```ql
66
* import csharp
7-
* import DefaultValueFlow::PathGraph
87
* import TestUtilities.InlineFlowTest
8+
* import DefaultFlowTest
9+
* import ValueFlow::PathGraph
910
*
10-
* from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink
11-
* where DefaultValueFlow::flowPath(source, sink)
11+
* from ValueFlow::PathNode source, ValueFlow::PathNode sink
12+
* where ValueFlow::flowPath(source, sink)
1213
* select sink, source, sink, "$@", source, source.toString()
1314
*
1415
* ```
@@ -32,23 +33,19 @@
3233
* }
3334
* ```
3435
*
35-
* If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows:
36-
* ```ql
37-
* class HasFlowTest extends InlineFlowTest {
38-
* override DataFlow::Configuration getTaintFlowConfig() { none() }
39-
*
40-
* override DataFlow::Configuration getValueFlowConfig() { none() }
41-
* }
42-
* ```
36+
* If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import
37+
* `ValueFlowTest<DefaultFlowConfig>`. Similarly, if you are only interested in taint flow, then instead of
38+
* importing `DefaultFlowTest`, you can import `TaintFlowTest<DefaultFlowConfig>`. In both cases
39+
* `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`.
4340
*
4441
* If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`.
4542
*/
4643

4744
import csharp
4845
import TestUtilities.InlineExpectationsTest
4946

50-
private predicate defaultSource(DataFlow::Node src) {
51-
src.asExpr().(MethodCall).getTarget().getUndecoratedName() = ["Source", "Taint"]
47+
private predicate defaultSource(DataFlow::Node source) {
48+
source.asExpr().(MethodCall).getTarget().getUndecoratedName() = ["Source", "Taint"]
5249
}
5350

5451
private predicate defaultSink(DataFlow::Node sink) {
@@ -58,42 +55,60 @@ private predicate defaultSink(DataFlow::Node sink) {
5855
}
5956

6057
module DefaultFlowConfig implements DataFlow::ConfigSig {
61-
predicate isSource(DataFlow::Node n) { defaultSource(n) }
58+
predicate isSource(DataFlow::Node source) { defaultSource(source) }
6259

63-
predicate isSink(DataFlow::Node n) { defaultSink(n) }
60+
predicate isSink(DataFlow::Node sink) { defaultSink(sink) }
6461

6562
int fieldFlowBranchLimit() { result = 1000 }
6663
}
6764

68-
module DefaultValueFlow = DataFlow::Global<DefaultFlowConfig>;
65+
private module NoFlowConfig implements DataFlow::ConfigSig {
66+
predicate isSource(DataFlow::Node source) { none() }
6967

70-
module DefaultTaintFlow = TaintTracking::Global<DefaultFlowConfig>;
68+
predicate isSink(DataFlow::Node sink) { none() }
69+
}
7170

7271
private string getSourceArgString(DataFlow::Node src) {
7372
defaultSource(src) and
7473
src.asExpr().(MethodCall).getAnArgument().getValue() = result
7574
}
7675

77-
class InlineFlowTest extends InlineExpectationsTest {
78-
InlineFlowTest() { this = "HasFlowTest" }
79-
80-
override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
81-
82-
override predicate hasActualResult(Location location, string element, string tag, string value) {
83-
tag = "hasValueFlow" and
84-
exists(DataFlow::Node src, DataFlow::Node sink | DefaultValueFlow::flow(src, sink) |
85-
sink.getLocation() = location and
86-
element = sink.toString() and
87-
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
88-
)
89-
or
90-
tag = "hasTaintFlow" and
91-
exists(DataFlow::Node src, DataFlow::Node sink |
92-
DefaultTaintFlow::flow(src, sink) and not DefaultValueFlow::flow(src, sink)
93-
|
94-
sink.getLocation() = location and
95-
element = sink.toString() and
96-
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
97-
)
76+
module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> {
77+
module ValueFlow = DataFlow::Global<ValueFlowConfig>;
78+
79+
module TaintFlow = TaintTracking::Global<TaintFlowConfig>;
80+
81+
private module InlineTest implements TestSig {
82+
string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
83+
84+
predicate hasActualResult(Location location, string element, string tag, string value) {
85+
tag = "hasValueFlow" and
86+
exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) |
87+
sink.getLocation() = location and
88+
element = sink.toString() and
89+
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
90+
)
91+
or
92+
tag = "hasTaintFlow" and
93+
exists(DataFlow::Node src, DataFlow::Node sink |
94+
TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink)
95+
|
96+
sink.getLocation() = location and
97+
element = sink.toString() and
98+
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
99+
)
100+
}
98101
}
102+
103+
import MakeTest<InlineTest>
104+
}
105+
106+
module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>;
107+
108+
module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> {
109+
import FlowTest<ValueFlowConfig, NoFlowConfig>
110+
}
111+
112+
module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> {
113+
import FlowTest<NoFlowConfig, TaintFlowConfig>
99114
}

csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
failures
2+
testFailures
23
edges
34
| A.cs:5:17:5:28 | call to method Source<C> : C | A.cs:6:24:6:24 | access to local variable c : C |
45
| A.cs:6:17:6:25 | call to method Make : B [field c] : C | A.cs:7:14:7:14 | access to local variable b : B [field c] : C |

csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
*/
44

55
import csharp
6-
import DefaultValueFlow::PathGraph
76
import TestUtilities.InlineFlowTest
7+
import DefaultFlowTest
8+
import ValueFlow::PathGraph
89

9-
from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink
10-
where DefaultValueFlow::flowPath(source, sink)
10+
from ValueFlow::PathNode source, ValueFlow::PathNode sink
11+
where ValueFlow::flowPath(source, sink)
1112
select sink, source, sink, "$@", source, source.toString()

csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
failures
2+
testFailures
23
edges
34
| Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C |
45
| Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C |

csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
*/
44

55
import csharp
6-
import DefaultValueFlow::PathGraph
76
import TestUtilities.InlineFlowTest
7+
import DefaultFlowTest
8+
import ValueFlow::PathGraph
89

9-
from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink
10-
where DefaultValueFlow::flowPath(source, sink)
10+
from ValueFlow::PathNode source, ValueFlow::PathNode sink
11+
where ValueFlow::flowPath(source, sink)
1112
select sink, source, sink, "$@", source, source.toString()

csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
failures
2+
testFailures
23
edges
34
nodes
45
subpaths

csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
*/
44

55
import csharp
6-
import DefaultValueFlow::PathGraph
76
import TestUtilities.InlineFlowTest
7+
import DefaultFlowTest
8+
import ValueFlow::PathGraph
89

9-
from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink
10-
where DefaultValueFlow::flowPath(source, sink)
10+
from ValueFlow::PathNode source, ValueFlow::PathNode sink
11+
where ValueFlow::flowPath(source, sink)
1112
select sink, source, sink, "$@", source, source.toString()

csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
failures
2+
testFailures
23
edges
34
| Tuples.cs:7:18:7:34 | call to method Source<Object> : Object | Tuples.cs:10:21:10:22 | access to local variable o1 : Object |
45
| Tuples.cs:8:18:8:34 | call to method Source<Object> : Object | Tuples.cs:10:29:10:30 | access to local variable o2 : Object |

csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
*/
44

55
import csharp
6-
import DefaultValueFlow::PathGraph
76
import TestUtilities.InlineFlowTest
7+
import DefaultFlowTest
8+
import ValueFlow::PathGraph
89

9-
from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink
10-
where DefaultValueFlow::flowPath(source, sink)
10+
from ValueFlow::PathNode source, ValueFlow::PathNode sink
11+
where ValueFlow::flowPath(source, sink)
1112
select sink, source, sink, "$@", source, source.toString()

0 commit comments

Comments
 (0)