Files
codeql/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll
2020-12-02 15:42:52 +01:00

72 lines
2.7 KiB
Plaintext

/**
* Helper library for implementing data or taint flow inline expectation tests.
* As long as data or taint flow configurations for IR and/or AST based data/taint flow
* are in scope, provides inline expectations tests.
* All sinks that have flow are annotated with `ast` (or respective `ir`) if there
* is a unique source for the flow.
* Otherwise, if there are multiple sources that can reach a given sink, the annotations
* have the form `ast=lineno:column` (or `ir=lineno:column`).
* If a sink is reachable through both AST and IR flow, the annotations have the form
* `ast,ir` or `ast,ir=lineno:column`.
* Intermediate steps from the source to the sink are not annotated.
*/
import cpp
private import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as IRDataFlow
private import semmle.code.cpp.dataflow.DataFlow::DataFlow as ASTDataFlow
import TestUtilities.InlineExpectationsTest
class IRFlowTest extends InlineExpectationsTest {
IRFlowTest() { this = "IRFlowTest" }
override string getARelevantTag() { result = "ir" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(IRDataFlow::Node source, IRDataFlow::Node sink, IRDataFlow::Configuration conf, int n |
tag = "ir" and
conf.hasFlow(source, sink) and
n = strictcount(IRDataFlow::Node otherSource | conf.hasFlow(otherSource, sink)) and
(
n = 1 and value = ""
or
// If there is more than one source for this sink
// we specify the source location explicitly.
n > 1 and
value =
source.getLocation().getStartLine().toString() + ":" +
source.getLocation().getStartColumn()
) and
location = sink.getLocation() and
element = sink.toString()
)
}
}
class ASTFlowTest extends InlineExpectationsTest {
ASTFlowTest() { this = "ASTFlowTest" }
override string getARelevantTag() { result = "ast" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(
ASTDataFlow::Node source, ASTDataFlow::Node sink, ASTDataFlow::Configuration conf, int n
|
tag = "ast" and
conf.hasFlow(source, sink) and
n = strictcount(ASTDataFlow::Node otherSource | conf.hasFlow(otherSource, sink)) and
(
n = 1 and value = ""
or
// If there is more than one source for this sink
// we specify the source location explicitly.
n > 1 and
value =
source.getLocation().getStartLine().toString() + ":" +
source.getLocation().getStartColumn()
) and
location = sink.getLocation() and
element = sink.toString()
)
}
}