Skip to content

Commit 09063c5

Browse files
committed
C#: Port and extend type dispatch tests from Java
1 parent 13ad6f8 commit 09063c5

File tree

4 files changed

+293
-0
lines changed

4 files changed

+293
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
public class A
6+
{
7+
static T Source<T>(T source) => throw null;
8+
9+
public static void Sink<T>(T t) { }
10+
11+
interface MyConsumer
12+
{
13+
void run(Object o);
14+
}
15+
16+
static void Apply1<T>(Action<T> f, T x)
17+
{
18+
f(x);
19+
}
20+
21+
static void ApplyWrap1<T>(Action<T> f, T x)
22+
{
23+
Apply1(f, x);
24+
}
25+
26+
void TestLambdaDispatch1()
27+
{
28+
ApplyWrap1(x => { Sink(x); }, Source("A")); // $ hasValueFlow=A
29+
ApplyWrap1(x => { Sink(x); }, "B"); // no flow
30+
ApplyWrap1(x => { }, Source("C"));
31+
ApplyWrap1(x => { }, "D");
32+
}
33+
34+
void ListForEachWrap<T>(List<T> l, Action<T> f)
35+
{
36+
l.ForEach(f);
37+
}
38+
39+
void TestLambdaDispatch2()
40+
{
41+
var tainted = new List<string> { Source("E") };
42+
var safe = new List<string>();
43+
ListForEachWrap(safe, x => { Sink(x); }); // no flow
44+
ListForEachWrap(tainted, x => { Sink(x); }); // $ hasValueFlow=E
45+
}
46+
47+
static void Apply2<T>(Action<T> f, T x)
48+
{
49+
f(x);
50+
}
51+
52+
static void ApplyWrap2<T>(Action<T> f, T x)
53+
{
54+
Apply2(f, x);
55+
}
56+
57+
void SinkMethodGroup1<T>(T t) => Sink(t); // $ hasValueFlow=F $ hasValueFlow=G
58+
void SinkMethodGroup2<T>(T t) => Sink(t);
59+
60+
void TestLambdaDispatch3()
61+
{
62+
ApplyWrap2(SinkMethodGroup1, Source("F"));
63+
ApplyWrap2(SinkMethodGroup2, "B");
64+
}
65+
66+
void ForEach<T>(List<T> l, Action<T> f)
67+
{
68+
foreach (var x in l)
69+
f(x);
70+
}
71+
72+
void ForEachWrap<T>(List<T> l, Action<T> f)
73+
{
74+
ForEach(l, f);
75+
}
76+
77+
void TestLambdaDispatch4()
78+
{
79+
var tainted = new List<string> { Source("G") };
80+
var safe = new List<string>();
81+
ForEachWrap(safe, SinkMethodGroup2);
82+
ForEachWrap(tainted, SinkMethodGroup1);
83+
}
84+
85+
class TaintedClass
86+
{
87+
public override string ToString() => Source("TaintedClass");
88+
}
89+
90+
class SafeClass
91+
{
92+
public override string ToString() => "safe";
93+
}
94+
95+
string ConvertToString(object o) => o.ToString();
96+
97+
string ConvertToStringWrap(object o) => ConvertToString(o);
98+
99+
void TestToString1()
100+
{
101+
var unused = ConvertToStringWrap(new TaintedClass());
102+
Sink(ConvertToStringWrap(new SafeClass())); // no flow
103+
}
104+
}

0 commit comments

Comments
 (0)