Skip to content

Commit 7f25caf

Browse files
committed
PS: Add various helper predicates.
1 parent 5e2051b commit 7f25caf

4 files changed

Lines changed: 72 additions & 9 deletions

File tree

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,14 @@ class Cmd extends @command, CmdBase {
1919

2020
StringConstExpr getCmdName() { result = this.getElement(0) }
2121

22-
Expr getAnArgument() { result = this.getArgument(_) or result = this.getNamedArgument(_) }
23-
22+
/** Gets any argument to this command. */
23+
Expr getAnArgument() { result = this.getArgument(_) }
24+
25+
/**
26+
* Gets the `i`th argument to this command.
27+
*
28+
* The argument may be named or positional.
29+
*/
2430
Expr getArgument(int i) {
2531
result =
2632
rank[i + 1](CmdElement e, int j |
@@ -32,6 +38,18 @@ class Cmd extends @command, CmdBase {
3238
)
3339
}
3440

41+
/** Gets the `i`th positional argument to this command. */
42+
Expr getPositionalArgument(int i) {
43+
result =
44+
rank[i + 1](Argument e, int j |
45+
e = this.getArgument(j) and
46+
e instanceof PositionalArgument
47+
|
48+
e order by j
49+
)
50+
}
51+
52+
/** Gets the named argument with the given name. */
3553
Expr getNamedArgument(string name) {
3654
exists(int i, CmdParameter p |
3755
this.getElement(i) = p and
@@ -53,11 +71,21 @@ class Cmd extends @command, CmdBase {
5371
class Argument extends Expr {
5472
Cmd cmd;
5573

56-
Argument() { cmd.getArgument(_) = this or cmd.getNamedArgument(_) = this }
74+
Argument() { cmd.getAnArgument() = this }
5775

5876
Cmd getCmd() { result = cmd }
5977

60-
int getIndex() { cmd.getArgument(result) = this }
78+
int getPosition() { cmd.getPositionalArgument(result) = this }
6179

6280
string getName() { cmd.getNamedArgument(result) = this }
6381
}
82+
83+
/** A positional argument to a command. */
84+
class PositionalArgument extends Argument {
85+
PositionalArgument() { not this instanceof NamedArgument }
86+
}
87+
88+
/** A named argument to a command. */
89+
class NamedArgument extends Argument {
90+
NamedArgument() { this = cmd.getNamedArgument(_) }
91+
}

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ private predicate hasParameterBlockImpl(Internal::Parameter p, ParamBlock block,
1414

1515
/**
1616
* Gets the enclosing scope of `p`.
17-
*
17+
*
1818
* For a function parameter, this is the function body. For a parameter from a
1919
* parameter block, this is the enclosing scope of the parameter block.
20-
*
20+
*
2121
* In both of the above cases, the enclosing scope is the function body.
2222
*/
2323
private Scope getEnclosingScopeImpl(Internal::Parameter p) {
@@ -176,6 +176,8 @@ class Parameter extends AbstractLocalScopeVariable, TParameter {
176176

177177
override string getName() { result = p.getName() }
178178

179+
final predicate hasName(string name) { name = p.getName() }
180+
179181
final override Scope getDeclaringScope() { result = p.getEnclosingScope() }
180182

181183
predicate hasParameterBlock(ParamBlock block, int i) { p.hasParameterBlock(block, i) }
@@ -186,7 +188,18 @@ class Parameter extends AbstractLocalScopeVariable, TParameter {
186188

187189
predicate hasDefaultValue() { exists(this.getDefaultValue()) }
188190

189-
int getIndex() { this.isFunctionParameter(_, result) }
191+
/**
192+
* Gets the index of this parameter.
193+
*
194+
* The parameter may be in a parameter block or a function parameter.
195+
*/
196+
int getIndex() { result = this.getFunctionIndex() or result = this.getBlockIndex() }
197+
198+
/** Gets the index of this parameter in the parameter block, if any. */
199+
int getBlockIndex() { this.hasParameterBlock(_, result) }
200+
201+
/** Gets the index of this parameter in the function, if any. */
202+
int getFunctionIndex() { this.isFunctionParameter(_, result) }
190203

191204
Function getFunction() { result.getBody() = this.getDeclaringScope() }
192205
}

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ module ExprNodes {
174174
override Argument e;
175175

176176
final override Argument getExpr() { result = super.getExpr() }
177+
178+
/** Gets the position of this argument, if any. */
179+
int getPosition() { result = e.getPosition() }
180+
181+
/** Gets the name of this argument, if any. */
182+
string getName() { result = e.getName() }
183+
184+
StmtNodes::CmdCfgNode getCmd() { result.getAnArgument() = this }
177185
}
178186

179187
private class InvokeMemberChildMapping extends ExprChildMapping, InvokeMemberExpr {
@@ -253,7 +261,7 @@ module ExprNodes {
253261

254262
module StmtNodes {
255263
private class CmdChildMapping extends NonExprChildMapping, Cmd {
256-
override predicate relevantChild(Ast n) { n = this.getElement(_) }
264+
override predicate relevantChild(Ast n) { n = this.getAnArgument() or n = this.getCommand() }
257265
}
258266

259267
/** A control-flow node that wraps a `Cmd` AST expression. */
@@ -263,6 +271,20 @@ module StmtNodes {
263271
override CmdChildMapping s;
264272

265273
override Cmd getStmt() { result = super.getStmt() }
274+
275+
ExprCfgNode getArgument(int i) { s.hasCfgChild(s.getArgument(i), this, result) }
276+
277+
ExprCfgNode getPositionalArgument(int i) {
278+
s.hasCfgChild(s.getPositionalArgument(i), this, result)
279+
}
280+
281+
ExprCfgNode getNamedArgument(string name) {
282+
s.hasCfgChild(s.getNamedArgument(name), this, result)
283+
}
284+
285+
ExprCfgNode getAnArgument() { s.hasCfgChild(s.getAnArgument(), this, result) }
286+
287+
ExprCfgNode getCommand() { s.hasCfgChild(s.getCommand(), this, result) }
266288
}
267289

268290
private class AssignStmtChildMapping extends NonExprChildMapping, AssignStmt {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ module Trees {
176176
exists(Parameter p |
177177
p =
178178
rank[i + 1](Parameter cand, int j |
179-
cand.hasDefaultValue() and j = cand.getIndex()
179+
cand.hasDefaultValue() and j = cand.getFunctionIndex()
180180
|
181181
cand order by j
182182
) and

0 commit comments

Comments
 (0)