Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a344707

Browse files
hvitvedTom Hvitved
authored andcommitted
C#: Add more data flow tests
Add tests that exhibit missing type pruning.
1 parent 78ddb37 commit a344707

5 files changed

Lines changed: 358 additions & 23 deletions

File tree

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,80 @@
1-
| dataflow.cs:18:18:18:26 | "tainted" | dataflow.cs:18:18:18:37 | call to method ToString |
2-
| dataflow.cs:20:27:20:27 | 2 | dataflow.cs:20:18:20:31 | call to method Max |
3-
| dataflow.cs:20:30:20:30 | 3 | dataflow.cs:20:18:20:31 | call to method Max |
4-
| dataflow.cs:21:29:21:31 | 0.5 | dataflow.cs:21:18:21:32 | call to method Round |
5-
| dataflow.cs:22:45:22:53 | "tainted" | dataflow.cs:22:18:22:54 | call to method GetFullPath |
6-
| dataflow.cs:29:44:29:46 | 1 | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
7-
| dataflow.cs:29:49:29:51 | 2 | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
8-
| dataflow.cs:40:34:40:37 | "d1" | dataflow.cs:40:18:40:38 | call to method Taint1 |
9-
| dataflow.cs:41:34:41:37 | "d2" | dataflow.cs:41:18:41:38 | call to method Taint2 |
10-
| dataflow.cs:42:34:42:37 | "d3" | dataflow.cs:42:18:42:38 | call to method Taint3 |
11-
| dataflow.cs:46:28:46:32 | "t1a" | dataflow.cs:46:18:46:40 | call to method Taint1 |
12-
| dataflow.cs:46:35:46:39 | "t1b" | dataflow.cs:46:18:46:40 | call to method Taint1 |
13-
| dataflow.cs:49:35:49:38 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
14-
| dataflow.cs:49:41:49:44 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
15-
| dataflow.cs:102:30:102:33 | null | dataflow.cs:74:21:74:52 | ... ?? ... |
16-
| dataflow.cs:102:30:102:33 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
17-
| dataflow.cs:102:30:102:33 | null | dataflow.cs:108:20:108:33 | call to method IndirectNull |
18-
| dataflow.cs:109:23:109:26 | null | dataflow.cs:74:21:74:52 | ... ?? ... |
19-
| dataflow.cs:109:23:109:26 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
1+
edges
2+
| dataflow.cs:18:18:18:26 | "tainted" : String | dataflow.cs:18:18:18:37 | call to method ToString |
3+
| dataflow.cs:20:27:20:27 | 2 : Int32 | dataflow.cs:20:18:20:31 | call to method Max |
4+
| dataflow.cs:20:30:20:30 | 3 : Int32 | dataflow.cs:20:18:20:31 | call to method Max |
5+
| dataflow.cs:21:29:21:31 | 0.5 : Double | dataflow.cs:21:18:21:32 | call to method Round |
6+
| dataflow.cs:22:45:22:53 | "tainted" : String | dataflow.cs:22:18:22:54 | call to method GetFullPath |
7+
| dataflow.cs:29:44:29:46 | 1 : Double | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
8+
| dataflow.cs:29:49:29:51 | 2 : Double | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
9+
| dataflow.cs:40:34:40:37 | "d1" : String | dataflow.cs:40:18:40:38 | call to method Taint1 |
10+
| dataflow.cs:41:34:41:37 | "d2" : String | dataflow.cs:41:18:41:38 | call to method Taint2 |
11+
| dataflow.cs:42:34:42:37 | "d3" : String | dataflow.cs:42:18:42:38 | call to method Taint3 |
12+
| dataflow.cs:46:28:46:32 | "t1a" : String | dataflow.cs:46:18:46:40 | call to method Taint1 |
13+
| dataflow.cs:46:35:46:39 | "t1b" : String | dataflow.cs:46:18:46:40 | call to method Taint1 |
14+
| dataflow.cs:49:35:49:38 | "t6" : String | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
15+
| dataflow.cs:49:41:49:44 | "t6" : String | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
16+
| dataflow.cs:74:21:74:34 | call to method NullFunction : null | dataflow.cs:74:21:74:52 | ... ?? ... |
17+
| dataflow.cs:74:39:74:52 | call to method IndirectNull : null | dataflow.cs:74:21:74:52 | ... ?? ... |
18+
| dataflow.cs:89:31:89:44 | call to method NullFunction : null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
19+
| dataflow.cs:102:30:102:33 | null : null | dataflow.cs:74:39:74:52 | call to method IndirectNull : null |
20+
| dataflow.cs:102:30:102:33 | null : null | dataflow.cs:108:20:108:33 | call to method IndirectNull |
21+
| dataflow.cs:102:30:102:33 | null : null | dataflow.cs:108:20:108:33 | call to method IndirectNull : null |
22+
| dataflow.cs:108:20:108:33 | call to method IndirectNull : null | dataflow.cs:110:16:110:16 | access to local variable x : null |
23+
| dataflow.cs:109:23:109:26 | null : null | dataflow.cs:110:16:110:16 | access to local variable x : null |
24+
| dataflow.cs:110:16:110:16 | access to local variable x : null | dataflow.cs:74:21:74:34 | call to method NullFunction : null |
25+
| dataflow.cs:110:16:110:16 | access to local variable x : null | dataflow.cs:89:31:89:44 | call to method NullFunction : null |
26+
nodes
27+
| dataflow.cs:18:18:18:26 | "tainted" : String | semmle.label | "tainted" : String |
28+
| dataflow.cs:18:18:18:37 | call to method ToString | semmle.label | call to method ToString |
29+
| dataflow.cs:20:18:20:31 | call to method Max | semmle.label | call to method Max |
30+
| dataflow.cs:20:27:20:27 | 2 : Int32 | semmle.label | 2 : Int32 |
31+
| dataflow.cs:20:30:20:30 | 3 : Int32 | semmle.label | 3 : Int32 |
32+
| dataflow.cs:21:18:21:32 | call to method Round | semmle.label | call to method Round |
33+
| dataflow.cs:21:29:21:31 | 0.5 : Double | semmle.label | 0.5 : Double |
34+
| dataflow.cs:22:18:22:54 | call to method GetFullPath | semmle.label | call to method GetFullPath |
35+
| dataflow.cs:22:45:22:53 | "tainted" : String | semmle.label | "tainted" : String |
36+
| dataflow.cs:29:18:29:52 | call to method IEEERemainder | semmle.label | call to method IEEERemainder |
37+
| dataflow.cs:29:44:29:46 | 1 : Double | semmle.label | 1 : Double |
38+
| dataflow.cs:29:49:29:51 | 2 : Double | semmle.label | 2 : Double |
39+
| dataflow.cs:40:18:40:38 | call to method Taint1 | semmle.label | call to method Taint1 |
40+
| dataflow.cs:40:34:40:37 | "d1" : String | semmle.label | "d1" : String |
41+
| dataflow.cs:41:18:41:38 | call to method Taint2 | semmle.label | call to method Taint2 |
42+
| dataflow.cs:41:34:41:37 | "d2" : String | semmle.label | "d2" : String |
43+
| dataflow.cs:42:18:42:38 | call to method Taint3 | semmle.label | call to method Taint3 |
44+
| dataflow.cs:42:34:42:37 | "d3" : String | semmle.label | "d3" : String |
45+
| dataflow.cs:46:18:46:40 | call to method Taint1 | semmle.label | call to method Taint1 |
46+
| dataflow.cs:46:28:46:32 | "t1a" : String | semmle.label | "t1a" : String |
47+
| dataflow.cs:46:35:46:39 | "t1b" : String | semmle.label | "t1b" : String |
48+
| dataflow.cs:49:18:49:45 | call to method TaintIndirect | semmle.label | call to method TaintIndirect |
49+
| dataflow.cs:49:35:49:38 | "t6" : String | semmle.label | "t6" : String |
50+
| dataflow.cs:49:41:49:44 | "t6" : String | semmle.label | "t6" : String |
51+
| dataflow.cs:74:21:74:34 | call to method NullFunction : null | semmle.label | call to method NullFunction : null |
52+
| dataflow.cs:74:21:74:52 | ... ?? ... | semmle.label | ... ?? ... |
53+
| dataflow.cs:74:39:74:52 | call to method IndirectNull : null | semmle.label | call to method IndirectNull : null |
54+
| dataflow.cs:89:24:89:51 | ... ? ... : ... | semmle.label | ... ? ... : ... |
55+
| dataflow.cs:89:31:89:44 | call to method NullFunction : null | semmle.label | call to method NullFunction : null |
56+
| dataflow.cs:102:30:102:33 | null : null | semmle.label | null : null |
57+
| dataflow.cs:108:20:108:33 | call to method IndirectNull | semmle.label | call to method IndirectNull |
58+
| dataflow.cs:108:20:108:33 | call to method IndirectNull : null | semmle.label | call to method IndirectNull : null |
59+
| dataflow.cs:109:23:109:26 | null : null | semmle.label | null : null |
60+
| dataflow.cs:110:16:110:16 | access to local variable x : null | semmle.label | access to local variable x : null |
61+
#select
62+
| dataflow.cs:18:18:18:26 | "tainted" : String | dataflow.cs:18:18:18:37 | call to method ToString | dataflow.cs:18:18:18:37 | call to method ToString | $@ | dataflow.cs:18:18:18:37 | call to method ToString | call to method ToString |
63+
| dataflow.cs:20:27:20:27 | 2 : Int32 | dataflow.cs:20:18:20:31 | call to method Max | dataflow.cs:20:18:20:31 | call to method Max | $@ | dataflow.cs:20:18:20:31 | call to method Max | call to method Max |
64+
| dataflow.cs:20:30:20:30 | 3 : Int32 | dataflow.cs:20:18:20:31 | call to method Max | dataflow.cs:20:18:20:31 | call to method Max | $@ | dataflow.cs:20:18:20:31 | call to method Max | call to method Max |
65+
| dataflow.cs:21:29:21:31 | 0.5 : Double | dataflow.cs:21:18:21:32 | call to method Round | dataflow.cs:21:18:21:32 | call to method Round | $@ | dataflow.cs:21:18:21:32 | call to method Round | call to method Round |
66+
| dataflow.cs:22:45:22:53 | "tainted" : String | dataflow.cs:22:18:22:54 | call to method GetFullPath | dataflow.cs:22:18:22:54 | call to method GetFullPath | $@ | dataflow.cs:22:18:22:54 | call to method GetFullPath | call to method GetFullPath |
67+
| dataflow.cs:29:44:29:46 | 1 : Double | dataflow.cs:29:18:29:52 | call to method IEEERemainder | dataflow.cs:29:18:29:52 | call to method IEEERemainder | $@ | dataflow.cs:29:18:29:52 | call to method IEEERemainder | call to method IEEERemainder |
68+
| dataflow.cs:29:49:29:51 | 2 : Double | dataflow.cs:29:18:29:52 | call to method IEEERemainder | dataflow.cs:29:18:29:52 | call to method IEEERemainder | $@ | dataflow.cs:29:18:29:52 | call to method IEEERemainder | call to method IEEERemainder |
69+
| dataflow.cs:40:34:40:37 | "d1" : String | dataflow.cs:40:18:40:38 | call to method Taint1 | dataflow.cs:40:18:40:38 | call to method Taint1 | $@ | dataflow.cs:40:18:40:38 | call to method Taint1 | call to method Taint1 |
70+
| dataflow.cs:41:34:41:37 | "d2" : String | dataflow.cs:41:18:41:38 | call to method Taint2 | dataflow.cs:41:18:41:38 | call to method Taint2 | $@ | dataflow.cs:41:18:41:38 | call to method Taint2 | call to method Taint2 |
71+
| dataflow.cs:42:34:42:37 | "d3" : String | dataflow.cs:42:18:42:38 | call to method Taint3 | dataflow.cs:42:18:42:38 | call to method Taint3 | $@ | dataflow.cs:42:18:42:38 | call to method Taint3 | call to method Taint3 |
72+
| dataflow.cs:46:28:46:32 | "t1a" : String | dataflow.cs:46:18:46:40 | call to method Taint1 | dataflow.cs:46:18:46:40 | call to method Taint1 | $@ | dataflow.cs:46:18:46:40 | call to method Taint1 | call to method Taint1 |
73+
| dataflow.cs:46:35:46:39 | "t1b" : String | dataflow.cs:46:18:46:40 | call to method Taint1 | dataflow.cs:46:18:46:40 | call to method Taint1 | $@ | dataflow.cs:46:18:46:40 | call to method Taint1 | call to method Taint1 |
74+
| dataflow.cs:49:35:49:38 | "t6" : String | dataflow.cs:49:18:49:45 | call to method TaintIndirect | dataflow.cs:49:18:49:45 | call to method TaintIndirect | $@ | dataflow.cs:49:18:49:45 | call to method TaintIndirect | call to method TaintIndirect |
75+
| dataflow.cs:49:41:49:44 | "t6" : String | dataflow.cs:49:18:49:45 | call to method TaintIndirect | dataflow.cs:49:18:49:45 | call to method TaintIndirect | $@ | dataflow.cs:49:18:49:45 | call to method TaintIndirect | call to method TaintIndirect |
76+
| dataflow.cs:102:30:102:33 | null : null | dataflow.cs:74:21:74:52 | ... ?? ... | dataflow.cs:74:21:74:52 | ... ?? ... | $@ | dataflow.cs:74:21:74:52 | ... ?? ... | ... ?? ... |
77+
| dataflow.cs:102:30:102:33 | null : null | dataflow.cs:89:24:89:51 | ... ? ... : ... | dataflow.cs:89:24:89:51 | ... ? ... : ... | $@ | dataflow.cs:89:24:89:51 | ... ? ... : ... | ... ? ... : ... |
78+
| dataflow.cs:102:30:102:33 | null : null | dataflow.cs:108:20:108:33 | call to method IndirectNull | dataflow.cs:108:20:108:33 | call to method IndirectNull | $@ | dataflow.cs:108:20:108:33 | call to method IndirectNull | call to method IndirectNull |
79+
| dataflow.cs:109:23:109:26 | null : null | dataflow.cs:74:21:74:52 | ... ?? ... | dataflow.cs:74:21:74:52 | ... ?? ... | $@ | dataflow.cs:74:21:74:52 | ... ?? ... | ... ?? ... |
80+
| dataflow.cs:109:23:109:26 | null : null | dataflow.cs:89:24:89:51 | ... ? ... : ... | dataflow.cs:89:24:89:51 | ... ? ... : ... | $@ | dataflow.cs:89:24:89:51 | ... ? ... : ... | ... ? ... : ... |
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
/**
2+
* @kind path-problem
3+
*/
4+
15
import csharp
2-
import semmle.code.csharp.dataflow.DataFlow::DataFlow
6+
import DataFlow
7+
import DataFlow::PathGraph
38

49
class FlowConfig extends Configuration {
510
FlowConfig() { this = "FlowConfig" }
@@ -11,6 +16,6 @@ class FlowConfig extends Configuration {
1116
}
1217
}
1318

14-
from FlowConfig config, Node source, Node sink
15-
where config.hasFlow(source, sink)
16-
select source, sink
19+
from DataFlow::PathNode source, DataFlow::PathNode sink, FlowConfig config
20+
where config.hasFlowPath(source, sink)
21+
select source, sink, sink, "$@", sink, sink.toString()
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
class Types
2+
{
3+
class A
4+
{
5+
public virtual void M() { }
6+
7+
public void CallM() => this.M();
8+
}
9+
10+
class B<T> : A { }
11+
12+
class C : B<int> { }
13+
14+
class D : B<string>
15+
{
16+
public override void M() => Sink(this);
17+
}
18+
19+
static void M1()
20+
{
21+
new C().M(); // no flow
22+
new C().CallM(); // no flow (FALSE POSITIVE)
23+
M2(new C()); // flow
24+
M3(new C()); // no flow (FALSE POSITIVE)
25+
M4(new C()); // flow
26+
M5(new C()); // flow
27+
M6(new C()); // flow
28+
M7(new C()); // flow
29+
M8(new C()); // no flow (FALSE POSITIVE)
30+
M9(new C()); // flow
31+
32+
new D().M(); // flow
33+
new D().CallM(); // flow
34+
M2(new D()); // no flow (FALSE POSITIVE)
35+
M3(new D()); // flow
36+
M4(new D()); // no flow (FALSE POSITIVE)
37+
M5(new D()); // flow
38+
M6(new D()); // flow
39+
M7(new D()); // flow
40+
M8(new D()); // flow
41+
M9(new D()); // no flow (FALSE POSITIVE)
42+
43+
object o = null; // flow
44+
Sink(o);
45+
}
46+
47+
static void M2(A a)
48+
{
49+
if (a is C c)
50+
Sink(c);
51+
}
52+
53+
static void M3(A a)
54+
{
55+
switch (a)
56+
{
57+
case D d:
58+
Sink(d);
59+
break;
60+
}
61+
}
62+
63+
static void M4(A a) => Sink((C)a);
64+
65+
static void M5<T>(T x) => Sink(x);
66+
67+
static void M6<T>(T x) where T : A => Sink(x);
68+
69+
static void M7<T>(T x) where T : class => Sink(x);
70+
71+
static void M8<T>(T x)
72+
{
73+
dynamic d = x;
74+
d.M();
75+
}
76+
77+
static void M9(A a)
78+
{
79+
if (a is B<int> b)
80+
Sink(b);
81+
}
82+
83+
static void Sink<T>(T x) { }
84+
85+
abstract class E<T>
86+
{
87+
E<T> Field;
88+
public abstract void M();
89+
90+
void M2(E<T> e)
91+
{
92+
this.Field = e;
93+
this.M();
94+
}
95+
96+
class E1 : E<C>
97+
{
98+
void M3()
99+
{
100+
this.M2(new E1()); // no flow
101+
}
102+
103+
public override void M() { }
104+
}
105+
106+
class E2 : E<D>
107+
{
108+
void M3()
109+
{
110+
this.M2(new E2()); // flow (FALSE NEGATIVE)
111+
}
112+
113+
public override void M()
114+
{
115+
Sink(this.Field);
116+
}
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)