Skip to content

Commit 4ffc4f5

Browse files
committed
Add test for dataflow through switches
1 parent 0ed3300 commit 4ffc4f5

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

go/ql/test/library-tests/semmle/go/dataflow/Switch/DataFlow.expected

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import go
2+
import TestUtilities.InlineFlowTest
3+
import DefaultFlowTest
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package main
2+
3+
type Type1 struct {
4+
field1 string
5+
}
6+
type Type2 struct {
7+
field2 string
8+
}
9+
type Type3 struct {
10+
field3 string
11+
}
12+
13+
func source() string {
14+
return "source"
15+
}
16+
17+
func sink(s string) {
18+
}
19+
20+
func typeSwitch1(input any, defaultValue string) string {
21+
switch x := input.(type) {
22+
case *Type1:
23+
return x.field1
24+
case *Type2, *Type3:
25+
if x3, ok := x.(*Type2); ok {
26+
return x3.field2
27+
}
28+
if x4, ok := x.(*Type3); ok {
29+
return x4.field3
30+
}
31+
return ""
32+
default:
33+
_ = x
34+
return defaultValue
35+
}
36+
}
37+
38+
func typeSwitch2(input any, defaultValue string) string {
39+
switch input.(type) {
40+
case *Type1:
41+
return input.(*Type1).field1
42+
case *Type2, *Type3:
43+
if x3, ok := input.(*Type2); ok {
44+
return x3.field2
45+
}
46+
if x4, ok := input.(*Type3); ok {
47+
return x4.field3
48+
}
49+
return ""
50+
default:
51+
_ = input
52+
return defaultValue
53+
}
54+
}
55+
56+
func expressionSwitch1(input string, defaultValue string) string {
57+
switch input {
58+
case "0":
59+
return "0"
60+
case "1", "2":
61+
return "1 or 2"
62+
case "3":
63+
fallthrough
64+
default:
65+
return defaultValue
66+
}
67+
}
68+
69+
func expressionSwitch2(input string, defaultValue string) string {
70+
switch def := defaultValue; input {
71+
case "0":
72+
return "0"
73+
case "1", "2":
74+
return "1 or 2"
75+
case "3":
76+
fallthrough
77+
default:
78+
return def
79+
}
80+
}
81+
82+
func main() {
83+
sink(typeSwitch1(&Type1{source()}, "default")) // $ MISSING: hasValueFlow="call to typeSwitch1"
84+
sink(typeSwitch1(&Type2{source()}, "default")) // $ MISSING: hasValueFlow="call to typeSwitch1"
85+
sink(typeSwitch1(&Type3{source()}, "default")) // $ MISSING: hasValueFlow="call to typeSwitch1"
86+
sink(typeSwitch1(nil, source())) // $ hasValueFlow="call to typeSwitch1"
87+
88+
sink(typeSwitch2(&Type1{source()}, "default")) // $ hasValueFlow="call to typeSwitch2"
89+
sink(typeSwitch2(&Type2{source()}, "default")) // $ hasValueFlow="call to typeSwitch2"
90+
sink(typeSwitch2(&Type3{source()}, "default")) // $ hasValueFlow="call to typeSwitch2"
91+
sink(typeSwitch2(nil, source())) // $ hasValueFlow="call to typeSwitch2"
92+
93+
sink(expressionSwitch1("1", source())) // $ SPURIOUS: hasValueFlow="call to expressionSwitch1"
94+
sink(expressionSwitch1("2", source())) // $ SPURIOUS: hasValueFlow="call to expressionSwitch1"
95+
sink(expressionSwitch1("3", source())) // $ hasValueFlow="call to expressionSwitch1"
96+
sink(expressionSwitch1("4", source())) // $ hasValueFlow="call to expressionSwitch1"
97+
98+
sink(expressionSwitch2("1", source())) // $ SPURIOUS: hasValueFlow="call to expressionSwitch2"
99+
sink(expressionSwitch2("2", source())) // $ SPURIOUS: hasValueFlow="call to expressionSwitch2"
100+
sink(expressionSwitch2("3", source())) // $ hasValueFlow="call to expressionSwitch2"
101+
sink(expressionSwitch2("4", source())) // $ hasValueFlow="call to expressionSwitch2"
102+
}

0 commit comments

Comments
 (0)