Skip to content

Commit b3332da

Browse files
committed
PS: Implement more control-flow trees.
1 parent a70cf44 commit b3332da

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

powershell/ql/lib/semmle/code/powershell/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,25 @@ predicate succExit(CfgScope scope, Ast last, Completion c) { scope.exit(last, c)
7575

7676
/** Defines the CFG by dispatch on the various AST types. */
7777
module Trees {
78+
class NonDefaultParameterTree extends LeafTree instanceof Parameter {
79+
NonDefaultParameterTree() { not exists(super.getDefaultValue()) }
80+
}
81+
82+
class DefaultParameterTree extends StandardPostOrderTree instanceof Parameter {
83+
DefaultParameterTree() { exists(super.getDefaultValue()) }
84+
85+
override AstNode getChildNode(int i) {
86+
i = 0 and
87+
result = super.getDefaultValue()
88+
}
89+
90+
final override predicate propagatesAbnormal(AstNode child) { child = super.getDefaultValue() }
91+
}
92+
93+
class ParameterBlockTree extends StandardPostOrderTree instanceof ParamBlock {
94+
override AstNode getChildNode(int i) { result = super.getParameter(i) }
95+
}
96+
7897
abstract class ScriptBlockTree extends ControlFlowTree instanceof ScriptBlock {
7998
abstract predicate succEntry(AstNode n, Completion c);
8099

@@ -160,6 +179,44 @@ module Trees {
160179
}
161180
}
162181

182+
class FunctionScriptBlockTree extends PreOrderTree, ScriptBlockTree {
183+
Function func;
184+
185+
FunctionScriptBlockTree() { func.getBody() = this }
186+
187+
AstNode getParameter(int i) { result = func.getFunctionParameter(i) }
188+
189+
int getNumberOfParameters() { result = func.getNumberOfFunctionParameters() }
190+
191+
override predicate succ(AstNode pred, AstNode succ, Completion c) {
192+
// Step to the first parameter
193+
pred = this and
194+
first(this.getParameter(0), succ) and
195+
completionIsSimple(c)
196+
or
197+
// Step to the next parameter
198+
exists(int i |
199+
last(this.getParameter(i), pred, c) and
200+
completionIsNormal(c) and
201+
first(this.getParameter(i + 1), succ)
202+
)
203+
or
204+
// Body steps
205+
super.succ(pred, succ, c)
206+
}
207+
208+
final override predicate succEntry(AstNode n, Completion c) {
209+
// If there are no paramters we enter the body directly
210+
not exists(this.getParameter(0)) and
211+
n = this and
212+
completionIsSimple(c)
213+
or
214+
// Once we are done with the last parameter we enter the body
215+
last(this.getParameter(this.getNumberOfParameters() - 1), n, c) and
216+
completionIsNormal(c)
217+
}
218+
}
219+
163220
class TopLevelScriptBlockTree extends PreOrderTree, ScriptBlockTree {
164221
TopLevelScriptBlockTree() { this.(ScriptBlock).isTopLevel() }
165222

@@ -179,6 +236,34 @@ module Trees {
179236
}
180237
}
181238

239+
class StmtBlockTree extends PreOrderTree instanceof StmtBlock {
240+
final override predicate propagatesAbnormal(AstNode child) { child = super.getAStmt() }
241+
242+
final override predicate last(AstNode last, Completion c) {
243+
last(super.getStmt(super.getNumberOfStmts() - 1), last, c)
244+
or
245+
not exists(super.getAStmt()) and
246+
last = this and
247+
completionIsSimple(c)
248+
}
249+
250+
final override predicate succ(AstNode pred, AstNode succ, Completion c) {
251+
this = pred and
252+
first(super.getStmt(0), succ) and
253+
completionIsSimple(c)
254+
or
255+
exists(int i |
256+
last(super.getStmt(i), pred, c) and
257+
completionIsNormal(c) and
258+
first(super.getStmt(i + 1), succ)
259+
)
260+
}
261+
}
262+
263+
class GotoStmtTree extends LeafTree instanceof GotoStmt { }
264+
265+
class FunctionStmtTree extends LeafTree instanceof Function { }
266+
182267
class VarAccessTree extends LeafTree instanceof VarAccess { }
183268

184269
class BinaryExprTree extends StandardPostOrderTree instanceof BinaryExpr {
@@ -189,11 +274,23 @@ module Trees {
189274
}
190275
}
191276

277+
class UnaryExprTree extends StandardPostOrderTree instanceof UnaryExpr {
278+
override AstNode getChildNode(int i) { i = 0 and result = super.getOperand() }
279+
}
280+
281+
class ArrayLiteralTree extends StandardPostOrderTree instanceof ArrayLiteral {
282+
override AstNode getChildNode(int i) { result = super.getElement(i) }
283+
}
284+
192285
class ConstExprTree extends LeafTree instanceof ConstExpr { }
193286

194287
class CmdExprTree extends StandardPreOrderTree instanceof CmdExpr {
195288
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
196289
}
290+
291+
class PipelineTree extends StandardPreOrderTree instanceof Pipeline {
292+
override AstNode getChildNode(int i) { result = super.getComponent(i) }
293+
}
197294
}
198295

199296
private import Scope

0 commit comments

Comments
 (0)