@@ -2,6 +2,7 @@ private import powershell
2
2
private import DataFlowDispatch
3
3
private import DataFlowPrivate
4
4
private import semmle.code.powershell.typetracking.internal.TypeTrackingImpl
5
+ private import semmle.code.powershell.ApiGraphs
5
6
private import semmle.code.powershell.Cfg
6
7
7
8
/**
@@ -95,11 +96,81 @@ class ParameterNode extends Node {
95
96
final Parameter getParameter ( ) { result = getParameter ( this ) }
96
97
}
97
98
99
+ /**
100
+ * A data flow node corresponding to a method, block, or lambda expression.
101
+ */
102
+ class CallableNode extends Node instanceof ScriptBlockNode {
103
+ private ParameterPosition getParameterPosition ( ParameterNodeImpl node ) {
104
+ exists ( DataFlowCallable c |
105
+ c .asCfgScope ( ) = this .asCallableAstNode ( ) and
106
+ result = getParameterPosition ( node , c )
107
+ )
108
+ }
109
+
110
+ /** Gets the underlying AST node as a `Callable`. */
111
+ ScriptBlock asCallableAstNode ( ) { result = super .getScriptBlock ( ) }
112
+
113
+ /** Gets the `n`th positional parameter. */
114
+ ParameterNode getParameter ( int n ) {
115
+ this .getParameterPosition ( result ) .isPositional ( n , emptyNamedSet ( ) )
116
+ }
117
+
118
+ /** Gets the number of positional parameters of this callable. */
119
+ final int getNumberOfParameters ( ) { result = count ( this .getParameter ( _) ) }
120
+
121
+ /** Gets the keyword parameter of the given name. */
122
+ ParameterNode getKeywordParameter ( string name ) {
123
+ this .getParameterPosition ( result ) .isKeyword ( name )
124
+ }
125
+
126
+ /**
127
+ * Gets a data flow node whose value is about to be returned by this callable.
128
+ */
129
+ Node getAReturnNode ( ) { result = getAReturnNode ( this .asCallableAstNode ( ) ) }
130
+ }
131
+
98
132
/**
99
133
* A data-flow node that is a source of local flow.
100
134
*/
101
135
class LocalSourceNode extends Node {
102
136
LocalSourceNode ( ) { isLocalSourceNode ( this ) }
137
+
138
+ /** Starts tracking this node forward using API graphs. */
139
+ pragma [ inline]
140
+ API:: Node track ( ) { result = API:: Internal:: getNodeForForwardTracking ( this ) }
141
+
142
+ /** Holds if this `LocalSourceNode` can flow to `nodeTo` in one or more local flow steps. */
143
+ pragma [ inline]
144
+ predicate flowsTo ( Node nodeTo ) { flowsTo ( this , nodeTo ) }
145
+
146
+ /**
147
+ * Gets a node that this node may flow to using one heap and/or interprocedural step.
148
+ *
149
+ * See `TypeTracker` for more details about how to use this.
150
+ */
151
+ pragma [ inline]
152
+ LocalSourceNode track ( TypeTracker t2 , TypeTracker t ) { t = t2 .step ( this , result ) }
153
+
154
+ /**
155
+ * Gets a node that may flow into this one using one heap and/or interprocedural step.
156
+ *
157
+ * See `TypeBackTracker` for more details about how to use this.
158
+ */
159
+ pragma [ inline]
160
+ LocalSourceNode backtrack ( TypeBackTracker t2 , TypeBackTracker t ) { t = t2 .step ( result , this ) }
161
+
162
+ /**
163
+ * Gets a node to which data may flow from this node in zero or
164
+ * more local data-flow steps.
165
+ */
166
+ pragma [ inline]
167
+ Node getALocalUse ( ) { flowsTo ( this , result ) }
168
+
169
+ /** Gets a method call where this node flows to the receiver. */
170
+ CallNode getAMethodCall ( ) { Cached:: hasMethodCall ( this , result , _) }
171
+
172
+ /** Gets a call to a method named `name`, where this node flows to the receiver. */
173
+ CallNode getAMethodCall ( string name ) { Cached:: hasMethodCall ( this , result , name ) }
103
174
}
104
175
105
176
/**
@@ -361,6 +432,8 @@ class ObjectCreationNode extends Node {
361
432
}
362
433
363
434
final CfgNodes:: ObjectCreationCfgNode getObjectCreationNode ( ) { result = objectCreation }
435
+
436
+ string getConstructedTypeName ( ) { result = this .getObjectCreationNode ( ) .getConstructedTypeName ( ) }
364
437
}
365
438
366
439
/** A call, viewed as a node in a data flow graph. */
@@ -370,4 +443,10 @@ class CallNode extends AstNode {
370
443
CallNode ( ) { call = this .getCfgNode ( ) }
371
444
372
445
CfgNodes:: CallCfgNode getCallNode ( ) { result = call }
446
+
447
+ string getName ( ) { result = call .getName ( ) }
448
+
449
+ Node getQualifier ( ) { result .asExpr ( ) = call .getQualifier ( ) }
450
+
451
+ int getNumberOfArguments ( ) { result = call .getNumberOfArguments ( ) }
373
452
}
0 commit comments