Skip to content

Commit 1af3374

Browse files
committed
Add tests for data flow through ranged for loops
Including the case where the type of the domain is a named type rather than an array type or map type or whatever.
1 parent 145873f commit 1af3374

File tree

7 files changed

+168
-96
lines changed

7 files changed

+168
-96
lines changed

go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.expected

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,35 @@ invalidModelRow
1010
| test.go:79:10:79:15 | taint6 | qltest |
1111
| test.go:82:10:82:15 | taint7 | qltest |
1212
| test.go:85:10:85:18 | index expression | qltest |
13-
| test.go:89:10:89:15 | taint9 | qltest |
14-
| test.go:92:10:92:33 | call to GetElement | qltest |
15-
| test.go:93:10:93:18 | <-... | qltest |
16-
| test.go:97:10:97:16 | taint11 | qltest |
17-
| test.go:100:10:100:32 | call to GetMapKey | qltest |
18-
| test.go:102:11:102:11 | k | qltest |
19-
| test.go:105:11:105:11 | k | qltest |
20-
| test.go:110:10:110:16 | taint13 | qltest |
21-
| test.go:113:10:113:20 | index expression | qltest |
22-
| test.go:117:10:117:16 | taint15 | qltest |
23-
| test.go:121:10:121:17 | index expression | qltest |
24-
| test.go:127:10:127:18 | index expression | qltest |
25-
| test.go:132:10:132:16 | taint16 | qltest |
26-
| test.go:136:10:136:13 | selection of F | qltest |
27-
| test.go:139:10:139:17 | call to Get | qltest |
28-
| test.go:143:10:143:17 | call to Get | qltest |
29-
| test.go:148:10:148:17 | call to Get | qltest |
30-
| test.go:152:10:152:14 | selection of F | qltest |
31-
| test.go:155:10:155:32 | call to GetThroughPointer | qltest |
32-
| test.go:159:10:159:32 | call to GetThroughPointer | qltest |
33-
| test.go:164:10:164:32 | call to GetThroughPointer | qltest |
34-
| test.go:170:17:170:20 | arg1 | qltest |
35-
| test.go:170:23:170:26 | arg2 | qltest |
36-
| test.go:170:29:170:32 | arg3 | qltest |
13+
| test.go:87:11:87:11 | x | qltest |
14+
| test.go:90:11:90:11 | x | qltest |
15+
| test.go:95:10:95:15 | taint9 | qltest |
16+
| test.go:98:10:98:33 | call to GetElement | qltest |
17+
| test.go:99:10:99:18 | <-... | qltest |
18+
| test.go:101:11:101:11 | e | qltest |
19+
| test.go:104:11:104:11 | e | qltest |
20+
| test.go:109:10:109:16 | taint11 | qltest |
21+
| test.go:112:10:112:32 | call to GetMapKey | qltest |
22+
| test.go:114:11:114:11 | k | qltest |
23+
| test.go:117:11:117:11 | k | qltest |
24+
| test.go:120:11:120:11 | k | qltest |
25+
| test.go:123:11:123:11 | k | qltest |
26+
| test.go:128:10:128:16 | taint13 | qltest |
27+
| test.go:131:10:131:20 | index expression | qltest |
28+
| test.go:133:11:133:11 | v | qltest |
29+
| test.go:136:11:136:11 | v | qltest |
30+
| test.go:141:10:141:16 | taint15 | qltest |
31+
| test.go:145:10:145:17 | index expression | qltest |
32+
| test.go:151:10:151:18 | index expression | qltest |
33+
| test.go:156:10:156:16 | taint16 | qltest |
34+
| test.go:160:10:160:13 | selection of F | qltest |
35+
| test.go:163:10:163:17 | call to Get | qltest |
36+
| test.go:167:10:167:17 | call to Get | qltest |
37+
| test.go:172:10:172:17 | call to Get | qltest |
38+
| test.go:176:10:176:14 | selection of F | qltest |
39+
| test.go:179:10:179:32 | call to GetThroughPointer | qltest |
40+
| test.go:183:10:183:32 | call to GetThroughPointer | qltest |
41+
| test.go:188:10:188:32 | call to GetThroughPointer | qltest |
42+
| test.go:194:17:194:20 | arg1 | qltest |
43+
| test.go:194:23:194:26 | arg2 | qltest |
44+
| test.go:194:29:194:32 | arg3 | qltest |

go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ invalidModelRow
99
| test.go:41:2:41:21 | ... = ...[1] | qltest-w-subtypes |
1010
| test.go:42:2:42:22 | ... = ...[1] | qltest-w-subtypes |
1111
| test.go:58:9:58:16 | call to Src1 | qltest |
12-
| test.go:91:46:91:53 | call to Src1 | qltest |
13-
| test.go:95:35:95:42 | call to Src1 | qltest |
14-
| test.go:99:42:99:49 | call to Src1 | qltest |
15-
| test.go:130:8:130:15 | call to Src1 | qltest |
16-
| test.go:135:9:135:16 | call to Src1 | qltest |
17-
| test.go:138:15:138:22 | call to Src1 | qltest |
18-
| test.go:142:9:142:16 | call to Src1 | qltest |
19-
| test.go:146:9:146:16 | call to Src1 | qltest |
20-
| test.go:151:24:151:31 | call to Src1 | qltest |
21-
| test.go:154:17:154:24 | call to Src1 | qltest |
22-
| test.go:158:24:158:31 | call to Src1 | qltest |
23-
| test.go:162:24:162:31 | call to Src1 | qltest |
12+
| test.go:97:46:97:53 | call to Src1 | qltest |
13+
| test.go:107:35:107:42 | call to Src1 | qltest |
14+
| test.go:111:42:111:49 | call to Src1 | qltest |
15+
| test.go:154:8:154:15 | call to Src1 | qltest |
16+
| test.go:159:9:159:16 | call to Src1 | qltest |
17+
| test.go:162:15:162:22 | call to Src1 | qltest |
18+
| test.go:166:9:166:16 | call to Src1 | qltest |
19+
| test.go:170:9:170:16 | call to Src1 | qltest |
20+
| test.go:175:24:175:31 | call to Src1 | qltest |
21+
| test.go:178:17:178:24 | call to Src1 | qltest |
22+
| test.go:182:24:182:31 | call to Src1 | qltest |
23+
| test.go:186:24:186:31 | call to Src1 | qltest |

go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ func simpleflow() {
8383

8484
taint8 := test.StepArgResArrayContent(src)
8585
b.Sink1(taint8[0]) // $ hasTaintFlow="index expression"
86+
for _, x := range taint8 {
87+
b.Sink1(x) // $ hasTaintFlow="x"
88+
}
89+
for _, x := range arraytype(taint8) {
90+
b.Sink1(x) // $ hasTaintFlow="x"
91+
}
8692

8793
srcArray := []interface{}{nil, src}
8894
taint9 := test.StepArgArrayContentRes(srcArray)
@@ -91,6 +97,12 @@ func simpleflow() {
9197
taint10 := test.StepArgResCollectionContent(a.Src1()).(chan interface{})
9298
b.Sink1(test.GetElement(taint10)) // $ hasTaintFlow="call to GetElement"
9399
b.Sink1(<-taint10) // $ hasTaintFlow="<-..."
100+
for e := range taint10 {
101+
b.Sink1(e) // $ MISSING: hasTaintFlow="e"
102+
}
103+
for e := range channeltype(taint10) {
104+
b.Sink1(e) // $ MISSING: hasTaintFlow="e"
105+
}
94106

95107
srcCollection := test.SetElement(a.Src1())
96108
taint11 := test.StepArgCollectionContentRes(srcCollection)
@@ -104,13 +116,25 @@ func simpleflow() {
104116
for k := range taint12 {
105117
b.Sink1(k) // $ hasTaintFlow="k"
106118
}
119+
for k, _ := range mapstringstringtype(taint12) {
120+
b.Sink1(k) // $ MISSING: hasTaintFlow="k"
121+
}
122+
for k := range mapstringstringtype(taint12) {
123+
b.Sink1(k) // $ MISSING: hasTaintFlow="k"
124+
}
107125

108126
srcMap13 := map[string]string{src.(string): ""}
109127
taint13 := test.StepArgMapKeyContentRes(srcMap13)
110128
b.Sink1(taint13) // $ hasTaintFlow="taint13"
111129

112130
taint14 := test.StepArgResMapValueContent(src).(map[string]string)
113131
b.Sink1(taint14[""]) // $ hasTaintFlow="index expression"
132+
for _, v := range taint14 {
133+
b.Sink1(v) // $ hasTaintFlow="v"
134+
}
135+
for _, v := range mapstringstringtype(taint14) {
136+
b.Sink1(v) // $ MISSING: hasTaintFlow="v"
137+
}
114138

115139
srcMap15 := map[string]string{"": src.(string)}
116140
taint15 := test.StepArgMapValueContentRes(srcMap15)
@@ -169,3 +193,7 @@ func simpleflow() {
169193
arg4 := src
170194
b.SinkManyArgs(arg1, arg2, arg3, arg4) // $ hasTaintFlow="arg1" hasTaintFlow="arg2" hasTaintFlow="arg3"
171195
}
196+
197+
type mapstringstringtype map[string]string
198+
type arraytype []interface{}
199+
type channeltype chan interface{}

go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/sinks.expected

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,41 @@ invalidModelRow
1010
| test.go:79:10:79:15 | taint6 | qltest |
1111
| test.go:82:10:82:15 | taint7 | qltest |
1212
| test.go:85:10:85:18 | index expression | qltest |
13-
| test.go:89:10:89:15 | taint9 | qltest |
14-
| test.go:92:10:92:33 | call to GetElement | qltest |
15-
| test.go:93:10:93:18 | <-... | qltest |
16-
| test.go:97:10:97:16 | taint11 | qltest |
17-
| test.go:100:10:100:32 | call to GetMapKey | qltest |
18-
| test.go:102:11:102:11 | k | qltest |
19-
| test.go:105:11:105:11 | k | qltest |
20-
| test.go:110:10:110:16 | taint13 | qltest |
21-
| test.go:113:10:113:20 | index expression | qltest |
22-
| test.go:117:10:117:16 | taint15 | qltest |
23-
| test.go:121:10:121:17 | index expression | qltest |
24-
| test.go:127:10:127:18 | index expression | qltest |
25-
| test.go:132:10:132:16 | taint16 | qltest |
26-
| test.go:136:10:136:13 | selection of F | qltest |
27-
| test.go:139:10:139:17 | call to Get | qltest |
28-
| test.go:143:10:143:17 | call to Get | qltest |
29-
| test.go:148:10:148:17 | call to Get | qltest |
30-
| test.go:152:10:152:14 | selection of F | qltest |
31-
| test.go:155:10:155:32 | call to GetThroughPointer | qltest |
32-
| test.go:159:10:159:32 | call to GetThroughPointer | qltest |
33-
| test.go:164:10:164:32 | call to GetThroughPointer | qltest |
34-
| test.go:170:17:170:20 | arg1 | qltest |
35-
| test.go:170:23:170:26 | arg2 | qltest |
36-
| test.go:170:29:170:32 | arg3 | qltest |
37-
| test.go:173:10:173:26 | call to max | qltest |
38-
| test.go:174:10:174:26 | call to max | qltest |
39-
| test.go:175:10:175:26 | call to max | qltest |
40-
| test.go:176:10:176:26 | call to min | qltest |
41-
| test.go:177:10:177:26 | call to min | qltest |
42-
| test.go:178:10:178:26 | call to min | qltest |
13+
| test.go:87:11:87:11 | x | qltest |
14+
| test.go:90:11:90:11 | x | qltest |
15+
| test.go:95:10:95:15 | taint9 | qltest |
16+
| test.go:98:10:98:33 | call to GetElement | qltest |
17+
| test.go:99:10:99:18 | <-... | qltest |
18+
| test.go:101:11:101:11 | e | qltest |
19+
| test.go:104:11:104:11 | e | qltest |
20+
| test.go:109:10:109:16 | taint11 | qltest |
21+
| test.go:112:10:112:32 | call to GetMapKey | qltest |
22+
| test.go:114:11:114:11 | k | qltest |
23+
| test.go:117:11:117:11 | k | qltest |
24+
| test.go:120:11:120:11 | k | qltest |
25+
| test.go:123:11:123:11 | k | qltest |
26+
| test.go:128:10:128:16 | taint13 | qltest |
27+
| test.go:131:10:131:20 | index expression | qltest |
28+
| test.go:133:11:133:11 | v | qltest |
29+
| test.go:136:11:136:11 | v | qltest |
30+
| test.go:141:10:141:16 | taint15 | qltest |
31+
| test.go:145:10:145:17 | index expression | qltest |
32+
| test.go:151:10:151:18 | index expression | qltest |
33+
| test.go:156:10:156:16 | taint16 | qltest |
34+
| test.go:160:10:160:13 | selection of F | qltest |
35+
| test.go:163:10:163:17 | call to Get | qltest |
36+
| test.go:167:10:167:17 | call to Get | qltest |
37+
| test.go:172:10:172:17 | call to Get | qltest |
38+
| test.go:176:10:176:14 | selection of F | qltest |
39+
| test.go:179:10:179:32 | call to GetThroughPointer | qltest |
40+
| test.go:183:10:183:32 | call to GetThroughPointer | qltest |
41+
| test.go:188:10:188:32 | call to GetThroughPointer | qltest |
42+
| test.go:194:17:194:20 | arg1 | qltest |
43+
| test.go:194:23:194:26 | arg2 | qltest |
44+
| test.go:194:29:194:32 | arg3 | qltest |
45+
| test.go:197:10:197:26 | call to max | qltest |
46+
| test.go:198:10:198:26 | call to max | qltest |
47+
| test.go:199:10:199:26 | call to max | qltest |
48+
| test.go:200:10:200:26 | call to min | qltest |
49+
| test.go:201:10:201:26 | call to min | qltest |
50+
| test.go:202:10:202:26 | call to min | qltest |

go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ invalidModelRow
99
| test.go:41:2:41:21 | ... = ...[1] | qltest-w-subtypes |
1010
| test.go:42:2:42:22 | ... = ...[1] | qltest-w-subtypes |
1111
| test.go:58:9:58:16 | call to Src1 | qltest |
12-
| test.go:91:46:91:53 | call to Src1 | qltest |
13-
| test.go:95:35:95:42 | call to Src1 | qltest |
14-
| test.go:99:42:99:49 | call to Src1 | qltest |
15-
| test.go:130:8:130:15 | call to Src1 | qltest |
16-
| test.go:135:9:135:16 | call to Src1 | qltest |
17-
| test.go:138:15:138:22 | call to Src1 | qltest |
18-
| test.go:142:9:142:16 | call to Src1 | qltest |
19-
| test.go:146:9:146:16 | call to Src1 | qltest |
20-
| test.go:151:24:151:31 | call to Src1 | qltest |
21-
| test.go:154:17:154:24 | call to Src1 | qltest |
22-
| test.go:158:24:158:31 | call to Src1 | qltest |
23-
| test.go:162:24:162:31 | call to Src1 | qltest |
12+
| test.go:97:46:97:53 | call to Src1 | qltest |
13+
| test.go:107:35:107:42 | call to Src1 | qltest |
14+
| test.go:111:42:111:49 | call to Src1 | qltest |
15+
| test.go:154:8:154:15 | call to Src1 | qltest |
16+
| test.go:159:9:159:16 | call to Src1 | qltest |
17+
| test.go:162:15:162:22 | call to Src1 | qltest |
18+
| test.go:166:9:166:16 | call to Src1 | qltest |
19+
| test.go:170:9:170:16 | call to Src1 | qltest |
20+
| test.go:175:24:175:31 | call to Src1 | qltest |
21+
| test.go:178:17:178:24 | call to Src1 | qltest |
22+
| test.go:182:24:182:31 | call to Src1 | qltest |
23+
| test.go:186:24:186:31 | call to Src1 | qltest |

go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/steps.expected

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ invalidModelRow
1414
| test.go:74:13:74:25 | type assertion | test.go:74:12:74:40 | call to StepQualRes |
1515
| test.go:78:3:78:15 | type assertion | test.go:77:6:77:11 | definition of taint6 |
1616
| test.go:81:34:81:36 | src | test.go:81:12:81:37 | call to StepArgResNoQual |
17-
| test.go:173:14:173:19 | srcInt | test.go:173:10:173:26 | call to max |
18-
| test.go:173:22:173:22 | 0 | test.go:173:10:173:26 | call to max |
19-
| test.go:173:25:173:25 | 1 | test.go:173:10:173:26 | call to max |
20-
| test.go:174:14:174:14 | 0 | test.go:174:10:174:26 | call to max |
21-
| test.go:174:17:174:22 | srcInt | test.go:174:10:174:26 | call to max |
22-
| test.go:174:25:174:25 | 1 | test.go:174:10:174:26 | call to max |
23-
| test.go:175:14:175:14 | 0 | test.go:175:10:175:26 | call to max |
24-
| test.go:175:17:175:17 | 1 | test.go:175:10:175:26 | call to max |
25-
| test.go:175:20:175:25 | srcInt | test.go:175:10:175:26 | call to max |
26-
| test.go:176:14:176:19 | srcInt | test.go:176:10:176:26 | call to min |
27-
| test.go:176:22:176:22 | 0 | test.go:176:10:176:26 | call to min |
28-
| test.go:176:25:176:25 | 1 | test.go:176:10:176:26 | call to min |
29-
| test.go:177:14:177:14 | 0 | test.go:177:10:177:26 | call to min |
30-
| test.go:177:17:177:22 | srcInt | test.go:177:10:177:26 | call to min |
31-
| test.go:177:25:177:25 | 1 | test.go:177:10:177:26 | call to min |
32-
| test.go:178:14:178:14 | 0 | test.go:178:10:178:26 | call to min |
33-
| test.go:178:17:178:17 | 1 | test.go:178:10:178:26 | call to min |
34-
| test.go:178:20:178:25 | srcInt | test.go:178:10:178:26 | call to min |
17+
| test.go:197:14:197:19 | srcInt | test.go:197:10:197:26 | call to max |
18+
| test.go:197:22:197:22 | 0 | test.go:197:10:197:26 | call to max |
19+
| test.go:197:25:197:25 | 1 | test.go:197:10:197:26 | call to max |
20+
| test.go:198:14:198:14 | 0 | test.go:198:10:198:26 | call to max |
21+
| test.go:198:17:198:22 | srcInt | test.go:198:10:198:26 | call to max |
22+
| test.go:198:25:198:25 | 1 | test.go:198:10:198:26 | call to max |
23+
| test.go:199:14:199:14 | 0 | test.go:199:10:199:26 | call to max |
24+
| test.go:199:17:199:17 | 1 | test.go:199:10:199:26 | call to max |
25+
| test.go:199:20:199:25 | srcInt | test.go:199:10:199:26 | call to max |
26+
| test.go:200:14:200:19 | srcInt | test.go:200:10:200:26 | call to min |
27+
| test.go:200:22:200:22 | 0 | test.go:200:10:200:26 | call to min |
28+
| test.go:200:25:200:25 | 1 | test.go:200:10:200:26 | call to min |
29+
| test.go:201:14:201:14 | 0 | test.go:201:10:201:26 | call to min |
30+
| test.go:201:17:201:22 | srcInt | test.go:201:10:201:26 | call to min |
31+
| test.go:201:25:201:25 | 1 | test.go:201:10:201:26 | call to min |
32+
| test.go:202:14:202:14 | 0 | test.go:202:10:202:26 | call to min |
33+
| test.go:202:17:202:17 | 1 | test.go:202:10:202:26 | call to min |
34+
| test.go:202:20:202:25 | srcInt | test.go:202:10:202:26 | call to min |

go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ func simpleflow() {
8383

8484
taint8 := test.StepArgResArrayContent(src)
8585
b.Sink1(taint8[0]) // $ hasValueFlow="index expression"
86+
for _, x := range taint8 {
87+
b.Sink1(x) // $ hasValueFlow="x"
88+
}
89+
for _, x := range arraytype(taint8) {
90+
b.Sink1(x) // $ MISSING: hasValueFlow="x"
91+
}
8692

8793
srcArray := []interface{}{nil, src}
8894
taint9 := test.StepArgArrayContentRes(srcArray)
@@ -91,6 +97,12 @@ func simpleflow() {
9197
taint10 := test.StepArgResCollectionContent(a.Src1()).(chan interface{})
9298
b.Sink1(test.GetElement(taint10)) // $ hasValueFlow="call to GetElement"
9399
b.Sink1(<-taint10) // $ hasValueFlow="<-..."
100+
for e := range taint10 {
101+
b.Sink1(e) // $ MISSING: hasValueFlow="e"
102+
}
103+
for e := range channeltype(taint10) {
104+
b.Sink1(e) // $ MISSING: hasValueFlow="e"
105+
}
94106

95107
srcCollection := test.SetElement(a.Src1())
96108
taint11 := test.StepArgCollectionContentRes(srcCollection)
@@ -104,13 +116,25 @@ func simpleflow() {
104116
for k := range taint12 {
105117
b.Sink1(k) // $ hasValueFlow="k"
106118
}
119+
for k, _ := range mapstringstringtype(taint12) {
120+
b.Sink1(k) // $ MISSING: hasValueFlow="k"
121+
}
122+
for k := range mapstringstringtype(taint12) {
123+
b.Sink1(k) // $ MISSING: hasValueFlow="k"
124+
}
107125

108126
srcMap13 := map[string]string{src.(string): ""}
109127
taint13 := test.StepArgMapKeyContentRes(srcMap13)
110128
b.Sink1(taint13) // $ hasValueFlow="taint13"
111129

112130
taint14 := test.StepArgResMapValueContent(src).(map[string]string)
113131
b.Sink1(taint14[""]) // $ hasValueFlow="index expression"
132+
for _, v := range taint14 {
133+
b.Sink1(v) // $ hasValueFlow="v"
134+
}
135+
for _, v := range mapstringstringtype(taint14) {
136+
b.Sink1(v) // $ MISSING: hasValueFlow="v"
137+
}
114138

115139
srcMap15 := map[string]string{"": src.(string)}
116140
taint15 := test.StepArgMapValueContentRes(srcMap15)
@@ -177,3 +201,7 @@ func simpleflow() {
177201
b.Sink1(min(0, srcInt, 1)) // $ hasValueFlow="call to min"
178202
b.Sink1(min(0, 1, srcInt)) // $ hasValueFlow="call to min"
179203
}
204+
205+
type mapstringstringtype map[string]string
206+
type arraytype []interface{}
207+
type channeltype chan interface{}

0 commit comments

Comments
 (0)