C++: Re-introduce most of the ast annotation test infrastructure

This commit is contained in:
Jeroen Ketema
2022-11-09 14:31:56 +01:00
parent bd301768ea
commit 0e33f4da6b
3 changed files with 111 additions and 0 deletions

View File

@@ -13,6 +13,7 @@
import cpp
private import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as IRDataFlow
private import semmle.code.cpp.dataflow.old.DataFlow::DataFlow as AstDataFlow
import TestUtilities.InlineExpectationsTest
class IRFlowTest extends InlineExpectationsTest {
@@ -40,3 +41,34 @@ class IRFlowTest extends InlineExpectationsTest {
)
}
}
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()
)
}
}
/** DEPRECATED: Alias for AstFlowTest */
deprecated class ASTFlowTest = AstFlowTest;

View File

@@ -1,5 +1,49 @@
import TestUtilities.dataflow.FlowTestCommon
module AstTest {
private import semmle.code.cpp.dataflow.old.DataFlow
private import semmle.code.cpp.controlflow.Guards
/**
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
* S in `if (guarded(x)) S`.
*/
// This is tested in `BarrierGuard.cpp`.
predicate testBarrierGuard(GuardCondition g, Expr checked, boolean isTrue) {
g.(FunctionCall).getTarget().getName() = "guarded" and
checked = g.(FunctionCall).getArgument(0) and
isTrue = true
}
/** Common data flow configuration to be used by tests. */
class AstTestAllocationConfig extends DataFlow::Configuration {
AstTestAllocationConfig() { this = "ASTTestAllocationConfig" }
override predicate isSource(DataFlow::Node source) {
source.asExpr().(FunctionCall).getTarget().getName() = "source"
or
source.asParameter().getName().matches("source%")
or
source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%")
or
// Track uninitialized variables
exists(source.asUninitialized())
}
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall call |
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument()
)
}
override predicate isBarrier(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode()
}
}
}
module IRTest {
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.IR

View File

@@ -38,6 +38,41 @@ module TaintModels {
}
}
module AstTest {
private import semmle.code.cpp.dataflow.old.TaintTracking
private import semmle.code.cpp.models.interfaces.Taint
/** Common data flow configuration to be used by tests. */
class AstTestAllocationConfig extends TaintTracking::Configuration {
AstTestAllocationConfig() { this = "ASTTestAllocationConfig" }
override predicate isSource(DataFlow::Node source) {
source.asExpr().(FunctionCall).getTarget().getName() = "source"
or
source.asParameter().getName().matches("source%")
or
// Track uninitialized variables
exists(source.asUninitialized())
or
exists(FunctionCall fc |
fc.getAnArgument() = source.asDefiningArgument() and
fc.getTarget().hasName("argument_source")
)
}
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall call |
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument()
)
}
override predicate isSanitizer(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("sanitizer")
}
}
}
module IRTest {
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.TaintTracking