diff --git a/powershell/ql/lib/semmle/code/powershell/ApiGraphs.qll b/powershell/ql/lib/semmle/code/powershell/ApiGraphs.qll index 8634161e5a01..78b84587908d 100644 --- a/powershell/ql/lib/semmle/code/powershell/ApiGraphs.qll +++ b/powershell/ql/lib/semmle/code/powershell/ApiGraphs.qll @@ -527,13 +527,25 @@ module API { pred = MkNamespaceOfTypeNameNode(typeName) and succ = getForwardStartNode(typeName) ) - // or - // TODO: Handle getAMember when the predecessor is a MkUsingNode? + or + pred = MkRoot() and + exists(DataFlow::AutomaticVariableNode automatic | + automatic.getName() = name and + succ = getForwardStartNode(automatic) + ) + or + exists(MemberExprReadAccess read | + read.getMemberName().toLowerCase() = name and + pred = getForwardEndNode(getALocalSourceStrict(getNodeFromExpr(read.getQualifier()))) and + succ = getForwardStartNode(getNodeFromExpr(read)) + ) } cached predicate methodEdge(Node pred, string name, Node succ) { - exists(DataFlow::CallNode call | succ = MkMethodAccessNode(call) and name = call.getName() | + exists(DataFlow::CallNode call | + succ = MkMethodAccessNode(call) and name = call.getName().toLowerCase() + | pred = getForwardEndNode(getALocalSourceStrict(call.getQualifier())) ) } diff --git a/powershell/ql/lib/semmle/code/powershell/ast/internal/ChildIndex.qll b/powershell/ql/lib/semmle/code/powershell/ast/internal/ChildIndex.qll index 4acc6683d767..772aab474ae3 100644 --- a/powershell/ql/lib/semmle/code/powershell/ast/internal/ChildIndex.qll +++ b/powershell/ql/lib/semmle/code/powershell/ast/internal/ChildIndex.qll @@ -32,8 +32,6 @@ newtype ChildIndex = // hasMemberInType(_, _, i, _) } or ThisVar() or - PipelineParamVar() or - PipelineByPropertyNameVar(Raw::PipelineByPropertyNameParameter p) or PipelineIteratorVar() or PipelineByPropertyNameIteratorVar(Raw::PipelineByPropertyNameParameter p) or RealVar(string name) { name = variableNameInScope(_, _) } or @@ -85,9 +83,6 @@ string stringOfChildIndex(ChildIndex i) { i = ThisVar() and result = "ThisVar" or - i = PipelineParamVar() and - result = "PipelineParamVar" - or i = PipelineIteratorVar() and result = "PipelineIteratorVar" or diff --git a/powershell/ql/lib/semmle/code/powershell/ast/internal/Parameter.qll b/powershell/ql/lib/semmle/code/powershell/ast/internal/Parameter.qll index 8a0a82f06ab2..6a3bc757ead7 100644 --- a/powershell/ql/lib/semmle/code/powershell/ast/internal/Parameter.qll +++ b/powershell/ql/lib/semmle/code/powershell/ast/internal/Parameter.qll @@ -34,23 +34,49 @@ class Parameter extends Variable instanceof ParameterImpl { class ThisParameter extends Parameter instanceof ThisParameterImpl { } -class PipelineParameter extends Parameter { - PipelineParameter() { any(Synthesis s).isPipelineParameter(this) } +/** The pipeline parameter of a function. */ +class PipelineParameter extends Parameter instanceof PipelineParameterImpl { + ScriptBlock getScriptBlock() { result = super.getScriptBlock() } } -class PipelineByPropertyNameParameter extends Parameter { - PipelineByPropertyNameParameter() { - exists(NamedAttributeArgument namedAttribute | - this.getAnAttribute().(Attribute).getANamedArgument() = namedAttribute and - namedAttribute.getName().toLowerCase() = "valuefrompipelinebypropertyname" - | - namedAttribute.getValue().getValue().asBoolean() = true - or - not exists(namedAttribute.getValue().getValue().asBoolean()) - ) - } +/** + * The iterator variable associated with a pipeline parameter. + * + * This is the variable that is bound to the current element in the pipeline. + */ +class PipelineIteratorVariable extends Variable instanceof PipelineIteratorVariableImpl { + ProcessBlock getProcessBlock() { result = super.getProcessBlock() } +} + +/** + * A pipeline-by-property-name parameter of a function. + */ +class PipelineByPropertyNameParameter extends Parameter instanceof PipelineByPropertyNameParameterImpl +{ + ScriptBlock getScriptBlock() { result = super.getScriptBlock() } - string getPropertyName() { result = this.getName() } + string getPropertyName() { result = super.getName() } + /** + * Gets the iterator variable that is used to iterate over the elements in the pipeline. + */ PipelineByPropertyNameIteratorVariable getIteratorVariable() { result.getParameter() = this } } + +/** + * The iterator variable associated with a pipeline-by-property-name parameter. + * + * This is the variable that is bound to the current element in the pipeline. + */ +class PipelineByPropertyNameIteratorVariable extends Variable instanceof PipelineByPropertyNameIteratorVariableImpl +{ + ProcessBlock getProcessBlock() { result = super.getProcessBlock() } + + string getPropertyName() { result = super.getPropertyName() } + + /** + * Gets the pipeline-by-property-name parameter that this variable + * iterates over. + */ + PipelineByPropertyNameParameter getParameter() { result = super.getParameter() } +} \ No newline at end of file diff --git a/powershell/ql/lib/semmle/code/powershell/ast/internal/ScriptBlock.qll b/powershell/ql/lib/semmle/code/powershell/ast/internal/ScriptBlock.qll index 343cd8927f1d..899bb8d805a8 100644 --- a/powershell/ql/lib/semmle/code/powershell/ast/internal/ScriptBlock.qll +++ b/powershell/ql/lib/semmle/code/powershell/ast/internal/ScriptBlock.qll @@ -88,12 +88,7 @@ class ScriptBlock extends Ast, TScriptBlock { ) } - Parameter getParameter(int i) { - synthChild(getRawAst(this), funParam(i), result) - or - any(Synthesis s).pipelineParameterHasIndex(this, i) and - synthChild(getRawAst(this), PipelineParamVar(), result) - } + Parameter getParameter(int i) { synthChild(getRawAst(this), funParam(i), result) } Parameter getThisParameter() { synthChild(getRawAst(this), ThisVar(), result) } diff --git a/powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll b/powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll index 2fee3dd99d6a..f504942e05ad 100644 --- a/powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll +++ b/powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll @@ -23,7 +23,6 @@ private import AutomaticVariable newtype VarKind = ThisVarKind() or ParamVarRealKind() or - ParamVarPipelineKind() or PipelineIteratorKind() or PipelineByPropertyNameIteratorKind(string name) { exists(Raw::ProcessBlock pb | @@ -78,9 +77,7 @@ class Synthesis extends TSynthesis { predicate parameterStaticType(Parameter p, string type) { none() } - predicate isPipelineParameter(Parameter p) { none() } - - predicate pipelineParameterHasIndex(ScriptBlock s, int i) { none() } + predicate pipelineParameterHasIndex(Raw::ScriptBlock s, int i) { none() } predicate functionName(FunctionBase f, string name) { none() } @@ -167,33 +164,28 @@ private module SetVariableAssignment { } } +/** Gets the pipeline parameter associated with `s`. */ +TVariable getPipelineParameter(Raw::ScriptBlock s) { + exists(ChildIndex i | + any(ParameterSynth::ParameterSynth ps).isPipelineParameterChild(s, _, i, _, _) and + result = TVariableSynth(s, i) + ) +} + /** * Syntesize parameters from parameter blocks and function definitions * so that they have a uniform API. */ private module ParameterSynth { - private class ParameterSynth extends Synthesis { + class ParameterSynth extends Synthesis { final override predicate isRelevant(Raw::Ast a) { a = any(Scope::Range r).getAParameter() } - private predicate parameter( - Raw::Ast parent, ChildIndex i, Raw::Parameter p, Child child, boolean isPipelineParameter - ) { + private predicate parameter(Raw::Ast parent, ChildIndex i, Raw::Parameter p, Child child) { exists(Scope::Range r, int index | p = r.getParameter(index) and parent = r and i = funParam(index) and - child = SynthChild(VarSynthKind(ParamVarRealKind())) and - if p instanceof Raw::PipelineParameter - then isPipelineParameter = true - else isPipelineParameter = false - ) - } - - final override predicate isPipelineParameter(Parameter p) { - exists(Raw::Ast parent, ChildIndex i | - parent = getRawAst(p.getFunction().getBody()) and - this.isPipelineParameterChild(parent, _, i) and - p = TVariableSynth(parent, i) + child = SynthChild(VarSynthKind(ParamVarRealKind())) ) } @@ -205,47 +197,49 @@ private module ParameterSynth { } final override predicate variableSynthName(VariableSynth v, string name) { - exists(Raw::Ast parent, int i, Raw::Parameter p | - this.parameter(parent, FunParam(i), p, _, false) and - v = TVariableSynth(parent, FunParam(i)) and - name = p.getName() - ) - or - exists(Raw::Ast parent | - this.child(parent, PipelineParamVar(), _) and - v = TVariableSynth(parent, PipelineParamVar()) and + exists(Raw::Ast parent, ChildIndex i | v = TVariableSynth(parent, i) | + exists(Raw::Parameter p | + this.parameter(parent, i, p, _) and + name = p.getName() + ) + or + this.isPipelineParameterChild(parent, _, i, _, true) and name = "[synth] pipeline" ) } - private predicate isPipelineParameterChild(Raw::Ast parent, int index, ChildIndex i) { - exists(Scope::Range r | parent = r and i = PipelineParamVar() | - r.getParameter(index) instanceof Raw::PipelineParameter + predicate isPipelineParameterChild( + Raw::Ast parent, int index, ChildIndex i, Child child, boolean synthesized + ) { + exists(Scope::Range r | + parent = r and + i = funParam(index) and + child = SynthChild(VarSynthKind(ParamVarRealKind())) + | + r.getParameter(index) instanceof Raw::PipelineParameter and + synthesized = false or not r.getAParameter() instanceof Raw::PipelineParameter and - index = synthPipelineParameterChildIndex(r) + index = synthPipelineParameterChildIndex(r) and + synthesized = true ) } - final override predicate pipelineParameterHasIndex(ScriptBlock s, int i) { - exists(Raw::ScriptBlock scriptBlock | - s = TScriptBlock(scriptBlock) and - this.isPipelineParameterChild(scriptBlock, i, _) - ) + final override predicate pipelineParameterHasIndex(Raw::ScriptBlock s, int i) { + this.isPipelineParameterChild(s, i, _, _, _) } final override predicate child(Raw::Ast parent, ChildIndex i, Child child) { // Synthesize parameters - this.parameter(parent, i, _, child, false) + this.parameter(parent, i, _, child) or - // Synthesize pipeline parameter - child = SynthChild(VarSynthKind(ParamVarPipelineKind())) and - this.isPipelineParameterChild(parent, _, i) + // Synthesize implicit pipeline parameter, if necessary + this.isPipelineParameterChild(parent, _, i, child, true) or // Synthesize default values exists(Raw::Parameter q | parent = q and - this.parameter(_, _, q, _, _) + this.parameter(_, _, q, _) | i = paramDefaultVal() and child = childRef(getResultAst(q.getDefaultValue())) @@ -258,30 +252,30 @@ private module ParameterSynth { } final override Parameter getResultAstImpl(Raw::Ast r) { - exists(Raw::Ast parent, int i | - this.parameter(parent, FunParam(i), r, _, false) and - result = TVariableSynth(parent, FunParam(i)) - ) - or - exists(Scope::Range scope, int i, ChildIndex index | - scope.getParameter(i) = r and - this.isPipelineParameterChild(scope, i, index) and - result = TVariableSynth(scope, index) + exists(Raw::Ast parent, ChildIndex i | + this.parameter(parent, i, r, _) and + result = TVariableSynth(parent, i) ) } final override Location getLocation(Ast n) { - exists(Raw::Ast parent, Raw::Parameter p, int i | - this.parameter(parent, _, p, _, _) and - n = TVariableSynth(parent, FunParam(i)) and - result = p.getLocation() + exists(Raw::Ast parent, ChildIndex i | n = TVariableSynth(parent, i) | + exists(Raw::Parameter p | + this.parameter(parent, i, p, _) and + result = p.getLocation() + ) + or + this.isPipelineParameterChild(parent, _, i, _, true) and + result = parent.getLocation() ) } final override predicate parameterStaticType(Parameter n, string type) { - exists(Raw::Ast parent, int i, Raw::Parameter p | - this.parameter(parent, FunParam(i), p, _, false) and - n = TVariableSynth(parent, FunParam(i)) and + exists(Raw::Ast parent, Raw::Parameter p, ChildIndex i | + // No need to consider the synthesized pipeline parameter as it never + // has a static type. + this.parameter(parent, i, p, _) and + n = TVariableSynth(parent, i) and type = p.getStaticType() ) } @@ -440,6 +434,11 @@ private module FunctionSynth { n = TFunctionSynth(fundefStmt, _) and result = fundefStmt.getLocation() ) + or + exists(Raw::TopLevelScriptBlock topLevelScriptBlock | + n = TTopLevelFunction(topLevelScriptBlock) and + result = topLevelScriptBlock.getLocation() + ) } } } @@ -857,8 +856,10 @@ private module IteratorAccessSynth { result = cmdExpr.getLocation() ) or - exists(Raw::Ast parent | - n = TVariableSynth(parent, _) and + exists(Raw::Ast parent, ChildIndex i | + i instanceof PipelineIteratorVar or i instanceof PipelineByPropertyNameIteratorVar + | + n = TVariableSynth(parent, i) and result = parent.getLocation() ) } @@ -870,12 +871,12 @@ private module PipelineAccess { final override predicate child(Raw::Ast parent, ChildIndex i, Child child) { exists(Raw::ProcessBlock pb | parent = pb | i = processBlockPipelineVarReadAccess() and - exists(PipelineVariable pipelineVar | - pipelineVar = TVariableSynth(pb.getScriptBlock(), PipelineParamVar()) and + exists(PipelineParameter pipelineVar | + pipelineVar = getPipelineParameter(pb.getScriptBlock()) and child = SynthChild(VarAccessSynthKind(pipelineVar)) ) or - exists(PipelineByPropertyNameVariable pipelineVar, Raw::PipelineByPropertyNameParameter p | + exists(PipelineByPropertyNameParameter pipelineVar, Raw::PipelineByPropertyNameParameter p | i = processBlockPipelineByPropertyNameVarReadAccess(p.getName()) and getResultAst(p) = pipelineVar and child = SynthChild(VarAccessSynthKind(pipelineVar)) diff --git a/powershell/ql/lib/semmle/code/powershell/ast/internal/TypeExpression.qll b/powershell/ql/lib/semmle/code/powershell/ast/internal/TypeExpression.qll index 73f1d1fe3714..92c015e9e13b 100644 --- a/powershell/ql/lib/semmle/code/powershell/ast/internal/TypeExpression.qll +++ b/powershell/ql/lib/semmle/code/powershell/ast/internal/TypeExpression.qll @@ -25,6 +25,11 @@ class TypeNameExpr extends Expr, TTypeNameExpr { override string toString() { result = this.getName() } predicate isQualified() { this.getNamespace() != "" } + + predicate hasQualifiedName(string namespace, string typename) { + this.isQualified() and + this.parseName(namespace, typename) + } } class QualifiedTypeNameExpr extends TypeNameExpr { diff --git a/powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll b/powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll index c1d0a53edfbb..bfff89bdd209 100644 --- a/powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll +++ b/powershell/ql/lib/semmle/code/powershell/ast/internal/Variable.qll @@ -38,7 +38,7 @@ module Private { override string getNameImpl() { any(Synthesis s).variableSynthName(this, result) } - override Location getLocationImpl() { result = scope.getLocation() } + override Location getLocationImpl() { result = any(Synthesis s).getLocation(this) } override Scope::Range getDeclaringScopeImpl() { result = scope } } @@ -46,7 +46,6 @@ module Private { class ParameterImpl extends VariableSynth { ParameterImpl() { i instanceof FunParam or - i instanceof PipelineParamVar or i instanceof ThisVar } } @@ -55,14 +54,21 @@ module Private { override ThisVar i; } - class PipelineVariableImpl extends ParameterImpl { - override PipelineParamVar i; + class PipelineParameterImpl extends ParameterImpl { + override FunParam i; + + PipelineParameterImpl() { + exists(int index | + i = FunParam(index) and + any(Synthesis s).pipelineParameterHasIndex(super.getDeclaringScopeImpl(), index) + ) + } ScriptBlock getScriptBlock() { this = TVariableSynth(getRawAst(result), _) } } - class PipelineByPropertyNameVariableImpl extends ParameterImpl { - PipelineByPropertyNameVariableImpl() { + class PipelineByPropertyNameParameterImpl extends ParameterImpl { + PipelineByPropertyNameParameterImpl() { getRawAst(this) instanceof Raw::PipelineByPropertyNameParameter } @@ -167,28 +173,6 @@ module Public { class VarReadAccess extends VarAccess { VarReadAccess() { not this instanceof VarWriteAccess } } - - class PipelineByPropertyNameIteratorVariable extends Variable instanceof PipelineByPropertyNameIteratorVariableImpl - { - ProcessBlock getProcessBlock() { result = super.getProcessBlock() } - - string getPropertyName() { result = super.getPropertyName() } - - PipelineByPropertyNameParameter getParameter() { result = super.getParameter() } - } - - class PipelineVariable extends Variable instanceof PipelineVariableImpl { - ScriptBlock getScriptBlock() { result = super.getScriptBlock() } - } - - class PipelineByPropertyNameVariable extends Variable instanceof PipelineByPropertyNameVariableImpl - { - ScriptBlock getScriptBlock() { result = super.getScriptBlock() } - } - - class PipelineIteratorVariable extends Variable instanceof PipelineIteratorVariableImpl { - ProcessBlock getProcessBlock() { result = super.getProcessBlock() } - } } import Public diff --git a/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll b/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll index 58ca40b5e714..ba6384044620 100644 --- a/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll +++ b/powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll @@ -291,11 +291,11 @@ class ProcessBlockCfgNode extends NamedBlockCfgNode { ScriptBlockCfgNode getScriptBlock() { result.getProcessBlock() = this } - PipelineVariable getPipelineVariable() { + PipelineParameter getPipelineParameter() { result.getScriptBlock() = this.getScriptBlock().getAstNode() } - ExprNodes::VarReadAccessCfgNode getPipelineVariableAccess() { + ExprNodes::VarReadAccessCfgNode getPipelineParameterAccess() { block.hasCfgChild(block.getPipelineParameterAccess(), this, result) } @@ -685,14 +685,24 @@ module ExprNodes { string getPossiblyQualifiedName() { result = e.getPossiblyQualifiedName() } predicate isQualified() { e.isQualified() } + + predicate hasQualifiedName(string namespace, string typename) { + e.hasQualifiedName(namespace, typename) + } + } + + private class QualifiedTypeNameExprChildMapping extends TypeNameExprChildMapping, + QualifiedTypeNameExpr + { + override predicate relevantChild(Ast child) { super.relevantChild(child) } } class QualifiedTypeNameExprCfgNode extends TypeNameExprCfgNode { - QualifiedTypeNameExprCfgNode() { e.isQualified() } + override QualifiedTypeNameExprChildMapping e; - override string getAPrimaryQlClass() { result = "QualifiedTypeNameExprCfgNode" } + override TypeNameExpr getExpr() { result = e } - override QualifiedTypeNameExpr getExpr() { result = e } + override string getAPrimaryQlClass() { result = "QualifiedTypeNameExprCfgNode" } } private class ErrorExprChildMapping extends ExprChildMapping, ErrorExpr { @@ -1061,6 +1071,20 @@ module ExprNodes { ExprCfgNode getAnOperand() { e.hasCfgChild(e.getAnOperand(), this, result) } } + + private class AutomaticVariableChildMapping extends ExprChildMapping, AutomaticVariable { + override predicate relevantChild(Ast child) { none() } + } + + class AutomaticVariableCfgNode extends ExprCfgNode { + override string getAPrimaryQlClass() { result = "AutomaticVariableCfgNode" } + + override AutomaticVariableChildMapping e; + + override AutomaticVariable getExpr() { result = e } + + string getName() { result = e.getName() } + } } module StmtNodes { 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 6619cb9887d7..3c3dba5cfd72 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowDispatch.qll @@ -242,6 +242,12 @@ class AdditionalCallTarget extends Unit { abstract DataFlowCallable viableTarget(CfgNodes::ExprNodes::CallExprCfgNode call); } +DataFlowCallable viableSourceCallable(DataFlowCall call) { + result.asCfgScope() = getTargetInstance(call.asCall()) + or + result = any(AdditionalCallTarget t).viableTarget(call.asCall()) +} + /** Holds if `call` may resolve to the returned summarized library method. */ DataFlowCallable viableLibraryCallable(DataFlowCall call) { exists(LibraryCallable callable | @@ -269,13 +275,13 @@ private module Cached { /** Gets a viable run-time target for the call `call`. */ cached DataFlowCallable viableCallable(DataFlowCall call) { - result.asCfgScope() = getTargetInstance(call.asCall()) + result = viableSourceCallable(call) or - result = any(AdditionalCallTarget t).viableTarget(call.asCall()) + result = viableLibraryCallable(call) } cached - CfgScope getTarget(DataFlowCall call) { result = viableCallable(call).asCfgScope() } + CfgScope getTarget(DataFlowCall call) { result = viableSourceCallable(call).asCfgScope() } cached newtype TArgumentPosition = 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 2197b71317c8..2c520b60a562 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll @@ -171,7 +171,7 @@ module LocalFlow { nodeTo = TProcessPropertyByNameNode(pbNode.getAccess().getVariable(), false) ) or - nodeTo.(PreProcessNode).getProcessBlock().getPipelineVariableAccess() = nodeFrom.asExpr() + nodeTo.(PreProcessNode).getProcessBlock().getPipelineParameterAccess() = nodeFrom.asExpr() or nodeTo.(ProcessNode).getProcessBlock() = nodeFrom.(PreProcessNode).getProcessBlock() } @@ -994,7 +994,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { or c.isAnyPositional() and exists(CfgNodes::ProcessBlockCfgNode processBlock | - processBlock.getPipelineVariableAccess() = node1.asExpr() and + processBlock.getPipelineParameterAccess() = node1.asExpr() and node2 = TProcessNode(processBlock) ) or diff --git a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPublic.qll b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPublic.qll index 28cfd4ed3040..9be635555c98 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPublic.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPublic.qll @@ -544,6 +544,10 @@ class TypeNameNode extends ExprNode { predicate isQualified() { n.isQualified() } + predicate hasQualifiedName(string namespace, string typename) { + n.hasQualifiedName(namespace, typename) + } + string getNamespace() { result = n.getNamespace() } string getPossiblyQualifiedName() { result = n.getPossiblyQualifiedName() } @@ -555,3 +559,12 @@ class QualifiedTypeNameNode extends TypeNameNode { final override CfgNodes::ExprNodes::QualifiedTypeNameExprCfgNode getExprNode() { result = n } } + +/** A use of an automatic variable, viewed as a node in a data flow graph. */ +class AutomaticVariableNode extends ExprNode { + override CfgNodes::ExprNodes::AutomaticVariableCfgNode n; + + final override CfgNodes::ExprNodes::AutomaticVariableCfgNode getExprNode() { result = n } + + string getName() { result = n.getName() } +} diff --git a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/TaintTrackingPrivate.qll b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/TaintTrackingPrivate.qll index 9c6132c7a291..d4fe6b6151bd 100644 --- a/powershell/ql/lib/semmle/code/powershell/dataflow/internal/TaintTrackingPrivate.qll +++ b/powershell/ql/lib/semmle/code/powershell/dataflow/internal/TaintTrackingPrivate.qll @@ -3,6 +3,7 @@ private import DataFlowPrivate private import TaintTrackingPublic private import semmle.code.powershell.Cfg private import semmle.code.powershell.dataflow.DataFlow +private import FlowSummaryImpl as FlowSummaryImpl /** * Holds if `node` should be a sanitizer in all global taint flow configurations @@ -58,6 +59,16 @@ private module Cached { ) ) and model = "" + or + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), false, model) + } + + cached + predicate summaryThroughStepTaint( + DataFlow::Node arg, DataFlow::Node out, FlowSummaryImpl::Public::SummarizedCallable sc + ) { + FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(arg, out, sc) } /** @@ -67,7 +78,10 @@ private module Cached { cached predicate localTaintStepCached(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { DataFlow::localFlowStep(nodeFrom, nodeTo) or - defaultAdditionalTaintStep(nodeFrom, nodeTo, _) + defaultAdditionalTaintStep(nodeFrom, nodeTo, _) or + // Simple flow through library code is included in the exposed local + // step relation, even though flow is technically inter-procedural + summaryThroughStepTaint(nodeFrom, nodeTo, _) } } diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomation/model.yml b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomation/model.yml index e6f507d6a296..856a958b8bcd 100644 --- a/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomation/model.yml +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/SystemManagementAutomation/model.yml @@ -1820,3 +1820,9 @@ extensions: - ["System.Collections.ObjectModel.ReadOnlyCollection", "System.Management.Automation.FunctionInfo", "Property[OutputType]"] - ["System.Management.Automation.Language.ParseError[]", "System.Management.Automation.ParseException", "Property[Errors]"] - ["System.Management.Automation.DSCResourceRunAsCredential", "System.Management.Automation.DscResourceAttribute", "Property[RunAsCredential]"] + + - addsTo: + pack: microsoft-sdl/powershell-all + extensible: summaryModel + data: + - ["System.Management.Automation.Language.CodeGeneration!", "Method[escapesinglequotedstringcontent]", "Argument[0]", "ReturnValue", "taint"] \ No newline at end of file diff --git a/powershell/ql/lib/semmle/code/powershell/frameworks/data/internal/ApiGraphModelsSpecific.qll b/powershell/ql/lib/semmle/code/powershell/frameworks/data/internal/ApiGraphModelsSpecific.qll index c2061c238b25..ef34f8c4f00a 100644 --- a/powershell/ql/lib/semmle/code/powershell/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/powershell/ql/lib/semmle/code/powershell/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -69,12 +69,23 @@ API::Node getExtraNodeFromPath(string type, AccessPath path, int n) { } /** Gets a Powershell-specific interpretation of the given `type`. */ -API::Node getExtraNodeFromType(string type) { - exists(string consts, string suffix | parseRelevantType(type, consts, suffix) | - none() // TODO +API::Node getExtraNodeFromType(string rawType) { + exists( + string type, string suffix, DataFlow::QualifiedTypeNameNode qualifiedTypeName, string namespace, + string typename + | + parseRelevantType(rawType, type, suffix) and + qualifiedTypeName.hasQualifiedName(namespace, typename) and + namespace + "." + typename = type + | + suffix = "!" and + result = qualifiedTypeName.(DataFlow::LocalSourceNode).track() + or + suffix = "" and + result = qualifiedTypeName.(DataFlow::LocalSourceNode).track().getInstance() ) or - type = "" and + rawType = "" and result = API::root() } diff --git a/powershell/ql/test/library-tests/ast/Blocks/blocks.expected b/powershell/ql/test/library-tests/ast/Blocks/blocks.expected index 0d4882c4c417..82ef295aa52d 100644 --- a/powershell/ql/test/library-tests/ast/Blocks/blocks.expected +++ b/powershell/ql/test/library-tests/ast/Blocks/blocks.expected @@ -1,2 +1,2 @@ -| ParamBlock.ps1:1:1:5:1 | {...} | 0 | ParamBlock.ps1:1:1:5:1 | Parameter | +| ParamBlock.ps1:1:1:5:1 | {...} | 0 | ParamBlock.ps1:3:5:4:22 | Parameter | | ParamBlock.ps1:1:1:5:1 | {...} | 1 | ParamBlock.ps1:1:1:5:1 | [synth] pipeline | diff --git a/powershell/ql/test/library-tests/ast/Statements/statements.expected b/powershell/ql/test/library-tests/ast/Statements/statements.expected index 6f85c09bdd1b..f8994f476941 100644 --- a/powershell/ql/test/library-tests/ast/Statements/statements.expected +++ b/powershell/ql/test/library-tests/ast/Statements/statements.expected @@ -22,4 +22,4 @@ | Try.ps1:11:9:13:1 | {...} | | Try.ps1:12:5:12:36 | [Stmt] The finally block is executed. | | UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | def of Get-Number | -| UseProcessBlockForPipelineCommand.ps1:10:5:10:11 | (no string representation) | +| UseProcessBlockForPipelineCommand.ps1:10:5:10:11 | [Stmt] Number | diff --git a/powershell/ql/test/library-tests/ast/parent.expected b/powershell/ql/test/library-tests/ast/parent.expected index 7fc8f9f9f727..7c27e9306670 100644 --- a/powershell/ql/test/library-tests/ast/parent.expected +++ b/powershell/ql/test/library-tests/ast/parent.expected @@ -2,8 +2,8 @@ | Arrays/Arrays.ps1:1:1:1:7 | array1 | Arrays/Arrays.ps1:1:1:1:36 | ...=... | | Arrays/Arrays.ps1:1:1:1:7 | array1 | Arrays/Arrays.ps1:1:1:15:14 | {...} | | Arrays/Arrays.ps1:1:1:1:36 | ...=... | Arrays/Arrays.ps1:1:1:15:14 | {...} | +| Arrays/Arrays.ps1:1:1:15:14 | {...} | Arrays/Arrays.ps1:1:1:15:14 | toplevel function for Arrays.ps1 | | Arrays/Arrays.ps1:1:1:15:14 | {...} | Arrays/Arrays.ps1:1:1:15:14 | {...} | -| Arrays/Arrays.ps1:1:1:15:14 | {...} | file://:0:0:0:0 | toplevel function for Arrays.ps1 | | Arrays/Arrays.ps1:1:11:1:11 | 1 | Arrays/Arrays.ps1:1:11:1:36 | ...,... | | Arrays/Arrays.ps1:1:11:1:36 | ...,... | Arrays/Arrays.ps1:1:1:1:36 | ...=... | | Arrays/Arrays.ps1:1:13:1:13 | 2 | Arrays/Arrays.ps1:1:11:1:36 | ...,... | @@ -84,17 +84,17 @@ | Arrays/Arrays.ps1:15:9:15:11 | Add | Arrays/Arrays.ps1:15:1:15:14 | Call to Add | | Arrays/Arrays.ps1:15:13:15:13 | 1 | Arrays/Arrays.ps1:15:1:15:14 | Call to Add | | Blocks/ParamBlock.ps1:1:1:1:17 | CmdletBinding | Blocks/ParamBlock.ps1:1:1:5:1 | {...} | -| Blocks/ParamBlock.ps1:1:1:5:1 | Parameter | Blocks/ParamBlock.ps1:1:1:5:1 | {...} | | Blocks/ParamBlock.ps1:1:1:5:1 | [synth] pipeline | Blocks/ParamBlock.ps1:1:1:5:1 | {...} | -| Blocks/ParamBlock.ps1:1:1:5:1 | {...} | file://:0:0:0:0 | toplevel function for ParamBlock.ps1 | +| Blocks/ParamBlock.ps1:1:1:5:1 | {...} | Blocks/ParamBlock.ps1:1:1:5:1 | toplevel function for ParamBlock.ps1 | | Blocks/ParamBlock.ps1:2:1:5:1 | {...} | Blocks/ParamBlock.ps1:1:1:5:1 | {...} | -| Blocks/ParamBlock.ps1:3:5:3:17 | Parameter | Blocks/ParamBlock.ps1:1:1:5:1 | Parameter | -| Blocks/ParamBlock.ps1:4:5:4:12 | string | Blocks/ParamBlock.ps1:1:1:5:1 | Parameter | +| Blocks/ParamBlock.ps1:3:5:3:17 | Parameter | Blocks/ParamBlock.ps1:3:5:4:22 | Parameter | +| Blocks/ParamBlock.ps1:3:5:4:22 | Parameter | Blocks/ParamBlock.ps1:1:1:5:1 | {...} | +| Blocks/ParamBlock.ps1:4:5:4:12 | string | Blocks/ParamBlock.ps1:3:5:4:22 | Parameter | | Dynamic/DynamicExecution.ps1:1:1:1:4 | foo | Dynamic/DynamicExecution.ps1:1:1:1:16 | ...=... | | Dynamic/DynamicExecution.ps1:1:1:1:4 | foo | Dynamic/DynamicExecution.ps1:1:1:5:7 | {...} | | Dynamic/DynamicExecution.ps1:1:1:1:16 | ...=... | Dynamic/DynamicExecution.ps1:1:1:5:7 | {...} | +| Dynamic/DynamicExecution.ps1:1:1:5:7 | {...} | Dynamic/DynamicExecution.ps1:1:1:5:7 | toplevel function for DynamicExecution.ps1 | | Dynamic/DynamicExecution.ps1:1:1:5:7 | {...} | Dynamic/DynamicExecution.ps1:1:1:5:7 | {...} | -| Dynamic/DynamicExecution.ps1:1:1:5:7 | {...} | file://:0:0:0:0 | toplevel function for DynamicExecution.ps1 | | Dynamic/DynamicExecution.ps1:1:8:1:16 | cmd.exe | Dynamic/DynamicExecution.ps1:1:1:1:16 | ...=... | | Dynamic/DynamicExecution.ps1:2:1:2:17 | Invoke-Expression | Dynamic/DynamicExecution.ps1:2:1:2:22 | Call to Invoke-Expression | | Dynamic/DynamicExecution.ps1:2:1:2:22 | Call to Invoke-Expression | Dynamic/DynamicExecution.ps1:2:1:2:22 | [Stmt] Call to Invoke-Expression | @@ -118,12 +118,12 @@ | Dynamic/DynamicExecution.ps1:5:3:5:6 | foo | Dynamic/DynamicExecution.ps1:5:2:5:7 | $foo | | Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | ExecuteAThing | Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | def of ExecuteAThing | | Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | def of ExecuteAThing | Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | {...} | +| Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | {...} | Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | toplevel function for DynamicExecutionWithFunc.ps1 | | Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | {...} | Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | {...} | -| Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | {...} | file://:0:0:0:0 | toplevel function for DynamicExecutionWithFunc.ps1 | | Dynamic/DynamicExecutionWithFunc.ps1:1:24:11:1 | [synth] pipeline | Dynamic/DynamicExecutionWithFunc.ps1:1:24:11:1 | {...} | -| Dynamic/DynamicExecutionWithFunc.ps1:1:24:11:1 | userInput | Dynamic/DynamicExecutionWithFunc.ps1:1:24:11:1 | {...} | | Dynamic/DynamicExecutionWithFunc.ps1:1:24:11:1 | {...} | Dynamic/DynamicExecutionWithFunc.ps1:1:1:11:1 | ExecuteAThing | | Dynamic/DynamicExecutionWithFunc.ps1:2:5:10:29 | {...} | Dynamic/DynamicExecutionWithFunc.ps1:1:24:11:1 | {...} | +| Dynamic/DynamicExecutionWithFunc.ps1:3:9:3:18 | userInput | Dynamic/DynamicExecutionWithFunc.ps1:1:24:11:1 | {...} | | Dynamic/DynamicExecutionWithFunc.ps1:5:5:5:8 | foo | Dynamic/DynamicExecutionWithFunc.ps1:1:24:11:1 | {...} | | Dynamic/DynamicExecutionWithFunc.ps1:5:5:5:8 | foo | Dynamic/DynamicExecutionWithFunc.ps1:5:5:5:33 | ...=... | | Dynamic/DynamicExecutionWithFunc.ps1:5:5:5:33 | ...=... | Dynamic/DynamicExecutionWithFunc.ps1:2:5:10:29 | {...} | @@ -160,8 +160,8 @@ | Expressions/BinaryExpression.ps1:1:1:1:5 | val1 | Expressions/BinaryExpression.ps1:1:1:1:9 | ...=... | | Expressions/BinaryExpression.ps1:1:1:1:5 | val1 | Expressions/BinaryExpression.ps1:1:1:4:7 | {...} | | Expressions/BinaryExpression.ps1:1:1:1:9 | ...=... | Expressions/BinaryExpression.ps1:1:1:4:7 | {...} | +| Expressions/BinaryExpression.ps1:1:1:4:7 | {...} | Expressions/BinaryExpression.ps1:1:1:4:7 | toplevel function for BinaryExpression.ps1 | | Expressions/BinaryExpression.ps1:1:1:4:7 | {...} | Expressions/BinaryExpression.ps1:1:1:4:7 | {...} | -| Expressions/BinaryExpression.ps1:1:1:4:7 | {...} | file://:0:0:0:0 | toplevel function for BinaryExpression.ps1 | | Expressions/BinaryExpression.ps1:1:9:1:9 | 1 | Expressions/BinaryExpression.ps1:1:1:1:9 | ...=... | | Expressions/BinaryExpression.ps1:2:1:2:5 | val2 | Expressions/BinaryExpression.ps1:1:1:4:7 | {...} | | Expressions/BinaryExpression.ps1:2:1:2:5 | val2 | Expressions/BinaryExpression.ps1:2:1:2:9 | ...=... | @@ -178,8 +178,8 @@ | Expressions/ConvertWithSecureString.ps1:1:1:1:10 | UserInput | Expressions/ConvertWithSecureString.ps1:1:1:1:54 | ...=... | | Expressions/ConvertWithSecureString.ps1:1:1:1:10 | UserInput | Expressions/ConvertWithSecureString.ps1:1:1:2:79 | {...} | | Expressions/ConvertWithSecureString.ps1:1:1:1:54 | ...=... | Expressions/ConvertWithSecureString.ps1:1:1:2:79 | {...} | +| Expressions/ConvertWithSecureString.ps1:1:1:2:79 | {...} | Expressions/ConvertWithSecureString.ps1:1:1:2:79 | toplevel function for ConvertWithSecureString.ps1 | | Expressions/ConvertWithSecureString.ps1:1:1:2:79 | {...} | Expressions/ConvertWithSecureString.ps1:1:1:2:79 | {...} | -| Expressions/ConvertWithSecureString.ps1:1:1:2:79 | {...} | file://:0:0:0:0 | toplevel function for ConvertWithSecureString.ps1 | | Expressions/ConvertWithSecureString.ps1:1:14:1:22 | Read-Host | Expressions/ConvertWithSecureString.ps1:1:14:1:54 | Call to Read-Host | | Expressions/ConvertWithSecureString.ps1:1:14:1:54 | Call to Read-Host | Expressions/ConvertWithSecureString.ps1:1:1:1:54 | ...=... | | Expressions/ConvertWithSecureString.ps1:1:24:1:54 | Please enter your secure code | Expressions/ConvertWithSecureString.ps1:1:14:1:54 | Call to Read-Host | @@ -191,8 +191,8 @@ | Expressions/ConvertWithSecureString.ps1:2:50:2:59 | UserInput | Expressions/ConvertWithSecureString.ps1:2:19:2:79 | Call to ConvertTo-SecureString | | Expressions/ExpandableString.ps1:1:1:1:39 | Date: $([DateTime]::Now)\nName: $name | Expressions/ExpandableString.ps1:1:1:1:39 | [Stmt] Date: $([DateTime]::Now)\nName: $name | | Expressions/ExpandableString.ps1:1:1:1:39 | [Stmt] Date: $([DateTime]::Now)\nName: $name | Expressions/ExpandableString.ps1:1:1:1:39 | {...} | +| Expressions/ExpandableString.ps1:1:1:1:39 | {...} | Expressions/ExpandableString.ps1:1:1:1:39 | toplevel function for ExpandableString.ps1 | | Expressions/ExpandableString.ps1:1:1:1:39 | {...} | Expressions/ExpandableString.ps1:1:1:1:39 | {...} | -| Expressions/ExpandableString.ps1:1:1:1:39 | {...} | file://:0:0:0:0 | toplevel function for ExpandableString.ps1 | | Expressions/ExpandableString.ps1:1:21:1:38 | $(...) | Expressions/ExpandableString.ps1:1:1:1:39 | Date: $([DateTime]::Now)\nName: $name | | Expressions/ExpandableString.ps1:1:23:1:32 | DateTime | Expressions/ExpandableString.ps1:1:23:1:37 | Now | | Expressions/ExpandableString.ps1:1:23:1:37 | Now | Expressions/ExpandableString.ps1:1:23:1:37 | [Stmt] Now | @@ -202,8 +202,8 @@ | Expressions/SubExpression.ps1:1:1:1:11 | $(...) | Expressions/SubExpression.ps1:1:1:1:23 | Call to AddDays | | Expressions/SubExpression.ps1:1:1:1:23 | Call to AddDays | Expressions/SubExpression.ps1:1:1:1:23 | [Stmt] Call to AddDays | | Expressions/SubExpression.ps1:1:1:1:23 | [Stmt] Call to AddDays | Expressions/SubExpression.ps1:1:1:2:21 | {...} | +| Expressions/SubExpression.ps1:1:1:2:21 | {...} | Expressions/SubExpression.ps1:1:1:2:21 | toplevel function for SubExpression.ps1 | | Expressions/SubExpression.ps1:1:1:2:21 | {...} | Expressions/SubExpression.ps1:1:1:2:21 | {...} | -| Expressions/SubExpression.ps1:1:1:2:21 | {...} | file://:0:0:0:0 | toplevel function for SubExpression.ps1 | | Expressions/SubExpression.ps1:1:3:1:10 | Call to Get-Date | Expressions/SubExpression.ps1:1:3:1:10 | [Stmt] Call to Get-Date | | Expressions/SubExpression.ps1:1:3:1:10 | Get-Date | Expressions/SubExpression.ps1:1:3:1:10 | Call to Get-Date | | Expressions/SubExpression.ps1:1:3:1:10 | [Stmt] Call to Get-Date | Expressions/SubExpression.ps1:1:3:1:10 | {...} | @@ -221,8 +221,8 @@ | Expressions/TernaryExpression.ps1:1:1:1:4 | var | Expressions/TernaryExpression.ps1:1:1:1:22 | ...=... | | Expressions/TernaryExpression.ps1:1:1:1:4 | var | Expressions/TernaryExpression.ps1:1:1:1:22 | {...} | | Expressions/TernaryExpression.ps1:1:1:1:22 | ...=... | Expressions/TernaryExpression.ps1:1:1:1:22 | {...} | +| Expressions/TernaryExpression.ps1:1:1:1:22 | {...} | Expressions/TernaryExpression.ps1:1:1:1:22 | toplevel function for TernaryExpression.ps1 | | Expressions/TernaryExpression.ps1:1:1:1:22 | {...} | Expressions/TernaryExpression.ps1:1:1:1:22 | {...} | -| Expressions/TernaryExpression.ps1:1:1:1:22 | {...} | file://:0:0:0:0 | toplevel function for TernaryExpression.ps1 | | Expressions/TernaryExpression.ps1:1:8:1:16 | (...) | Expressions/TernaryExpression.ps1:1:8:1:22 | ...?...:... | | Expressions/TernaryExpression.ps1:1:8:1:22 | ...?...:... | Expressions/TernaryExpression.ps1:1:1:1:22 | ...=... | | Expressions/TernaryExpression.ps1:1:9:1:9 | 6 | Expressions/TernaryExpression.ps1:1:9:1:15 | ... -gt ... | @@ -231,8 +231,8 @@ | Expressions/TernaryExpression.ps1:1:20:1:20 | 1 | Expressions/TernaryExpression.ps1:1:8:1:22 | ...?...:... | | Expressions/TernaryExpression.ps1:1:22:1:22 | 2 | Expressions/TernaryExpression.ps1:1:8:1:22 | ...?...:... | | Loops/DoUntil.ps1:1:1:7:18 | do...until... | Loops/DoUntil.ps1:1:1:7:18 | {...} | +| Loops/DoUntil.ps1:1:1:7:18 | {...} | Loops/DoUntil.ps1:1:1:7:18 | toplevel function for DoUntil.ps1 | | Loops/DoUntil.ps1:1:1:7:18 | {...} | Loops/DoUntil.ps1:1:1:7:18 | {...} | -| Loops/DoUntil.ps1:1:1:7:18 | {...} | file://:0:0:0:0 | toplevel function for DoUntil.ps1 | | Loops/DoUntil.ps1:2:1:7:1 | {...} | Loops/DoUntil.ps1:1:1:7:18 | do...until... | | Loops/DoUntil.ps1:3:2:3:19 | Starting Loop $a | Loops/DoUntil.ps1:3:2:3:19 | [Stmt] Starting Loop $a | | Loops/DoUntil.ps1:3:2:3:19 | [Stmt] Starting Loop $a | Loops/DoUntil.ps1:2:1:7:1 | {...} | @@ -244,8 +244,8 @@ | Loops/DoUntil.ps1:7:10:7:17 | ... -le ... | Loops/DoUntil.ps1:1:1:7:18 | do...until... | | Loops/DoUntil.ps1:7:17:7:17 | 5 | Loops/DoUntil.ps1:7:10:7:17 | ... -le ... | | Loops/DoWhile.ps1:1:1:7:18 | do...while... | Loops/DoWhile.ps1:1:1:7:18 | {...} | +| Loops/DoWhile.ps1:1:1:7:18 | {...} | Loops/DoWhile.ps1:1:1:7:18 | toplevel function for DoWhile.ps1 | | Loops/DoWhile.ps1:1:1:7:18 | {...} | Loops/DoWhile.ps1:1:1:7:18 | {...} | -| Loops/DoWhile.ps1:1:1:7:18 | {...} | file://:0:0:0:0 | toplevel function for DoWhile.ps1 | | Loops/DoWhile.ps1:2:1:7:1 | {...} | Loops/DoWhile.ps1:1:1:7:18 | do...while... | | Loops/DoWhile.ps1:3:2:3:19 | Starting Loop $a | Loops/DoWhile.ps1:3:2:3:19 | [Stmt] Starting Loop $a | | Loops/DoWhile.ps1:3:2:3:19 | [Stmt] Starting Loop $a | Loops/DoWhile.ps1:2:1:7:1 | {...} | @@ -259,8 +259,8 @@ | Loops/While.ps1:1:1:1:4 | var | Loops/While.ps1:1:1:1:8 | ...=... | | Loops/While.ps1:1:1:1:4 | var | Loops/While.ps1:1:1:13:1 | {...} | | Loops/While.ps1:1:1:1:8 | ...=... | Loops/While.ps1:1:1:13:1 | {...} | +| Loops/While.ps1:1:1:13:1 | {...} | Loops/While.ps1:1:1:13:1 | toplevel function for While.ps1 | | Loops/While.ps1:1:1:13:1 | {...} | Loops/While.ps1:1:1:13:1 | {...} | -| Loops/While.ps1:1:1:13:1 | {...} | file://:0:0:0:0 | toplevel function for While.ps1 | | Loops/While.ps1:1:8:1:8 | 1 | Loops/While.ps1:1:1:1:8 | ...=... | | Loops/While.ps1:2:1:13:1 | while(...) {...} | Loops/While.ps1:1:1:13:1 | {...} | | Loops/While.ps1:2:8:2:11 | var | Loops/While.ps1:2:8:2:17 | ... -le ... | @@ -290,8 +290,8 @@ | Loops/While.ps1:11:9:11:13 | break | Loops/While.ps1:10:5:12:5 | {...} | | Redirections/FileRedirection.ps1:1:1:3:1 | $(...) | Redirections/FileRedirection.ps1:1:1:3:19 | [Stmt] $(...) | | Redirections/FileRedirection.ps1:1:1:3:19 | [Stmt] $(...) | Redirections/FileRedirection.ps1:1:1:3:19 | {...} | +| Redirections/FileRedirection.ps1:1:1:3:19 | {...} | Redirections/FileRedirection.ps1:1:1:3:19 | toplevel function for FileRedirection.ps1 | | Redirections/FileRedirection.ps1:1:1:3:19 | {...} | Redirections/FileRedirection.ps1:1:1:3:19 | {...} | -| Redirections/FileRedirection.ps1:1:1:3:19 | {...} | file://:0:0:0:0 | toplevel function for FileRedirection.ps1 | | Redirections/FileRedirection.ps1:2:5:2:8 | Here | Redirections/FileRedirection.ps1:2:5:2:31 | Call to Here | | Redirections/FileRedirection.ps1:2:5:2:31 | Call to Here | Redirections/FileRedirection.ps1:2:5:2:31 | [Stmt] Call to Here | | Redirections/FileRedirection.ps1:2:5:2:31 | [Stmt] Call to Here | Redirections/FileRedirection.ps1:2:5:2:31 | {...} | @@ -302,14 +302,14 @@ | Redirections/FileRedirection.ps1:2:26:2:31 | script | Redirections/FileRedirection.ps1:2:5:2:31 | Call to Here | | Redirections/FileRedirection.ps1:3:10:3:19 | output.txt | Redirections/FileRedirection.ps1:3:8:3:19 | FileRedirection | | Statements/ExitStatement.ps1:1:1:1:7 | exit ... | Statements/ExitStatement.ps1:1:1:1:7 | {...} | +| Statements/ExitStatement.ps1:1:1:1:7 | {...} | Statements/ExitStatement.ps1:1:1:1:7 | toplevel function for ExitStatement.ps1 | | Statements/ExitStatement.ps1:1:1:1:7 | {...} | Statements/ExitStatement.ps1:1:1:1:7 | {...} | -| Statements/ExitStatement.ps1:1:1:1:7 | {...} | file://:0:0:0:0 | toplevel function for ExitStatement.ps1 | | Statements/ExitStatement.ps1:1:6:1:7 | -1 | Statements/ExitStatement.ps1:1:1:1:7 | exit ... | | Statements/IfStatement.ps1:1:1:1:2 | x | Statements/IfStatement.ps1:1:1:1:6 | ...=... | | Statements/IfStatement.ps1:1:1:1:2 | x | Statements/IfStatement.ps1:1:1:8:1 | {...} | | Statements/IfStatement.ps1:1:1:1:6 | ...=... | Statements/IfStatement.ps1:1:1:8:1 | {...} | +| Statements/IfStatement.ps1:1:1:8:1 | {...} | Statements/IfStatement.ps1:1:1:8:1 | toplevel function for IfStatement.ps1 | | Statements/IfStatement.ps1:1:1:8:1 | {...} | Statements/IfStatement.ps1:1:1:8:1 | {...} | -| Statements/IfStatement.ps1:1:1:8:1 | {...} | file://:0:0:0:0 | toplevel function for IfStatement.ps1 | | Statements/IfStatement.ps1:1:6:1:6 | 4 | Statements/IfStatement.ps1:1:1:1:6 | ...=... | | Statements/IfStatement.ps1:3:1:8:1 | [Stmt] if (...) {...} else {...} | Statements/IfStatement.ps1:1:1:8:1 | {...} | | Statements/IfStatement.ps1:3:1:8:1 | if (...) {...} else {...} | Statements/IfStatement.ps1:3:1:8:1 | [Stmt] if (...) {...} else {...} | @@ -326,8 +326,8 @@ | Statements/IfStatement.ps1:7:3:7:4 | x | Statements/IfStatement.ps1:7:2:7:20 | $x is less than 3 | | Statements/TrapStatement.ps1:1:1:4:1 | TrapTest | Statements/TrapStatement.ps1:1:1:4:1 | def of TrapTest | | Statements/TrapStatement.ps1:1:1:4:1 | def of TrapTest | Statements/TrapStatement.ps1:1:1:6:8 | {...} | +| Statements/TrapStatement.ps1:1:1:6:8 | {...} | Statements/TrapStatement.ps1:1:1:6:8 | toplevel function for TrapStatement.ps1 | | Statements/TrapStatement.ps1:1:1:6:8 | {...} | Statements/TrapStatement.ps1:1:1:6:8 | {...} | -| Statements/TrapStatement.ps1:1:1:6:8 | {...} | file://:0:0:0:0 | toplevel function for TrapStatement.ps1 | | Statements/TrapStatement.ps1:1:19:4:1 | [synth] pipeline | Statements/TrapStatement.ps1:1:19:4:1 | {...} | | Statements/TrapStatement.ps1:1:19:4:1 | {...} | Statements/TrapStatement.ps1:1:1:4:1 | TrapTest | | Statements/TrapStatement.ps1:2:5:2:25 | trap {...} | Statements/TrapStatement.ps1:2:5:3:18 | {...} | @@ -342,8 +342,8 @@ | Statements/TrapStatement.ps1:6:1:6:8 | TrapTest | Statements/TrapStatement.ps1:6:1:6:8 | Call to TrapTest | | Statements/TrapStatement.ps1:6:1:6:8 | [Stmt] Call to TrapTest | Statements/TrapStatement.ps1:1:1:6:8 | {...} | | Statements/Try.ps1:1:1:13:1 | try {...} | Statements/Try.ps1:1:1:13:1 | {...} | +| Statements/Try.ps1:1:1:13:1 | {...} | Statements/Try.ps1:1:1:13:1 | toplevel function for Try.ps1 | | Statements/Try.ps1:1:1:13:1 | {...} | Statements/Try.ps1:1:1:13:1 | {...} | -| Statements/Try.ps1:1:1:13:1 | {...} | file://:0:0:0:0 | toplevel function for Try.ps1 | | Statements/Try.ps1:1:5:4:1 | {...} | Statements/Try.ps1:1:1:13:1 | try {...} | | Statements/Try.ps1:2:4:2:13 | Exception | Statements/Try.ps1:1:1:13:1 | {...} | | Statements/Try.ps1:2:4:2:13 | Exception | Statements/Try.ps1:2:4:2:94 | ...=... | @@ -374,14 +374,15 @@ | Statements/Try.ps1:12:5:12:36 | [Stmt] The finally block is executed. | Statements/Try.ps1:11:9:13:1 | {...} | | Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | Get-Number | Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | def of Get-Number | | Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | def of Get-Number | Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | {...} | +| Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | {...} | Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | toplevel function for UseProcessBlockForPipelineCommand.ps1 | | Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | {...} | Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | {...} | -| Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | {...} | file://:0:0:0:0 | toplevel function for UseProcessBlockForPipelineCommand.ps1 | -| Statements/UseProcessBlockForPipelineCommand.ps1:2:1:11:1 | [synth] pipeline | Statements/UseProcessBlockForPipelineCommand.ps1:2:1:11:1 | {...} | | Statements/UseProcessBlockForPipelineCommand.ps1:2:1:11:1 | {...} | Statements/UseProcessBlockForPipelineCommand.ps1:1:1:11:1 | Get-Number | | Statements/UseProcessBlockForPipelineCommand.ps1:3:5:3:21 | CmdletBinding | Statements/UseProcessBlockForPipelineCommand.ps1:2:1:11:1 | {...} | | Statements/UseProcessBlockForPipelineCommand.ps1:4:5:10:11 | {...} | Statements/UseProcessBlockForPipelineCommand.ps1:2:1:11:1 | {...} | -| Statements/UseProcessBlockForPipelineCommand.ps1:5:9:5:38 | ValueFromPipeline | Statements/UseProcessBlockForPipelineCommand.ps1:2:1:11:1 | [synth] pipeline | +| Statements/UseProcessBlockForPipelineCommand.ps1:5:9:5:38 | ValueFromPipeline | Statements/UseProcessBlockForPipelineCommand.ps1:5:9:7:15 | Number | +| Statements/UseProcessBlockForPipelineCommand.ps1:5:9:7:15 | Number | Statements/UseProcessBlockForPipelineCommand.ps1:2:1:11:1 | {...} | | Statements/UseProcessBlockForPipelineCommand.ps1:5:20:5:36 | (no string representation) | Statements/UseProcessBlockForPipelineCommand.ps1:5:20:5:36 | ValueFromPipeline | | Statements/UseProcessBlockForPipelineCommand.ps1:5:20:5:36 | ValueFromPipeline | Statements/UseProcessBlockForPipelineCommand.ps1:5:9:5:38 | ValueFromPipeline | -| Statements/UseProcessBlockForPipelineCommand.ps1:6:9:6:13 | int | Statements/UseProcessBlockForPipelineCommand.ps1:2:1:11:1 | [synth] pipeline | -| Statements/UseProcessBlockForPipelineCommand.ps1:10:5:10:11 | (no string representation) | Statements/UseProcessBlockForPipelineCommand.ps1:4:5:10:11 | {...} | +| Statements/UseProcessBlockForPipelineCommand.ps1:6:9:6:13 | int | Statements/UseProcessBlockForPipelineCommand.ps1:5:9:7:15 | Number | +| Statements/UseProcessBlockForPipelineCommand.ps1:10:5:10:11 | Number | Statements/UseProcessBlockForPipelineCommand.ps1:10:5:10:11 | [Stmt] Number | +| Statements/UseProcessBlockForPipelineCommand.ps1:10:5:10:11 | [Stmt] Number | Statements/UseProcessBlockForPipelineCommand.ps1:4:5:10:11 | {...} | diff --git a/powershell/ql/test/library-tests/controlflow/graph/Cfg.expected b/powershell/ql/test/library-tests/controlflow/graph/Cfg.expected index 51cfda6735d2..ad0746a58c49 100644 --- a/powershell/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/powershell/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -6,9 +6,9 @@ | conditionals.ps1:1:18:9:1 | [synth] pipeline | conditionals.ps1:2:5:8:13 | {...} | | | conditionals.ps1:1:18:9:1 | enter {...} | conditionals.ps1:1:18:9:1 | {...} | | | conditionals.ps1:1:18:9:1 | exit {...} (normal) | conditionals.ps1:1:18:9:1 | exit {...} | | -| conditionals.ps1:1:18:9:1 | myBool | conditionals.ps1:1:18:9:1 | [synth] pipeline | | -| conditionals.ps1:1:18:9:1 | {...} | conditionals.ps1:1:18:9:1 | myBool | | +| conditionals.ps1:1:18:9:1 | {...} | conditionals.ps1:2:11:2:17 | myBool | | | conditionals.ps1:2:5:8:13 | {...} | conditionals.ps1:4:5:7:5 | [Stmt] if (...) {...} | | +| conditionals.ps1:2:11:2:17 | myBool | conditionals.ps1:1:18:9:1 | [synth] pipeline | | | conditionals.ps1:4:5:7:5 | [Stmt] if (...) {...} | conditionals.ps1:4:8:4:14 | myBool | | | conditionals.ps1:4:5:7:5 | if (...) {...} | conditionals.ps1:8:5:8:13 | return ... | | | conditionals.ps1:4:8:4:14 | myBool | conditionals.ps1:4:5:7:5 | if (...) {...} | false | @@ -22,9 +22,9 @@ | conditionals.ps1:11:23:22:1 | [synth] pipeline | conditionals.ps1:12:5:21:5 | {...} | | | conditionals.ps1:11:23:22:1 | enter {...} | conditionals.ps1:11:23:22:1 | {...} | | | conditionals.ps1:11:23:22:1 | exit {...} (normal) | conditionals.ps1:11:23:22:1 | exit {...} | | -| conditionals.ps1:11:23:22:1 | myBool | conditionals.ps1:11:23:22:1 | [synth] pipeline | | -| conditionals.ps1:11:23:22:1 | {...} | conditionals.ps1:11:23:22:1 | myBool | | +| conditionals.ps1:11:23:22:1 | {...} | conditionals.ps1:12:11:12:17 | myBool | | | conditionals.ps1:12:5:21:5 | {...} | conditionals.ps1:14:5:21:5 | [Stmt] if (...) {...} else {...} | | +| conditionals.ps1:12:11:12:17 | myBool | conditionals.ps1:11:23:22:1 | [synth] pipeline | | | conditionals.ps1:14:5:21:5 | [Stmt] if (...) {...} else {...} | conditionals.ps1:14:8:14:14 | myBool | | | conditionals.ps1:14:5:21:5 | if (...) {...} else {...} | conditionals.ps1:11:23:22:1 | exit {...} (normal) | | | conditionals.ps1:14:8:14:14 | myBool | conditionals.ps1:15:5:17:5 | {...} | true | @@ -39,10 +39,10 @@ | conditionals.ps1:24:23:32:1 | [synth] pipeline | conditionals.ps1:25:5:31:13 | {...} | | | conditionals.ps1:24:23:32:1 | enter {...} | conditionals.ps1:24:23:32:1 | {...} | | | conditionals.ps1:24:23:32:1 | exit {...} (normal) | conditionals.ps1:24:23:32:1 | exit {...} | | -| conditionals.ps1:24:23:32:1 | myBool1 | conditionals.ps1:24:23:32:1 | myBool2 | | -| conditionals.ps1:24:23:32:1 | myBool2 | conditionals.ps1:24:23:32:1 | [synth] pipeline | | -| conditionals.ps1:24:23:32:1 | {...} | conditionals.ps1:24:23:32:1 | myBool1 | | +| conditionals.ps1:24:23:32:1 | {...} | conditionals.ps1:25:11:25:18 | myBool1 | | | conditionals.ps1:25:5:31:13 | {...} | conditionals.ps1:27:5:30:5 | [Stmt] if (...) {...} | | +| conditionals.ps1:25:11:25:18 | myBool1 | conditionals.ps1:25:21:25:28 | myBool2 | | +| conditionals.ps1:25:21:25:28 | myBool2 | conditionals.ps1:24:23:32:1 | [synth] pipeline | | | conditionals.ps1:27:5:30:5 | [Stmt] if (...) {...} | conditionals.ps1:27:8:27:15 | myBool1 | | | conditionals.ps1:27:5:30:5 | if (...) {...} | conditionals.ps1:31:5:31:13 | return ... | | | conditionals.ps1:27:8:27:15 | myBool1 | conditionals.ps1:27:22:27:29 | myBool2 | false, true | @@ -59,10 +59,10 @@ | conditionals.ps1:34:28:45:1 | [synth] pipeline | conditionals.ps1:35:5:44:5 | {...} | | | conditionals.ps1:34:28:45:1 | enter {...} | conditionals.ps1:34:28:45:1 | {...} | | | conditionals.ps1:34:28:45:1 | exit {...} (normal) | conditionals.ps1:34:28:45:1 | exit {...} | | -| conditionals.ps1:34:28:45:1 | myBool1 | conditionals.ps1:34:28:45:1 | myBool2 | | -| conditionals.ps1:34:28:45:1 | myBool2 | conditionals.ps1:34:28:45:1 | [synth] pipeline | | -| conditionals.ps1:34:28:45:1 | {...} | conditionals.ps1:34:28:45:1 | myBool1 | | +| conditionals.ps1:34:28:45:1 | {...} | conditionals.ps1:35:11:35:18 | myBool1 | | | conditionals.ps1:35:5:44:5 | {...} | conditionals.ps1:37:5:44:5 | [Stmt] if (...) {...} else {...} | | +| conditionals.ps1:35:11:35:18 | myBool1 | conditionals.ps1:35:21:35:28 | myBool2 | | +| conditionals.ps1:35:21:35:28 | myBool2 | conditionals.ps1:34:28:45:1 | [synth] pipeline | | | conditionals.ps1:37:5:44:5 | [Stmt] if (...) {...} else {...} | conditionals.ps1:37:8:37:15 | myBool1 | | | conditionals.ps1:37:5:44:5 | if (...) {...} else {...} | conditionals.ps1:34:28:45:1 | exit {...} (normal) | | | conditionals.ps1:37:8:37:15 | myBool1 | conditionals.ps1:37:22:37:29 | myBool2 | false, true | @@ -80,10 +80,10 @@ | conditionals.ps1:47:23:55:1 | [synth] pipeline | conditionals.ps1:48:5:54:13 | {...} | | | conditionals.ps1:47:23:55:1 | enter {...} | conditionals.ps1:47:23:55:1 | {...} | | | conditionals.ps1:47:23:55:1 | exit {...} (normal) | conditionals.ps1:47:23:55:1 | exit {...} | | -| conditionals.ps1:47:23:55:1 | myBool1 | conditionals.ps1:47:23:55:1 | myBool2 | | -| conditionals.ps1:47:23:55:1 | myBool2 | conditionals.ps1:47:23:55:1 | [synth] pipeline | | -| conditionals.ps1:47:23:55:1 | {...} | conditionals.ps1:47:23:55:1 | myBool1 | | +| conditionals.ps1:47:23:55:1 | {...} | conditionals.ps1:48:11:48:18 | myBool1 | | | conditionals.ps1:48:5:54:13 | {...} | conditionals.ps1:50:5:53:5 | [Stmt] if (...) {...} | | +| conditionals.ps1:48:11:48:18 | myBool1 | conditionals.ps1:48:21:48:28 | myBool2 | | +| conditionals.ps1:48:21:48:28 | myBool2 | conditionals.ps1:47:23:55:1 | [synth] pipeline | | | conditionals.ps1:50:5:53:5 | [Stmt] if (...) {...} | conditionals.ps1:50:8:50:15 | myBool1 | | | conditionals.ps1:50:5:53:5 | if (...) {...} | conditionals.ps1:54:5:54:13 | return ... | | | conditionals.ps1:50:8:50:15 | myBool1 | conditionals.ps1:50:21:50:28 | myBool2 | false, true | @@ -100,10 +100,10 @@ | conditionals.ps1:57:28:68:1 | [synth] pipeline | conditionals.ps1:58:5:67:5 | {...} | | | conditionals.ps1:57:28:68:1 | enter {...} | conditionals.ps1:57:28:68:1 | {...} | | | conditionals.ps1:57:28:68:1 | exit {...} (normal) | conditionals.ps1:57:28:68:1 | exit {...} | | -| conditionals.ps1:57:28:68:1 | myBool1 | conditionals.ps1:57:28:68:1 | myBool2 | | -| conditionals.ps1:57:28:68:1 | myBool2 | conditionals.ps1:57:28:68:1 | [synth] pipeline | | -| conditionals.ps1:57:28:68:1 | {...} | conditionals.ps1:57:28:68:1 | myBool1 | | +| conditionals.ps1:57:28:68:1 | {...} | conditionals.ps1:58:11:58:18 | myBool1 | | | conditionals.ps1:58:5:67:5 | {...} | conditionals.ps1:60:5:67:5 | [Stmt] if (...) {...} else {...} | | +| conditionals.ps1:58:11:58:18 | myBool1 | conditionals.ps1:58:21:58:28 | myBool2 | | +| conditionals.ps1:58:21:58:28 | myBool2 | conditionals.ps1:57:28:68:1 | [synth] pipeline | | | conditionals.ps1:60:5:67:5 | [Stmt] if (...) {...} else {...} | conditionals.ps1:60:8:60:15 | myBool1 | | | conditionals.ps1:60:5:67:5 | if (...) {...} else {...} | conditionals.ps1:57:28:68:1 | exit {...} (normal) | | | conditionals.ps1:60:8:60:15 | myBool1 | conditionals.ps1:60:21:60:28 | myBool2 | false, true | @@ -121,10 +121,10 @@ | conditionals.ps1:70:23:82:1 | [synth] pipeline | conditionals.ps1:71:5:81:13 | {...} | | | conditionals.ps1:70:23:82:1 | enter {...} | conditionals.ps1:70:23:82:1 | {...} | | | conditionals.ps1:70:23:82:1 | exit {...} (normal) | conditionals.ps1:70:23:82:1 | exit {...} | | -| conditionals.ps1:70:23:82:1 | myBool1 | conditionals.ps1:70:23:82:1 | myBool2 | | -| conditionals.ps1:70:23:82:1 | myBool2 | conditionals.ps1:70:23:82:1 | [synth] pipeline | | -| conditionals.ps1:70:23:82:1 | {...} | conditionals.ps1:70:23:82:1 | myBool1 | | +| conditionals.ps1:70:23:82:1 | {...} | conditionals.ps1:71:11:71:18 | myBool1 | | | conditionals.ps1:71:5:81:13 | {...} | conditionals.ps1:73:5:80:5 | [Stmt] if (...) {...} | | +| conditionals.ps1:71:11:71:18 | myBool1 | conditionals.ps1:71:21:71:28 | myBool2 | | +| conditionals.ps1:71:21:71:28 | myBool2 | conditionals.ps1:70:23:82:1 | [synth] pipeline | | | conditionals.ps1:73:5:80:5 | [Stmt] if (...) {...} | conditionals.ps1:73:8:73:15 | myBool1 | | | conditionals.ps1:73:5:80:5 | if (...) {...} | conditionals.ps1:81:5:81:13 | return ... | | | conditionals.ps1:73:8:73:15 | myBool1 | conditionals.ps1:73:5:80:5 | if (...) {...} | false | @@ -138,10 +138,10 @@ | conditionals.ps1:84:28:99:1 | [synth] pipeline | conditionals.ps1:85:5:98:5 | {...} | | | conditionals.ps1:84:28:99:1 | enter {...} | conditionals.ps1:84:28:99:1 | {...} | | | conditionals.ps1:84:28:99:1 | exit {...} (normal) | conditionals.ps1:84:28:99:1 | exit {...} | | -| conditionals.ps1:84:28:99:1 | myBool1 | conditionals.ps1:84:28:99:1 | myBool2 | | -| conditionals.ps1:84:28:99:1 | myBool2 | conditionals.ps1:84:28:99:1 | [synth] pipeline | | -| conditionals.ps1:84:28:99:1 | {...} | conditionals.ps1:84:28:99:1 | myBool1 | | +| conditionals.ps1:84:28:99:1 | {...} | conditionals.ps1:85:11:85:18 | myBool1 | | | conditionals.ps1:85:5:98:5 | {...} | conditionals.ps1:87:5:98:5 | [Stmt] if (...) {...} else {...} | | +| conditionals.ps1:85:11:85:18 | myBool1 | conditionals.ps1:85:21:85:28 | myBool2 | | +| conditionals.ps1:85:21:85:28 | myBool2 | conditionals.ps1:84:28:99:1 | [synth] pipeline | | | conditionals.ps1:87:5:98:5 | [Stmt] if (...) {...} else {...} | conditionals.ps1:87:8:87:15 | myBool1 | | | conditionals.ps1:87:5:98:5 | if (...) {...} else {...} | conditionals.ps1:84:28:99:1 | exit {...} (normal) | | | conditionals.ps1:87:8:87:15 | myBool1 | conditionals.ps1:88:5:90:5 | {...} | true | @@ -153,11 +153,11 @@ | conditionals.ps1:97:9:97:17 | return ... | conditionals.ps1:97:16:97:17 | 12 | | | conditionals.ps1:97:16:97:17 | 12 | conditionals.ps1:87:5:98:5 | if (...) {...} else {...} | | | conditionals.ps1:101:1:108:1 | def of test-switch | conditionals.ps1:110:1:121:1 | def of test-switch-default | | +| conditionals.ps1:101:22:101:23 | n | conditionals.ps1:101:26:108:1 | [synth] pipeline | | | conditionals.ps1:101:26:108:1 | [synth] pipeline | conditionals.ps1:102:5:107:5 | {...} | | | conditionals.ps1:101:26:108:1 | enter {...} | conditionals.ps1:101:26:108:1 | {...} | | | conditionals.ps1:101:26:108:1 | exit {...} (normal) | conditionals.ps1:101:26:108:1 | exit {...} | | -| conditionals.ps1:101:26:108:1 | n | conditionals.ps1:101:26:108:1 | [synth] pipeline | | -| conditionals.ps1:101:26:108:1 | {...} | conditionals.ps1:101:26:108:1 | n | | +| conditionals.ps1:101:26:108:1 | {...} | conditionals.ps1:101:22:101:23 | n | | | conditionals.ps1:102:5:107:5 | switch(...) {...} | conditionals.ps1:102:12:102:13 | n | | | conditionals.ps1:102:5:107:5 | {...} | conditionals.ps1:102:5:107:5 | switch(...) {...} | | | conditionals.ps1:102:12:102:13 | n | conditionals.ps1:104:9:104:10 | 0: | | @@ -177,11 +177,11 @@ | conditionals.ps1:106:14:106:21 | return ... | conditionals.ps1:106:21:106:21 | 2 | | | conditionals.ps1:106:21:106:21 | 2 | conditionals.ps1:101:26:108:1 | exit {...} (normal) | | | conditionals.ps1:110:1:121:1 | def of test-switch-default | conditionals.ps1:123:1:129:1 | def of test-switch-assign | | +| conditionals.ps1:110:30:110:31 | n | conditionals.ps1:110:34:121:1 | [synth] pipeline | | | conditionals.ps1:110:34:121:1 | [synth] pipeline | conditionals.ps1:111:5:120:5 | {...} | | | conditionals.ps1:110:34:121:1 | enter {...} | conditionals.ps1:110:34:121:1 | {...} | | | conditionals.ps1:110:34:121:1 | exit {...} (normal) | conditionals.ps1:110:34:121:1 | exit {...} | | -| conditionals.ps1:110:34:121:1 | n | conditionals.ps1:110:34:121:1 | [synth] pipeline | | -| conditionals.ps1:110:34:121:1 | {...} | conditionals.ps1:110:34:121:1 | n | | +| conditionals.ps1:110:34:121:1 | {...} | conditionals.ps1:110:30:110:31 | n | | | conditionals.ps1:111:5:120:5 | switch(...) {...} | conditionals.ps1:111:12:111:13 | n | | | conditionals.ps1:111:5:120:5 | {...} | conditionals.ps1:111:5:120:5 | switch(...) {...} | | | conditionals.ps1:111:12:111:13 | n | conditionals.ps1:113:9:113:10 | 0: | | @@ -210,11 +210,11 @@ | conditionals.ps1:118:13:118:20 | return ... | conditionals.ps1:118:20:118:20 | 3 | | | conditionals.ps1:118:20:118:20 | 3 | conditionals.ps1:110:34:121:1 | exit {...} (normal) | | | conditionals.ps1:123:1:129:1 | def of test-switch-assign | conditionals.ps1:1:1:129:1 | exit {...} (normal) | | +| conditionals.ps1:123:29:123:30 | n | conditionals.ps1:123:33:129:1 | [synth] pipeline | | | conditionals.ps1:123:33:129:1 | [synth] pipeline | conditionals.ps1:124:5:128:5 | {...} | | | conditionals.ps1:123:33:129:1 | enter {...} | conditionals.ps1:123:33:129:1 | {...} | | | conditionals.ps1:123:33:129:1 | exit {...} (normal) | conditionals.ps1:123:33:129:1 | exit {...} | | -| conditionals.ps1:123:33:129:1 | n | conditionals.ps1:123:33:129:1 | [synth] pipeline | | -| conditionals.ps1:123:33:129:1 | {...} | conditionals.ps1:123:33:129:1 | n | | +| conditionals.ps1:123:33:129:1 | {...} | conditionals.ps1:123:29:123:30 | n | | | conditionals.ps1:124:5:124:6 | a | conditionals.ps1:123:33:129:1 | exit {...} (normal) | | | conditionals.ps1:124:5:128:5 | ...=... | conditionals.ps1:124:5:124:6 | a | | | conditionals.ps1:124:5:128:5 | {...} | conditionals.ps1:124:5:128:5 | ...=... | | @@ -226,37 +226,37 @@ | functions.ps1:1:32:9:1 | [synth] pipeline | functions.ps1:3:5:8:23 | {...} | | | functions.ps1:1:32:9:1 | enter {...} | functions.ps1:1:32:9:1 | {...} | | | functions.ps1:1:32:9:1 | exit {...} (normal) | functions.ps1:1:32:9:1 | exit {...} | | -| functions.ps1:1:32:9:1 | number1 | functions.ps1:1:32:9:1 | number2 | | -| functions.ps1:1:32:9:1 | number2 | functions.ps1:1:32:9:1 | [synth] pipeline | | -| functions.ps1:1:32:9:1 | {...} | functions.ps1:1:32:9:1 | number1 | | +| functions.ps1:1:32:9:1 | {...} | functions.ps1:4:9:4:22 | number1 | | | functions.ps1:3:5:8:23 | {...} | functions.ps1:8:5:8:23 | [Stmt] ...+... | | +| functions.ps1:4:9:4:22 | number1 | functions.ps1:5:9:5:22 | number2 | | +| functions.ps1:5:9:5:22 | number2 | functions.ps1:1:32:9:1 | [synth] pipeline | | | functions.ps1:8:5:8:12 | number1 | functions.ps1:8:16:8:23 | number2 | | | functions.ps1:8:5:8:23 | ...+... | functions.ps1:1:32:9:1 | exit {...} (normal) | | | functions.ps1:8:5:8:23 | [Stmt] ...+... | functions.ps1:8:5:8:12 | number1 | | | functions.ps1:8:16:8:23 | number2 | functions.ps1:8:5:8:23 | ...+... | | | functions.ps1:11:1:11:28 | def of foo | functions.ps1:13:1:20:1 | def of Default-Arguments | | | functions.ps1:11:16:11:28 | [synth] pipeline | functions.ps1:11:18:11:26 | {...} | | -| functions.ps1:11:16:11:28 | a | functions.ps1:11:16:11:28 | [synth] pipeline | | | functions.ps1:11:16:11:28 | enter {...} | functions.ps1:11:16:11:28 | {...} | | | functions.ps1:11:16:11:28 | exit {...} (normal) | functions.ps1:11:16:11:28 | exit {...} | | -| functions.ps1:11:16:11:28 | {...} | functions.ps1:11:16:11:28 | a | | +| functions.ps1:11:16:11:28 | {...} | functions.ps1:11:24:11:25 | a | | | functions.ps1:11:18:11:26 | {...} | functions.ps1:11:16:11:28 | exit {...} (normal) | | +| functions.ps1:11:24:11:25 | a | functions.ps1:11:16:11:28 | [synth] pipeline | | | functions.ps1:13:1:20:1 | def of Default-Arguments | functions.ps1:22:1:34:1 | def of Add-Numbers-From-Array | | | functions.ps1:13:28:20:1 | [synth] pipeline | functions.ps1:14:5:19:18 | {...} | | | functions.ps1:13:28:20:1 | enter {...} | functions.ps1:13:28:20:1 | {...} | | | functions.ps1:13:28:20:1 | exit {...} (normal) | functions.ps1:13:28:20:1 | exit {...} | | -| functions.ps1:13:28:20:1 | name0 | functions.ps1:13:28:20:1 | name1 | | -| functions.ps1:13:28:20:1 | name1 | functions.ps1:13:28:20:1 | name2 | | -| functions.ps1:13:28:20:1 | name1 | functions.ps1:16:24:16:24 | 0 | | -| functions.ps1:13:28:20:1 | name2 | functions.ps1:13:28:20:1 | [synth] pipeline | | -| functions.ps1:13:28:20:1 | name2 | functions.ps1:17:24:17:29 | name1 | | | functions.ps1:13:28:20:1 | {...} | functions.ps1:16:24:16:24 | 0 | | | functions.ps1:14:5:19:18 | {...} | functions.ps1:19:5:19:18 | [Stmt] ...+... | | -| functions.ps1:16:24:16:24 | 0 | functions.ps1:13:28:20:1 | name2 | | +| functions.ps1:15:9:15:20 | name0 | functions.ps1:16:9:16:24 | name1 | | +| functions.ps1:16:9:16:24 | name1 | functions.ps1:16:24:16:24 | 0 | | +| functions.ps1:16:9:16:24 | name1 | functions.ps1:17:9:17:33 | name2 | | +| functions.ps1:16:24:16:24 | 0 | functions.ps1:17:9:17:33 | name2 | | | functions.ps1:16:24:16:24 | 0 | functions.ps1:17:24:17:29 | name1 | | +| functions.ps1:17:9:17:33 | name2 | functions.ps1:13:28:20:1 | [synth] pipeline | | +| functions.ps1:17:9:17:33 | name2 | functions.ps1:17:24:17:29 | name1 | | | functions.ps1:17:24:17:29 | name1 | functions.ps1:17:33:17:33 | 1 | | | functions.ps1:17:24:17:33 | ...+... | functions.ps1:13:28:20:1 | [synth] pipeline | | -| functions.ps1:17:24:17:33 | ...+... | functions.ps1:13:28:20:1 | name0 | | +| functions.ps1:17:24:17:33 | ...+... | functions.ps1:15:9:15:20 | name0 | | | functions.ps1:17:33:17:33 | 1 | functions.ps1:17:24:17:33 | ...+... | | | functions.ps1:19:5:19:18 | ...+... | functions.ps1:13:28:20:1 | exit {...} (normal) | | | functions.ps1:19:5:19:18 | [Stmt] ...+... | functions.ps1:19:13:19:18 | name2 | | @@ -265,9 +265,9 @@ | functions.ps1:22:33:34:1 | [synth] pipeline | functions.ps1:24:5:33:8 | {...} | | | functions.ps1:22:33:34:1 | enter {...} | functions.ps1:22:33:34:1 | {...} | | | functions.ps1:22:33:34:1 | exit {...} (normal) | functions.ps1:22:33:34:1 | exit {...} | | -| functions.ps1:22:33:34:1 | numbers | functions.ps1:22:33:34:1 | [synth] pipeline | | -| functions.ps1:22:33:34:1 | {...} | functions.ps1:22:33:34:1 | numbers | | +| functions.ps1:22:33:34:1 | {...} | functions.ps1:25:9:25:24 | numbers | | | functions.ps1:24:5:33:8 | {...} | functions.ps1:28:5:28:12 | ...=... | | +| functions.ps1:25:9:25:24 | numbers | functions.ps1:22:33:34:1 | [synth] pipeline | | | functions.ps1:28:5:28:8 | sum | functions.ps1:28:12:28:12 | 0 | | | functions.ps1:28:5:28:12 | ...=... | functions.ps1:28:5:28:8 | sum | | | functions.ps1:28:12:28:12 | 0 | functions.ps1:29:25:29:32 | numbers | | @@ -285,8 +285,8 @@ | functions.ps1:36:36:52:1 | [synth] pipeline | functions.ps1:41:5:43:5 | {...} | | | functions.ps1:36:36:52:1 | enter {...} | functions.ps1:36:36:52:1 | {...} | | | functions.ps1:36:36:52:1 | exit {...} (normal) | functions.ps1:36:36:52:1 | exit {...} | | -| functions.ps1:36:36:52:1 | numbers | functions.ps1:36:36:52:1 | [synth] pipeline | | -| functions.ps1:36:36:52:1 | {...} | functions.ps1:36:36:52:1 | numbers | | +| functions.ps1:36:36:52:1 | {...} | functions.ps1:39:9:39:24 | numbers | | +| functions.ps1:39:9:39:24 | numbers | functions.ps1:36:36:52:1 | [synth] pipeline | | | functions.ps1:41:5:43:5 | {...} | functions.ps1:42:9:42:16 | ...=... | | | functions.ps1:42:9:42:12 | sum | functions.ps1:42:16:42:16 | 0 | | | functions.ps1:42:9:42:16 | ...=... | functions.ps1:42:9:42:12 | sum | | @@ -506,11 +506,11 @@ | try.ps1:7:5:7:12 | return ... | try.ps1:7:12:7:12 | 1 | | | try.ps1:7:12:7:12 | 1 | try.ps1:1:25:8:1 | exit {...} (normal) | | | try.ps1:10:1:19:1 | def of test-try-with-throw-catch | try.ps1:21:1:30:1 | def of test-try-with-throw-catch-with-throw | | +| try.ps1:10:36:10:37 | b | try.ps1:10:40:19:1 | [synth] pipeline | | | try.ps1:10:40:19:1 | [synth] pipeline | try.ps1:11:5:18:12 | {...} | | -| try.ps1:10:40:19:1 | b | try.ps1:10:40:19:1 | [synth] pipeline | | | try.ps1:10:40:19:1 | enter {...} | try.ps1:10:40:19:1 | {...} | | | try.ps1:10:40:19:1 | exit {...} (normal) | try.ps1:10:40:19:1 | exit {...} | | -| try.ps1:10:40:19:1 | {...} | try.ps1:10:40:19:1 | b | | +| try.ps1:10:40:19:1 | {...} | try.ps1:10:36:10:37 | b | | | try.ps1:11:5:17:5 | try {...} | try.ps1:11:9:15:5 | {...} | | | try.ps1:11:5:18:12 | {...} | try.ps1:11:5:17:5 | try {...} | | | try.ps1:11:9:15:5 | {...} | try.ps1:12:9:14:9 | [Stmt] if (...) {...} | | @@ -524,11 +524,11 @@ | try.ps1:18:5:18:12 | return ... | try.ps1:18:12:18:12 | 1 | | | try.ps1:18:12:18:12 | 1 | try.ps1:10:40:19:1 | exit {...} (normal) | | | try.ps1:21:1:30:1 | def of test-try-with-throw-catch-with-throw | try.ps1:32:1:41:1 | def of test-try-with-throw-catch-with-rethrow | | +| try.ps1:21:47:21:48 | b | try.ps1:21:51:30:1 | [synth] pipeline | | | try.ps1:21:51:30:1 | [synth] pipeline | try.ps1:22:5:29:12 | {...} | | -| try.ps1:21:51:30:1 | b | try.ps1:21:51:30:1 | [synth] pipeline | | | try.ps1:21:51:30:1 | enter {...} | try.ps1:21:51:30:1 | {...} | | | try.ps1:21:51:30:1 | exit {...} (normal) | try.ps1:21:51:30:1 | exit {...} | | -| try.ps1:21:51:30:1 | {...} | try.ps1:21:51:30:1 | b | | +| try.ps1:21:51:30:1 | {...} | try.ps1:21:47:21:48 | b | | | try.ps1:22:5:28:5 | try {...} | try.ps1:22:9:26:5 | {...} | | | try.ps1:22:5:29:12 | {...} | try.ps1:22:5:28:5 | try {...} | | | try.ps1:22:9:26:5 | {...} | try.ps1:23:9:25:9 | [Stmt] if (...) {...} | | @@ -542,11 +542,11 @@ | try.ps1:29:5:29:12 | return ... | try.ps1:29:12:29:12 | 1 | | | try.ps1:29:12:29:12 | 1 | try.ps1:21:51:30:1 | exit {...} (normal) | | | try.ps1:32:1:41:1 | def of test-try-with-throw-catch-with-rethrow | try.ps1:43:1:50:1 | def of test-try-catch-specific-1 | | +| try.ps1:32:49:32:50 | b | try.ps1:32:53:41:1 | [synth] pipeline | | | try.ps1:32:53:41:1 | [synth] pipeline | try.ps1:33:5:40:12 | {...} | | -| try.ps1:32:53:41:1 | b | try.ps1:32:53:41:1 | [synth] pipeline | | | try.ps1:32:53:41:1 | enter {...} | try.ps1:32:53:41:1 | {...} | | | try.ps1:32:53:41:1 | exit {...} (normal) | try.ps1:32:53:41:1 | exit {...} | | -| try.ps1:32:53:41:1 | {...} | try.ps1:32:53:41:1 | b | | +| try.ps1:32:53:41:1 | {...} | try.ps1:32:49:32:50 | b | | | try.ps1:33:5:39:5 | try {...} | try.ps1:33:9:37:5 | {...} | | | try.ps1:33:5:40:12 | {...} | try.ps1:33:5:39:5 | try {...} | | | try.ps1:33:9:37:5 | {...} | try.ps1:34:9:36:9 | [Stmt] if (...) {...} | | diff --git a/powershell/ql/test/library-tests/controlflow/graph/consistency.expected b/powershell/ql/test/library-tests/controlflow/graph/consistency.expected index 6f6c4e8dca39..0a8f7a69ad2d 100644 --- a/powershell/ql/test/library-tests/controlflow/graph/consistency.expected +++ b/powershell/ql/test/library-tests/controlflow/graph/consistency.expected @@ -4,14 +4,14 @@ breakInvariant3 breakInvariant4 breakInvariant5 multipleSuccessors -| functions.ps1:13:28:20:1 | name1 | successor | functions.ps1:13:28:20:1 | name2 | -| functions.ps1:13:28:20:1 | name1 | successor | functions.ps1:16:24:16:24 | 0 | -| functions.ps1:13:28:20:1 | name2 | successor | functions.ps1:13:28:20:1 | [synth] pipeline | -| functions.ps1:13:28:20:1 | name2 | successor | functions.ps1:17:24:17:29 | name1 | -| functions.ps1:16:24:16:24 | 0 | successor | functions.ps1:13:28:20:1 | name2 | +| functions.ps1:16:9:16:24 | name1 | successor | functions.ps1:16:24:16:24 | 0 | +| functions.ps1:16:9:16:24 | name1 | successor | functions.ps1:17:9:17:33 | name2 | +| functions.ps1:16:24:16:24 | 0 | successor | functions.ps1:17:9:17:33 | name2 | | functions.ps1:16:24:16:24 | 0 | successor | functions.ps1:17:24:17:29 | name1 | +| functions.ps1:17:9:17:33 | name2 | successor | functions.ps1:13:28:20:1 | [synth] pipeline | +| functions.ps1:17:9:17:33 | name2 | successor | functions.ps1:17:24:17:29 | name1 | | functions.ps1:17:24:17:33 | ...+... | successor | functions.ps1:13:28:20:1 | [synth] pipeline | -| functions.ps1:17:24:17:33 | ...+... | successor | functions.ps1:13:28:20:1 | name0 | +| functions.ps1:17:24:17:33 | ...+... | successor | functions.ps1:15:9:15:20 | name0 | | functions.ps1:46:17:46:18 | __pipeline_iterator | successor | functions.ps1:44:5:47:5 | [synth] pipeline | | functions.ps1:46:17:46:18 | __pipeline_iterator | successor | functions.ps1:48:5:51:5 | {...} | | loops.ps1:45:14:45:19 | ...+... | successor | loops.ps1:44:18:44:19 | i | diff --git a/powershell/ql/test/library-tests/dataflow/local/taint.expected b/powershell/ql/test/library-tests/dataflow/local/taint.expected index 1d2bd8ef34b3..9b7f161a3306 100644 --- a/powershell/ql/test/library-tests/dataflow/local/taint.expected +++ b/powershell/ql/test/library-tests/dataflow/local/taint.expected @@ -1,3 +1,4 @@ +| file://:0:0:0:0 | [summary param] pos(0, {}) in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | file://:0:0:0:0 | [summary] to write: ReturnValue in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | | test.ps1:1:1:1:3 | a1 | test.ps1:2:6:2:8 | a1 | | test.ps1:1:1:24:22 | implicit unwrapping of {...} | test.ps1:1:1:24:22 | return value for {...} | | test.ps1:1:1:24:22 | pre-return value for {...} | test.ps1:1:1:24:22 | implicit unwrapping of {...} | diff --git a/powershell/ql/test/library-tests/dataflow/mad/flow.expected b/powershell/ql/test/library-tests/dataflow/mad/flow.expected new file mode 100644 index 000000000000..fb2743556a90 --- /dev/null +++ b/powershell/ql/test/library-tests/dataflow/mad/flow.expected @@ -0,0 +1,19 @@ +models +edges +| file://:0:0:0:0 | [summary param] pos(0, {}) in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | file://:0:0:0:0 | [summary] to write: ReturnValue in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | provenance | | +| test.ps1:1:6:1:15 | Call to Source | test.ps1:2:94:2:95 | x | provenance | | +| test.ps1:2:6:2:96 | Call to EscapeSingleQuotedStringContent | test.ps1:3:6:3:7 | y | provenance | | +| test.ps1:2:94:2:95 | x | file://:0:0:0:0 | [summary param] pos(0, {}) in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | provenance | | +| test.ps1:2:94:2:95 | x | test.ps1:2:6:2:96 | Call to EscapeSingleQuotedStringContent | provenance | | +nodes +| file://:0:0:0:0 | [summary param] pos(0, {}) in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | semmle.label | [summary param] pos(0, {}) in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | +| file://:0:0:0:0 | [summary] to write: ReturnValue in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | semmle.label | [summary] to write: ReturnValue in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | +| test.ps1:1:6:1:15 | Call to Source | semmle.label | Call to Source | +| test.ps1:2:6:2:96 | Call to EscapeSingleQuotedStringContent | semmle.label | Call to EscapeSingleQuotedStringContent | +| test.ps1:2:94:2:95 | x | semmle.label | x | +| test.ps1:3:6:3:7 | y | semmle.label | y | +subpaths +| test.ps1:2:94:2:95 | x | file://:0:0:0:0 | [summary param] pos(0, {}) in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | file://:0:0:0:0 | [summary] to write: ReturnValue in System.Management.Automation.Language.CodeGeneration!;Method[escapesinglequotedstringcontent] | test.ps1:2:6:2:96 | Call to EscapeSingleQuotedStringContent | +testFailures +#select +| test.ps1:3:6:3:7 | y | test.ps1:1:6:1:15 | Call to Source | test.ps1:3:6:3:7 | y | $@ | test.ps1:1:6:1:15 | Call to Source | Call to Source | diff --git a/powershell/ql/test/library-tests/dataflow/mad/flow.ql b/powershell/ql/test/library-tests/dataflow/mad/flow.ql new file mode 100644 index 000000000000..33fcac2162e0 --- /dev/null +++ b/powershell/ql/test/library-tests/dataflow/mad/flow.ql @@ -0,0 +1,13 @@ +/** + * @kind path-problem + */ + +import powershell +import semmle.code.powershell.dataflow.DataFlow +private import TestUtilities.InlineFlowTest +import DefaultFlowTest +import TaintFlow::PathGraph + +from TaintFlow::PathNode source, TaintFlow::PathNode sink +where TaintFlow::flowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/powershell/ql/test/library-tests/dataflow/mad/test.ps1 b/powershell/ql/test/library-tests/dataflow/mad/test.ps1 new file mode 100644 index 000000000000..8f1e23b99074 --- /dev/null +++ b/powershell/ql/test/library-tests/dataflow/mad/test.ps1 @@ -0,0 +1,3 @@ +$x = Source "1" +$y = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($x) +Sink $y # $ hasTaintFlow=1 \ No newline at end of file diff --git a/powershell/ql/test/library-tests/dataflow/params/test.expected b/powershell/ql/test/library-tests/dataflow/params/test.expected index fa4b4a3bf859..d4009c646e9a 100644 --- a/powershell/ql/test/library-tests/dataflow/params/test.expected +++ b/powershell/ql/test/library-tests/dataflow/params/test.expected @@ -1,15 +1,15 @@ models edges -| global.ps1:1:1:6:32 | Source1 | global.ps1:3:6:3:13 | Source1 | provenance | | -| global.ps1:1:1:6:32 | Source2 | global.ps1:4:6:4:13 | Source2 | provenance | | -| global.ps1:1:1:6:32 | Source3 | global.ps1:5:6:5:13 | Source3 | provenance | | -| global.ps1:1:1:6:32 | Source4 | global.ps1:6:6:6:13 | Source4 | provenance | | -| test.ps1:1:18:3:1 | a | test.ps1:2:10:2:11 | a | provenance | | +| global.ps1:1:7:1:22 | Source1 | global.ps1:3:6:3:13 | Source1 | provenance | | +| global.ps1:1:25:1:40 | Source2 | global.ps1:4:6:4:13 | Source2 | provenance | | +| global.ps1:1:43:1:58 | Source3 | global.ps1:5:6:5:13 | Source3 | provenance | | +| global.ps1:1:61:1:76 | Source4 | global.ps1:6:6:6:13 | Source4 | provenance | | +| test.ps1:1:14:1:15 | a | test.ps1:2:10:2:11 | a | provenance | | | test.ps1:5:6:5:15 | Call to Source | test.ps1:6:5:6:6 | x | provenance | | -| test.ps1:6:5:6:6 | x | test.ps1:1:18:3:1 | a | provenance | | -| test.ps1:8:32:12:1 | x | test.ps1:9:10:9:11 | x | provenance | | -| test.ps1:8:32:12:1 | y | test.ps1:10:10:10:11 | y | provenance | | -| test.ps1:8:32:12:1 | z | test.ps1:11:10:11:11 | z | provenance | | +| test.ps1:6:5:6:6 | x | test.ps1:1:14:1:15 | a | provenance | | +| test.ps1:8:20:8:21 | x | test.ps1:9:10:9:11 | x | provenance | | +| test.ps1:8:24:8:25 | y | test.ps1:10:10:10:11 | y | provenance | | +| test.ps1:8:28:8:29 | z | test.ps1:11:10:11:11 | z | provenance | | | test.ps1:14:10:14:19 | Call to Source | test.ps1:18:11:18:16 | first | provenance | | | test.ps1:14:10:14:19 | Call to Source | test.ps1:19:22:19:27 | first | provenance | | | test.ps1:14:10:14:19 | Call to Source | test.ps1:20:14:20:19 | first | provenance | | @@ -76,91 +76,91 @@ edges | test.ps1:16:10:16:19 | Call to Source | test.ps1:37:14:37:19 | third | provenance | | | test.ps1:16:10:16:19 | Call to Source | test.ps1:38:14:38:19 | third | provenance | | | test.ps1:16:10:16:19 | Call to Source | test.ps1:39:14:39:19 | third | provenance | | -| test.ps1:18:11:18:16 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:18:18:18:24 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:18:26:18:31 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:19:11:19:17 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:19:22:19:27 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:19:29:19:34 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:20:14:20:19 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:20:21:20:27 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:20:29:20:34 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:21:11:21:16 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:21:21:21:27 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:21:29:21:34 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:22:14:22:20 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:22:22:22:27 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:22:29:22:34 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:23:11:23:17 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:23:22:23:27 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:23:32:23:37 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:24:14:24:19 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:24:21:24:27 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:24:32:24:37 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:25:11:25:16 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:25:21:25:27 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:25:32:25:37 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:26:14:26:20 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:26:22:26:27 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:26:32:26:37 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:27:11:27:17 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:27:22:27:27 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:27:32:27:37 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:28:14:28:19 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:28:24:28:29 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:28:31:28:37 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:29:11:29:16 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:29:21:29:27 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:29:32:29:37 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:30:14:30:20 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:30:25:30:30 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:30:32:30:37 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:31:11:31:17 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:31:22:31:27 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:31:32:31:37 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:32:14:32:19 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:32:24:32:29 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:32:31:32:37 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:33:11:33:16 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:33:21:33:26 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:33:31:33:37 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:34:14:34:20 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:34:25:34:30 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:34:32:34:37 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:35:14:35:19 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:35:24:35:30 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:35:32:35:37 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:36:14:36:19 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:36:21:36:27 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:36:32:36:37 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:37:14:37:19 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:37:24:37:29 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:37:31:37:37 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:38:14:38:19 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:38:21:38:26 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:38:31:38:37 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:39:14:39:19 | third | test.ps1:8:32:12:1 | z | provenance | | -| test.ps1:39:24:39:30 | second | test.ps1:8:32:12:1 | y | provenance | | -| test.ps1:39:32:39:37 | first | test.ps1:8:32:12:1 | x | provenance | | -| test.ps1:42:1:45:1 | UserInput | test.ps1:44:10:44:19 | UserInput | provenance | | +| test.ps1:18:11:18:16 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:18:18:18:24 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:18:26:18:31 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:19:11:19:17 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:19:22:19:27 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:19:29:19:34 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:20:14:20:19 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:20:21:20:27 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:20:29:20:34 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:21:11:21:16 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:21:21:21:27 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:21:29:21:34 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:22:14:22:20 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:22:22:22:27 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:22:29:22:34 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:23:11:23:17 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:23:22:23:27 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:23:32:23:37 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:24:14:24:19 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:24:21:24:27 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:24:32:24:37 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:25:11:25:16 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:25:21:25:27 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:25:32:25:37 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:26:14:26:20 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:26:22:26:27 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:26:32:26:37 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:27:11:27:17 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:27:22:27:27 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:27:32:27:37 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:28:14:28:19 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:28:24:28:29 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:28:31:28:37 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:29:11:29:16 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:29:21:29:27 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:29:32:29:37 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:30:14:30:20 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:30:25:30:30 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:30:32:30:37 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:31:11:31:17 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:31:22:31:27 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:31:32:31:37 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:32:14:32:19 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:32:24:32:29 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:32:31:32:37 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:33:11:33:16 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:33:21:33:26 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:33:31:33:37 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:34:14:34:20 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:34:25:34:30 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:34:32:34:37 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:35:14:35:19 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:35:24:35:30 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:35:32:35:37 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:36:14:36:19 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:36:21:36:27 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:36:32:36:37 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:37:14:37:19 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:37:24:37:29 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:37:31:37:37 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:38:14:38:19 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:38:21:38:26 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:38:31:38:37 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:39:14:39:19 | third | test.ps1:8:28:8:29 | z | provenance | | +| test.ps1:39:24:39:30 | second | test.ps1:8:24:8:25 | y | provenance | | +| test.ps1:39:32:39:37 | first | test.ps1:8:20:8:21 | x | provenance | | +| test.ps1:43:11:43:20 | UserInput | test.ps1:44:10:44:19 | UserInput | provenance | | | test.ps1:47:10:47:19 | Call to Source | test.ps1:48:46:48:51 | input | provenance | | -| test.ps1:48:46:48:51 | input | test.ps1:42:1:45:1 | UserInput | provenance | | +| test.ps1:48:46:48:51 | input | test.ps1:43:11:43:20 | UserInput | provenance | | nodes -| global.ps1:1:1:6:32 | Source1 | semmle.label | Source1 | -| global.ps1:1:1:6:32 | Source2 | semmle.label | Source2 | -| global.ps1:1:1:6:32 | Source3 | semmle.label | Source3 | -| global.ps1:1:1:6:32 | Source4 | semmle.label | Source4 | +| global.ps1:1:7:1:22 | Source1 | semmle.label | Source1 | +| global.ps1:1:25:1:40 | Source2 | semmle.label | Source2 | +| global.ps1:1:43:1:58 | Source3 | semmle.label | Source3 | +| global.ps1:1:61:1:76 | Source4 | semmle.label | Source4 | | global.ps1:3:6:3:13 | Source1 | semmle.label | Source1 | | global.ps1:4:6:4:13 | Source2 | semmle.label | Source2 | | global.ps1:5:6:5:13 | Source3 | semmle.label | Source3 | | global.ps1:6:6:6:13 | Source4 | semmle.label | Source4 | -| test.ps1:1:18:3:1 | a | semmle.label | a | +| test.ps1:1:14:1:15 | a | semmle.label | a | | test.ps1:2:10:2:11 | a | semmle.label | a | | test.ps1:5:6:5:15 | Call to Source | semmle.label | Call to Source | | test.ps1:6:5:6:6 | x | semmle.label | x | -| test.ps1:8:32:12:1 | x | semmle.label | x | -| test.ps1:8:32:12:1 | y | semmle.label | y | -| test.ps1:8:32:12:1 | z | semmle.label | z | +| test.ps1:8:20:8:21 | x | semmle.label | x | +| test.ps1:8:24:8:25 | y | semmle.label | y | +| test.ps1:8:28:8:29 | z | semmle.label | z | | test.ps1:9:10:9:11 | x | semmle.label | x | | test.ps1:10:10:10:11 | y | semmle.label | y | | test.ps1:11:10:11:11 | z | semmle.label | z | @@ -233,17 +233,17 @@ nodes | test.ps1:39:14:39:19 | third | semmle.label | third | | test.ps1:39:24:39:30 | second | semmle.label | second | | test.ps1:39:32:39:37 | first | semmle.label | first | -| test.ps1:42:1:45:1 | UserInput | semmle.label | UserInput | +| test.ps1:43:11:43:20 | UserInput | semmle.label | UserInput | | test.ps1:44:10:44:19 | UserInput | semmle.label | UserInput | | test.ps1:47:10:47:19 | Call to Source | semmle.label | Call to Source | | test.ps1:48:46:48:51 | input | semmle.label | input | subpaths testFailures #select -| global.ps1:3:6:3:13 | Source1 | global.ps1:1:1:6:32 | Source1 | global.ps1:3:6:3:13 | Source1 | $@ | global.ps1:1:1:6:32 | Source1 | Source1 | -| global.ps1:4:6:4:13 | Source2 | global.ps1:1:1:6:32 | Source2 | global.ps1:4:6:4:13 | Source2 | $@ | global.ps1:1:1:6:32 | Source2 | Source2 | -| global.ps1:5:6:5:13 | Source3 | global.ps1:1:1:6:32 | Source3 | global.ps1:5:6:5:13 | Source3 | $@ | global.ps1:1:1:6:32 | Source3 | Source3 | -| global.ps1:6:6:6:13 | Source4 | global.ps1:1:1:6:32 | Source4 | global.ps1:6:6:6:13 | Source4 | $@ | global.ps1:1:1:6:32 | Source4 | Source4 | +| global.ps1:3:6:3:13 | Source1 | global.ps1:1:7:1:22 | Source1 | global.ps1:3:6:3:13 | Source1 | $@ | global.ps1:1:7:1:22 | Source1 | Source1 | +| global.ps1:4:6:4:13 | Source2 | global.ps1:1:25:1:40 | Source2 | global.ps1:4:6:4:13 | Source2 | $@ | global.ps1:1:25:1:40 | Source2 | Source2 | +| global.ps1:5:6:5:13 | Source3 | global.ps1:1:43:1:58 | Source3 | global.ps1:5:6:5:13 | Source3 | $@ | global.ps1:1:43:1:58 | Source3 | Source3 | +| global.ps1:6:6:6:13 | Source4 | global.ps1:1:61:1:76 | Source4 | global.ps1:6:6:6:13 | Source4 | $@ | global.ps1:1:61:1:76 | Source4 | Source4 | | test.ps1:2:10:2:11 | a | test.ps1:5:6:5:15 | Call to Source | test.ps1:2:10:2:11 | a | $@ | test.ps1:5:6:5:15 | Call to Source | Call to Source | | test.ps1:9:10:9:11 | x | test.ps1:14:10:14:19 | Call to Source | test.ps1:9:10:9:11 | x | $@ | test.ps1:14:10:14:19 | Call to Source | Call to Source | | test.ps1:10:10:10:11 | y | test.ps1:15:11:15:20 | Call to Source | test.ps1:10:10:10:11 | y | $@ | test.ps1:15:11:15:20 | Call to Source | Call to Source | diff --git a/powershell/ql/test/library-tests/dataflow/pipeline/test.expected b/powershell/ql/test/library-tests/dataflow/pipeline/test.expected index b94675c879d6..b80489a6fae6 100644 --- a/powershell/ql/test/library-tests/dataflow/pipeline/test.expected +++ b/powershell/ql/test/library-tests/dataflow/pipeline/test.expected @@ -6,18 +6,18 @@ edges | test.ps1:5:5:5:6 | x | test.ps1:17:1:17:7 | Call to produce [unknown index] | provenance | | | test.ps1:6:5:6:6 | y | test.ps1:17:1:17:7 | Call to produce [unknown index] | provenance | | | test.ps1:6:9:6:10 | z | test.ps1:17:1:17:7 | Call to produce [unknown index] | provenance | | -| test.ps1:9:29:15:1 | [synth] pipeline [element 0] | test.ps1:12:5:14:5 | [synth] pipeline [element 0] | provenance | | -| test.ps1:9:29:15:1 | [synth] pipeline [element 1] | test.ps1:12:5:14:5 | [synth] pipeline [element 1] | provenance | | -| test.ps1:9:29:15:1 | [synth] pipeline [unknown index] | test.ps1:12:5:14:5 | [synth] pipeline [unknown index] | provenance | | -| test.ps1:12:5:14:5 | [synth] pipeline [element 0] | test.ps1:13:9:13:15 | __pipeline_iterator | provenance | | -| test.ps1:12:5:14:5 | [synth] pipeline [element 1] | test.ps1:13:9:13:15 | __pipeline_iterator | provenance | | -| test.ps1:12:5:14:5 | [synth] pipeline [unknown index] | test.ps1:13:9:13:15 | __pipeline_iterator | provenance | | -| test.ps1:17:1:17:7 | Call to produce [unknown index] | test.ps1:9:29:15:1 | [synth] pipeline [unknown index] | provenance | | +| test.ps1:10:11:10:43 | x [element 0] | test.ps1:12:5:14:5 | x [element 0] | provenance | | +| test.ps1:10:11:10:43 | x [element 1] | test.ps1:12:5:14:5 | x [element 1] | provenance | | +| test.ps1:10:11:10:43 | x [unknown index] | test.ps1:12:5:14:5 | x [unknown index] | provenance | | +| test.ps1:12:5:14:5 | x [element 0] | test.ps1:13:9:13:15 | __pipeline_iterator | provenance | | +| test.ps1:12:5:14:5 | x [element 1] | test.ps1:13:9:13:15 | __pipeline_iterator | provenance | | +| test.ps1:12:5:14:5 | x [unknown index] | test.ps1:13:9:13:15 | __pipeline_iterator | provenance | | +| test.ps1:17:1:17:7 | Call to produce [unknown index] | test.ps1:10:11:10:43 | x [unknown index] | provenance | | | test.ps1:19:6:19:15 | Call to Source | test.ps1:21:1:21:2 | x | provenance | | | test.ps1:20:6:20:15 | Call to Source | test.ps1:21:5:21:6 | y | provenance | | | test.ps1:21:1:21:2 | x | test.ps1:21:1:21:6 | ...,... [element 0] | provenance | | -| test.ps1:21:1:21:6 | ...,... [element 0] | test.ps1:9:29:15:1 | [synth] pipeline [element 0] | provenance | | -| test.ps1:21:1:21:6 | ...,... [element 1] | test.ps1:9:29:15:1 | [synth] pipeline [element 1] | provenance | | +| test.ps1:21:1:21:6 | ...,... [element 0] | test.ps1:10:11:10:43 | x [element 0] | provenance | | +| test.ps1:21:1:21:6 | ...,... [element 1] | test.ps1:10:11:10:43 | x [element 1] | provenance | | | test.ps1:21:5:21:6 | y | test.ps1:21:1:21:6 | ...,... [element 1] | provenance | | | test.ps1:23:38:27:1 | [synth] pipeline [element 0] | test.ps1:24:5:26:5 | [synth] pipeline [element 0] | provenance | | | test.ps1:23:38:27:1 | [synth] pipeline [element 1] | test.ps1:24:5:26:5 | [synth] pipeline [element 1] | provenance | | @@ -29,16 +29,16 @@ edges | test.ps1:31:1:31:6 | ...,... [element 0] | test.ps1:23:38:27:1 | [synth] pipeline [element 0] | provenance | | | test.ps1:31:1:31:6 | ...,... [element 1] | test.ps1:23:38:27:1 | [synth] pipeline [element 1] | provenance | | | test.ps1:31:5:31:6 | y | test.ps1:31:1:31:6 | ...,... [element 1] | provenance | | -| test.ps1:42:60:48:1 | x [element 0, element x] | test.ps1:45:5:47:5 | x [element 0, element x] | provenance | | -| test.ps1:42:60:48:1 | x [element 1, element x] | test.ps1:45:5:47:5 | x [element 1, element x] | provenance | | -| test.ps1:42:60:48:1 | x [element 2, element x] | test.ps1:45:5:47:5 | x [element 2, element x] | provenance | | +| test.ps1:43:11:43:57 | x [element 0, element x] | test.ps1:45:5:47:5 | x [element 0, element x] | provenance | | +| test.ps1:43:11:43:57 | x [element 1, element x] | test.ps1:45:5:47:5 | x [element 1, element x] | provenance | | +| test.ps1:43:11:43:57 | x [element 2, element x] | test.ps1:45:5:47:5 | x [element 2, element x] | provenance | | | test.ps1:45:5:47:5 | x [element 0, element x] | test.ps1:46:9:46:15 | __pipeline_iterator for x | provenance | | | test.ps1:45:5:47:5 | x [element 1, element x] | test.ps1:46:9:46:15 | __pipeline_iterator for x | provenance | | | test.ps1:45:5:47:5 | x [element 2, element x] | test.ps1:46:9:46:15 | __pipeline_iterator for x | provenance | | | test.ps1:50:1:50:33 | [...]... [element x] | test.ps1:50:1:50:105 | ...,... [element 0, element x] | provenance | | -| test.ps1:50:1:50:105 | ...,... [element 0, element x] | test.ps1:42:60:48:1 | x [element 0, element x] | provenance | | -| test.ps1:50:1:50:105 | ...,... [element 1, element x] | test.ps1:42:60:48:1 | x [element 1, element x] | provenance | | -| test.ps1:50:1:50:105 | ...,... [element 2, element x] | test.ps1:42:60:48:1 | x [element 2, element x] | provenance | | +| test.ps1:50:1:50:105 | ...,... [element 0, element x] | test.ps1:43:11:43:57 | x [element 0, element x] | provenance | | +| test.ps1:50:1:50:105 | ...,... [element 1, element x] | test.ps1:43:11:43:57 | x [element 1, element x] | provenance | | +| test.ps1:50:1:50:105 | ...,... [element 2, element x] | test.ps1:43:11:43:57 | x [element 2, element x] | provenance | | | test.ps1:50:17:50:33 | ${...} [element x] | test.ps1:50:1:50:33 | [...]... [element x] | provenance | | | test.ps1:50:23:50:32 | Call to Source | test.ps1:50:17:50:33 | ${...} [element x] | provenance | | | test.ps1:50:36:50:69 | [...]... [element x] | test.ps1:50:1:50:105 | ...,... [element 1, element x] | provenance | | @@ -54,12 +54,12 @@ nodes | test.ps1:5:5:5:6 | x | semmle.label | x | | test.ps1:6:5:6:6 | y | semmle.label | y | | test.ps1:6:9:6:10 | z | semmle.label | z | -| test.ps1:9:29:15:1 | [synth] pipeline [element 0] | semmle.label | [synth] pipeline [element 0] | -| test.ps1:9:29:15:1 | [synth] pipeline [element 1] | semmle.label | [synth] pipeline [element 1] | -| test.ps1:9:29:15:1 | [synth] pipeline [unknown index] | semmle.label | [synth] pipeline [unknown index] | -| test.ps1:12:5:14:5 | [synth] pipeline [element 0] | semmle.label | [synth] pipeline [element 0] | -| test.ps1:12:5:14:5 | [synth] pipeline [element 1] | semmle.label | [synth] pipeline [element 1] | -| test.ps1:12:5:14:5 | [synth] pipeline [unknown index] | semmle.label | [synth] pipeline [unknown index] | +| test.ps1:10:11:10:43 | x [element 0] | semmle.label | x [element 0] | +| test.ps1:10:11:10:43 | x [element 1] | semmle.label | x [element 1] | +| test.ps1:10:11:10:43 | x [unknown index] | semmle.label | x [unknown index] | +| test.ps1:12:5:14:5 | x [element 0] | semmle.label | x [element 0] | +| test.ps1:12:5:14:5 | x [element 1] | semmle.label | x [element 1] | +| test.ps1:12:5:14:5 | x [unknown index] | semmle.label | x [unknown index] | | test.ps1:13:9:13:15 | __pipeline_iterator | semmle.label | __pipeline_iterator | | test.ps1:17:1:17:7 | Call to produce [unknown index] | semmle.label | Call to produce [unknown index] | | test.ps1:19:6:19:15 | Call to Source | semmle.label | Call to Source | @@ -79,9 +79,9 @@ nodes | test.ps1:31:1:31:6 | ...,... [element 0] | semmle.label | ...,... [element 0] | | test.ps1:31:1:31:6 | ...,... [element 1] | semmle.label | ...,... [element 1] | | test.ps1:31:5:31:6 | y | semmle.label | y | -| test.ps1:42:60:48:1 | x [element 0, element x] | semmle.label | x [element 0, element x] | -| test.ps1:42:60:48:1 | x [element 1, element x] | semmle.label | x [element 1, element x] | -| test.ps1:42:60:48:1 | x [element 2, element x] | semmle.label | x [element 2, element x] | +| test.ps1:43:11:43:57 | x [element 0, element x] | semmle.label | x [element 0, element x] | +| test.ps1:43:11:43:57 | x [element 1, element x] | semmle.label | x [element 1, element x] | +| test.ps1:43:11:43:57 | x [element 2, element x] | semmle.label | x [element 2, element x] | | test.ps1:45:5:47:5 | x [element 0, element x] | semmle.label | x [element 0, element x] | | test.ps1:45:5:47:5 | x [element 1, element x] | semmle.label | x [element 1, element x] | | test.ps1:45:5:47:5 | x [element 2, element x] | semmle.label | x [element 2, element x] | diff --git a/powershell/ql/test/library-tests/ssa/ssa.expected b/powershell/ql/test/library-tests/ssa/ssa.expected index b7615522d8ed..dbf962aea84d 100644 --- a/powershell/ql/test/library-tests/ssa/ssa.expected +++ b/powershell/ql/test/library-tests/ssa/ssa.expected @@ -1,6 +1,6 @@ | explicit.ps1:5:5:5:6 | a | explicit.ps1:5:5:5:6 | a | | explicit.ps1:6:5:6:6 | b | explicit.ps1:6:5:6:6 | b | -| parameters.ps1:1:45:3:1 | n1 | parameters.ps1:1:45:3:1 | n1 | -| parameters.ps1:1:45:3:1 | n2 | parameters.ps1:1:45:3:1 | n2 | -| parameters.ps1:5:22:11:1 | a | parameters.ps1:5:22:11:1 | a | -| parameters.ps1:5:22:11:1 | b | parameters.ps1:5:22:11:1 | b | +| parameters.ps1:1:25:1:32 | n1 | parameters.ps1:1:25:1:32 | n1 | +| parameters.ps1:1:35:1:42 | n2 | parameters.ps1:1:35:1:42 | n2 | +| parameters.ps1:7:9:7:15 | a | parameters.ps1:7:9:7:15 | a | +| parameters.ps1:8:9:8:15 | b | parameters.ps1:8:9:8:15 | b |