Add variadic functions test for external flow

This commit is contained in:
Owen Mansel-Chan
2021-11-25 21:34:53 -05:00
parent d9848fe515
commit b75def62fe
7 changed files with 145 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
failures
invalidModelRow

View File

@@ -0,0 +1,72 @@
import go
import semmle.go.dataflow.ExternalFlow
import CsvValidation
import TestUtilities.InlineExpectationsTest
class SummaryModelTest extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//`namespace; type; subtypes; name; signature; ext; input; output; kind`
"github.com/nonexistent/test;;false;FunctionWithParameter;;;Argument[0];ReturnValue;value",
"github.com/nonexistent/test;;false;FunctionWithSliceParameter;;;ArrayElement of Argument[0];ReturnValue;value",
"github.com/nonexistent/test;;false;FunctionWithVarArgsParameter;;;ArrayElement of Argument[0];ReturnValue;value",
"github.com/nonexistent/test;;false;FunctionWithSliceOfStructsParameter;;;Field[github.com/nonexistent/test.A.Field] of ArrayElement of Argument[0];ReturnValue;value",
"github.com/nonexistent/test;;false;FunctionWithVarArgsOfStructsParameter;;;Field[github.com/nonexistent/test.A.Field] of ArrayElement of Argument[0];ReturnValue;value",
]
}
}
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, _, _, _)
)
}
}

View File

@@ -0,0 +1,5 @@
module semmle.go.Packages
go 1.17
require github.com/nonexistent/test v0.0.0-20200203000000-0000000000000

View File

@@ -0,0 +1,38 @@
package main
import (
"github.com/nonexistent/test"
)
func source() string {
return "untrusted data"
}
func sink(string) {
}
func main() {
s := source()
sink(test.FunctionWithParameter(s)) // $ taintflow dataflow
stringSlice := []string{source()}
sink(stringSlice[0]) // $ taintflow dataflow
s0 := ""
s1 := source()
sSlice := []string{s0, s1}
sink(test.FunctionWithParameter(sSlice[1])) // $ taintflow dataflow
sink(test.FunctionWithSliceParameter(sSlice)) // $ taintflow dataflow
sink(test.FunctionWithVarArgsParameter(sSlice...)) // $ taintflow dataflow
sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ MISSING: taintflow dataflow
sliceOfStructs := []test.A{{Field: source()}}
sink(sliceOfStructs[0].Field) // $ taintflow dataflow
a0 := test.A{Field: ""}
a1 := test.A{Field: source()}
aSlice := []test.A{a0, a1}
sink(test.FunctionWithSliceOfStructsParameter(aSlice)) // $ taintflow dataflow
sink(test.FunctionWithVarArgsOfStructsParameter(aSlice...)) // $ taintflow dataflow
sink(test.FunctionWithVarArgsOfStructsParameter(a0, a1)) // $ MISSING: taintflow dataflow
}

View File

@@ -0,0 +1,25 @@
package test
type A struct {
Field string
}
func FunctionWithParameter(s string) string {
return ""
}
func FunctionWithSliceParameter(s []string) string {
return ""
}
func FunctionWithVarArgsParameter(s ...string) string {
return ""
}
func FunctionWithSliceOfStructsParameter(s []A) string {
return ""
}
func FunctionWithVarArgsOfStructsParameter(s ...A) string {
return ""
}

View File

@@ -0,0 +1,3 @@
# github.com/nonexistent/test v0.0.0-20200203000000-0000000000000
## explicit
github.com/nonexistent/test