diff --git a/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.expected b/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.ql b/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.ql new file mode 100644 index 00000000000..90c078b7088 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dataflow/VarArgs/Flows.ql @@ -0,0 +1,56 @@ +import go +import TestUtilities.InlineExpectationsTest + +class DataConfiguration extends DataFlow::Configuration { + DataConfiguration() { this = "data-configuration" } + + override predicate isSource(DataFlow::Node source) { + source = any(DataFlow::CallNode c | c.getCalleeName() = "source").getResult(0) + } + + override predicate isSink(DataFlow::Node sink) { + sink = any(DataFlow::CallNode c | c.getCalleeName() = "sink").getArgument(0) + } +} + +class DataFlowTest extends InlineExpectationsTest { + DataFlowTest() { this = "DataFlowTest" } + + override string getARelevantTag() { result = "dataflow" } + + override predicate hasActualResult(string file, int line, string element, string tag, string value) { + tag = "dataflow" and + exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | + element = sink.toString() and + value = "" and + sink.hasLocationInfo(file, line, _, _, _) + ) + } +} + +class TaintConfiguration extends TaintTracking::Configuration { + TaintConfiguration() { this = "taint-configuration" } + + override predicate isSource(DataFlow::Node source) { + source = any(DataFlow::CallNode c | c.getCalleeName() = "source").getResult(0) + } + + override predicate isSink(DataFlow::Node sink) { + sink = any(DataFlow::CallNode c | c.getCalleeName() = "sink").getArgument(0) + } +} + +class TaintFlowTest extends InlineExpectationsTest { + TaintFlowTest() { this = "TaintFlowTest" } + + override string getARelevantTag() { result = "taintflow" } + + override predicate hasActualResult(string file, int line, string element, string tag, string value) { + tag = "taintflow" and + exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | + element = sink.toString() and + value = "" and + sink.hasLocationInfo(file, line, _, _, _) + ) + } +} diff --git a/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go b/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go new file mode 100644 index 00000000000..37e4476e655 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dataflow/VarArgs/main.go @@ -0,0 +1,27 @@ +package main + +func source() string { + return "untrusted data" +} + +func sink(string) { +} + +type A struct { + f string +} + +func functionWithVarArgsOfStructsParameter(s ...A) { + sink(s[0].f) // $ MISSING: taintflow dataflow +} + +func main() { + stringSlice := []string{source()} + sink(stringSlice[0]) // $ taintflow MISSING: dataflow + + arrayOfStructs := []A{{f: source()}} + sink(arrayOfStructs[0].f) // $ MISSING: taintflow dataflow + + a := A{f: source()} + functionWithVarArgsOfStructsParameter(a) +}