Skip to content

Commit f91af7d

Browse files
committed
C#: Add more data-flow tests
1 parent 05ec755 commit f91af7d

File tree

5 files changed

+89
-11
lines changed

5 files changed

+89
-11
lines changed
Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
import csharp
22
private import semmle.code.csharp.controlflow.Guards
33

4+
private predicate outRefDef(DataFlow::ExprNode ne, int outRef) {
5+
exists(Ssa::ExplicitDefinition def, Parameter outRefParameter |
6+
outRefParameter.isOutOrRef() and
7+
ne.getExpr() = def.getADefinition().getSource() and
8+
def.isLiveOutRefParameterDefinition(outRefParameter) and
9+
outRef = outRefParameter.getPosition()
10+
)
11+
}
12+
413
class Configuration extends DataFlow::Configuration {
514
Configuration() { this = "Configuration" }
615

7-
override predicate isSource(DataFlow::Node source) { any() }
16+
override predicate isSource(DataFlow::Node source) { source instanceof DataFlow::ParameterNode }
817

9-
override predicate isSink(DataFlow::Node sink) { any() }
18+
override predicate isSink(DataFlow::Node sink) {
19+
any(Callable c).canReturn(sink.asExpr()) or outRefDef(sink, _)
20+
}
1021

1122
override predicate isBarrier(DataFlow::Node node) {
1223
exists(AbstractValues::NullValue nv | node.(GuardedDataFlowNode).mustHaveValue(nv) |
@@ -24,15 +35,9 @@ predicate flowOutFromParameter(DataFlow::Configuration c, Parameter p) {
2435
}
2536

2637
predicate flowOutFromParameterOutOrRef(DataFlow::Configuration c, Parameter p, int outRef) {
27-
exists(
28-
DataFlow::ExprNode ne, Ssa::ExplicitDefinition def, DataFlow::ParameterNode np,
29-
Parameter outRefParameter
30-
|
31-
outRefParameter.isOutOrRef() and
38+
exists(DataFlow::ExprNode ne, DataFlow::ParameterNode np |
39+
outRefDef(ne, outRef) and
3240
np.getParameter() = p and
33-
ne.getExpr() = def.getADefinition().getSource() and
34-
def.isLiveOutRefParameterDefinition(outRefParameter) and
35-
c.hasFlow(np, ne) and
36-
outRef = outRefParameter.getPosition()
41+
c.hasFlow(np, ne)
3742
)
3843
}

csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,20 @@ edges
201201
| H.cs:131:18:131:18 | access to local variable a [FieldA] : Object | H.cs:131:14:131:19 | call to method Get |
202202
| H.cs:147:17:147:32 | call to method Through : A | H.cs:148:14:148:14 | access to local variable a |
203203
| H.cs:147:25:147:31 | object creation of type A : A | H.cs:147:17:147:32 | call to method Through : A |
204+
| H.cs:155:17:155:23 | object creation of type B : B | H.cs:157:20:157:20 | access to local variable b : B |
205+
| H.cs:157:9:157:9 | [post] access to parameter a [FieldA] : B | H.cs:164:19:164:19 | [post] access to local variable a [FieldA] : B |
206+
| H.cs:157:20:157:20 | access to local variable b : B | H.cs:157:9:157:9 | [post] access to parameter a [FieldA] : B |
207+
| H.cs:163:17:163:28 | object creation of type Object : Object | H.cs:164:22:164:22 | access to local variable o : Object |
208+
| H.cs:164:19:164:19 | [post] access to local variable a [FieldA, FieldB] | H.cs:165:21:165:21 | access to local variable a [FieldA, FieldB] |
209+
| H.cs:164:19:164:19 | [post] access to local variable a [FieldA] : B | H.cs:165:21:165:21 | access to local variable a [FieldA] : B |
210+
| H.cs:164:22:164:22 | access to local variable o : Object | H.cs:164:19:164:19 | [post] access to local variable a [FieldA, FieldB] |
211+
| H.cs:165:17:165:28 | (...) ... : B | H.cs:166:14:166:14 | access to local variable b |
212+
| H.cs:165:17:165:28 | (...) ... [FieldB] : Object | H.cs:167:14:167:14 | access to local variable b [FieldB] : Object |
213+
| H.cs:165:21:165:21 | access to local variable a [FieldA, FieldB] | H.cs:165:21:165:28 | access to field FieldA [FieldB] : Object |
214+
| H.cs:165:21:165:21 | access to local variable a [FieldA] : B | H.cs:165:21:165:28 | access to field FieldA : B |
215+
| H.cs:165:21:165:28 | access to field FieldA : B | H.cs:165:17:165:28 | (...) ... : B |
216+
| H.cs:165:21:165:28 | access to field FieldA [FieldB] : Object | H.cs:165:17:165:28 | (...) ... [FieldB] : Object |
217+
| H.cs:167:14:167:14 | access to local variable b [FieldB] : Object | H.cs:167:14:167:21 | access to field FieldB |
204218
nodes
205219
| A.cs:5:17:5:23 | object creation of type C : C | semmle.label | object creation of type C : C |
206220
| A.cs:6:17:6:25 | call to method Make [c] : C | semmle.label | call to method Make [c] : C |
@@ -434,6 +448,22 @@ nodes
434448
| H.cs:147:17:147:32 | call to method Through : A | semmle.label | call to method Through : A |
435449
| H.cs:147:25:147:31 | object creation of type A : A | semmle.label | object creation of type A : A |
436450
| H.cs:148:14:148:14 | access to local variable a | semmle.label | access to local variable a |
451+
| H.cs:155:17:155:23 | object creation of type B : B | semmle.label | object creation of type B : B |
452+
| H.cs:157:9:157:9 | [post] access to parameter a [FieldA] : B | semmle.label | [post] access to parameter a [FieldA] : B |
453+
| H.cs:157:20:157:20 | access to local variable b : B | semmle.label | access to local variable b : B |
454+
| H.cs:163:17:163:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
455+
| H.cs:164:19:164:19 | [post] access to local variable a [FieldA, FieldB] | semmle.label | [post] access to local variable a [FieldA, FieldB] |
456+
| H.cs:164:19:164:19 | [post] access to local variable a [FieldA] : B | semmle.label | [post] access to local variable a [FieldA] : B |
457+
| H.cs:164:22:164:22 | access to local variable o : Object | semmle.label | access to local variable o : Object |
458+
| H.cs:165:17:165:28 | (...) ... : B | semmle.label | (...) ... : B |
459+
| H.cs:165:17:165:28 | (...) ... [FieldB] : Object | semmle.label | (...) ... [FieldB] : Object |
460+
| H.cs:165:21:165:21 | access to local variable a [FieldA, FieldB] | semmle.label | access to local variable a [FieldA, FieldB] |
461+
| H.cs:165:21:165:21 | access to local variable a [FieldA] : B | semmle.label | access to local variable a [FieldA] : B |
462+
| H.cs:165:21:165:28 | access to field FieldA : B | semmle.label | access to field FieldA : B |
463+
| H.cs:165:21:165:28 | access to field FieldA [FieldB] : Object | semmle.label | access to field FieldA [FieldB] : Object |
464+
| H.cs:166:14:166:14 | access to local variable b | semmle.label | access to local variable b |
465+
| H.cs:167:14:167:14 | access to local variable b [FieldB] : Object | semmle.label | access to local variable b [FieldB] : Object |
466+
| H.cs:167:14:167:21 | access to field FieldB | semmle.label | access to field FieldB |
437467
#select
438468
| A.cs:7:14:7:16 | access to field c | A.cs:5:17:5:23 | object creation of type C : C | A.cs:7:14:7:16 | access to field c | $@ | A.cs:5:17:5:23 | object creation of type C : C | object creation of type C : C |
439469
| A.cs:14:14:14:20 | call to method Get | A.cs:13:15:13:22 | object creation of type C1 : C1 | A.cs:14:14:14:20 | call to method Get | $@ | A.cs:13:15:13:22 | object creation of type C1 : C1 | object creation of type C1 : C1 |
@@ -481,3 +511,5 @@ nodes
481511
| H.cs:114:14:114:21 | access to field FieldB | H.cs:112:20:112:31 | object creation of type Object : Object | H.cs:114:14:114:21 | access to field FieldB | $@ | H.cs:112:20:112:31 | object creation of type Object : Object | object creation of type Object : Object |
482512
| H.cs:131:14:131:19 | call to method Get | H.cs:130:20:130:31 | object creation of type Object : Object | H.cs:131:14:131:19 | call to method Get | $@ | H.cs:130:20:130:31 | object creation of type Object : Object | object creation of type Object : Object |
483513
| H.cs:148:14:148:14 | access to local variable a | H.cs:147:25:147:31 | object creation of type A : A | H.cs:148:14:148:14 | access to local variable a | $@ | H.cs:147:25:147:31 | object creation of type A : A | object creation of type A : A |
514+
| H.cs:166:14:166:14 | access to local variable b | H.cs:155:17:155:23 | object creation of type B : B | H.cs:166:14:166:14 | access to local variable b | $@ | H.cs:155:17:155:23 | object creation of type B : B | object creation of type B : B |
515+
| H.cs:167:14:167:21 | access to field FieldB | H.cs:163:17:163:28 | object creation of type Object : Object | H.cs:167:14:167:21 | access to field FieldB | $@ | H.cs:163:17:163:28 | object creation of type Object : Object | object creation of type Object : Object |

csharp/ql/test/library-tests/dataflow/fields/H.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,22 @@ void M7()
150150
Sink(b); // no flow
151151
}
152152

153+
void SetNested(A a, object o)
154+
{
155+
var b = new B();
156+
b.FieldB = o;
157+
a.FieldA = b;
158+
}
159+
160+
void M8()
161+
{
162+
var a = new A();
163+
var o = new object();
164+
SetNested(a, o);
165+
var b = (B) a.FieldA;
166+
Sink(b); // flow (from `new B()` inside `SetNested`)
167+
Sink(b.FieldB); // flow
168+
}
169+
153170
public static void Sink(object o) { }
154171
}

csharp/ql/test/library-tests/dataflow/types/Types.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,18 @@ public override void M()
114114
{
115115
Sink(this.Field);
116116
}
117+
118+
void M10()
119+
{
120+
var a = new A();
121+
var e2 = new E2();
122+
Sink(Through(a)); // flow
123+
Sink(Through(e2)); // flow
124+
Sink((E2)Through(a)); // no flow
125+
Sink((A)Through(e2)); // no flow
126+
}
117127
}
118128
}
129+
130+
static object Through(object x) => x;
119131
}

csharp/ql/test/library-tests/dataflow/types/Types.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ edges
3939
| Types.cs:110:25:110:32 | object creation of type E2 : E2 | Types.cs:90:22:90:22 | e : E2 |
4040
| Types.cs:113:34:113:34 | this [Field] : E2 | Types.cs:115:22:115:25 | this access [Field] : E2 |
4141
| Types.cs:115:22:115:25 | this access [Field] : E2 | Types.cs:115:22:115:31 | access to field Field |
42+
| Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:30:122:30 | access to local variable a : A |
43+
| Types.cs:121:26:121:33 | object creation of type E2 : E2 | Types.cs:123:30:123:31 | access to local variable e2 : E2 |
44+
| Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:122:22:122:31 | call to method Through |
45+
| Types.cs:123:30:123:31 | access to local variable e2 : E2 | Types.cs:123:22:123:32 | call to method Through |
4246
nodes
4347
| Types.cs:7:21:7:25 | this : D | semmle.label | this : D |
4448
| Types.cs:7:32:7:35 | this access : D | semmle.label | this access : D |
@@ -90,6 +94,12 @@ nodes
9094
| Types.cs:113:34:113:34 | this [Field] : E2 | semmle.label | this [Field] : E2 |
9195
| Types.cs:115:22:115:25 | this access [Field] : E2 | semmle.label | this access [Field] : E2 |
9296
| Types.cs:115:22:115:31 | access to field Field | semmle.label | access to field Field |
97+
| Types.cs:120:25:120:31 | object creation of type A : A | semmle.label | object creation of type A : A |
98+
| Types.cs:121:26:121:33 | object creation of type E2 : E2 | semmle.label | object creation of type E2 : E2 |
99+
| Types.cs:122:22:122:31 | call to method Through | semmle.label | call to method Through |
100+
| Types.cs:122:30:122:30 | access to local variable a : A | semmle.label | access to local variable a : A |
101+
| Types.cs:123:22:123:32 | call to method Through | semmle.label | call to method Through |
102+
| Types.cs:123:30:123:31 | access to local variable e2 : E2 | semmle.label | access to local variable e2 : E2 |
93103
#select
94104
| Types.cs:23:12:23:18 | object creation of type C : C | Types.cs:50:18:50:18 | access to local variable c | Types.cs:50:18:50:18 | access to local variable c | $@ | Types.cs:50:18:50:18 | access to local variable c | access to local variable c |
95105
| Types.cs:25:12:25:18 | object creation of type C : C | Types.cs:63:33:63:36 | (...) ... | Types.cs:63:33:63:36 | (...) ... | $@ | Types.cs:63:33:63:36 | (...) ... | (...) ... |
@@ -106,3 +116,5 @@ nodes
106116
| Types.cs:40:12:40:18 | object creation of type D : D | Types.cs:16:42:16:45 | this access | Types.cs:16:42:16:45 | this access | $@ | Types.cs:16:42:16:45 | this access | this access |
107117
| Types.cs:43:20:43:23 | null : null | Types.cs:44:14:44:14 | access to local variable o | Types.cs:44:14:44:14 | access to local variable o | $@ | Types.cs:44:14:44:14 | access to local variable o | access to local variable o |
108118
| Types.cs:110:25:110:32 | object creation of type E2 : E2 | Types.cs:115:22:115:31 | access to field Field | Types.cs:115:22:115:31 | access to field Field | $@ | Types.cs:115:22:115:31 | access to field Field | access to field Field |
119+
| Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:22:122:31 | call to method Through | Types.cs:122:22:122:31 | call to method Through | $@ | Types.cs:122:22:122:31 | call to method Through | call to method Through |
120+
| Types.cs:121:26:121:33 | object creation of type E2 : E2 | Types.cs:123:22:123:32 | call to method Through | Types.cs:123:22:123:32 | call to method Through | $@ | Types.cs:123:22:123:32 | call to method Through | call to method Through |

0 commit comments

Comments
 (0)