Skip to content

Commit b75def6

Browse files
committed
Add variadic functions test for external flow
1 parent d9848fe commit b75def6

File tree

7 files changed

+145
-0
lines changed

7 files changed

+145
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
failures
2+
invalidModelRow
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import go
2+
import semmle.go.dataflow.ExternalFlow
3+
import CsvValidation
4+
import TestUtilities.InlineExpectationsTest
5+
6+
class SummaryModelTest extends SummaryModelCsv {
7+
override predicate row(string row) {
8+
row =
9+
[
10+
//`namespace; type; subtypes; name; signature; ext; input; output; kind`
11+
"github.com/nonexistent/test;;false;FunctionWithParameter;;;Argument[0];ReturnValue;value",
12+
"github.com/nonexistent/test;;false;FunctionWithSliceParameter;;;ArrayElement of Argument[0];ReturnValue;value",
13+
"github.com/nonexistent/test;;false;FunctionWithVarArgsParameter;;;ArrayElement of Argument[0];ReturnValue;value",
14+
"github.com/nonexistent/test;;false;FunctionWithSliceOfStructsParameter;;;Field[github.com/nonexistent/test.A.Field] of ArrayElement of Argument[0];ReturnValue;value",
15+
"github.com/nonexistent/test;;false;FunctionWithVarArgsOfStructsParameter;;;Field[github.com/nonexistent/test.A.Field] of ArrayElement of Argument[0];ReturnValue;value",
16+
]
17+
}
18+
}
19+
20+
class DataConfiguration extends DataFlow::Configuration {
21+
DataConfiguration() { this = "data-configuration" }
22+
23+
override predicate isSource(DataFlow::Node source) {
24+
source = any(DataFlow::CallNode c | c.getCalleeName() = "source").getResult(0)
25+
}
26+
27+
override predicate isSink(DataFlow::Node sink) {
28+
sink = any(DataFlow::CallNode c | c.getCalleeName() = "sink").getArgument(0)
29+
}
30+
}
31+
32+
class DataFlowTest extends InlineExpectationsTest {
33+
DataFlowTest() { this = "DataFlowTest" }
34+
35+
override string getARelevantTag() { result = "dataflow" }
36+
37+
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
38+
tag = "dataflow" and
39+
exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) |
40+
element = sink.toString() and
41+
value = "" and
42+
sink.hasLocationInfo(file, line, _, _, _)
43+
)
44+
}
45+
}
46+
47+
class TaintConfiguration extends TaintTracking::Configuration {
48+
TaintConfiguration() { this = "taint-configuration" }
49+
50+
override predicate isSource(DataFlow::Node source) {
51+
source = any(DataFlow::CallNode c | c.getCalleeName() = "source").getResult(0)
52+
}
53+
54+
override predicate isSink(DataFlow::Node sink) {
55+
sink = any(DataFlow::CallNode c | c.getCalleeName() = "sink").getArgument(0)
56+
}
57+
}
58+
59+
class TaintFlowTest extends InlineExpectationsTest {
60+
TaintFlowTest() { this = "TaintFlowTest" }
61+
62+
override string getARelevantTag() { result = "taintflow" }
63+
64+
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
65+
tag = "taintflow" and
66+
exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) |
67+
element = sink.toString() and
68+
value = "" and
69+
sink.hasLocationInfo(file, line, _, _, _)
70+
)
71+
}
72+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module semmle.go.Packages
2+
3+
go 1.17
4+
5+
require github.com/nonexistent/test v0.0.0-20200203000000-0000000000000
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import (
4+
"github.com/nonexistent/test"
5+
)
6+
7+
func source() string {
8+
return "untrusted data"
9+
}
10+
11+
func sink(string) {
12+
}
13+
14+
func main() {
15+
s := source()
16+
sink(test.FunctionWithParameter(s)) // $ taintflow dataflow
17+
18+
stringSlice := []string{source()}
19+
sink(stringSlice[0]) // $ taintflow dataflow
20+
21+
s0 := ""
22+
s1 := source()
23+
sSlice := []string{s0, s1}
24+
sink(test.FunctionWithParameter(sSlice[1])) // $ taintflow dataflow
25+
sink(test.FunctionWithSliceParameter(sSlice)) // $ taintflow dataflow
26+
sink(test.FunctionWithVarArgsParameter(sSlice...)) // $ taintflow dataflow
27+
sink(test.FunctionWithVarArgsParameter(s0, s1)) // $ MISSING: taintflow dataflow
28+
29+
sliceOfStructs := []test.A{{Field: source()}}
30+
sink(sliceOfStructs[0].Field) // $ taintflow dataflow
31+
32+
a0 := test.A{Field: ""}
33+
a1 := test.A{Field: source()}
34+
aSlice := []test.A{a0, a1}
35+
sink(test.FunctionWithSliceOfStructsParameter(aSlice)) // $ taintflow dataflow
36+
sink(test.FunctionWithVarArgsOfStructsParameter(aSlice...)) // $ taintflow dataflow
37+
sink(test.FunctionWithVarArgsOfStructsParameter(a0, a1)) // $ MISSING: taintflow dataflow
38+
}
Binary file not shown.

ql/test/library-tests/semmle/go/dataflow/ExternalFlowVarArgs/vendor/github.com/nonexistent/test/stub.go

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# github.com/nonexistent/test v0.0.0-20200203000000-0000000000000
2+
## explicit
3+
github.com/nonexistent/test

0 commit comments

Comments
 (0)