@@ -2,8 +2,10 @@ private import codeql.util.Boolean
2
2
private import codeql.util.Unit
3
3
private import powershell
4
4
private import semmle.code.powershell.Cfg
5
+ private import semmle.code.powershell.dataflow.Ssa
5
6
private import DataFlowPublic
6
7
private import DataFlowDispatch
8
+ private import SsaImpl as SsaImpl
7
9
8
10
/** Gets the callable in which this node occurs. */
9
11
DataFlowCallable nodeGetEnclosingCallable ( Node n ) { result = n .( NodeImpl ) .getEnclosingCallable ( ) }
@@ -39,9 +41,40 @@ private class ExprNodeImpl extends ExprNode, NodeImpl {
39
41
override string toStringImpl ( ) { result = this .getExprNode ( ) .toString ( ) }
40
42
}
41
43
44
+ /** Gets the SSA definition node corresponding to parameter `p`. */
45
+ pragma [ nomagic]
46
+ SsaImpl:: DefinitionExt getParameterDef ( Parameter p ) {
47
+ exists ( EntryBasicBlock bb , int i |
48
+ SsaImpl:: parameterWrite ( bb , i , p ) and
49
+ result .definesAt ( p , bb , i , _)
50
+ )
51
+ }
52
+
42
53
/** Provides logic related to SSA. */
43
54
module SsaFlow {
44
- // TODO
55
+ private module Impl = SsaImpl:: DataFlowIntegration;
56
+
57
+ private ParameterNodeImpl toParameterNode ( SsaImpl:: ParameterExt p ) {
58
+ result = TNormalParameterNode ( p .asParameter ( ) )
59
+ }
60
+
61
+ Impl:: Node asNode ( Node n ) {
62
+ n = TSsaNode ( result )
63
+ or
64
+ result .( Impl:: ExprNode ) .getExpr ( ) = n .asExpr ( )
65
+ or
66
+ result .( Impl:: ExprPostUpdateNode ) .getExpr ( ) = n .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
67
+ or
68
+ n = toParameterNode ( result .( Impl:: ParameterNode ) .getParameter ( ) )
69
+ }
70
+
71
+ predicate localFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo , boolean isUseStep ) {
72
+ Impl:: localFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) , isUseStep )
73
+ }
74
+
75
+ predicate localMustFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo ) {
76
+ Impl:: localMustFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) )
77
+ }
45
78
}
46
79
47
80
/** Provides predicates related to local data flow. */
@@ -54,19 +87,6 @@ module LocalFlow {
54
87
predicate localMustFlowStep ( Node node1 , Node node2 ) { none ( ) }
55
88
}
56
89
57
- /** An argument of a call (including qualifier arguments and block arguments). */
58
- private class Argument extends CfgNodes:: ExprCfgNode {
59
- private CfgNodes:: StmtNodes:: CmdCfgNode call ;
60
- private ArgumentPosition arg ;
61
-
62
- Argument ( ) { none ( ) }
63
-
64
- /** Holds if this expression is the `i`th argument of `c`. */
65
- predicate isArgumentOf ( CfgNodes:: StmtNodes:: CmdCfgNode c , ArgumentPosition pos ) {
66
- c = call and pos = arg
67
- }
68
- }
69
-
70
90
/** Provides logic related to captured variables. */
71
91
module VariableCapture {
72
92
// TODO
@@ -78,8 +98,11 @@ private module Cached {
78
98
cached
79
99
newtype TNode =
80
100
TExprNode ( CfgNodes:: ExprCfgNode n ) or
101
+ TSsaNode ( SsaImpl:: DataFlowIntegration:: SsaNode node ) or
102
+ TNormalParameterNode ( Parameter p ) or
81
103
TExprPostUpdateNode ( CfgNodes:: ExprCfgNode n ) {
82
- none ( ) // TODO
104
+ n instanceof CfgNodes:: ExprNodes:: ArgumentCfgNode or
105
+ n instanceof CfgNodes:: ExprNodes:: QualifierCfgNode
83
106
}
84
107
85
108
cached
@@ -117,6 +140,60 @@ import Cached
117
140
/** Holds if `n` should be hidden from path explanations. */
118
141
predicate nodeIsHidden ( Node n ) { none ( ) }
119
142
143
+ /** An SSA node. */
144
+ abstract class SsaNode extends NodeImpl , TSsaNode {
145
+ SsaImpl:: DataFlowIntegration:: SsaNode node ;
146
+ SsaImpl:: DefinitionExt def ;
147
+
148
+ SsaNode ( ) {
149
+ this = TSsaNode ( node ) and
150
+ def = node .getDefinitionExt ( )
151
+ }
152
+
153
+ SsaImpl:: DefinitionExt getDefinitionExt ( ) { result = def }
154
+
155
+ /** Holds if this node should be hidden from path explanations. */
156
+ abstract predicate isHidden ( ) ;
157
+
158
+ override Location getLocationImpl ( ) { result = node .getLocation ( ) }
159
+
160
+ override string toStringImpl ( ) { result = node .toString ( ) }
161
+ }
162
+
163
+ /** An (extended) SSA definition, viewed as a node in a data flow graph. */
164
+ class SsaDefinitionExtNode extends SsaNode {
165
+ override SsaImpl:: DataFlowIntegration:: SsaDefinitionExtNode node ;
166
+
167
+ /** Gets the underlying variable. */
168
+ Variable getVariable ( ) { result = def .getSourceVariable ( ) }
169
+
170
+ override predicate isHidden ( ) {
171
+ not def instanceof Ssa:: WriteDefinition
172
+ or
173
+ def = getParameterDef ( _)
174
+ }
175
+
176
+ override CfgScope getCfgScope ( ) { result = def .getBasicBlock ( ) .getScope ( ) }
177
+ }
178
+
179
+ class SsaDefinitionNodeImpl extends SsaDefinitionExtNode {
180
+ Ssa:: Definition ssaDef ;
181
+
182
+ SsaDefinitionNodeImpl ( ) { ssaDef = def }
183
+
184
+ override Location getLocationImpl ( ) { result = ssaDef .getLocation ( ) }
185
+
186
+ override string toStringImpl ( ) { result = ssaDef .toString ( ) }
187
+ }
188
+
189
+ class SsaInputNode extends SsaNode {
190
+ override SsaImpl:: DataFlowIntegration:: SsaInputNode node ;
191
+
192
+ override predicate isHidden ( ) { any ( ) }
193
+
194
+ override CfgScope getCfgScope ( ) { result = node .getDefinitionExt ( ) .getBasicBlock ( ) .getScope ( ) }
195
+ }
196
+
120
197
private module ParameterNodes {
121
198
abstract class ParameterNodeImpl extends NodeImpl {
122
199
abstract Parameter getParameter ( ) ;
@@ -130,7 +207,30 @@ private module ParameterNodes {
130
207
)
131
208
}
132
209
}
133
- // TODO
210
+
211
+ /**
212
+ * The value of a normal parameter at function entry, viewed as a node in a data
213
+ * flow graph.
214
+ */
215
+ class NormalParameterNode extends ParameterNodeImpl , TNormalParameterNode {
216
+ Parameter parameter ;
217
+
218
+ NormalParameterNode ( ) { this = TNormalParameterNode ( parameter ) }
219
+
220
+ override Parameter getParameter ( ) { result = parameter }
221
+
222
+ override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
223
+ exists ( CfgScope callable , int i |
224
+ callable = c .asCfgScope ( ) and pos .isPositional ( i ) and callable .getParameter ( i ) = parameter
225
+ )
226
+ }
227
+
228
+ override CfgScope getCfgScope ( ) { result .getAParameter ( ) = parameter }
229
+
230
+ override Location getLocationImpl ( ) { result = parameter .getLocation ( ) }
231
+
232
+ override string toStringImpl ( ) { result = parameter .toString ( ) }
233
+ }
134
234
}
135
235
136
236
import ParameterNodes
@@ -252,7 +352,19 @@ abstract class PostUpdateNodeImpl extends Node {
252
352
}
253
353
254
354
private module PostUpdateNodes {
255
- // TODO
355
+ class ExprPostUpdateNode extends PostUpdateNodeImpl , NodeImpl , TExprPostUpdateNode {
356
+ private CfgNodes:: ExprCfgNode e ;
357
+
358
+ ExprPostUpdateNode ( ) { this = TExprPostUpdateNode ( e ) }
359
+
360
+ override ExprNode getPreUpdateNode ( ) { e = result .getExprNode ( ) }
361
+
362
+ override CfgScope getCfgScope ( ) { result = e .getExpr ( ) .getEnclosingScope ( ) }
363
+
364
+ override Location getLocationImpl ( ) { result = e .getLocation ( ) }
365
+
366
+ override string toStringImpl ( ) { result = "[post] " + e .toString ( ) }
367
+ }
256
368
}
257
369
258
370
private import PostUpdateNodes
@@ -276,7 +388,7 @@ class NodeRegion instanceof Unit {
276
388
predicate contains ( Node n ) { none ( ) }
277
389
278
390
/** Gets a best-effort total ordering. */
279
- int totalOrder ( ) { none ( ) }
391
+ int totalOrder ( ) { result = 1 }
280
392
}
281
393
282
394
/**
0 commit comments