Skip to content

Commit 3fa466e

Browse files
authored
Merge pull request #102 from microsoft/powershell-very-basic-flow-steps
PS: Add very basic dataflow steps
2 parents dd2c5ef + f2d89a2 commit 3fa466e

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,29 @@ module ExprNodes {
197197

198198
InvokeMemberCfgNode getInvokeMember() { this = result.getQualifier() }
199199
}
200+
201+
class ConditionalChildMapping extends ExprChildMapping, ConditionalExpr {
202+
override predicate relevantChild(Ast n) { n = this.getCondition() or n = this.getABranch() }
203+
}
204+
205+
/** A control-flow node that wraps a `ConditionalExpr` expression. */
206+
class ConditionalCfgNode extends ExprCfgNode {
207+
override string getAPrimaryQlClass() { result = "ConditionalCfgNode" }
208+
209+
override ConditionalChildMapping e;
210+
211+
final override ConditionalExpr getExpr() { result = super.getExpr() }
212+
213+
final ExprCfgNode getCondition() { e.hasCfgChild(e.getCondition(), this, result) }
214+
215+
final ExprCfgNode getBranch(boolean value) { e.hasCfgChild(e.getBranch(value), this, result) }
216+
217+
final ExprCfgNode getABranch() { result = this.getBranch(_) }
218+
219+
final ExprCfgNode getIfTrue() { e.hasCfgChild(e.getIfTrue(), this, result) }
220+
221+
final ExprCfgNode getIfFalse() { e.hasCfgChild(e.getIfFalse(), this, result) }
222+
}
200223
}
201224

202225
module StmtNodes {

powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,14 @@ module SsaFlow {
8989
module LocalFlow {
9090
pragma[nomagic]
9191
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
92-
none() // TODO
92+
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::ConditionalCfgNode).getABranch()
93+
or
94+
nodeFrom.asStmt() = nodeTo.asStmt().(CfgNodes::StmtNodes::AssignStmtCfgNode).getRightHandSide()
9395
}
9496

95-
predicate localMustFlowStep(Node node1, Node node2) { none() }
97+
predicate localMustFlowStep(Node nodeFrom, Node nodeTo) {
98+
nodeFrom.asStmt() = nodeTo.asStmt().(CfgNodes::StmtNodes::AssignStmtCfgNode).getRightHandSide()
99+
}
96100
}
97101

98102
/** Provides logic related to captured variables. */
@@ -125,11 +129,22 @@ private module Cached {
125129
* data flow.
126130
*/
127131
cached
128-
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) { none() }
132+
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
133+
(
134+
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
135+
or
136+
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
137+
) and
138+
model = ""
139+
}
129140

130141
/** This is the local flow predicate that is exposed. */
131142
cached
132-
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) { none() }
143+
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) {
144+
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
145+
or
146+
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
147+
}
133148

134149
cached
135150
newtype TContentSet = TSingletonContent(Content c)

0 commit comments

Comments
 (0)