Skip to content

Commit f21cde2

Browse files
committed
PS: Implement _just enough_ control flow to make the first example work.
1 parent 626328c commit f21cde2

File tree

3 files changed

+155
-4
lines changed

3 files changed

+155
-4
lines changed

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

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,95 @@ 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-
// TODO
78+
class ScriptBlockTree extends PreOrderTree instanceof ScriptBlock {
79+
final override predicate last(AstNode last, Completion c) {
80+
last(super.getEndBlock(), last, c)
81+
or
82+
not exists(super.getEndBlock()) and
83+
last(super.getProcessBlock(), last, c)
84+
or
85+
not exists(super.getEndBlock()) and
86+
not exists(super.getProcessBlock()) and
87+
last(super.getBeginBlock(), last, c)
88+
or
89+
not exists(super.getEndBlock()) and
90+
not exists(super.getProcessBlock()) and
91+
not exists(super.getBeginBlock()) and
92+
last = this and
93+
completionIsSimple(c)
94+
}
95+
96+
final override predicate propagatesAbnormal(AstNode child) {
97+
child = [super.getBeginBlock(), super.getProcessBlock(), super.getEndBlock()]
98+
}
99+
100+
final override predicate succ(AstNode pred, AstNode succ, Completion c) {
101+
pred = this and
102+
(
103+
first(super.getBeginBlock(), succ)
104+
or
105+
not exists(super.getBeginBlock()) and
106+
first(super.getProcessBlock(), succ)
107+
or
108+
not exists(super.getBeginBlock()) and
109+
not exists(super.getProcessBlock()) and
110+
first(super.getEndBlock(), succ)
111+
) and
112+
completionIsSimple(c)
113+
or
114+
last(super.getBeginBlock(), pred, c) and
115+
c instanceof NormalCompletion and
116+
(
117+
first(super.getProcessBlock(), succ)
118+
or
119+
not exists(super.getProcessBlock()) and
120+
first(super.getEndBlock(), succ)
121+
or
122+
not exists(super.getProcessBlock()) and
123+
not exists(super.getEndBlock()) and
124+
succ = this
125+
)
126+
or
127+
last(super.getProcessBlock(), pred, c) and
128+
c instanceof NormalCompletion and
129+
(
130+
// If we process multiple items we will loop back to the process block
131+
first(super.getProcessBlock(), succ)
132+
or
133+
// Once we're done process all items we will go to the end block
134+
first(super.getEndBlock(), succ)
135+
)
136+
}
137+
}
138+
139+
class NamedBlockTree extends StandardPostOrderTree instanceof NamedBlock {
140+
// TODO: Handle trap
141+
override AstNode getChildNode(int i) { result = super.getStatement(i) }
142+
}
143+
144+
class AssignStmtTree extends StandardPostOrderTree instanceof AssignStmt {
145+
override AstNode getChildNode(int i) {
146+
i = 0 and result = super.getLeftHandSide()
147+
or
148+
i = 1 and result = super.getRightHandSide()
149+
}
150+
}
151+
152+
class VarAccessTree extends LeafTree instanceof VarAccess { }
153+
154+
class BinaryExprTree extends StandardPostOrderTree instanceof BinaryExpr {
155+
override AstNode getChildNode(int i) {
156+
i = 0 and result = super.getLeft()
157+
or
158+
i = 1 and result = super.getRight()
159+
}
160+
}
161+
162+
class ConstExprTree extends LeafTree instanceof ConstExpr { }
163+
164+
class CmdExprTree extends StandardPreOrderTree instanceof CmdExpr {
165+
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
166+
}
79167
}
80168

81169
private import Scope
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
global.ps1:
2+
# 1| {...}
3+
#-----| -> c
4+
5+
# 1| enter global.ps1
6+
#-----| -> global.ps1
7+
8+
# 1| exit global.ps1
9+
10+
# 1| exit global.ps1 (normal)
11+
#-----| -> exit global.ps1
12+
13+
# 1| global.ps1
14+
#-----| -> a
15+
16+
# 2| a
17+
#-----| -> 1
18+
19+
# 2| ...=...
20+
#-----| -> b
21+
22+
# 2| 1
23+
#-----| -> ...=...
24+
25+
# 2| 1
26+
#-----| -> 1
27+
28+
# 3| b
29+
#-----| -> 2
30+
31+
# 3| ...=...
32+
#-----| -> {...}
33+
34+
# 3| 2
35+
#-----| -> ...=...
36+
37+
# 3| 2
38+
#-----| -> 2
39+
40+
# 5| {...}
41+
#-----| -> exit global.ps1 (normal)
42+
43+
# 6| c
44+
#-----| -> ...+...
45+
46+
# 6| ...=...
47+
#-----| -> {...}
48+
49+
# 6| a
50+
#-----| -> b
51+
52+
# 6| ...+...
53+
#-----| -> ...=...
54+
55+
# 6| ...+...
56+
#-----| -> a
57+
58+
# 6| b
59+
#-----| -> ...+...
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
$a = 1
2-
$b = 2
3-
$c = $a + $b
1+
Begin {
2+
$a = 1
3+
$b = 2
4+
}
5+
End {
6+
$c = $a + $b
7+
}

0 commit comments

Comments
 (0)