@@ -2,6 +2,7 @@ private import powershell
22private import DataFlowDispatch
33private import DataFlowPrivate
44private import semmle.code.powershell.typetracking.internal.TypeTrackingImpl
5+ private import semmle.code.powershell.ApiGraphs
56private import semmle.code.powershell.Cfg
67
78/**
@@ -95,11 +96,81 @@ class ParameterNode extends Node {
9596 final Parameter getParameter ( ) { result = getParameter ( this ) }
9697}
9798
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+
98132/**
99133 * A data-flow node that is a source of local flow.
100134 */
101135class LocalSourceNode extends Node {
102136 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 ) }
103174}
104175
105176/**
@@ -361,6 +432,8 @@ class ObjectCreationNode extends Node {
361432 }
362433
363434 final CfgNodes:: ObjectCreationCfgNode getObjectCreationNode ( ) { result = objectCreation }
435+
436+ string getConstructedTypeName ( ) { result = this .getObjectCreationNode ( ) .getConstructedTypeName ( ) }
364437}
365438
366439/** A call, viewed as a node in a data flow graph. */
@@ -370,4 +443,10 @@ class CallNode extends AstNode {
370443 CallNode ( ) { call = this .getCfgNode ( ) }
371444
372445 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 ( ) }
373452}
0 commit comments