Skip to content

Commit e4c702e

Browse files
committed
PS: Represent sets of parameter names.
1 parent 7f25caf commit e4c702e

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

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

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,66 @@ class SsaInputNode extends SsaNode {
229229
override CfgScope getCfgScope() { result = node.getDefinitionExt().getBasicBlock().getScope() }
230230
}
231231

232+
private string getANamedArgument(Cmd c) { exists(c.getNamedArgument(result)) }
233+
234+
private module NamedSetModule = QlBuiltins::InternSets<Cmd, string, getANamedArgument/1>;
235+
236+
private newtype NamedSet0 =
237+
TEmptyNamedSet() or
238+
TNonEmptyNamedSet(NamedSetModule::Set ns)
239+
240+
/** A (possiby empty) set of argument names. */
241+
class NamedSet extends NamedSet0 {
242+
/** Gets the non-empty set of names, if any. */
243+
NamedSetModule::Set asNonEmpty() { this = TNonEmptyNamedSet(result) }
244+
245+
/** Holds if this is the empty set. */
246+
predicate isEmpty() { this = TEmptyNamedSet() }
247+
248+
/** Gets a name in this set. */
249+
string getAName() { this.asNonEmpty().contains(result) }
250+
251+
/** Gets the textual representation of this set. */
252+
string toString() {
253+
result = "{" + strictconcat(this.getAName(), ", ") + "}"
254+
or
255+
this.isEmpty() and
256+
result = "{}"
257+
}
258+
259+
/**
260+
* Gets a `Cmd` that provides a named parameter for every name in `this`.
261+
*
262+
* NOTE: The `Cmd` may also provide more names.
263+
*/
264+
Cmd getABindingCall() {
265+
forex(string name | name = this.getAName() | exists(result.getNamedArgument(name)))
266+
or
267+
this.isEmpty() and
268+
exists(result)
269+
}
270+
271+
/**
272+
* Gets a `Cmd` that provides exactly the named parameters represented by
273+
* this set.
274+
*/
275+
Cmd getAnExactBindingCall() {
276+
forex(string name | name = this.getAName() | exists(result.getNamedArgument(name))) and
277+
forex(string name | exists(result.getNamedArgument(name)) | name = this.getAName())
278+
or
279+
this.isEmpty() and
280+
not exists(result.getNamedArgument(_))
281+
}
282+
283+
/** Gets a function that has a parameter for each name in this set. */
284+
Function getAFunction() {
285+
forex(string name | name = this.getAName() | result.getAParameter().hasName(name))
286+
or
287+
this.isEmpty() and
288+
exists(result)
289+
}
290+
}
291+
232292
private module ParameterNodes {
233293
abstract class ParameterNodeImpl extends NodeImpl {
234294
abstract Parameter getParameter();

0 commit comments

Comments
 (0)