Skip to content

Commit b79f366

Browse files
committed
PS: Replace a 'forex' with explicit recursion.
1 parent ebc167c commit b79f366

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,21 @@ class NamedSet extends NamedSet0 {
465465
/** Gets the non-empty set of names, if any. */
466466
NamedSetModule::Set asNonEmpty() { this = TNonEmptyNamedSet(result) }
467467

468+
/** Gets the `i`'th name in this set according to some ordering. */
469+
private string getRankedName(int i) {
470+
result = rank[i + 1](string s | s = this.getALowerCaseName() | s)
471+
}
472+
468473
/** Holds if this is the empty set. */
469474
predicate isEmpty() { this = TEmptyNamedSet() }
470475

476+
int getSize() {
477+
result = strictcount(this.getALowerCaseName())
478+
or
479+
this.isEmpty() and
480+
result = 0
481+
}
482+
471483
/** Gets a lower-case name in this set. */
472484
string getALowerCaseName() { this.asNonEmpty().contains(result) }
473485

@@ -479,13 +491,21 @@ class NamedSet extends NamedSet0 {
479491
result = "{}"
480492
}
481493

494+
private CfgNodes::ExprNodes::CallExprCfgNode getABindingCallRec(int i) {
495+
exists(string name | name = this.getRankedName(i) and exists(result.getNamedArgument(name)) |
496+
i = 0
497+
or
498+
result = this.getABindingCallRec(i - 1)
499+
)
500+
}
501+
482502
/**
483503
* Gets a `CfgNodes::CallCfgNode` that provides a named parameter for every name in `this`.
484504
*
485505
* NOTE: The `CfgNodes::CallCfgNode` may also provide more names.
486506
*/
487507
CfgNodes::ExprNodes::CallExprCfgNode getABindingCall() {
488-
forex(string name | name = this.getAName() | exists(result.getNamedArgument(name)))
508+
result = this.getABindingCallRec(this.getSize() - 1)
489509
or
490510
this.isEmpty() and
491511
exists(result)

0 commit comments

Comments
 (0)