Skip to content

Commit 3faca03

Browse files
committed
C#: Introduce ObjectInitializerNode
1 parent 83050d9 commit 3faca03

File tree

2 files changed

+52
-6
lines changed

2 files changed

+52
-6
lines changed

csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,9 @@ private module Cached {
431431
)
432432
} or
433433
TMallocNode(ControlFlow::Nodes::ElementNode cfn) { cfn.getElement() instanceof ObjectCreation } or
434+
TObjectInitializerNode(ControlFlow::Nodes::ElementNode cfn) {
435+
cfn.getElement().(ObjectCreation).hasInitializer()
436+
} or
434437
TExprPostUpdateNode(ControlFlow::Nodes::ElementNode cfn) {
435438
exists(Argument a, Type t |
436439
a = cfn.getElement() and
@@ -486,6 +489,8 @@ private module Cached {
486489
n = nodeFrom and
487490
nodeTo = n.getSuccessor(AccessPath::empty())
488491
)
492+
or
493+
nodeTo.(ObjectCreationNode).getPreUpdateNode() = nodeFrom.(ObjectInitializerNode)
489494
}
490495

491496
/**
@@ -556,7 +561,7 @@ private module Cached {
556561
predicate clearsContent(Node n, Content c) {
557562
fieldOrPropertyAssign(_, c, _, n.asExpr())
558563
or
559-
fieldOrPropertyInit(n.asExpr(), c, _)
564+
fieldOrPropertyInit(n.(ObjectInitializerNode).getObjectCreation(), c, _)
560565
or
561566
exists(n.(LibraryCodeNode).getSuccessor(any(AccessPath ap | ap.getHead() = c)))
562567
}
@@ -1664,9 +1669,50 @@ abstract class PostUpdateNode extends Node {
16641669

16651670
private module PostUpdateNodes {
16661671
class ObjectCreationNode extends PostUpdateNode, ExprNode, TExprNode {
1667-
ObjectCreationNode() { exists(ObjectCreation oc | this = TExprNode(oc.getAControlFlowNode())) }
1672+
private ObjectCreation oc;
1673+
1674+
ObjectCreationNode() { this = TExprNode(oc.getAControlFlowNode()) }
1675+
1676+
override Node getPreUpdateNode() {
1677+
exists(ControlFlow::Nodes::ElementNode cfn | this = TExprNode(cfn) |
1678+
result.(ObjectInitializerNode).getControlFlowNode() = cfn
1679+
or
1680+
not oc.hasInitializer() and
1681+
result.(MallocNode).getControlFlowNode() = cfn
1682+
)
1683+
}
1684+
}
1685+
1686+
/**
1687+
* A node that represents the value of a newly created object after the object
1688+
* has been created, but before the object initializer has been executed.
1689+
*
1690+
* Such a node acts as both a post-update node for the `MallocNode`, as well as
1691+
* a pre-update node for the `ObjectCreationNode`.
1692+
*/
1693+
class ObjectInitializerNode extends PostUpdateNode, NodeImpl, TObjectInitializerNode {
1694+
private ObjectCreation oc;
1695+
private ControlFlow::Nodes::ElementNode cfn;
1696+
1697+
ObjectInitializerNode() {
1698+
this = TObjectInitializerNode(cfn) and
1699+
cfn = oc.getAControlFlowNode()
1700+
}
1701+
1702+
/** Gets the object creation to which this initializer node belongs. */
1703+
ObjectCreation getObjectCreation() { result = oc }
1704+
1705+
override MallocNode getPreUpdateNode() { result.getControlFlowNode() = cfn }
1706+
1707+
override DataFlowCallable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() }
1708+
1709+
override DotNet::Type getTypeImpl() { result = oc.getType() }
1710+
1711+
override ControlFlow::Nodes::ElementNode getControlFlowNodeImpl() { result = cfn }
1712+
1713+
override Location getLocationImpl() { result = cfn.getLocation() }
16681714

1669-
override MallocNode getPreUpdateNode() { this = TExprNode(result.getControlFlowNode()) }
1715+
override string toStringImpl() { result = "[pre-initializer] " + cfn }
16701716
}
16711717

16721718
class ExprPostUpdateNode extends PostUpdateNode, NodeImpl, TExprPostUpdateNode {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ edges
217217
| H.cs:165:21:165:28 | access to field FieldA [FieldB] : Object | H.cs:165:17:165:28 | (...) ... [FieldB] : Object |
218218
| H.cs:167:14:167:14 | access to local variable b [FieldB] : Object | H.cs:167:14:167:21 | access to field FieldB |
219219
| I.cs:7:9:7:14 | [post] this access [Field1] : Object | I.cs:21:13:21:19 | object creation of type I [Field1] : Object |
220-
| I.cs:7:9:7:14 | [post] this access [Field1] : Object | I.cs:26:13:26:37 | object creation of type I [Field1] : Object |
220+
| I.cs:7:9:7:14 | [post] this access [Field1] : Object | I.cs:26:13:26:37 | [pre-initializer] object creation of type I [Field1] : Object |
221221
| I.cs:7:18:7:29 | object creation of type Object : Object | I.cs:7:9:7:14 | [post] this access [Field1] : Object |
222222
| I.cs:13:17:13:28 | object creation of type Object : Object | I.cs:15:20:15:20 | access to local variable o : Object |
223223
| I.cs:15:9:15:9 | [post] access to local variable i [Field1] : Object | I.cs:16:9:16:9 | access to local variable i [Field1] : Object |
@@ -228,7 +228,7 @@ edges
228228
| I.cs:21:13:21:19 | object creation of type I [Field1] : Object | I.cs:22:9:22:9 | access to local variable i [Field1] : Object |
229229
| I.cs:22:9:22:9 | access to local variable i [Field1] : Object | I.cs:23:14:23:14 | access to local variable i [Field1] : Object |
230230
| I.cs:23:14:23:14 | access to local variable i [Field1] : Object | I.cs:23:14:23:21 | access to field Field1 |
231-
| I.cs:26:13:26:37 | object creation of type I [Field1] : Object | I.cs:27:14:27:14 | access to local variable i [Field1] : Object |
231+
| I.cs:26:13:26:37 | [pre-initializer] object creation of type I [Field1] : Object | I.cs:27:14:27:14 | access to local variable i [Field1] : Object |
232232
| I.cs:27:14:27:14 | access to local variable i [Field1] : Object | I.cs:27:14:27:21 | access to field Field1 |
233233
| I.cs:31:13:31:24 | object creation of type Object : Object | I.cs:32:20:32:20 | access to local variable o : Object |
234234
| I.cs:32:9:32:9 | [post] access to local variable i [Field1] : Object | I.cs:33:9:33:9 | access to local variable i [Field1] : Object |
@@ -501,7 +501,7 @@ nodes
501501
| I.cs:22:9:22:9 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object |
502502
| I.cs:23:14:23:14 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object |
503503
| I.cs:23:14:23:21 | access to field Field1 | semmle.label | access to field Field1 |
504-
| I.cs:26:13:26:37 | object creation of type I [Field1] : Object | semmle.label | object creation of type I [Field1] : Object |
504+
| I.cs:26:13:26:37 | [pre-initializer] object creation of type I [Field1] : Object | semmle.label | [pre-initializer] object creation of type I [Field1] : Object |
505505
| I.cs:27:14:27:14 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object |
506506
| I.cs:27:14:27:21 | access to field Field1 | semmle.label | access to field Field1 |
507507
| I.cs:31:13:31:24 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |

0 commit comments

Comments
 (0)