diff --git a/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll b/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll index 81cfeec47dc..65a9b689028 100644 --- a/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll +++ b/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll @@ -213,6 +213,8 @@ module ExprNodes { override VarAccessChildMapping e; override VarAccess getExpr() { result = super.getExpr() } + + Variable getVariable() { result = e.getVariable() } } private class VarReadAccessChildMapping extends VarAccessChildMapping, VarReadAccess { } @@ -234,8 +236,6 @@ module ExprNodes { override VarWriteAccess getExpr() { result = super.getExpr() } - Variable getVariable() { result = e.getVariable() } - predicate isExplicitWrite(StmtNodes::AssignStmtCfgNode assignment) { this = assignment.getLeftHandSide() } diff --git a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll index 8a48e03dca8..befbe9fc7fe 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll @@ -229,7 +229,8 @@ private module Cached { call = ns.getABindingCall() and exists(call.getArgument(pos)) ) - } + } or + TPipelineArgumentPosition() cached newtype TParameterPosition = @@ -240,7 +241,8 @@ private module Cached { call = ns.getABindingCall() and exists(call.getArgument(pos)) ) - } + } or + TPipelineParameter() } import Cached @@ -259,6 +261,8 @@ class ParameterPosition extends TParameterPosition { /** Holds if this parameter is a keyword parameter with `name`. */ predicate isKeyword(string name) { this = TKeywordParameter(name) } + predicate isPipeline() { this = TPipelineParameter() } + /** Gets a textual representation of this position. */ string toString() { this.isThis() and result = "this" @@ -268,6 +272,8 @@ class ParameterPosition extends TParameterPosition { ) or exists(string name | this.isKeyword(name) and result = "kw(" + name + ")") + or + this.isPipeline() and result = "pipeline" } } @@ -281,6 +287,8 @@ class ArgumentPosition extends TArgumentPosition { predicate isKeyword(string name) { this = TKeywordArgumentPosition(name) } + predicate isPipeline() { this = TPipelineArgumentPosition() } + /** Gets a textual representation of this position. */ string toString() { this.isThis() and result = "this" @@ -290,6 +298,8 @@ class ArgumentPosition extends TArgumentPosition { ) or exists(string name | this.isKeyword(name) and result = "kw(" + name + ")") + or + this.isPipeline() and result = "pipeline" } } @@ -307,4 +317,6 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos.isPositional(pos, ns) and apos.isPositional(pos, ns) ) + or + ppos.isPipeline() and apos.isPipeline() } diff --git a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll index e7764e6b607..5da938a973f 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll @@ -449,12 +449,18 @@ private module ParameterNodes { // keywords in S are specified. exists(int i, int j, string name, NamedSet ns, Function f | pos.isPositional(j, ns) and - parameter.getIndex() = i and + parameter.getIndexExcludingPipeline() = i and f = parameter.getFunction() and f = ns.getAFunction() and name = parameter.getName() and not name = ns.getAName() and - j = i - count(int k | k < i and f.getParameter(k).getName() = ns.getAName()) + j = + i - + count(int k, Parameter p | + k < i and + p = f.getParameterExcludingPipline(k) and + p.getName() = ns.getAName() + ) ) ) }