diff --git a/csharp/ql/test/TestUtilities/InlineFlowTest.qll b/csharp/ql/test/TestUtilities/InlineFlowTest.qll index a31d531e1b6..dc95063f03f 100644 --- a/csharp/ql/test/TestUtilities/InlineFlowTest.qll +++ b/csharp/ql/test/TestUtilities/InlineFlowTest.qll @@ -4,11 +4,12 @@ * Example for a test.ql: * ```ql * import csharp - * import DefaultValueFlow::PathGraph * import TestUtilities.InlineFlowTest + * import DefaultFlowTest + * import ValueFlow::PathGraph * - * from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink - * where DefaultValueFlow::flowPath(source, sink) + * from ValueFlow::PathNode source, ValueFlow::PathNode sink + * where ValueFlow::flowPath(source, sink) * select sink, source, sink, "$@", source, source.toString() * * ``` @@ -32,14 +33,10 @@ * } * ``` * - * If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows: - * ```ql - * class HasFlowTest extends InlineFlowTest { - * override DataFlow::Configuration getTaintFlowConfig() { none() } - * - * override DataFlow::Configuration getValueFlowConfig() { none() } - * } - * ``` + * If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import + * `ValueFlowTest`. Similarly, if you are only interested in taint flow, then instead of + * importing `DefaultFlowTest`, you can import `TaintFlowTest`. In both cases + * `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`. * * If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`. */ @@ -47,8 +44,8 @@ import csharp import TestUtilities.InlineExpectationsTest -private predicate defaultSource(DataFlow::Node src) { - src.asExpr().(MethodCall).getTarget().getUndecoratedName() = ["Source", "Taint"] +private predicate defaultSource(DataFlow::Node source) { + source.asExpr().(MethodCall).getTarget().getUndecoratedName() = ["Source", "Taint"] } private predicate defaultSink(DataFlow::Node sink) { @@ -58,42 +55,60 @@ private predicate defaultSink(DataFlow::Node sink) { } module DefaultFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node n) { defaultSource(n) } + predicate isSource(DataFlow::Node source) { defaultSource(source) } - predicate isSink(DataFlow::Node n) { defaultSink(n) } + predicate isSink(DataFlow::Node sink) { defaultSink(sink) } int fieldFlowBranchLimit() { result = 1000 } } -module DefaultValueFlow = DataFlow::Global; +private module NoFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { none() } -module DefaultTaintFlow = TaintTracking::Global; + predicate isSink(DataFlow::Node sink) { none() } +} private string getSourceArgString(DataFlow::Node src) { defaultSource(src) and src.asExpr().(MethodCall).getAnArgument().getValue() = result } -class InlineFlowTest extends InlineExpectationsTest { - InlineFlowTest() { this = "HasFlowTest" } +module FlowTest { + module ValueFlow = DataFlow::Global; - override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + module TaintFlow = TaintTracking::Global; - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "hasValueFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | DefaultValueFlow::flow(src, sink) | - sink.getLocation() = location and - element = sink.toString() and - if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" - ) - or - tag = "hasTaintFlow" and - exists(DataFlow::Node src, DataFlow::Node sink | - DefaultTaintFlow::flow(src, sink) and not DefaultValueFlow::flow(src, sink) - | - sink.getLocation() = location and - element = sink.toString() and - if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" - ) + private module InlineTest implements TestSig { + string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasValueFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) + or + tag = "hasTaintFlow" and + exists(DataFlow::Node src, DataFlow::Node sink | + TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink) + | + sink.getLocation() = location and + element = sink.toString() and + if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = "" + ) + } } + + import MakeTest +} + +module DefaultFlowTest = FlowTest; + +module ValueFlowTest { + import FlowTest +} + +module TaintFlowTest { + import FlowTest } diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected index aa9ac0493aa..a0d9a917702 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | A.cs:5:17:5:28 | call to method Source : C | A.cs:6:24:6:24 | access to local variable c : C | | 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 | diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql index b01c0f7fcaf..39395ad831b 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.ql @@ -3,9 +3,10 @@ */ import csharp -import DefaultValueFlow::PathGraph import TestUtilities.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph -from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink -where DefaultValueFlow::flowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected index 7b173a98e41..3f4f02ff6a1 100644 --- a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.expected @@ -1,4 +1,5 @@ failures +testFailures edges | Operator.cs:9:39:9:39 | x : C | Operator.cs:9:50:9:50 | access to parameter x : C | | Operator.cs:16:38:16:38 | x : C | Operator.cs:16:49:16:49 | access to parameter x : C | diff --git a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql index b01c0f7fcaf..39395ad831b 100644 --- a/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/operators/operatorFlow.ql @@ -3,9 +3,10 @@ */ import csharp -import DefaultValueFlow::PathGraph import TestUtilities.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph -from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink -where DefaultValueFlow::flowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected index f965891244c..f2ab31c12b3 100644 --- a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.expected @@ -1,4 +1,5 @@ failures +testFailures edges nodes subpaths diff --git a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql index b01c0f7fcaf..39395ad831b 100644 --- a/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/patterns/PatternFlow.ql @@ -3,9 +3,10 @@ */ import csharp -import DefaultValueFlow::PathGraph import TestUtilities.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph -from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink -where DefaultValueFlow::flowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString() diff --git a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected index dae85aa45aa..bb1715df029 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected +++ b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected @@ -1,4 +1,5 @@ failures +testFailures edges | Tuples.cs:7:18:7:34 | call to method Source : Object | Tuples.cs:10:21:10:22 | access to local variable o1 : Object | | Tuples.cs:8:18:8:34 | call to method Source : Object | Tuples.cs:10:29:10:30 | access to local variable o2 : Object | diff --git a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql index b01c0f7fcaf..39395ad831b 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql +++ b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.ql @@ -3,9 +3,10 @@ */ import csharp -import DefaultValueFlow::PathGraph import TestUtilities.InlineFlowTest +import DefaultFlowTest +import ValueFlow::PathGraph -from DefaultValueFlow::PathNode source, DefaultValueFlow::PathNode sink -where DefaultValueFlow::flowPath(source, sink) +from ValueFlow::PathNode source, ValueFlow::PathNode sink +where ValueFlow::flowPath(source, sink) select sink, source, sink, "$@", source, source.toString()