Skip to content

Commit 7197c64

Browse files
committed
C#: Add more variable capture tests
1 parent 2683e40 commit 7197c64

File tree

6 files changed

+441
-119
lines changed

6 files changed

+441
-119
lines changed

csharp/ql/test/library-tests/dataflow/global/Capture.cs

Lines changed: 153 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,12 @@ void M()
111111
string sink40 = "";
112112
void CaptureOutMultipleLambdas()
113113
{
114-
RunAction(() => {
114+
RunAction(() =>
115+
{
115116
sink40 = "taint source";
116117
});
117-
RunAction(() => {
118+
RunAction(() =>
119+
{
118120
nonSink0 = "not tainted";
119121
});
120122
};
@@ -197,10 +199,159 @@ string Id(string s)
197199
Check(nonSink0);
198200
}
199201

202+
void M1(string s)
203+
{
204+
Action a = () =>
205+
{
206+
Check(s);
207+
};
208+
a();
209+
}
210+
211+
void M2() => M1("taint source");
212+
213+
Action M3(string s)
214+
{
215+
return () =>
216+
{
217+
Check(s); // missing flow from lines 221 and 223
218+
};
219+
}
220+
221+
void M4() => M3("taint source")();
222+
223+
void M5() => RunAction(M3("taint source"));
224+
225+
void M6()
226+
{
227+
List<int> xs = new List<int> { 0, 1, 2 };
228+
var x = "taint source";
229+
xs.ForEach(_ =>
230+
{
231+
Check(x);
232+
x = "taint source";
233+
});
234+
Check(x);
235+
}
236+
237+
public string Field;
238+
239+
void M7()
240+
{
241+
var c = new Capture();
242+
c.Field = "taint source";
243+
244+
Action a = () =>
245+
{
246+
Check(c.Field); // missing flow from line 242
247+
c.Field = "taint source";
248+
};
249+
a();
250+
251+
Check(c.Field); // missing flow from line 247
252+
}
253+
254+
void M7(bool b)
255+
{
256+
var c = new Capture();
257+
if (b)
258+
{
259+
c = null;
260+
}
261+
262+
Action a = () =>
263+
{
264+
c.Field = "taint source";
265+
};
266+
a();
267+
268+
Check(c.Field); // missing flow from line 264
269+
}
270+
271+
void M8()
272+
{
273+
RunAction(x => Check(x), "taint source");
274+
}
275+
276+
void M9()
277+
{
278+
var x = "taint source";
279+
280+
Action middle = () =>
281+
{
282+
Action inner = () =>
283+
{
284+
Check(x);
285+
x = "taint source";
286+
};
287+
inner();
288+
};
289+
290+
middle();
291+
292+
Check(x);
293+
}
294+
295+
void M10()
296+
{
297+
this.Field = "taint source";
298+
299+
Action a = () =>
300+
{
301+
Check(this.Field); // missing flow from line 297
302+
this.Field = "taint source";
303+
};
304+
a();
305+
306+
Check(this.Field); // missing flow from line 302
307+
}
308+
309+
void M11()
310+
{
311+
var x = "taint source";
312+
Check(x);
313+
x = "safe";
314+
Check(x);
315+
316+
Action a = () =>
317+
{
318+
x = "taint source";
319+
Check(x);
320+
x = "safe";
321+
Check(x);
322+
};
323+
a();
324+
}
325+
326+
void M12()
327+
{
328+
var x = "taint source";
329+
330+
void CapturedLocalFunction() => Check(x); // missing flow from line 328
331+
332+
void CapturingLocalFunction() => CapturedLocalFunction();
333+
}
334+
335+
void M13()
336+
{
337+
var x = "taint source";
338+
339+
Action capturedLambda = () => Check(x);
340+
341+
Action capturingLambda = () => capturedLambda();
342+
343+
capturingLambda();
344+
}
345+
200346
static void Check<T>(T x) { }
201347

202348
static void RunAction(Action a)
203349
{
204350
a.Invoke();
205351
}
352+
353+
static void RunAction<T>(Action<T> a, T x)
354+
{
355+
a(x);
356+
}
206357
}

csharp/ql/test/library-tests/dataflow/global/DataFlow.expected

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,24 @@
55
| Capture.cs:72:15:72:20 | access to local variable sink30 |
66
| Capture.cs:84:15:84:20 | access to local variable sink31 |
77
| Capture.cs:93:15:93:20 | access to local variable sink32 |
8-
| Capture.cs:122:15:122:20 | access to local variable sink40 |
9-
| Capture.cs:133:15:133:20 | access to local variable sink33 |
10-
| Capture.cs:145:15:145:20 | access to local variable sink34 |
11-
| Capture.cs:154:15:154:20 | access to local variable sink35 |
12-
| Capture.cs:161:15:161:20 | access to local variable sink36 |
13-
| Capture.cs:169:15:169:20 | access to local variable sink37 |
14-
| Capture.cs:195:15:195:20 | access to local variable sink38 |
8+
| Capture.cs:124:15:124:20 | access to local variable sink40 |
9+
| Capture.cs:135:15:135:20 | access to local variable sink33 |
10+
| Capture.cs:147:15:147:20 | access to local variable sink34 |
11+
| Capture.cs:156:15:156:20 | access to local variable sink35 |
12+
| Capture.cs:163:15:163:20 | access to local variable sink36 |
13+
| Capture.cs:171:15:171:20 | access to local variable sink37 |
14+
| Capture.cs:197:15:197:20 | access to local variable sink38 |
15+
| Capture.cs:206:19:206:19 | access to parameter s |
16+
| Capture.cs:231:19:231:19 | access to local variable x |
17+
| Capture.cs:234:15:234:15 | access to local variable x |
18+
| Capture.cs:251:15:251:21 | access to field Field |
19+
| Capture.cs:273:30:273:30 | access to parameter x |
20+
| Capture.cs:284:23:284:23 | access to local variable x |
21+
| Capture.cs:292:15:292:15 | access to local variable x |
22+
| Capture.cs:306:15:306:24 | access to field Field |
23+
| Capture.cs:312:15:312:15 | access to local variable x |
24+
| Capture.cs:319:19:319:19 | access to local variable x |
25+
| Capture.cs:339:45:339:45 | access to local variable x |
1526
| GlobalDataFlow.cs:19:15:19:29 | access to field SinkField0 |
1627
| GlobalDataFlow.cs:27:15:27:32 | access to property SinkProperty0 |
1728
| GlobalDataFlow.cs:45:50:45:59 | access to parameter sinkParam2 |

0 commit comments

Comments
 (0)