Skip to content

Commit c36142f

Browse files
committed
C#: Add data-flow test for collections
1 parent 922e52f commit c36142f

File tree

3 files changed

+487
-0
lines changed

3 files changed

+487
-0
lines changed
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
// semmle-extractor-options: /r:System.Linq.dll
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
6+
public class A
7+
{
8+
public void M1()
9+
{
10+
var a = new A();
11+
var @as = new[] { a };
12+
Sink(@as[0]); // flow
13+
SinkElem(@as); // flow
14+
Sink(First(@as)); // flow
15+
}
16+
17+
public void M2(A other)
18+
{
19+
var a = new A();
20+
var @as = new[] { other };
21+
Sink(@as[0]); // no flow
22+
SinkElem(@as); // no flow
23+
Sink(First(@as)); // no flow
24+
}
25+
26+
public void M3()
27+
{
28+
var a = new A();
29+
var @as = new A[1];
30+
@as[0] = a;
31+
Sink(@as[0]); // flow
32+
SinkElem(@as); // flow
33+
Sink(First(@as)); // flow
34+
}
35+
36+
public void M4(A other)
37+
{
38+
var a = new A();
39+
var @as = new A[1];
40+
@as[0] = other;
41+
Sink(@as[0]); // no flow
42+
SinkElem(@as); // no flow
43+
Sink(First(@as)); // no flow
44+
}
45+
46+
public void M5()
47+
{
48+
var a = new A();
49+
var list = new List<A>();
50+
list[0] = a;
51+
Sink(list[0]); // flow
52+
SinkListElem(list); // flow
53+
Sink(ListFirst(list)); // flow
54+
}
55+
56+
public void M6(A other)
57+
{
58+
var list = new List<A>();
59+
list[0] = other;
60+
Sink(list[0]); // no flow
61+
SinkListElem(list); // no flow
62+
Sink(ListFirst(list)); // no flow
63+
}
64+
65+
public void M7()
66+
{
67+
var a = new A();
68+
var list = new List<A>() { a };
69+
Sink(list[0]); // flow
70+
SinkListElem(list); // flow
71+
Sink(ListFirst(list)); // flow
72+
}
73+
74+
public void M8(A other)
75+
{
76+
var list = new List<A>() { other };
77+
Sink(list[0]); // no flow
78+
SinkListElem(list); // no flow
79+
Sink(ListFirst(list)); // no flow
80+
}
81+
82+
public void M9()
83+
{
84+
var a = new A();
85+
var list = new List<A>();
86+
list.Add(a);
87+
Sink(list[0]); // flow
88+
SinkListElem(list); // flow
89+
Sink(ListFirst(list)); // flow
90+
}
91+
92+
public void M10(A other)
93+
{
94+
var list = new List<A>();
95+
list.Add(other);
96+
Sink(list[0]); // no flow
97+
SinkListElem(list); // no flow
98+
Sink(ListFirst(list)); // no flow
99+
}
100+
101+
public void M11()
102+
{
103+
var a = new A();
104+
var dict = new Dictionary<int, A>();
105+
dict[0] = a;
106+
Sink(dict[0]); // flow
107+
SinkDictValue(dict); // flow
108+
Sink(DictFirstValueA(dict)); // flow
109+
Sink(DictFirstValueB(dict)); // flow [MISSING]
110+
Sink(DictFirstValueC(dict)); // flow
111+
}
112+
113+
public void M12(A other)
114+
{
115+
var dict = new Dictionary<int, A>();
116+
dict[0] = other;
117+
Sink(dict[0]); // no flow
118+
SinkDictValue(dict); // no flow
119+
Sink(DictFirstValueA(dict)); // no flow
120+
Sink(DictFirstValueB(dict)); // no flow
121+
Sink(DictFirstValueC(dict)); // no flow
122+
}
123+
124+
public void M13()
125+
{
126+
var a = new A();
127+
var dict = new Dictionary<int, A>() { { 0, a } };
128+
Sink(dict[0]); // flow
129+
SinkDictValue(dict); // flow
130+
Sink(DictFirstValueA(dict)); // flow
131+
Sink(DictFirstValueB(dict)); // flow [MISSING]
132+
Sink(DictFirstValueC(dict)); // flow
133+
}
134+
135+
public void M14(A other)
136+
{
137+
var dict = new Dictionary<int, A>() { { 0, other } };
138+
Sink(dict[0]); // no flow
139+
SinkDictValue(dict); // no flow
140+
Sink(DictFirstValueA(dict)); // no flow
141+
Sink(DictFirstValueB(dict)); // no flow
142+
Sink(DictFirstValueC(dict)); // no flow
143+
}
144+
145+
public void M15()
146+
{
147+
var a = new A();
148+
var dict = new Dictionary<A, int>() { { a, 0 } };
149+
Sink(dict.Keys.First()); // flow [MISSING]
150+
SinkDictKey(dict); // flow [MISSING]
151+
Sink(DictFirstKeyA(dict)); // flow [MISSING]
152+
Sink(DictFirstKeyB(dict)); // flow [MISSING]
153+
}
154+
155+
public void M16(A other)
156+
{
157+
var dict = new Dictionary<A, int>() { { other, 0 } };
158+
Sink(dict.Keys.First()); // no flow
159+
SinkDictKey(dict); // no flow
160+
Sink(DictFirstKeyA(dict)); // no flow
161+
Sink(DictFirstKeyB(dict)); // no flow
162+
}
163+
164+
public void M17()
165+
{
166+
var a = new A();
167+
var @as = new[] { a };
168+
foreach (var x in @as)
169+
Sink(x); // flow
170+
}
171+
172+
public void M18(A other)
173+
{
174+
var @as = new[] { other };
175+
foreach (var x in @as)
176+
Sink(x); // no flow
177+
}
178+
179+
public void M19()
180+
{
181+
var a = new A();
182+
var @as = new[] { a };
183+
var enumerator = @as.GetEnumerator();
184+
while (enumerator.MoveNext())
185+
Sink(enumerator.Current); // flow
186+
}
187+
188+
public void M20(A other)
189+
{
190+
var @as = new[] { other };
191+
var enumerator = @as.GetEnumerator();
192+
while (enumerator.MoveNext())
193+
Sink(enumerator.Current); // no flow
194+
}
195+
196+
public void M21()
197+
{
198+
var a = new A();
199+
var list = new List<A>();
200+
list.Add(a);
201+
var enumerator = list.GetEnumerator();
202+
while (enumerator.MoveNext())
203+
Sink(enumerator.Current); // flow [MISSING]
204+
}
205+
206+
public static void Sink<T>(T t) { }
207+
208+
public static void SinkElem<T>(T[] ts) => Sink(ts[0]);
209+
210+
public static void SinkListElem<T>(IList<T> list) => Sink(list[0]);
211+
212+
public static void SinkDictValue<T>(IDictionary<int, T> dict) => Sink(dict[0]);
213+
214+
public static void SinkDictKey<T>(IDictionary<T, int> dict) => Sink(dict.Keys.First());
215+
216+
public static T First<T>(T[] ts) => ts[0];
217+
218+
public static T ListFirst<T>(IList<T> list) => list[0];
219+
220+
public static T DictFirstValueA<T>(IDictionary<int, T> dict) => dict[0];
221+
222+
public static T DictFirstValueB<T>(IDictionary<int, T> dict) => dict.First().Value;
223+
224+
public static T DictFirstValueC<T>(IDictionary<int, T> dict) => dict.Values.First();
225+
226+
public static T DictFirstKeyA<T>(IDictionary<T, int> dict) => dict.Keys.First();
227+
228+
public static T DictFirstKeyB<T>(IDictionary<T, int> dict) => dict.First().Key;
229+
}

0 commit comments

Comments
 (0)