Skip to content

Commit 455e56d

Browse files
committed
PS: Support 'this' as a parameter in SSA and dataflow.
1 parent 61d5f44 commit 455e56d

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ abstract class LibraryCallable extends string {
3737
LibraryCallable() { any() }
3838

3939
/** Gets a call to this library callable. */
40-
Cmd getACall() { none() }
40+
Call getACall() { none() }
4141
}
4242

4343
/**
@@ -222,7 +222,8 @@ private module Cached {
222222

223223
cached
224224
newtype TArgumentPosition =
225-
TKeywordArgumentPosition(string name) { name = any(CmdParameter p).getName() } or
225+
TThisArgumentPosition() or
226+
TKeywordArgumentPosition(string name) { name = any(Argument p).getName() } or
226227
TPositionalArgumentPosition(int pos, NamedSet ns) {
227228
exists(CfgNodes::CallCfgNode call |
228229
call = ns.getABindingCall() and
@@ -232,7 +233,8 @@ private module Cached {
232233

233234
cached
234235
newtype TParameterPosition =
235-
TKeywordParameter(string name) { name = any(CmdParameter p).getName() } or
236+
TThisParameterPosition() or
237+
TKeywordParameter(string name) { name = any(Argument p).getName() } or
236238
TPositionalParameter(int pos, NamedSet ns) {
237239
exists(CfgNodes::CallCfgNode call |
238240
call = ns.getABindingCall() and
@@ -245,6 +247,9 @@ import Cached
245247

246248
/** A parameter position. */
247249
class ParameterPosition extends TParameterPosition {
250+
/** Holds if this position represents a `this` parameter. */
251+
predicate isThis() { this = TThisParameterPosition() }
252+
248253
/**
249254
* Holds if this position represents a positional parameter at position `pos`
250255
* with function is called with exactly the named parameters from the set `ns`
@@ -256,6 +261,8 @@ class ParameterPosition extends TParameterPosition {
256261

257262
/** Gets a textual representation of this position. */
258263
string toString() {
264+
this.isThis() and result = "this"
265+
or
259266
exists(int pos, NamedSet ns |
260267
this.isPositional(pos, ns) and result = "pos(" + pos + ", " + ns.toString() + ")"
261268
)
@@ -266,13 +273,18 @@ class ParameterPosition extends TParameterPosition {
266273

267274
/** An argument position. */
268275
class ArgumentPosition extends TArgumentPosition {
276+
/** Holds if this position represents a `this` argument. */
277+
predicate isThis() { this = TThisArgumentPosition() }
278+
269279
/** Holds if this position represents a positional argument at position `pos`. */
270280
predicate isPositional(int pos, NamedSet ns) { this = TPositionalArgumentPosition(pos, ns) }
271281

272282
predicate isKeyword(string name) { this = TKeywordArgumentPosition(name) }
273283

274284
/** Gets a textual representation of this position. */
275285
string toString() {
286+
this.isThis() and result = "this"
287+
or
276288
exists(int pos, NamedSet ns |
277289
this.isPositional(pos, ns) and result = "pos(" + pos + ", " + ns.toString() + ")"
278290
)
@@ -284,6 +296,8 @@ class ArgumentPosition extends TArgumentPosition {
284296
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
285297
pragma[nomagic]
286298
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
299+
ppos.isThis() and apos.isThis()
300+
or
287301
exists(string name |
288302
ppos.isKeyword(name) and
289303
apos.isKeyword(name)

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@ private module ParameterNodes {
407407
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
408408
parameter.getDeclaringScope() = c.asCfgScope() and
409409
(
410+
pos.isThis() and
411+
parameter.isThis()
412+
or
410413
pos.isKeyword(parameter.getName())
411414
or
412415
// Given a function f with parameters x, y we map
@@ -432,7 +435,9 @@ private module ParameterNodes {
432435
)
433436
}
434437

435-
override CfgScope getCfgScope() { result.getAParameter() = parameter }
438+
override CfgScope getCfgScope() {
439+
result.getAParameter() = parameter or result.getThisParameter() = parameter
440+
}
436441

437442
override Location getLocationImpl() { result = parameter.getLocation() }
438443

@@ -458,7 +463,7 @@ module ArgumentNodes {
458463
ExplicitArgumentNode() { this.asExpr() = arg }
459464

460465
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
461-
arg.getCmd() = call.asCall() and
466+
arg.getCall() = call.asCall() and
462467
(
463468
pos.isKeyword(arg.getName())
464469
or
@@ -467,6 +472,9 @@ module ArgumentNodes {
467472
ns.getAnExactBindingCall() = call.asCall() and
468473
pos.isPositional(i, ns)
469474
)
475+
or
476+
arg.isQualifier() and
477+
pos.isThis()
470478
)
471479
}
472480
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,14 @@ predicate uninitializedWrite(Cfg::EntryBasicBlock bb, int i, LocalVariable v) {
6969
* function f($a, $b) { ... }
7070
* ```
7171
* the inverted index of `$a` is 1, and the inverted index of `$b` is 0.
72+
*
73+
* The inverted index of `$this` is always always the number of
74+
* parameters (excluding `this`).
7275
*/
7376
private int getInvertedIndex(Parameter p) {
77+
p.isThis() and
78+
result = p.getFunction().getNumberOfParameters()
79+
or
7480
exists(int i |
7581
p.getIndex() = i or
7682
p.hasParameterBlock(_, i)

0 commit comments

Comments
 (0)