Skip to content

Commit 28b654d

Browse files
committed
PS: Add helper clases for index expression.
1 parent 22e508b commit 28b654d

File tree

5 files changed

+66
-11
lines changed

5 files changed

+66
-11
lines changed

powershell/ql/lib/semmle/code/powershell/IndexExpr.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import powershell
2+
private import internal.ExplicitWrite
23

34
class IndexExpr extends @index_expression, Expr {
45
override string toString() { result = "...[...]" }
@@ -11,3 +12,19 @@ class IndexExpr extends @index_expression, Expr {
1112

1213
predicate isNullConditional() { index_expression(this, _, _, true) }
1314
}
15+
16+
private predicate isImplicitIndexWrite(Expr e) { none() }
17+
18+
/** An index expression that is being written to. */
19+
class IndexExprWrite extends IndexExpr {
20+
IndexExprWrite() { isExplicitWrite(this, _) or isImplicitIndexWrite(this) }
21+
22+
predicate isExplicit(AssignStmt assign) { isExplicitWrite(this, assign) }
23+
24+
predicate isImplicit() { isImplicitIndexWrite(this) }
25+
}
26+
27+
/** An index expression that is being read from. */
28+
class IndexExprRead extends IndexExpr {
29+
IndexExprRead() { not this instanceof IndexExprWrite }
30+
}

powershell/ql/lib/semmle/code/powershell/VariableExpression.qll

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import powershell
2+
private import internal.ExplicitWrite
23

34
private predicate isParameterName(@variable_expression ve) { parameter(_, ve, _, _) }
45

@@ -34,24 +35,16 @@ class VarAccess extends @variable_expression, Expr {
3435
Variable getVariable() { result.getAnAccess() = this }
3536
}
3637

37-
private predicate isExplicitVariableWriteAccess(Expr e, AssignStmt assign) {
38-
e = assign.getLeftHandSide()
39-
or
40-
e = any(ConvertExpr convert | isExplicitVariableWriteAccess(convert, assign)).getExpr()
41-
or
42-
e = any(ArrayLiteral array | isExplicitVariableWriteAccess(array, assign)).getAnElement()
43-
}
44-
4538
private predicate isImplicitVariableWriteAccess(Expr e) { none() }
4639

4740
class VarReadAccess extends VarAccess {
4841
VarReadAccess() { not this instanceof VarWriteAccess }
4942
}
5043

5144
class VarWriteAccess extends VarAccess {
52-
VarWriteAccess() { isExplicitVariableWriteAccess(this, _) or isImplicitVariableWriteAccess(this) }
45+
VarWriteAccess() { isExplicitWrite(this, _) or isImplicitVariableWriteAccess(this) }
5346

54-
predicate isExplicit(AssignStmt assign) { isExplicitVariableWriteAccess(this, assign) }
47+
predicate isExplicit(AssignStmt assign) { isExplicitWrite(this, assign) }
5548

5649
predicate isImplicit() { isImplicitVariableWriteAccess(this) }
5750
}

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,12 +325,41 @@ module ExprNodes {
325325
/** A control-flow node that wraps a `MemberExpr` expression that is being written to. */
326326
class MemberCfgWriteAccessNode extends MemberCfgNode {
327327
MemberCfgWriteAccessNode() { this.getExpr() instanceof MemberExprWriteAccess }
328+
329+
StmtNodes::AssignStmtCfgNode getAssignStmt() { result.getLeftHandSide() = this }
328330
}
329331

330332
/** A control-flow node that wraps a `MemberExpr` expression that is being read from. */
331333
class MemberCfgReadAccessNode extends MemberCfgNode {
332334
MemberCfgReadAccessNode() { this.getExpr() instanceof MemberExprReadAccess }
333335
}
336+
337+
class IndexChildMapping extends ExprChildMapping, IndexExpr {
338+
override predicate relevantChild(Ast n) { n = this.getBase() or n = this.getIndex() }
339+
}
340+
341+
/** A control-flow node that wraps a `MemberExpr` expression. */
342+
class IndexCfgNode extends ExprCfgNode {
343+
override string getAPrimaryQlClass() { result = "IndexCfgNode" }
344+
345+
override IndexChildMapping e;
346+
347+
final ExprCfgNode getBase() { e.hasCfgChild(e.getBase(), this, result) }
348+
349+
final ExprCfgNode getIndex() { e.hasCfgChild(e.getIndex(), this, result) }
350+
}
351+
352+
/** A control-flow node that wraps a `MemberExpr` expression that is being written to. */
353+
class IndexCfgWriteNode extends IndexCfgNode {
354+
IndexCfgWriteNode() { this.getExpr() instanceof IndexExprWrite }
355+
356+
StmtNodes::AssignStmtCfgNode getAssignStmt() { result.getLeftHandSide() = this }
357+
}
358+
359+
/** A control-flow node that wraps a `MemberExpr` expression that is being read from. */
360+
class IndexCfgReadNode extends IndexCfgNode {
361+
IndexCfgReadNode() { this.getExpr() instanceof IndexExprRead }
362+
}
334363
}
335364

336365
module StmtNodes {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
private import powershell
2+
3+
/**
4+
* Holds if `e` is written to by `assign`.
5+
*
6+
* Note there may be more than one `e` for which `isExplicitWrite(e, assign)`
7+
* holds if the left-hand side is an array literal.
8+
*/
9+
predicate isExplicitWrite(Expr e, AssignStmt assign) {
10+
e = assign.getLeftHandSide()
11+
or
12+
e = any(ConvertExpr convert | isExplicitWrite(convert, assign)).getExpr()
13+
or
14+
e = any(ArrayLiteral array | isExplicitWrite(array, assign)).getAnElement()
15+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
import Parameter
1+
import Parameter
2+
import ExplicitWrite

0 commit comments

Comments
 (0)