mirror of
https://github.com/github/codeql.git
synced 2026-05-25 00:27:09 +02:00
Merge branch 'main' of https://github.com/microsoft/codeql into powershell-injectionhunter-port
This commit is contained in:
@@ -33,11 +33,14 @@ newtype ChildIndex =
|
||||
} or
|
||||
ThisVar() or
|
||||
PipelineParamVar() or
|
||||
// PipelineByPropertNameVar(Raw::PipelineByPropertyNameParameter p) or
|
||||
PipelineByPropertyNameVar(Raw::PipelineByPropertyNameParameter p) or
|
||||
PipelineIteratorVar() or
|
||||
PipelineByPropertyNameIteratorVar(Raw::PipelineByPropertyNameParameter p) or
|
||||
RealVar(string name) { name = variableNameInScope(_, _) } or
|
||||
ProcessBlockPipelineVarReadAccess()
|
||||
ProcessBlockPipelineVarReadAccess() or
|
||||
ProcessBlockPipelineByPropertyNameVarReadAccess(string name) {
|
||||
name = any(Raw::PipelineByPropertyNameParameter p).getName()
|
||||
}
|
||||
|
||||
int synthPipelineParameterChildIndex(Raw::ScriptBlock sb) {
|
||||
// If there is a parameter block, but no pipeline parameter
|
||||
@@ -340,3 +343,7 @@ ChildIndex whileStmtCond() { result = RawChildIndex(Raw::WhileStmtCond()) }
|
||||
ChildIndex whileStmtBody() { result = RawChildIndex(Raw::WhileStmtBody()) }
|
||||
|
||||
ChildIndex processBlockPipelineVarReadAccess() { result = ProcessBlockPipelineVarReadAccess() }
|
||||
|
||||
ChildIndex processBlockPipelineByPropertyNameVarReadAccess(string name) {
|
||||
result = ProcessBlockPipelineByPropertyNameVarReadAccess(name)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,20 @@ class ProcessBlock extends NamedBlock {
|
||||
synthChild(getRawAst(this), processBlockPipelineVarReadAccess(), result)
|
||||
}
|
||||
|
||||
PipelineByPropertyNameParameter getPipelineByPropertyNameParameter(string name) {
|
||||
result = scriptBlock.getAParameter() and
|
||||
result.getPropertyName() = name
|
||||
}
|
||||
|
||||
PipelineByPropertyNameParameter getAPipelineByPropertyNameParameter() {
|
||||
result = scriptBlock.getEnclosingFunction().getAParameter()
|
||||
result = this.getPipelineByPropertyNameParameter(_)
|
||||
}
|
||||
|
||||
VarReadAccess getPipelineByPropertyNameParameterAccess(string name) {
|
||||
synthChild(getRawAst(this), processBlockPipelineByPropertyNameVarReadAccess(name), result)
|
||||
}
|
||||
|
||||
VarReadAccess getAPipelineByPropertyNameParameterAccess() {
|
||||
result = this.getPipelineByPropertyNameParameterAccess(_)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,7 +615,7 @@ private module LiteralSynth {
|
||||
|
||||
/**
|
||||
* Holds if `va` is an access to the automatic variable named `name`.
|
||||
*
|
||||
*
|
||||
* Unlike `Raw::isAutomaticVariableAccess`, this predicate also checks for
|
||||
* shadowing.
|
||||
*/
|
||||
@@ -770,6 +770,13 @@ private module IteratorAccessSynth {
|
||||
or
|
||||
va.getUserPath().toLowerCase() =
|
||||
pb.getScriptBlock().getParamBlock().getPipelineParameter().getName().toLowerCase()
|
||||
or
|
||||
va.getUserPath().toLowerCase() =
|
||||
pb.getScriptBlock()
|
||||
.getParamBlock()
|
||||
.getAPipelineByPropertyNameParameter()
|
||||
.getName()
|
||||
.toLowerCase()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -867,12 +874,19 @@ private module PipelineAccess {
|
||||
pipelineVar = TVariableSynth(pb.getScriptBlock(), PipelineParamVar()) and
|
||||
child = SynthChild(VarAccessSynthKind(pipelineVar))
|
||||
)
|
||||
or
|
||||
exists(PipelineByPropertyNameVariable pipelineVar, Raw::PipelineByPropertyNameParameter p |
|
||||
i = processBlockPipelineByPropertyNameVarReadAccess(p.getName()) and
|
||||
getResultAst(p) = pipelineVar and
|
||||
child = SynthChild(VarAccessSynthKind(pipelineVar))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
final override Location getLocation(Ast n) {
|
||||
exists(ProcessBlock pb |
|
||||
pb.getPipelineParameterAccess() = n and
|
||||
pb.getPipelineParameterAccess() = n or pb.getAPipelineByPropertyNameParameterAccess() = n
|
||||
|
|
||||
result = pb.getLocation()
|
||||
)
|
||||
}
|
||||
@@ -881,6 +895,23 @@ private module PipelineAccess {
|
||||
exists(ProcessBlock pb |
|
||||
pb.getPipelineParameterAccess() = va and
|
||||
v = pb.getPipelineParameter()
|
||||
or
|
||||
exists(string name |
|
||||
pb.getPipelineByPropertyNameParameterAccess(name) = va and
|
||||
v = pb.getPipelineByPropertyNameParameter(name)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private module ImplicitAssignmentInForEach {
|
||||
private class ForEachAssignment extends Synthesis {
|
||||
override predicate implicitAssignment(Raw::Ast dest, string name) {
|
||||
exists(Raw::ForEachStmt forEach, Raw::VarAccess va |
|
||||
va = forEach.getVarAccess() and
|
||||
va = dest and
|
||||
va.getUserPath() = name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,9 @@ module Private {
|
||||
|
||||
class ParameterImpl extends VariableSynth {
|
||||
ParameterImpl() {
|
||||
i instanceof FunParam or i instanceof PipelineParamVar or i instanceof ThisVar
|
||||
i instanceof FunParam or
|
||||
i instanceof PipelineParamVar or
|
||||
i instanceof ThisVar
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +61,14 @@ module Private {
|
||||
ScriptBlock getScriptBlock() { this = TVariableSynth(getRawAst(result), _) }
|
||||
}
|
||||
|
||||
class PipelineByPropertyNameVariableImpl extends ParameterImpl {
|
||||
PipelineByPropertyNameVariableImpl() {
|
||||
getRawAst(this) instanceof Raw::PipelineByPropertyNameParameter
|
||||
}
|
||||
|
||||
ScriptBlock getScriptBlock() { this = TVariableSynth(getRawAst(result), _) }
|
||||
}
|
||||
|
||||
class PipelineIteratorVariableImpl extends VariableSynth {
|
||||
override PipelineIteratorVar i;
|
||||
|
||||
@@ -171,6 +181,11 @@ module Public {
|
||||
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() }
|
||||
}
|
||||
|
||||
@@ -277,6 +277,8 @@ private class ProcessBlockChildMapping extends NamedBlockChildMapping, ProcessBl
|
||||
super.relevantChild(child)
|
||||
or
|
||||
child = super.getPipelineParameterAccess()
|
||||
or
|
||||
child = super.getAPipelineByPropertyNameParameterAccess()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +302,23 @@ class ProcessBlockCfgNode extends NamedBlockCfgNode {
|
||||
PipelineIteratorVariable getPipelineIteratorVariable() {
|
||||
result.getProcessBlock().getScriptBlock() = this.getScriptBlock().getAstNode()
|
||||
}
|
||||
|
||||
PipelineByPropertyNameIteratorVariable getPipelineBypropertyNameIteratorVariable(string name) {
|
||||
result.getPropertyName() = name and
|
||||
result.getProcessBlock().getScriptBlock() = this.getScriptBlock().getAstNode()
|
||||
}
|
||||
|
||||
PipelineByPropertyNameIteratorVariable getAPipelineBypropertyNameIteratorVariable() {
|
||||
result = this.getPipelineBypropertyNameIteratorVariable(_)
|
||||
}
|
||||
|
||||
ExprNodes::VarReadAccessCfgNode getPipelineByPropertyNameParameterAccess(string name) {
|
||||
block.hasCfgChild(block.getPipelineByPropertyNameParameterAccess(name), this, result)
|
||||
}
|
||||
|
||||
ExprNodes::VarReadAccessCfgNode getAPipelineByPropertyNameParameterAccess() {
|
||||
result = this.getPipelineByPropertyNameParameterAccess(_)
|
||||
}
|
||||
}
|
||||
|
||||
private class CatchClauseChildMapping extends NonExprChildMapping, CatchClause {
|
||||
|
||||
@@ -188,7 +188,11 @@ private predicate inMatchingContext(Ast n) {
|
||||
* Holds if a normal completion of `cfe` must be an emptiness completion. Thats is,
|
||||
* whether `cfe` determines whether to execute the body of a `foreach` statement.
|
||||
*/
|
||||
private predicate mustHaveEmptinessCompletion(Ast n) { n instanceof ForEachStmt }
|
||||
private predicate mustHaveEmptinessCompletion(Ast n) {
|
||||
n instanceof ForEachStmt
|
||||
or
|
||||
any(CfgImpl::Trees::ProcessBlockTree pbtree).lastEmptinessCheck(n)
|
||||
}
|
||||
|
||||
/**
|
||||
* A completion that represents normal evaluation of a statement or an
|
||||
|
||||
@@ -221,13 +221,7 @@ module Trees {
|
||||
or
|
||||
last(super.getProcessBlock(), pred, c) and
|
||||
completionIsNormal(c) and
|
||||
(
|
||||
// If we process multiple items we will loop back to the process block
|
||||
first(super.getProcessBlock(), succ)
|
||||
or
|
||||
// Once we're done process all items we will go to the end block
|
||||
first(super.getEndBlock(), succ)
|
||||
)
|
||||
first(super.getEndBlock(), succ)
|
||||
}
|
||||
|
||||
final override predicate propagatesAbnormal(AstNode child) {
|
||||
@@ -292,25 +286,17 @@ module Trees {
|
||||
final override predicate succEntry(Ast n, Completion c) { n = this and completionIsSimple(c) }
|
||||
}
|
||||
|
||||
abstract class NamedBlockTreeBase extends ControlFlowTree instanceof NamedBlock {
|
||||
final override predicate last(Ast last, Completion c) {
|
||||
abstract class NamedBlockTreeBase extends PreOrderTree instanceof NamedBlock {
|
||||
override predicate last(Ast last, Completion c) {
|
||||
exists(int i | last(super.getStmt(i), last, c) |
|
||||
completionIsNormal(c) and
|
||||
not exists(super.getStmt(i + 1))
|
||||
or
|
||||
not completionIsNormal(c)
|
||||
)
|
||||
or
|
||||
not exists(super.getAStmt()) and
|
||||
completionIsSimple(c) and
|
||||
last = this
|
||||
}
|
||||
|
||||
override predicate succ(Ast pred, Ast succ, Completion c) {
|
||||
pred = this and
|
||||
completionIsSimple(c) and
|
||||
first(super.getStmt(0), succ)
|
||||
or
|
||||
exists(int i |
|
||||
last(super.getStmt(i), pred, c) and
|
||||
completionIsNormal(c) and
|
||||
@@ -324,20 +310,85 @@ module Trees {
|
||||
class NamedBlockTree extends NamedBlockTreeBase instanceof NamedBlock {
|
||||
NamedBlockTree() { not this instanceof ProcessBlock }
|
||||
|
||||
final override predicate first(Ast first) { first = this }
|
||||
final override predicate last(Ast last, Completion c) {
|
||||
super.last(last, c)
|
||||
or
|
||||
not exists(super.getAStmt()) and
|
||||
completionIsSimple(c) and
|
||||
last = this
|
||||
}
|
||||
|
||||
final override predicate succ(Ast pred, Ast succ, Completion c) {
|
||||
pred = this and
|
||||
completionIsSimple(c) and
|
||||
first(super.getStmt(0), succ)
|
||||
or
|
||||
super.succ(pred, succ, c)
|
||||
}
|
||||
|
||||
final override predicate propagatesAbnormal(Ast child) { super.propagatesAbnormal(child) }
|
||||
}
|
||||
|
||||
private VarAccess getRankedPipelineByPropertyNameVariable(ProcessBlock pb, int i) {
|
||||
result =
|
||||
rank[i + 1](string name | | pb.getPipelineByPropertyNameParameterAccess(name) order by name)
|
||||
}
|
||||
|
||||
class ProcessBlockTree extends NamedBlockTreeBase instanceof ProcessBlock {
|
||||
final override predicate first(Ast first) { first = super.getPipelineParameterAccess() }
|
||||
predicate lastEmptinessCheck(AstNode last) {
|
||||
last = super.getPipelineParameterAccess() and
|
||||
not exists(super.getAPipelineByPropertyNameParameterAccess())
|
||||
or
|
||||
exists(int i |
|
||||
last = getRankedPipelineByPropertyNameVariable(this, i) and
|
||||
not exists(getRankedPipelineByPropertyNameVariable(this, i + 1))
|
||||
)
|
||||
}
|
||||
|
||||
private predicate succEmptinessCheck(AstNode pred, AstNode succ, Completion c) {
|
||||
last(super.getPipelineParameterAccess(), pred, c) and
|
||||
first(getRankedPipelineByPropertyNameVariable(this, 0), succ)
|
||||
or
|
||||
exists(int i |
|
||||
last(getRankedPipelineByPropertyNameVariable(this, i), pred, c) and
|
||||
first(getRankedPipelineByPropertyNameVariable(this, i + 1), succ)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate firstEmptinessCheck(AstNode first) {
|
||||
first(super.getPipelineParameterAccess(), first)
|
||||
}
|
||||
|
||||
final override predicate last(AstNode last, Completion c) {
|
||||
// Emptiness test exits with no more elements
|
||||
this.lastEmptinessCheck(last) and
|
||||
c.(EmptinessCompletion).isEmpty()
|
||||
or
|
||||
super.last(last, c)
|
||||
}
|
||||
|
||||
final override predicate succ(Ast pred, Ast succ, Completion c) {
|
||||
this.first(pred) and
|
||||
completionIsSimple(c) and
|
||||
succ = this
|
||||
// Evaluate the pipeline access
|
||||
pred = this and
|
||||
this.firstEmptinessCheck(succ) and
|
||||
completionIsSimple(c)
|
||||
or
|
||||
this.succEmptinessCheck(pred, succ, c)
|
||||
or
|
||||
this.lastEmptinessCheck(pred) and
|
||||
c = any(EmptinessCompletion ec | not ec.isEmpty()) and
|
||||
first(super.getStmt(0), succ)
|
||||
or
|
||||
super.succ(pred, succ, c)
|
||||
or
|
||||
// Body to emptiness test
|
||||
exists(Ast last0 |
|
||||
super.last(last0, _) and
|
||||
last(last0, pred, c) and
|
||||
// TODO: I don't think this correctly models the semantics inside process blocks
|
||||
c.continuesLoop()
|
||||
) and
|
||||
this.firstEmptinessCheck(succ)
|
||||
}
|
||||
|
||||
final override predicate propagatesAbnormal(Ast child) { super.propagatesAbnormal(child) }
|
||||
|
||||
@@ -158,7 +158,7 @@ module Ssa {
|
||||
not exists(this.getSplitString()) and
|
||||
prefix = ""
|
||||
|
|
||||
result = prefix + "phi"
|
||||
result = prefix + "phi (" + this.getSourceVariable() + ")"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@ module SsaFlow {
|
||||
result = TThisParameterNode(p.asThis())
|
||||
or
|
||||
result = TPipelineParameterNode(p.asPipelineParameter())
|
||||
or
|
||||
result = TPipelineByPropertyNameParameterNode(p.asPipelineByPropertyNameParameter())
|
||||
}
|
||||
|
||||
/** Gets the SSA node corresponding to the PowerShell node `n`. */
|
||||
@@ -83,6 +85,16 @@ module SsaFlow {
|
||||
.definesAt(pb.getPipelineIteratorVariable(), bb, i)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
BasicBlock bb, int i, PipelineByPropertyNameParameter p, ProcessPropertyByNameNode pbNode
|
||||
|
|
||||
pbNode = n and
|
||||
pbNode.hasRead() and
|
||||
pbNode.getParameter() = p and
|
||||
bb.getNode(i) = pbNode.getProcessBlock() and
|
||||
result.(Impl::SsaDefinitionNode).getDefinition().definesAt(p.getIteratorVariable(), bb, i)
|
||||
)
|
||||
or
|
||||
result.(Impl::ExprPostUpdateNode).getExpr() = n.(PostUpdateNode).getPreUpdateNode().asExpr()
|
||||
or
|
||||
n = toParameterNode(result.(Impl::ParameterNode).getParameter())
|
||||
@@ -145,13 +157,16 @@ module LocalFlow {
|
||||
nodeTo.(ReturnNodeImpl).getCfgScope() = scriptBlock.getAstNode()
|
||||
)
|
||||
or
|
||||
exists(CfgNodes::ExprNodes::PipelineArgumentCfgNode e | nodeFrom.asExpr() = e |
|
||||
// If we are not already tracking as element content
|
||||
nodeTo = TPrePipelineArgumentNode(e)
|
||||
or
|
||||
// If we are already tracking an element content
|
||||
nodeTo = TPipelineArgumentNode(e)
|
||||
nodeTo.(PreProcessPropertyByNameNode).getAccess() = nodeFrom.asExpr()
|
||||
or
|
||||
exists(PreProcessPropertyByNameNode pbNode |
|
||||
pbNode = nodeFrom and
|
||||
nodeTo = TProcessPropertyByNameNode(pbNode.getAccess().getVariable(), false)
|
||||
)
|
||||
or
|
||||
nodeTo.(PreProcessNode).getProcessBlock().getPipelineVariableAccess() = nodeFrom.asExpr()
|
||||
or
|
||||
nodeTo.(ProcessNode).getProcessBlock() = nodeFrom.(PreProcessNode).getProcessBlock()
|
||||
}
|
||||
|
||||
predicate flowSummaryLocalStep(
|
||||
@@ -179,12 +194,6 @@ module VariableCapture {
|
||||
// TODO
|
||||
}
|
||||
|
||||
private predicate isProcessPropertyByNameNode(
|
||||
PipelineByPropertyNameIteratorVariable iter, ProcessBlock pb
|
||||
) {
|
||||
pb = iter.getProcessBlock()
|
||||
}
|
||||
|
||||
/** A collection of cached types and predicates to be evaluated in the same stage. */
|
||||
cached
|
||||
private module Cached {
|
||||
@@ -198,8 +207,6 @@ private module Cached {
|
||||
TThisParameterNode(Method m) or
|
||||
TPipelineByPropertyNameParameterNode(PipelineByPropertyNameParameter p) or
|
||||
TPipelineParameterNode(PipelineParameter p) or
|
||||
TPrePipelineArgumentNode(CfgNodes::ExprNodes::PipelineArgumentCfgNode n) or
|
||||
TPipelineArgumentNode(CfgNodes::ExprNodes::PipelineArgumentCfgNode n) or
|
||||
TExprPostUpdateNode(CfgNodes::ExprCfgNode n) {
|
||||
n instanceof CfgNodes::ExprNodes::ArgumentCfgNode
|
||||
or
|
||||
@@ -220,9 +227,13 @@ private module Cached {
|
||||
blockMayReturnMultipleValues(scriptBlock)
|
||||
} or
|
||||
TReturnNodeImpl(CfgScope scope) or
|
||||
TPreProcessNode(CfgNodes::ProcessBlockCfgNode process) or
|
||||
TProcessNode(CfgNodes::ProcessBlockCfgNode process) or
|
||||
TProcessPropertyByNameNode(PipelineByPropertyNameIteratorVariable iter) {
|
||||
isProcessPropertyByNameNode(iter, _)
|
||||
TPreProcessPropertyByNameNode(CfgNodes::ExprNodes::VarReadAccessCfgNode va) {
|
||||
any(CfgNodes::ProcessBlockCfgNode pb).getAPipelineByPropertyNameParameterAccess() = va
|
||||
} or
|
||||
TProcessPropertyByNameNode(PipelineByPropertyNameParameter p, Boolean hasRead) {
|
||||
p.getDeclaringScope() = any(ProcessBlock pb).getScriptBlock()
|
||||
} or
|
||||
TScriptBlockNode(ScriptBlock scriptBlock) or
|
||||
TForbiddenRecursionGuard() {
|
||||
@@ -333,15 +344,13 @@ private module Cached {
|
||||
|
||||
cached
|
||||
newtype TContentSet =
|
||||
TSingletonContent(Content c) or
|
||||
TAnyElementContent() or
|
||||
TKnownOrUnknownElementContent(Content::KnownElementContent c)
|
||||
|
||||
private predicate trackKnownValue(ConstantValue cv) {
|
||||
exists(cv.asString())
|
||||
or
|
||||
cv.asInt() = [0 .. 10]
|
||||
}
|
||||
TSingletonContentSet(Content c) or
|
||||
TAnyElementContentSet() or
|
||||
TAnyPositionalContentSet() or
|
||||
TKnownOrUnknownKeyContentSet(Content::KnownKeyContent c) or
|
||||
TKnownOrUnknownPositionalContentSet(Content::KnownPositionalContent c) or
|
||||
TUnknownPositionalElementContentSet() or
|
||||
TUnknownKeyContentSet()
|
||||
|
||||
cached
|
||||
newtype TContent =
|
||||
@@ -350,20 +359,41 @@ private module Cached {
|
||||
or
|
||||
name = any(MemberExpr me).getMemberName()
|
||||
} or
|
||||
TKnownElementContent(ConstantValue cv) { trackKnownValue(cv) } or
|
||||
TUnknownElementContent()
|
||||
// A known map key
|
||||
TKnownKeyContent(ConstantValue cv) { exists(cv.asString()) } or
|
||||
// A known array index
|
||||
TKnownPositionalContent(ConstantValue cv) { cv.asInt() = [0 .. 10] } or
|
||||
// An unknown key
|
||||
TUnknownKeyContent() or
|
||||
// An unknown positional element
|
||||
TUnknownPositionalContent() or
|
||||
// A unknown position or key - and we dont even know what kind it is
|
||||
TUnknownKeyOrPositionContent()
|
||||
|
||||
cached
|
||||
newtype TContentApprox =
|
||||
// A field
|
||||
TNonElementContentApprox(Content c) { not c instanceof Content::ElementContent } or
|
||||
TUnknownElementContentApprox() or
|
||||
TKnownIntegerElementContentApprox() or
|
||||
TKnownElementContentApprox(string approx) { approx = approxKnownElementIndex(_) }
|
||||
// An unknown key
|
||||
TUnkownKeyContentApprox() or
|
||||
// A known map key
|
||||
TKnownKeyContentApprox(string approx) { approx = approxKnownElementIndex(_) } or
|
||||
// A known positional element
|
||||
TKnownPositionalContentApprox() or
|
||||
// An unknown positional element
|
||||
TUnknownPositionalContentApprox() or
|
||||
TUnknownContentApprox()
|
||||
|
||||
cached
|
||||
newtype TDataFlowType = TUnknownDataFlowType()
|
||||
}
|
||||
|
||||
class TKnownElementContent = TKnownKeyContent or TKnownPositionalContent;
|
||||
|
||||
class TKnownKindContent = TUnknownPositionalContent or TUnknownKeyContent;
|
||||
|
||||
class TUnknownElementContent = TKnownKindContent or TUnknownKeyOrPositionContent;
|
||||
|
||||
class TElementContent = TKnownElementContent or TUnknownElementContent;
|
||||
|
||||
/** Gets a string for approximating known element indices. */
|
||||
@@ -623,10 +653,10 @@ private module ParameterNodes {
|
||||
|
||||
PipelineByPropertyNameParameterNode() { this = TPipelineByPropertyNameParameterNode(parameter) }
|
||||
|
||||
override PipelineParameter getParameter() { result = parameter }
|
||||
override PipelineByPropertyNameParameter getParameter() { result = parameter }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
|
||||
pos.isPipeline() and // what about when it is applied as a normal parameter?
|
||||
pos.isPipeline() and
|
||||
c.asCfgScope() = parameter.getEnclosingScope()
|
||||
}
|
||||
|
||||
@@ -690,22 +720,6 @@ abstract class ArgumentNode extends Node {
|
||||
final DataFlowCall getCall() { this.argumentOf(result, _) }
|
||||
}
|
||||
|
||||
class PrePipelineArgumentNodeImpl extends NodeImpl, TPrePipelineArgumentNode {
|
||||
CfgNodes::ExprNodes::PipelineArgumentCfgNode e;
|
||||
|
||||
PrePipelineArgumentNodeImpl() { this = TPrePipelineArgumentNode(e) }
|
||||
|
||||
final override CfgScope getCfgScope() { result = e.getScope() }
|
||||
|
||||
final override Location getLocationImpl() { result = e.getLocation() }
|
||||
|
||||
final override string toStringImpl() { result = "[pre pipeline] " + e.toString() }
|
||||
|
||||
final override predicate nodeIsHidden() { any() }
|
||||
|
||||
CfgNodes::ExprNodes::PipelineArgumentCfgNode getPipelineArgument() { result = e }
|
||||
}
|
||||
|
||||
module ArgumentNodes {
|
||||
class ExplicitArgumentNode extends ArgumentNode {
|
||||
CfgNodes::ExprNodes::ArgumentCfgNode arg;
|
||||
@@ -749,23 +763,15 @@ module ArgumentNodes {
|
||||
}
|
||||
}
|
||||
|
||||
class PipelineArgumentNodeImpl extends NodeImpl, TPipelineArgumentNode {
|
||||
CfgNodes::ExprNodes::PipelineArgumentCfgNode e;
|
||||
class PipelineArgumentNode extends ArgumentNode instanceof ExprNode {
|
||||
PipelineArgumentNode() {
|
||||
this.getExprNode() instanceof CfgNodes::ExprNodes::PipelineArgumentCfgNode
|
||||
}
|
||||
|
||||
PipelineArgumentNodeImpl() { this = TPipelineArgumentNode(e) }
|
||||
CfgNodes::ExprNodes::PipelineArgumentCfgNode getPipelineArgument() {
|
||||
result = super.getExprNode()
|
||||
}
|
||||
|
||||
final override CfgScope getCfgScope() { result = e.getScope() }
|
||||
|
||||
final override Location getLocationImpl() { result = e.getLocation() }
|
||||
|
||||
final override string toStringImpl() { result = e.toString() }
|
||||
|
||||
final override predicate nodeIsHidden() { none() }
|
||||
|
||||
CfgNodes::ExprNodes::PipelineArgumentCfgNode getPipelineArgument() { result = e }
|
||||
}
|
||||
|
||||
class PipelineArgumentNode extends ArgumentNode instanceof PipelineArgumentNodeImpl {
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
this.sourceArgumentOf(call.asCall(), pos)
|
||||
}
|
||||
@@ -773,7 +779,7 @@ module ArgumentNodes {
|
||||
override predicate sourceArgumentOf(
|
||||
CfgNodes::ExprNodes::CallExprCfgNode call, ArgumentPosition pos
|
||||
) {
|
||||
call = super.getPipelineArgument().getCall() and
|
||||
call = this.getPipelineArgument().getCall() and
|
||||
pos.isPipeline()
|
||||
}
|
||||
}
|
||||
@@ -923,7 +929,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
|
||||
e.getValue() = ec.getIndex()
|
||||
)
|
||||
or
|
||||
not exists(e.getValue().asInt()) and
|
||||
not exists(Content::KnownElementContent ec | ec.getIndex() = e.getValue()) and
|
||||
c.isAnyElement()
|
||||
)
|
||||
or
|
||||
@@ -931,7 +937,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
|
||||
e = node1.asExpr() and
|
||||
not arrayExprStore(node1, _, _, e) and
|
||||
node2.asExpr().(CfgNodes::ExprNodes::ArrayLiteralCfgNode).getExpr(index) = e and
|
||||
c.isKnownOrUnknownElement(ec) and
|
||||
c.isKnownOrUnknownPositional(ec) and
|
||||
index = ec.getIndex().asInt()
|
||||
)
|
||||
or
|
||||
@@ -939,32 +945,32 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
|
||||
node2.asExpr().(CfgNodes::ExprNodes::HashTableExprCfgNode).getValueFromKey(key) = node1.asExpr()
|
||||
|
|
||||
exists(Content::KnownElementContent ec |
|
||||
c.isKnownOrUnknownElement(ec) and
|
||||
ec.getIndex() = key.getValue()
|
||||
c.isKnownOrUnknownKeyContent(ec) and
|
||||
key.getValue() = ec.getIndex()
|
||||
)
|
||||
or
|
||||
not exists(key.getValue()) and
|
||||
c.isAnyElement()
|
||||
not exists(Content::KnownKeyContent ec | ec.getIndex() = key.getValue()) and
|
||||
c.isUnknownKeyContent()
|
||||
)
|
||||
or
|
||||
arrayExprStore(node1, c, node2, _)
|
||||
or
|
||||
c.isAnyElement() and
|
||||
c.isUnknownPositionalContent() and
|
||||
exists(CfgNode cfgNode |
|
||||
node1 = TPreReturnNodeImpl(cfgNode, false) and
|
||||
node2.(ReturnNodeImpl).getCfgScope() = cfgNode.getScope()
|
||||
)
|
||||
or
|
||||
c.isAnyElement() and
|
||||
c.isUnknownPositionalContent() and
|
||||
exists(CfgNode cfgNode |
|
||||
node1 = TImplicitWrapNode(cfgNode, true) and
|
||||
node2.(ReturnNodeImpl).getCfgScope() = cfgNode.getScope()
|
||||
)
|
||||
or
|
||||
c.isAnyElement() and
|
||||
exists(CfgNodes::ExprNodes::PipelineArgumentCfgNode arg |
|
||||
node1 = TPrePipelineArgumentNode(arg) and
|
||||
node2 = TPipelineArgumentNode(arg)
|
||||
c.isUnknownPositionalContent() and
|
||||
exists(CfgNodes::ProcessBlockCfgNode process |
|
||||
node1 = TPreProcessNode(process) and
|
||||
node2 = TProcessNode(process)
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
@@ -992,7 +998,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
|
||||
e.getValue() = ec.getIndex()
|
||||
)
|
||||
or
|
||||
not exists(e.getValue()) and
|
||||
not exists(Content::KnownElementContent ec | ec.getIndex() = e.getValue()) and
|
||||
c.isAnyElement()
|
||||
)
|
||||
or
|
||||
@@ -1002,27 +1008,24 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
|
||||
c.isSingleton(any(Content::KnownElementContent ec | exists(ec.getIndex().asInt())))
|
||||
)
|
||||
or
|
||||
c.isAnyElement() and
|
||||
c.isAnyPositional() and
|
||||
exists(CfgNodes::ProcessBlockCfgNode processBlock |
|
||||
processBlock.getPipelineVariableAccess() = node1.asExpr() and
|
||||
node2 = TProcessNode(processBlock)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
Content::KnownElementContent ec, PipelineByPropertyNameParameter p, SsaImpl::DefinitionExt def
|
||||
|
|
||||
c.isSingleton(ec) and
|
||||
p.getIteratorVariable() = node1.(ProcessPropertyByNameNode).getVariable() and
|
||||
p.getName() = ec.getIndex().asString() and
|
||||
def.getSourceVariable() = p.getIteratorVariable() and
|
||||
SsaImpl::firstRead(def, node2.asExpr())
|
||||
c.isAnyPositional() and
|
||||
exists(CfgNodes::ProcessBlockCfgNode pb, CfgNodes::ExprNodes::VarReadAccessCfgNode va |
|
||||
va = pb.getAPipelineByPropertyNameParameterAccess() and
|
||||
node1.asExpr() = va and
|
||||
node2 = TProcessPropertyByNameNode(va.getVariable(), false)
|
||||
)
|
||||
or
|
||||
exists(Content::KnownElementContent ec, SsaImpl::DefinitionExt def |
|
||||
c.isSingleton(ec) and
|
||||
node1.(PipelineByPropertyNameParameterNode).getPropertyName() = ec.getIndex().asString() and
|
||||
def = SsaImpl::getParameterDef(node1.(PipelineByPropertyNameParameterNode).getParameter()) and
|
||||
SsaImpl::firstRead(def, node2.asExpr())
|
||||
exists(PipelineByPropertyNameParameter p, Content::KnownElementContent ec |
|
||||
c.isKnownOrUnknownElement(ec) and
|
||||
ec.getIndex().asString() = p.getPropertyName() and
|
||||
node1 = TProcessPropertyByNameNode(p, false) and
|
||||
node2 = TProcessPropertyByNameNode(p, true)
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
@@ -1043,8 +1046,11 @@ predicate clearsContent(Node n, ContentSet c) {
|
||||
n = TPreReturnNodeImpl(_, false) and
|
||||
c.isAnyElement()
|
||||
or
|
||||
n instanceof PrePipelineArgumentNodeImpl and
|
||||
c.isAnyElement()
|
||||
c.isAnyPositional() and
|
||||
n instanceof PreProcessPropertyByNameNode
|
||||
or
|
||||
c.isAnyPositional() and
|
||||
n instanceof PreProcessNode
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1059,9 +1065,6 @@ predicate expectsContent(Node n, ContentSet c) {
|
||||
or
|
||||
n = TImplicitWrapNode(_, false) and
|
||||
c.isSingleton(any(Content::UnknownElementContent ec))
|
||||
or
|
||||
n instanceof PipelineArgumentNode and
|
||||
c.isAnyElement()
|
||||
}
|
||||
|
||||
class DataFlowType extends TDataFlowType {
|
||||
@@ -1191,6 +1194,22 @@ private class ReturnNodeImpl extends TReturnNodeImpl, NodeImpl {
|
||||
override predicate nodeIsHidden() { any() }
|
||||
}
|
||||
|
||||
private class PreProcessNode extends TPreProcessNode, NodeImpl {
|
||||
CfgNodes::ProcessBlockCfgNode process;
|
||||
|
||||
PreProcessNode() { this = TPreProcessNode(process) }
|
||||
|
||||
override CfgScope getCfgScope() { result = process.getScope() }
|
||||
|
||||
override Location getLocationImpl() { result = process.getLocation() }
|
||||
|
||||
override string toStringImpl() { result = "pre-process node for " + process.toString() }
|
||||
|
||||
override predicate nodeIsHidden() { any() }
|
||||
|
||||
CfgNodes::ProcessBlockCfgNode getProcessBlock() { result = process }
|
||||
}
|
||||
|
||||
private class ProcessNode extends TProcessNode, NodeImpl {
|
||||
CfgNodes::ProcessBlockCfgNode process;
|
||||
|
||||
@@ -1211,26 +1230,53 @@ private class ProcessNode extends TProcessNode, NodeImpl {
|
||||
CfgNodes::ProcessBlockCfgNode getProcessBlock() { result = process }
|
||||
}
|
||||
|
||||
private class ProcessPropertyByNameNode extends TProcessPropertyByNameNode, NodeImpl {
|
||||
private PipelineByPropertyNameIteratorVariable iter;
|
||||
private class PreProcessPropertyByNameNode extends TPreProcessPropertyByNameNode, NodeImpl {
|
||||
private CfgNodes::ExprNodes::VarReadAccessCfgNode va;
|
||||
|
||||
ProcessPropertyByNameNode() { this = TProcessPropertyByNameNode(iter) }
|
||||
PreProcessPropertyByNameNode() { this = TPreProcessPropertyByNameNode(va) }
|
||||
|
||||
PipelineByPropertyNameIteratorVariable getVariable() { result = iter }
|
||||
CfgNodes::ExprNodes::VarReadAccessCfgNode getAccess() { result = va }
|
||||
|
||||
override CfgScope getCfgScope() { result = iter.getDeclaringScope() }
|
||||
override CfgScope getCfgScope() { result = va.getScope() }
|
||||
|
||||
override Location getLocationImpl() { result = iter.getLocation() }
|
||||
override Location getLocationImpl() { result = this.getProcessBlock().getLocation() }
|
||||
|
||||
override string toStringImpl() { result = "process node for " + iter.toString() }
|
||||
override string toStringImpl() { result = "pre-process node for " + va.toString() }
|
||||
|
||||
override predicate nodeIsHidden() { any() }
|
||||
|
||||
CfgNodes::ProcessBlockCfgNode getProcessBlock() {
|
||||
isProcessPropertyByNameNode(iter, result.getAstNode())
|
||||
result.getAPipelineByPropertyNameParameterAccess() = va
|
||||
}
|
||||
}
|
||||
|
||||
private class ProcessPropertyByNameNode extends TProcessPropertyByNameNode, NodeImpl {
|
||||
private PipelineByPropertyNameParameter p;
|
||||
private boolean hasRead;
|
||||
|
||||
ProcessPropertyByNameNode() { this = TProcessPropertyByNameNode(p, hasRead) }
|
||||
|
||||
PipelineByPropertyNameParameter getParameter() { result = p }
|
||||
|
||||
override CfgScope getCfgScope() { result = p.getDeclaringScope() }
|
||||
|
||||
override Location getLocationImpl() { result = this.getProcessBlock().getLocation() }
|
||||
|
||||
override string toStringImpl() {
|
||||
hasRead = false and
|
||||
result = "process node for " + p.toString()
|
||||
or
|
||||
hasRead = true and
|
||||
result = "[has read] process node for " + p.toString()
|
||||
}
|
||||
|
||||
override predicate nodeIsHidden() { any() }
|
||||
|
||||
CfgNodes::ProcessBlockCfgNode getProcessBlock() { result.getScope().getAParameter() = p }
|
||||
|
||||
predicate hasRead() { hasRead = true }
|
||||
}
|
||||
|
||||
class ScriptBlockNode extends TScriptBlockNode, NodeImpl {
|
||||
private ScriptBlock scriptBlock;
|
||||
|
||||
@@ -1338,18 +1384,38 @@ class ContentApprox extends TContentApprox {
|
||||
|
||||
/** Gets an approximated value for content `c`. */
|
||||
ContentApprox getContentApprox(Content c) {
|
||||
c instanceof Content::UnknownElementContent and
|
||||
result = TUnknownElementContentApprox()
|
||||
c instanceof Content::KnownPositionalContent and
|
||||
result = TKnownPositionalContentApprox()
|
||||
or
|
||||
exists(c.(Content::KnownElementContent).getIndex().asInt()) and
|
||||
result = TKnownIntegerElementContentApprox()
|
||||
or
|
||||
result =
|
||||
TKnownElementContentApprox(approxKnownElementIndex(c.(Content::KnownElementContent).getIndex()))
|
||||
result = TKnownKeyContentApprox(approxKnownElementIndex(c.(Content::KnownKeyContent).getIndex()))
|
||||
or
|
||||
result = TNonElementContentApprox(c)
|
||||
or
|
||||
c instanceof Content::UnknownKeyContent and
|
||||
result = TUnkownKeyContentApprox()
|
||||
or
|
||||
c instanceof Content::UnknownPositionalContent and
|
||||
result = TUnknownPositionalContentApprox()
|
||||
or
|
||||
c instanceof Content::UnknownKeyOrPositionContent and
|
||||
result = TUnknownContentApprox()
|
||||
}
|
||||
|
||||
// TFieldContent(string name) {
|
||||
// name = any(PropertyMember member).getName()
|
||||
// or
|
||||
// name = any(MemberExpr me).getMemberName()
|
||||
// } or
|
||||
// // A known map key
|
||||
// TKnownKeyContent(ConstantValue cv) { exists(cv.asString()) } or
|
||||
// // A known array index
|
||||
// TKnownPositionalContent(ConstantValue cv) { cv.asInt() = [0 .. 10] } or
|
||||
// // An unknown key
|
||||
// TUnknownKeyContent() or
|
||||
// // An unknown positional element
|
||||
// TUnknownPositionalContent() or
|
||||
// // A unknown position or key - and we dont even know what kind it is
|
||||
// TUnknownKeyOrPositionContent()
|
||||
/**
|
||||
* A unit class for adding additional jump steps.
|
||||
*
|
||||
|
||||
@@ -255,21 +255,43 @@ module Content {
|
||||
/** An element in a collection, for example an element in an array or in a hash. */
|
||||
class ElementContent extends Content, TElementContent { }
|
||||
|
||||
/** An element in a collection at a known index. */
|
||||
class KnownElementContent extends ElementContent, TKnownElementContent {
|
||||
private ConstantValue cv;
|
||||
|
||||
KnownElementContent() { this = TKnownElementContent(cv) }
|
||||
abstract class KnownElementContent extends ElementContent, TKnownElementContent {
|
||||
ConstantValue cv;
|
||||
|
||||
/** Gets the index in the collection. */
|
||||
ConstantValue getIndex() { result = cv }
|
||||
final ConstantValue getIndex() { result = cv }
|
||||
|
||||
override string toString() { result = "element " + cv }
|
||||
}
|
||||
|
||||
/** An element in a collection at an unknown index. */
|
||||
class UnknownElementContent extends ElementContent, TUnknownElementContent {
|
||||
override string toString() { result = "element" }
|
||||
/** An element in a collection at a known index. */
|
||||
class KnownKeyContent extends KnownElementContent, TKnownKeyContent {
|
||||
KnownKeyContent() { this = TKnownKeyContent(cv) }
|
||||
}
|
||||
|
||||
/** An element in a collection at a known index. */
|
||||
class KnownPositionalContent extends KnownElementContent, TKnownPositionalContent {
|
||||
KnownPositionalContent() { this = TKnownPositionalContent(cv) }
|
||||
}
|
||||
|
||||
class UnknownElementContent extends ElementContent, TUnknownElementContent { }
|
||||
|
||||
class UnknownKeyContent extends UnknownElementContent, TUnknownKeyContent {
|
||||
UnknownKeyContent() { this = TUnknownKeyContent() }
|
||||
|
||||
override string toString() { result = "unknown map key" }
|
||||
}
|
||||
|
||||
class UnknownPositionalContent extends UnknownElementContent, TUnknownPositionalContent {
|
||||
UnknownPositionalContent() { this = TUnknownPositionalContent() }
|
||||
|
||||
override string toString() { result = "unknown index" }
|
||||
}
|
||||
|
||||
class UnknownKeyOrPositionContent extends UnknownElementContent, TUnknownKeyOrPositionContent {
|
||||
UnknownKeyOrPositionContent() { this = TUnknownKeyOrPositionContent() }
|
||||
|
||||
override string toString() { result = "unknown" }
|
||||
}
|
||||
|
||||
/** A field of an object. */
|
||||
@@ -285,20 +307,18 @@ module Content {
|
||||
}
|
||||
|
||||
/** Gets the element content corresponding to constant value `cv`. */
|
||||
ElementContent getElementContent(ConstantValue cv) {
|
||||
result = TKnownElementContent(cv)
|
||||
KnownElementContent getKnownElementContent(ConstantValue cv) {
|
||||
result = TKnownPositionalContent(cv)
|
||||
or
|
||||
not exists(TKnownElementContent(cv)) and
|
||||
result = TUnknownElementContent()
|
||||
result = TKnownKeyContent(cv)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the constant value of `e`, which corresponds to a valid known
|
||||
* element index. Unlike calling simply `e.getConstantValue()`, this
|
||||
* excludes negative array indices.
|
||||
* element index.
|
||||
*/
|
||||
ConstantValue getKnownElementIndex(Expr e) {
|
||||
result = getElementContent(e.getValue()).(KnownElementContent).getIndex()
|
||||
result = getKnownElementContent(e.getValue()).getIndex()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,19 +330,31 @@ module Content {
|
||||
*/
|
||||
class ContentSet extends TContentSet {
|
||||
/** Holds if this content set is the singleton `{c}`. */
|
||||
predicate isSingleton(Content c) { this = TSingletonContent(c) }
|
||||
predicate isSingleton(Content c) { this = TSingletonContentSet(c) }
|
||||
|
||||
/** Holds if this content set represents all `ElementContent`s. */
|
||||
predicate isAnyElement() { this = TAnyElementContent() }
|
||||
|
||||
/**
|
||||
* Holds if this content set represents a specific known element index, or an
|
||||
* unknown element index.
|
||||
*/
|
||||
predicate isKnownOrUnknownElement(Content::KnownElementContent c) {
|
||||
this = TKnownOrUnknownElementContent(c)
|
||||
predicate isKnownOrUnknownKeyContent(Content::KnownKeyContent c) {
|
||||
this = TKnownOrUnknownKeyContentSet(c)
|
||||
}
|
||||
|
||||
predicate isKnownOrUnknownPositional(Content::KnownPositionalContent c) {
|
||||
this = TKnownOrUnknownPositionalContentSet(c)
|
||||
}
|
||||
|
||||
predicate isKnownOrUnknownElement(Content::KnownElementContent c) {
|
||||
this.isKnownOrUnknownKeyContent(c)
|
||||
or
|
||||
this.isKnownOrUnknownPositional(c)
|
||||
}
|
||||
|
||||
predicate isUnknownPositionalContent() { this = TUnknownPositionalElementContentSet() }
|
||||
|
||||
predicate isUnknownKeyContent() { this = TUnknownKeyContentSet() }
|
||||
|
||||
predicate isAnyElement() { this = TAnyElementContentSet() }
|
||||
|
||||
predicate isAnyPositional() { this = TAnyPositionalContentSet() }
|
||||
|
||||
// predicate isPipelineContentSet() { this = TPipelineContentSet() }
|
||||
/** Gets a textual representation of this content set. */
|
||||
string toString() {
|
||||
exists(Content c |
|
||||
@@ -330,15 +362,25 @@ class ContentSet extends TContentSet {
|
||||
result = c.toString()
|
||||
)
|
||||
or
|
||||
this.isAnyElement() and
|
||||
result = "any element"
|
||||
or
|
||||
exists(Content::KnownElementContent c |
|
||||
this.isKnownOrUnknownElement(c) and
|
||||
result = c + " or unknown"
|
||||
result = c.toString() + " or unknown"
|
||||
)
|
||||
or
|
||||
this.isUnknownPositionalContent() and
|
||||
result = "unknown positional"
|
||||
or
|
||||
this.isUnknownKeyContent() and
|
||||
result = "unknown key"
|
||||
or
|
||||
this.isAnyPositional() and
|
||||
result = "any positional"
|
||||
or
|
||||
this.isAnyElement() and
|
||||
result = "any element"
|
||||
}
|
||||
|
||||
/** Gets a content that may be stored into when storing into this set. */
|
||||
Content getAStoreContent() {
|
||||
this.isSingleton(result)
|
||||
or
|
||||
@@ -346,20 +388,25 @@ class ContentSet extends TContentSet {
|
||||
// from `a` to `a[unknown]` (which can read any element), gets translated into
|
||||
// a reverse store step that store only into `?`
|
||||
this.isAnyElement() and
|
||||
result = TUnknownElementContent()
|
||||
result = TUnknownKeyOrPositionContent()
|
||||
or
|
||||
// For reverse stores, `a[1][0] = x`, it is important that the read-step
|
||||
// from `a` to `a[1]` (which can read both elements stored at exactly index `1`
|
||||
// and elements stored at unknown index), gets translated into a reverse store
|
||||
// step that store only into `1`
|
||||
this.isKnownOrUnknownElement(result)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Content getAnElementReadContent() {
|
||||
exists(Content::KnownElementContent c | this.isKnownOrUnknownElement(c) |
|
||||
result = c or
|
||||
result = TUnknownElementContent()
|
||||
or
|
||||
this.isUnknownPositionalContent() and
|
||||
result = TUnknownPositionalContent()
|
||||
or
|
||||
this.isUnknownKeyContent() and
|
||||
result = TUnknownKeyContent()
|
||||
or
|
||||
this.isAnyPositional() and
|
||||
(
|
||||
result instanceof Content::KnownPositionalContent
|
||||
or
|
||||
result = TUnknownPositionalContent()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -370,7 +417,36 @@ class ContentSet extends TContentSet {
|
||||
this.isAnyElement() and
|
||||
result instanceof Content::ElementContent
|
||||
or
|
||||
result = this.getAnElementReadContent()
|
||||
exists(Content::KnownElementContent c |
|
||||
this.isKnownOrUnknownKeyContent(c) and
|
||||
(
|
||||
result = c
|
||||
or
|
||||
result = TUnknownKeyContent()
|
||||
or
|
||||
result = TUnknownKeyOrPositionContent()
|
||||
)
|
||||
or
|
||||
this.isKnownOrUnknownPositional(c) and
|
||||
(
|
||||
result = c or
|
||||
result = TUnknownPositionalContent() or
|
||||
result = TUnknownKeyOrPositionContent()
|
||||
)
|
||||
)
|
||||
or
|
||||
this.isUnknownPositionalContent() and
|
||||
result = TUnknownPositionalContent()
|
||||
or
|
||||
this.isUnknownKeyContent() and
|
||||
result = TUnknownKeyContent()
|
||||
or
|
||||
this.isAnyPositional() and
|
||||
(
|
||||
result instanceof Content::KnownPositionalContent
|
||||
or
|
||||
result = TUnknownPositionalContent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,22 +52,24 @@ module Input implements InputSig<Location, DataFlowImplSpecific::PowershellDataF
|
||||
}
|
||||
|
||||
string encodeContent(ContentSet cs, string arg) {
|
||||
exists(Content c | cs = TSingletonContent(c) |
|
||||
exists(Content c | cs = TSingletonContentSet(c) |
|
||||
c = TFieldContent(arg) and result = "Field"
|
||||
or
|
||||
exists(ConstantValue cv |
|
||||
c = TKnownElementContent(cv) and
|
||||
exists(ConstantValue cv | c = TKnownKeyContent(cv) or c = TKnownPositionalContent(cv) |
|
||||
result = "Element" and
|
||||
arg = cv.serialize() + "!"
|
||||
)
|
||||
or
|
||||
c = TUnknownElementContent() and result = "Element" and arg = "?"
|
||||
(c = TUnknownPositionalContent() or c = TUnknownKeyContent()) and
|
||||
result = "Element" and
|
||||
arg = "?"
|
||||
)
|
||||
or
|
||||
cs = TAnyElementContent() and result = "Element" and arg = "any"
|
||||
cs = TAnyElementContentSet() and result = "Element" and arg = "any"
|
||||
or
|
||||
exists(Content::KnownElementContent kec |
|
||||
cs = TKnownOrUnknownElementContent(kec) and
|
||||
cs = TKnownOrUnknownKeyContentSet(kec) or cs = TKnownOrUnknownPositionalContentSet(kec)
|
||||
|
|
||||
result = "Element" and
|
||||
arg = kec.getIndex().serialize()
|
||||
)
|
||||
@@ -102,13 +104,13 @@ module Input implements InputSig<Location, DataFlowImplSpecific::PowershellDataF
|
||||
bindingset[token]
|
||||
ContentSet decodeUnknownContent(AccessPath::AccessPathTokenBase token) {
|
||||
token.getName() = "Element" and
|
||||
result = TSingletonContent(TUnknownElementContent())
|
||||
result = TSingletonContentSet(TUnknownKeyOrPositionContent())
|
||||
}
|
||||
|
||||
bindingset[token]
|
||||
ContentSet decodeUnknownWithContent(AccessPath::AccessPathTokenBase token) {
|
||||
token.getName() = "WithElement" and
|
||||
result = TAnyElementContent()
|
||||
result = TAnyElementContentSet()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,12 +154,12 @@ module Private {
|
||||
|
||||
/** Gets a summary component that represents an element in a collection at an unknown index. */
|
||||
SummaryComponent elementUnknown() {
|
||||
result = SC::content(TSingletonContent(TUnknownElementContent()))
|
||||
result = SC::content(TSingletonContentSet(TUnknownKeyOrPositionContent()))
|
||||
}
|
||||
|
||||
/** Gets a summary component that represents an element in a collection at a known index. */
|
||||
SummaryComponent elementKnown(ConstantValue cv) {
|
||||
result = SC::content(TSingletonContent(Content::getElementContent(cv)))
|
||||
result = SC::content(TSingletonContentSet(Content::getKnownElementContent(cv)))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,9 +167,14 @@ module Private {
|
||||
* known index `cv`, or an unknown index.
|
||||
*/
|
||||
SummaryComponent elementKnownOrUnknown(ConstantValue cv) {
|
||||
result = SC::content(TKnownOrUnknownElementContent(TKnownElementContent(cv)))
|
||||
result =
|
||||
SC::content(any(ContentSet cs |
|
||||
cs.isKnownOrUnknownElement(Content::getKnownElementContent(cv))
|
||||
))
|
||||
or
|
||||
not exists(TKnownElementContent(cv)) and
|
||||
not exists(
|
||||
any(ContentSet cs | cs.isKnownOrUnknownElement(Content::getKnownElementContent(cv)))
|
||||
) and
|
||||
result = elementUnknown()
|
||||
}
|
||||
|
||||
@@ -181,7 +188,7 @@ module Private {
|
||||
*
|
||||
* but is more efficient, because it is represented by a single value.
|
||||
*/
|
||||
SummaryComponent elementAny() { result = SC::content(TAnyElementContent()) }
|
||||
SummaryComponent elementAny() { result = SC::content(TAnyElementContentSet()) }
|
||||
|
||||
/** Gets a summary component that represents the return value of a call. */
|
||||
SummaryComponent return() { result = SC::return(any(NormalReturnKind rk)) }
|
||||
|
||||
@@ -31,9 +31,10 @@ module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
or
|
||||
variableWriteActual(bb, i, v, _)
|
||||
or
|
||||
exists(ProcessBlockCfgNode processBlock |
|
||||
bb.getNode(i) = processBlock and
|
||||
exists(ProcessBlockCfgNode processBlock | bb.getNode(i) = processBlock |
|
||||
processBlock.getPipelineIteratorVariable() = v
|
||||
or
|
||||
processBlock.getAPipelineBypropertyNameIteratorVariable() = v
|
||||
)
|
||||
or
|
||||
parameterWrite(bb, i, v)
|
||||
@@ -301,7 +302,8 @@ class NormalParameter extends Parameter {
|
||||
private newtype TParameterExt =
|
||||
TNormalParameter(NormalParameter p) or
|
||||
TThisMethodParameter(Method m) or
|
||||
TPipelineParameter(PipelineParameter p)
|
||||
TPipelineParameter(PipelineParameter p) or
|
||||
TPipelineByPropertyNameParameter(PipelineByPropertyNameParameter p)
|
||||
|
||||
/** A normal parameter or an implicit `this` parameter. */
|
||||
class ParameterExt extends TParameterExt {
|
||||
@@ -311,11 +313,17 @@ class ParameterExt extends TParameterExt {
|
||||
|
||||
PipelineParameter asPipelineParameter() { this = TPipelineParameter(result) }
|
||||
|
||||
PipelineByPropertyNameParameter asPipelineByPropertyNameParameter() {
|
||||
this = TPipelineByPropertyNameParameter(result)
|
||||
}
|
||||
|
||||
predicate isInitializedBy(WriteDefinition def) {
|
||||
def = getParameterDef(this.asParameter())
|
||||
or
|
||||
def = getParameterDef(this.asPipelineParameter())
|
||||
or
|
||||
def = getParameterDef(this.asPipelineByPropertyNameParameter())
|
||||
or
|
||||
def.(Ssa::ThisDefinition).getSourceVariable().getDeclaringScope() = this.asThis().getBody()
|
||||
}
|
||||
|
||||
@@ -323,7 +331,7 @@ class ParameterExt extends TParameterExt {
|
||||
result =
|
||||
[
|
||||
this.asParameter().toString(), this.asThis().toString(),
|
||||
this.asPipelineParameter().toString()
|
||||
this.asPipelineParameter().toString(), this.asPipelineByPropertyNameParameter().toString()
|
||||
]
|
||||
}
|
||||
|
||||
@@ -331,7 +339,8 @@ class ParameterExt extends TParameterExt {
|
||||
result =
|
||||
[
|
||||
this.asParameter().getLocation(), this.asThis().getLocation(),
|
||||
this.asPipelineParameter().getLocation()
|
||||
this.asPipelineParameter().getLocation(),
|
||||
this.asPipelineByPropertyNameParameter().getLocation()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,8 +271,14 @@
|
||||
| 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 | |
|
||||
| functions.ps1:29:5:32:5 | forach(... in ...) | functions.ps1:29:14:29:20 | number | non-empty |
|
||||
| functions.ps1:29:5:32:5 | forach(... in ...) | functions.ps1:33:5:33:8 | [Stmt] sum | empty |
|
||||
| functions.ps1:29:14:29:20 | number | functions.ps1:29:35:32:5 | {...} | |
|
||||
| functions.ps1:29:25:29:32 | numbers | functions.ps1:29:5:32:5 | forach(... in ...) | |
|
||||
| functions.ps1:29:35:32:5 | {...} | functions.ps1:31:9:31:23 | ...=... | |
|
||||
| functions.ps1:31:9:31:12 | sum | functions.ps1:31:17:31:23 | number | |
|
||||
| functions.ps1:31:9:31:23 | ...=... | functions.ps1:31:9:31:12 | sum | |
|
||||
| functions.ps1:31:17:31:23 | number | functions.ps1:29:5:32:5 | forach(... in ...) | |
|
||||
| functions.ps1:33:5:33:8 | [Stmt] sum | functions.ps1:33:5:33:8 | sum | |
|
||||
| functions.ps1:33:5:33:8 | sum | functions.ps1:22:33:34:1 | exit {...} (normal) | |
|
||||
| functions.ps1:36:1:52:1 | def of Add-Numbers-From-Pipeline | functions.ps1:1:1:54:0 | exit {...} (normal) | |
|
||||
@@ -284,9 +290,10 @@
|
||||
| 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 | |
|
||||
| functions.ps1:42:16:42:16 | 0 | functions.ps1:44:5:47:5 | [synth] pipeline | |
|
||||
| functions.ps1:44:5:47:5 | [synth] pipeline | functions.ps1:44:5:47:5 | {...} | |
|
||||
| functions.ps1:44:5:47:5 | {...} | functions.ps1:46:9:46:18 | ...=... | |
|
||||
| functions.ps1:42:16:42:16 | 0 | functions.ps1:44:5:47:5 | {...} | |
|
||||
| functions.ps1:44:5:47:5 | [synth] pipeline | functions.ps1:46:9:46:18 | ...=... | non-empty |
|
||||
| functions.ps1:44:5:47:5 | [synth] pipeline | functions.ps1:48:5:51:5 | {...} | empty |
|
||||
| functions.ps1:44:5:47:5 | {...} | functions.ps1:44:5:47:5 | [synth] pipeline | |
|
||||
| functions.ps1:46:9:46:12 | sum | functions.ps1:46:17:46:18 | __pipeline_iterator | |
|
||||
| functions.ps1:46:9:46:18 | ...=... | functions.ps1:46:9:46:12 | sum | |
|
||||
| functions.ps1:46:17:46:18 | __pipeline_iterator | functions.ps1:44:5:47:5 | [synth] pipeline | |
|
||||
@@ -452,7 +459,15 @@
|
||||
| loops.ps1:51:5:51:10 | ...=... | loops.ps1:51:5:51:6 | a | |
|
||||
| loops.ps1:51:10:51:10 | 0 | loops.ps1:52:25:52:36 | letterArray | |
|
||||
| loops.ps1:52:5:55:5 | forach(... in ...) | loops.ps1:49:23:56:1 | exit {...} (normal) | empty |
|
||||
| loops.ps1:52:5:55:5 | forach(... in ...) | loops.ps1:52:14:52:20 | letter | non-empty |
|
||||
| loops.ps1:52:14:52:20 | letter | loops.ps1:53:5:55:5 | {...} | |
|
||||
| loops.ps1:52:25:52:36 | letterArray | loops.ps1:52:5:55:5 | forach(... in ...) | |
|
||||
| loops.ps1:53:5:55:5 | {...} | loops.ps1:54:9:54:19 | ...=... | |
|
||||
| loops.ps1:54:9:54:10 | a | loops.ps1:54:14:54:15 | a | |
|
||||
| loops.ps1:54:9:54:19 | ...=... | loops.ps1:54:9:54:10 | a | |
|
||||
| loops.ps1:54:14:54:15 | a | loops.ps1:54:19:54:19 | 1 | |
|
||||
| loops.ps1:54:14:54:19 | ...+... | loops.ps1:52:5:55:5 | forach(... in ...) | |
|
||||
| loops.ps1:54:19:54:19 | 1 | loops.ps1:54:14:54:19 | ...+... | |
|
||||
| loops.ps1:58:1:68:1 | def of Test-For-Ever | loops.ps1:1:1:70:0 | exit {...} (normal) | |
|
||||
| loops.ps1:58:24:68:1 | [synth] pipeline | loops.ps1:59:5:67:5 | {...} | |
|
||||
| loops.ps1:58:24:68:1 | enter {...} | loops.ps1:58:24:68:1 | {...} | |
|
||||
|
||||
@@ -6,33 +6,33 @@ edges
|
||||
| test.ps1:10:1:10:5 | [post] arr1 [element 3] | test.ps1:11:6:11:10 | arr1 [element 3] | provenance | |
|
||||
| test.ps1:10:12:10:21 | Call to Source | test.ps1:10:1:10:5 | [post] arr1 [element 3] | provenance | |
|
||||
| test.ps1:11:6:11:10 | arr1 [element 3] | test.ps1:11:6:11:13 | ...[...] | provenance | |
|
||||
| test.ps1:14:1:14:5 | [post] arr2 [element] | test.ps1:15:6:15:10 | arr2 [element] | provenance | |
|
||||
| test.ps1:14:19:14:28 | Call to Source | test.ps1:14:1:14:5 | [post] arr2 [element] | provenance | |
|
||||
| test.ps1:15:6:15:10 | arr2 [element] | test.ps1:15:6:15:13 | ...[...] | provenance | |
|
||||
| test.ps1:14:1:14:5 | [post] arr2 [unknown] | test.ps1:15:6:15:10 | arr2 [unknown] | provenance | |
|
||||
| test.ps1:14:19:14:28 | Call to Source | test.ps1:14:1:14:5 | [post] arr2 [unknown] | provenance | |
|
||||
| test.ps1:15:6:15:10 | arr2 [unknown] | test.ps1:15:6:15:13 | ...[...] | provenance | |
|
||||
| test.ps1:17:1:17:5 | [post] arr3 [element 3] | test.ps1:18:6:18:10 | arr3 [element 3] | provenance | |
|
||||
| test.ps1:17:12:17:21 | Call to Source | test.ps1:17:1:17:5 | [post] arr3 [element 3] | provenance | |
|
||||
| test.ps1:18:6:18:10 | arr3 [element 3] | test.ps1:18:6:18:20 | ...[...] | provenance | |
|
||||
| test.ps1:20:1:20:5 | [post] arr4 [element] | test.ps1:21:6:21:10 | arr4 [element] | provenance | |
|
||||
| test.ps1:20:20:20:29 | Call to Source | test.ps1:20:1:20:5 | [post] arr4 [element] | provenance | |
|
||||
| test.ps1:21:6:21:10 | arr4 [element] | test.ps1:21:6:21:21 | ...[...] | provenance | |
|
||||
| test.ps1:23:1:23:5 | [post] arr5 [element, element 1] | test.ps1:24:6:24:10 | arr5 [element, element 1] | provenance | |
|
||||
| test.ps1:23:1:23:16 | [post] ...[...] [element 1] | test.ps1:23:1:23:5 | [post] arr5 [element, element 1] | provenance | |
|
||||
| test.ps1:20:1:20:5 | [post] arr4 [unknown] | test.ps1:21:6:21:10 | arr4 [unknown] | provenance | |
|
||||
| test.ps1:20:20:20:29 | Call to Source | test.ps1:20:1:20:5 | [post] arr4 [unknown] | provenance | |
|
||||
| test.ps1:21:6:21:10 | arr4 [unknown] | test.ps1:21:6:21:21 | ...[...] | provenance | |
|
||||
| test.ps1:23:1:23:5 | [post] arr5 [unknown, element 1] | test.ps1:24:6:24:10 | arr5 [unknown, element 1] | provenance | |
|
||||
| test.ps1:23:1:23:16 | [post] ...[...] [element 1] | test.ps1:23:1:23:5 | [post] arr5 [unknown, element 1] | provenance | |
|
||||
| test.ps1:23:23:23:32 | Call to Source | test.ps1:23:1:23:16 | [post] ...[...] [element 1] | provenance | |
|
||||
| test.ps1:24:6:24:10 | arr5 [element, element 1] | test.ps1:24:6:24:21 | ...[...] [element 1] | provenance | |
|
||||
| test.ps1:24:6:24:10 | arr5 [unknown, element 1] | test.ps1:24:6:24:21 | ...[...] [element 1] | provenance | |
|
||||
| test.ps1:24:6:24:21 | ...[...] [element 1] | test.ps1:24:6:24:24 | ...[...] | provenance | |
|
||||
| test.ps1:27:1:27:5 | [post] arr6 [element 1, element] | test.ps1:28:6:28:10 | arr6 [element 1, element] | provenance | |
|
||||
| test.ps1:27:1:27:8 | [post] ...[...] [element] | test.ps1:27:1:27:5 | [post] arr6 [element 1, element] | provenance | |
|
||||
| test.ps1:27:23:27:32 | Call to Source | test.ps1:27:1:27:8 | [post] ...[...] [element] | provenance | |
|
||||
| test.ps1:28:6:28:10 | arr6 [element 1, element] | test.ps1:28:6:28:13 | ...[...] [element] | provenance | |
|
||||
| test.ps1:28:6:28:13 | ...[...] [element] | test.ps1:28:6:28:24 | ...[...] | provenance | |
|
||||
| test.ps1:31:1:31:5 | [post] arr7 [element, element] | test.ps1:32:6:32:10 | arr7 [element, element] | provenance | |
|
||||
| test.ps1:31:1:31:5 | [post] arr7 [element, element] | test.ps1:33:6:33:10 | arr7 [element, element] | provenance | |
|
||||
| test.ps1:31:1:31:16 | [post] ...[...] [element] | test.ps1:31:1:31:5 | [post] arr7 [element, element] | provenance | |
|
||||
| test.ps1:31:31:31:40 | Call to Source | test.ps1:31:1:31:16 | [post] ...[...] [element] | provenance | |
|
||||
| test.ps1:32:6:32:10 | arr7 [element, element] | test.ps1:32:6:32:13 | ...[...] [element] | provenance | |
|
||||
| test.ps1:32:6:32:13 | ...[...] [element] | test.ps1:32:6:32:16 | ...[...] | provenance | |
|
||||
| test.ps1:33:6:33:10 | arr7 [element, element] | test.ps1:33:6:33:21 | ...[...] [element] | provenance | |
|
||||
| test.ps1:33:6:33:21 | ...[...] [element] | test.ps1:33:6:33:32 | ...[...] | provenance | |
|
||||
| test.ps1:27:1:27:5 | [post] arr6 [element 1, unknown] | test.ps1:28:6:28:10 | arr6 [element 1, unknown] | provenance | |
|
||||
| test.ps1:27:1:27:8 | [post] ...[...] [unknown] | test.ps1:27:1:27:5 | [post] arr6 [element 1, unknown] | provenance | |
|
||||
| test.ps1:27:23:27:32 | Call to Source | test.ps1:27:1:27:8 | [post] ...[...] [unknown] | provenance | |
|
||||
| test.ps1:28:6:28:10 | arr6 [element 1, unknown] | test.ps1:28:6:28:13 | ...[...] [unknown] | provenance | |
|
||||
| test.ps1:28:6:28:13 | ...[...] [unknown] | test.ps1:28:6:28:24 | ...[...] | provenance | |
|
||||
| test.ps1:31:1:31:5 | [post] arr7 [unknown, unknown] | test.ps1:32:6:32:10 | arr7 [unknown, unknown] | provenance | |
|
||||
| test.ps1:31:1:31:5 | [post] arr7 [unknown, unknown] | test.ps1:33:6:33:10 | arr7 [unknown, unknown] | provenance | |
|
||||
| test.ps1:31:1:31:16 | [post] ...[...] [unknown] | test.ps1:31:1:31:5 | [post] arr7 [unknown, unknown] | provenance | |
|
||||
| test.ps1:31:31:31:40 | Call to Source | test.ps1:31:1:31:16 | [post] ...[...] [unknown] | provenance | |
|
||||
| test.ps1:32:6:32:10 | arr7 [unknown, unknown] | test.ps1:32:6:32:13 | ...[...] [unknown] | provenance | |
|
||||
| test.ps1:32:6:32:13 | ...[...] [unknown] | test.ps1:32:6:32:16 | ...[...] | provenance | |
|
||||
| test.ps1:33:6:33:10 | arr7 [unknown, unknown] | test.ps1:33:6:33:21 | ...[...] [unknown] | provenance | |
|
||||
| test.ps1:33:6:33:21 | ...[...] [unknown] | test.ps1:33:6:33:32 | ...[...] | provenance | |
|
||||
| test.ps1:35:6:35:16 | Call to Source | test.ps1:37:15:37:16 | x | provenance | |
|
||||
| test.ps1:37:9:37:16 | ...,... [element 2] | test.ps1:40:6:40:10 | arr8 [element 2] | provenance | |
|
||||
| test.ps1:37:9:37:16 | ...,... [element 2] | test.ps1:41:6:41:10 | arr8 [element 2] | provenance | |
|
||||
@@ -53,15 +53,15 @@ edges
|
||||
| test.ps1:66:10:66:20 | Call to Source | test.ps1:69:5:69:6 | x | provenance | |
|
||||
| test.ps1:67:10:67:20 | Call to Source | test.ps1:70:5:70:6 | y | provenance | |
|
||||
| test.ps1:68:10:68:20 | Call to Source | test.ps1:70:9:70:10 | z | provenance | |
|
||||
| test.ps1:69:5:69:6 | x | test.ps1:73:6:73:12 | Call to produce [element] | provenance | |
|
||||
| test.ps1:70:5:70:6 | y | test.ps1:73:6:73:12 | Call to produce [element] | provenance | |
|
||||
| test.ps1:70:9:70:10 | z | test.ps1:73:6:73:12 | Call to produce [element] | provenance | |
|
||||
| test.ps1:73:6:73:12 | Call to produce [element] | test.ps1:74:6:74:7 | x [element] | provenance | |
|
||||
| test.ps1:73:6:73:12 | Call to produce [element] | test.ps1:75:6:75:7 | x [element] | provenance | |
|
||||
| test.ps1:73:6:73:12 | Call to produce [element] | test.ps1:76:6:76:7 | x [element] | provenance | |
|
||||
| test.ps1:74:6:74:7 | x [element] | test.ps1:74:6:74:10 | ...[...] | provenance | |
|
||||
| test.ps1:75:6:75:7 | x [element] | test.ps1:75:6:75:10 | ...[...] | provenance | |
|
||||
| test.ps1:76:6:76:7 | x [element] | test.ps1:76:6:76:10 | ...[...] | provenance | |
|
||||
| test.ps1:69:5:69:6 | x | test.ps1:73:6:73:12 | Call to produce [unknown index] | provenance | |
|
||||
| test.ps1:70:5:70:6 | y | test.ps1:73:6:73:12 | Call to produce [unknown index] | provenance | |
|
||||
| test.ps1:70:9:70:10 | z | test.ps1:73:6:73:12 | Call to produce [unknown index] | provenance | |
|
||||
| test.ps1:73:6:73:12 | Call to produce [unknown index] | test.ps1:74:6:74:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:73:6:73:12 | Call to produce [unknown index] | test.ps1:75:6:75:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:73:6:73:12 | Call to produce [unknown index] | test.ps1:76:6:76:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:74:6:74:7 | x [unknown index] | test.ps1:74:6:74:10 | ...[...] | provenance | |
|
||||
| test.ps1:75:6:75:7 | x [unknown index] | test.ps1:75:6:75:10 | ...[...] | provenance | |
|
||||
| test.ps1:76:6:76:7 | x [unknown index] | test.ps1:76:6:76:10 | ...[...] | provenance | |
|
||||
| test.ps1:78:9:81:1 | ${...} [element a] | test.ps1:83:6:83:10 | hash [element a] | provenance | |
|
||||
| test.ps1:78:9:81:1 | ${...} [element a] | test.ps1:87:6:87:10 | hash [element a] | provenance | |
|
||||
| test.ps1:79:7:79:17 | Call to Source | test.ps1:78:9:81:1 | ${...} [element a] | provenance | |
|
||||
@@ -79,38 +79,38 @@ nodes
|
||||
| test.ps1:10:12:10:21 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:11:6:11:10 | arr1 [element 3] | semmle.label | arr1 [element 3] |
|
||||
| test.ps1:11:6:11:13 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:14:1:14:5 | [post] arr2 [element] | semmle.label | [post] arr2 [element] |
|
||||
| test.ps1:14:1:14:5 | [post] arr2 [unknown] | semmle.label | [post] arr2 [unknown] |
|
||||
| test.ps1:14:19:14:28 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:15:6:15:10 | arr2 [element] | semmle.label | arr2 [element] |
|
||||
| test.ps1:15:6:15:10 | arr2 [unknown] | semmle.label | arr2 [unknown] |
|
||||
| test.ps1:15:6:15:13 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:17:1:17:5 | [post] arr3 [element 3] | semmle.label | [post] arr3 [element 3] |
|
||||
| test.ps1:17:12:17:21 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:18:6:18:10 | arr3 [element 3] | semmle.label | arr3 [element 3] |
|
||||
| test.ps1:18:6:18:20 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:20:1:20:5 | [post] arr4 [element] | semmle.label | [post] arr4 [element] |
|
||||
| test.ps1:20:1:20:5 | [post] arr4 [unknown] | semmle.label | [post] arr4 [unknown] |
|
||||
| test.ps1:20:20:20:29 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:21:6:21:10 | arr4 [element] | semmle.label | arr4 [element] |
|
||||
| test.ps1:21:6:21:10 | arr4 [unknown] | semmle.label | arr4 [unknown] |
|
||||
| test.ps1:21:6:21:21 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:23:1:23:5 | [post] arr5 [element, element 1] | semmle.label | [post] arr5 [element, element 1] |
|
||||
| test.ps1:23:1:23:5 | [post] arr5 [unknown, element 1] | semmle.label | [post] arr5 [unknown, element 1] |
|
||||
| test.ps1:23:1:23:16 | [post] ...[...] [element 1] | semmle.label | [post] ...[...] [element 1] |
|
||||
| test.ps1:23:23:23:32 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:24:6:24:10 | arr5 [element, element 1] | semmle.label | arr5 [element, element 1] |
|
||||
| test.ps1:24:6:24:10 | arr5 [unknown, element 1] | semmle.label | arr5 [unknown, element 1] |
|
||||
| test.ps1:24:6:24:21 | ...[...] [element 1] | semmle.label | ...[...] [element 1] |
|
||||
| test.ps1:24:6:24:24 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:27:1:27:5 | [post] arr6 [element 1, element] | semmle.label | [post] arr6 [element 1, element] |
|
||||
| test.ps1:27:1:27:8 | [post] ...[...] [element] | semmle.label | [post] ...[...] [element] |
|
||||
| test.ps1:27:1:27:5 | [post] arr6 [element 1, unknown] | semmle.label | [post] arr6 [element 1, unknown] |
|
||||
| test.ps1:27:1:27:8 | [post] ...[...] [unknown] | semmle.label | [post] ...[...] [unknown] |
|
||||
| test.ps1:27:23:27:32 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:28:6:28:10 | arr6 [element 1, element] | semmle.label | arr6 [element 1, element] |
|
||||
| test.ps1:28:6:28:13 | ...[...] [element] | semmle.label | ...[...] [element] |
|
||||
| test.ps1:28:6:28:10 | arr6 [element 1, unknown] | semmle.label | arr6 [element 1, unknown] |
|
||||
| test.ps1:28:6:28:13 | ...[...] [unknown] | semmle.label | ...[...] [unknown] |
|
||||
| test.ps1:28:6:28:24 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:31:1:31:5 | [post] arr7 [element, element] | semmle.label | [post] arr7 [element, element] |
|
||||
| test.ps1:31:1:31:16 | [post] ...[...] [element] | semmle.label | [post] ...[...] [element] |
|
||||
| test.ps1:31:1:31:5 | [post] arr7 [unknown, unknown] | semmle.label | [post] arr7 [unknown, unknown] |
|
||||
| test.ps1:31:1:31:16 | [post] ...[...] [unknown] | semmle.label | [post] ...[...] [unknown] |
|
||||
| test.ps1:31:31:31:40 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:32:6:32:10 | arr7 [element, element] | semmle.label | arr7 [element, element] |
|
||||
| test.ps1:32:6:32:13 | ...[...] [element] | semmle.label | ...[...] [element] |
|
||||
| test.ps1:32:6:32:10 | arr7 [unknown, unknown] | semmle.label | arr7 [unknown, unknown] |
|
||||
| test.ps1:32:6:32:13 | ...[...] [unknown] | semmle.label | ...[...] [unknown] |
|
||||
| test.ps1:32:6:32:16 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:33:6:33:10 | arr7 [element, element] | semmle.label | arr7 [element, element] |
|
||||
| test.ps1:33:6:33:21 | ...[...] [element] | semmle.label | ...[...] [element] |
|
||||
| test.ps1:33:6:33:10 | arr7 [unknown, unknown] | semmle.label | arr7 [unknown, unknown] |
|
||||
| test.ps1:33:6:33:21 | ...[...] [unknown] | semmle.label | ...[...] [unknown] |
|
||||
| test.ps1:33:6:33:32 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:35:6:35:16 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:37:9:37:16 | ...,... [element 2] | semmle.label | ...,... [element 2] |
|
||||
@@ -138,12 +138,12 @@ nodes
|
||||
| test.ps1:69:5:69:6 | x | semmle.label | x |
|
||||
| test.ps1:70:5:70:6 | y | semmle.label | y |
|
||||
| test.ps1:70:9:70:10 | z | semmle.label | z |
|
||||
| test.ps1:73:6:73:12 | Call to produce [element] | semmle.label | Call to produce [element] |
|
||||
| test.ps1:74:6:74:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:73:6:73:12 | Call to produce [unknown index] | semmle.label | Call to produce [unknown index] |
|
||||
| test.ps1:74:6:74:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:74:6:74:10 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:75:6:75:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:75:6:75:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:75:6:75:10 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:76:6:76:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:76:6:76:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:76:6:76:10 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:78:9:81:1 | ${...} [element a] | semmle.label | ${...} [element a] |
|
||||
| test.ps1:79:7:79:17 | Call to Source | semmle.label | Call to Source |
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
| test.ps1:2:1:2:8 | Call to Sink | test.ps1:1:1:24:22 | pre-return value for {...} |
|
||||
| test.ps1:4:1:4:2 | b | test.ps1:5:4:5:5 | b |
|
||||
| test.ps1:4:6:4:12 | Call to GetBool | test.ps1:4:1:4:2 | b |
|
||||
| test.ps1:5:1:7:1 | phi | test.ps1:8:6:8:8 | a2 |
|
||||
| test.ps1:5:1:7:1 | phi (a2) | test.ps1:8:6:8:8 | a2 |
|
||||
| test.ps1:5:4:5:5 | b | test.ps1:10:14:10:15 | b |
|
||||
| test.ps1:6:5:6:7 | a2 | test.ps1:6:11:6:16 | [input] phi |
|
||||
| test.ps1:6:5:6:7 | a2 | test.ps1:6:11:6:16 | [input] phi (a2) |
|
||||
| test.ps1:6:11:6:16 | Call to Source | test.ps1:6:5:6:7 | a2 |
|
||||
| test.ps1:6:11:6:16 | [input] phi | test.ps1:5:1:7:1 | phi |
|
||||
| test.ps1:6:11:6:16 | [input] phi (a2) | test.ps1:5:1:7:1 | phi (a2) |
|
||||
| test.ps1:8:1:8:8 | Call to Sink | test.ps1:1:1:24:22 | pre-return value for {...} |
|
||||
| test.ps1:8:1:8:8 | Call to Sink | test.ps1:1:1:24:22 | pre-return value for {...} |
|
||||
| test.ps1:10:1:10:2 | c | test.ps1:11:6:11:7 | c |
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
| test.ps1:2:1:2:8 | Call to Sink | test.ps1:1:1:24:22 | pre-return value for {...} |
|
||||
| test.ps1:4:1:4:2 | b | test.ps1:5:4:5:5 | b |
|
||||
| test.ps1:4:6:4:12 | Call to GetBool | test.ps1:4:1:4:2 | b |
|
||||
| test.ps1:5:1:7:1 | phi | test.ps1:8:6:8:8 | a2 |
|
||||
| test.ps1:5:1:7:1 | phi (a2) | test.ps1:8:6:8:8 | a2 |
|
||||
| test.ps1:5:4:5:5 | b | test.ps1:10:14:10:15 | b |
|
||||
| test.ps1:6:5:6:7 | a2 | test.ps1:6:11:6:16 | [input] phi |
|
||||
| test.ps1:6:5:6:7 | a2 | test.ps1:6:11:6:16 | [input] phi (a2) |
|
||||
| test.ps1:6:11:6:16 | Call to Source | test.ps1:6:5:6:7 | a2 |
|
||||
| test.ps1:6:11:6:16 | [input] phi | test.ps1:5:1:7:1 | phi |
|
||||
| test.ps1:6:11:6:16 | [input] phi (a2) | test.ps1:5:1:7:1 | phi (a2) |
|
||||
| test.ps1:8:1:8:8 | Call to Sink | test.ps1:1:1:24:22 | pre-return value for {...} |
|
||||
| test.ps1:8:1:8:8 | Call to Sink | test.ps1:1:1:24:22 | pre-return value for {...} |
|
||||
| test.ps1:10:1:10:2 | c | test.ps1:11:6:11:7 | c |
|
||||
|
||||
@@ -3,24 +3,21 @@ edges
|
||||
| test.ps1:2:10:2:19 | Call to Source | test.ps1:5:5:5:6 | x | provenance | |
|
||||
| test.ps1:3:10:3:19 | Call to Source | test.ps1:6:5:6:6 | y | provenance | |
|
||||
| test.ps1:4:10:4:19 | Call to Source | test.ps1:6:9:6:10 | z | provenance | |
|
||||
| test.ps1:5:5:5:6 | x | test.ps1:17:1:17:7 | Call to produce [element] | provenance | |
|
||||
| test.ps1:6:5:6:6 | y | test.ps1:17:1:17:7 | Call to produce [element] | provenance | |
|
||||
| test.ps1:6:9:6:10 | z | test.ps1:17:1:17:7 | Call to produce [element] | provenance | |
|
||||
| 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 [element] | test.ps1:12:5:14:5 | [synth] pipeline [element] | 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 [element] | test.ps1:13:9:13:15 | __pipeline_iterator | provenance | |
|
||||
| test.ps1:17:1:17:7 | Call to produce [element] | test.ps1:9:29:15:1 | [synth] pipeline [element] | provenance | |
|
||||
| test.ps1:17:1:17:7 | Call to produce [element] | test.ps1:17:1:17:7 | Call to produce [element] | 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: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 0] | test.ps1:21:1:21:6 | ...,... [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 1] | test.ps1:21:1:21:6 | ...,... [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 | |
|
||||
@@ -30,10 +27,26 @@ edges
|
||||
| test.ps1:30:6:30:15 | Call to Source | test.ps1:31:5:31:6 | y | provenance | |
|
||||
| test.ps1:31:1:31:2 | x | test.ps1:31:1:31:6 | ...,... [element 0] | provenance | |
|
||||
| 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 0] | test.ps1:31:1:31:6 | ...,... [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:1:31:6 | ...,... [element 1] | test.ps1:31:1:31:6 | ...,... [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: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: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 | |
|
||||
| test.ps1:50:52:50:69 | ${...} [element x] | test.ps1:50:36:50:69 | [...]... [element x] | provenance | |
|
||||
| test.ps1:50:58:50:68 | Call to Source | test.ps1:50:52:50:69 | ${...} [element x] | provenance | |
|
||||
| test.ps1:50:72:50:105 | [...]... [element x] | test.ps1:50:1:50:105 | ...,... [element 2, element x] | provenance | |
|
||||
| test.ps1:50:88:50:105 | ${...} [element x] | test.ps1:50:72:50:105 | [...]... [element x] | provenance | |
|
||||
| test.ps1:50:94:50:104 | Call to Source | test.ps1:50:88:50:105 | ${...} [element x] | provenance | |
|
||||
nodes
|
||||
| test.ps1:2:10:2:19 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:3:10:3:19 | Call to Source | semmle.label | Call to Source |
|
||||
@@ -43,19 +56,16 @@ nodes
|
||||
| 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 [element] | semmle.label | [synth] pipeline [element] |
|
||||
| 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 [element] | semmle.label | [synth] pipeline [element] |
|
||||
| test.ps1:12:5:14:5 | [synth] pipeline [unknown index] | semmle.label | [synth] pipeline [unknown index] |
|
||||
| test.ps1:13:9:13:15 | __pipeline_iterator | semmle.label | __pipeline_iterator |
|
||||
| test.ps1:17:1:17:7 | Call to produce [element] | semmle.label | Call to produce [element] |
|
||||
| test.ps1:17:1:17:7 | Call to produce [element] | semmle.label | Call to produce [element] |
|
||||
| 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 |
|
||||
| test.ps1:20:6:20:15 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:21:1:21:2 | x | semmle.label | x |
|
||||
| test.ps1:21:1:21:6 | ...,... [element 0] | semmle.label | ...,... [element 0] |
|
||||
| test.ps1:21:1:21:6 | ...,... [element 0] | semmle.label | ...,... [element 0] |
|
||||
| test.ps1:21:1:21:6 | ...,... [element 1] | semmle.label | ...,... [element 1] |
|
||||
| test.ps1:21:1:21:6 | ...,... [element 1] | semmle.label | ...,... [element 1] |
|
||||
| test.ps1:21:5:21:6 | y | semmle.label | y |
|
||||
| test.ps1:23:38:27:1 | [synth] pipeline [element 0] | semmle.label | [synth] pipeline [element 0] |
|
||||
@@ -67,16 +77,29 @@ nodes
|
||||
| test.ps1:30:6:30:15 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:31:1:31:2 | x | semmle.label | x |
|
||||
| test.ps1:31:1:31:6 | ...,... [element 0] | semmle.label | ...,... [element 0] |
|
||||
| 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: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: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] |
|
||||
| test.ps1:46:9:46:15 | __pipeline_iterator for x | semmle.label | __pipeline_iterator for x |
|
||||
| test.ps1:50:1:50:33 | [...]... [element x] | semmle.label | [...]... [element x] |
|
||||
| test.ps1:50:1:50:105 | ...,... [element 0, element x] | semmle.label | ...,... [element 0, element x] |
|
||||
| test.ps1:50:1:50:105 | ...,... [element 1, element x] | semmle.label | ...,... [element 1, element x] |
|
||||
| test.ps1:50:1:50:105 | ...,... [element 2, element x] | semmle.label | ...,... [element 2, element x] |
|
||||
| test.ps1:50:17:50:33 | ${...} [element x] | semmle.label | ${...} [element x] |
|
||||
| test.ps1:50:23:50:32 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:50:36:50:69 | [...]... [element x] | semmle.label | [...]... [element x] |
|
||||
| test.ps1:50:52:50:69 | ${...} [element x] | semmle.label | ${...} [element x] |
|
||||
| test.ps1:50:58:50:68 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:50:72:50:105 | [...]... [element x] | semmle.label | [...]... [element x] |
|
||||
| test.ps1:50:88:50:105 | ${...} [element x] | semmle.label | ${...} [element x] |
|
||||
| test.ps1:50:94:50:104 | Call to Source | semmle.label | Call to Source |
|
||||
subpaths
|
||||
testFailures
|
||||
| test.ps1:36:13:36:30 | # $ hasValueFlow=8 | Missing result: hasValueFlow=8 |
|
||||
| test.ps1:46:17:46:66 | # $ hasValueFlow=9 hasValueFlow=10 hasValueFlow=11 | Missing result: hasValueFlow=9 |
|
||||
| test.ps1:46:17:46:66 | # $ hasValueFlow=9 hasValueFlow=10 hasValueFlow=11 | Missing result: hasValueFlow=10 |
|
||||
| test.ps1:46:17:46:66 | # $ hasValueFlow=9 hasValueFlow=10 hasValueFlow=11 | Missing result: hasValueFlow=11 |
|
||||
#select
|
||||
| test.ps1:13:9:13:15 | __pipeline_iterator | test.ps1:2:10:2:19 | Call to Source | test.ps1:13:9:13:15 | __pipeline_iterator | $@ | test.ps1:2:10:2:19 | Call to Source | Call to Source |
|
||||
| test.ps1:13:9:13:15 | __pipeline_iterator | test.ps1:3:10:3:19 | Call to Source | test.ps1:13:9:13:15 | __pipeline_iterator | $@ | test.ps1:3:10:3:19 | Call to Source | Call to Source |
|
||||
@@ -85,3 +108,6 @@ testFailures
|
||||
| test.ps1:13:9:13:15 | __pipeline_iterator | test.ps1:20:6:20:15 | Call to Source | test.ps1:13:9:13:15 | __pipeline_iterator | $@ | test.ps1:20:6:20:15 | Call to Source | Call to Source |
|
||||
| test.ps1:25:9:25:15 | __pipeline_iterator | test.ps1:29:6:29:15 | Call to Source | test.ps1:25:9:25:15 | __pipeline_iterator | $@ | test.ps1:29:6:29:15 | Call to Source | Call to Source |
|
||||
| test.ps1:25:9:25:15 | __pipeline_iterator | test.ps1:30:6:30:15 | Call to Source | test.ps1:25:9:25:15 | __pipeline_iterator | $@ | test.ps1:30:6:30:15 | Call to Source | Call to Source |
|
||||
| test.ps1:46:9:46:15 | __pipeline_iterator for x | test.ps1:50:23:50:32 | Call to Source | test.ps1:46:9:46:15 | __pipeline_iterator for x | $@ | test.ps1:50:23:50:32 | Call to Source | Call to Source |
|
||||
| test.ps1:46:9:46:15 | __pipeline_iterator for x | test.ps1:50:58:50:68 | Call to Source | test.ps1:46:9:46:15 | __pipeline_iterator for x | $@ | test.ps1:50:58:50:68 | Call to Source | Call to Source |
|
||||
| test.ps1:46:9:46:15 | __pipeline_iterator for x | test.ps1:50:94:50:104 | Call to Source | test.ps1:46:9:46:15 | __pipeline_iterator for x | $@ | test.ps1:50:94:50:104 | Call to Source | Call to Source |
|
||||
|
||||
@@ -33,7 +33,7 @@ $x, $y | consumeWithProcessAnonymous
|
||||
function consumeValueFromPipelineByPropertyNameWithoutProcess {
|
||||
Param([Parameter(ValueFromPipelineByPropertyName)] $x)
|
||||
|
||||
Sink $x # $ hasValueFlow=8
|
||||
Sink $x # $ MISSING: hasValueFlow=8
|
||||
}
|
||||
|
||||
$x = Source "8"
|
||||
|
||||
@@ -2,37 +2,37 @@ models
|
||||
edges
|
||||
| test.ps1:2:5:2:14 | Call to Source | test.ps1:5:6:5:19 | Call to callSourceOnce | provenance | |
|
||||
| test.ps1:5:6:5:19 | Call to callSourceOnce | test.ps1:6:6:6:7 | x | provenance | |
|
||||
| test.ps1:9:5:9:14 | Call to Source | test.ps1:13:6:13:20 | Call to callSourceTwice [element] | provenance | |
|
||||
| test.ps1:10:5:10:14 | Call to Source | test.ps1:13:6:13:20 | Call to callSourceTwice [element] | provenance | |
|
||||
| test.ps1:13:6:13:20 | Call to callSourceTwice [element] | test.ps1:15:6:15:7 | x [element] | provenance | |
|
||||
| test.ps1:13:6:13:20 | Call to callSourceTwice [element] | test.ps1:16:6:16:7 | x [element] | provenance | |
|
||||
| test.ps1:15:6:15:7 | x [element] | test.ps1:15:6:15:10 | ...[...] | provenance | |
|
||||
| test.ps1:16:6:16:7 | x [element] | test.ps1:16:6:16:10 | ...[...] | provenance | |
|
||||
| test.ps1:9:5:9:14 | Call to Source | test.ps1:13:6:13:20 | Call to callSourceTwice [unknown index] | provenance | |
|
||||
| test.ps1:10:5:10:14 | Call to Source | test.ps1:13:6:13:20 | Call to callSourceTwice [unknown index] | provenance | |
|
||||
| test.ps1:13:6:13:20 | Call to callSourceTwice [unknown index] | test.ps1:15:6:15:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:13:6:13:20 | Call to callSourceTwice [unknown index] | test.ps1:16:6:16:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:15:6:15:7 | x [unknown index] | test.ps1:15:6:15:10 | ...[...] | provenance | |
|
||||
| test.ps1:16:6:16:7 | x [unknown index] | test.ps1:16:6:16:10 | ...[...] | provenance | |
|
||||
| test.ps1:19:12:19:21 | Call to Source | test.ps1:22:6:22:18 | Call to returnSource1 | provenance | |
|
||||
| test.ps1:22:6:22:18 | Call to returnSource1 | test.ps1:23:6:23:7 | x | provenance | |
|
||||
| test.ps1:26:10:26:19 | Call to Source | test.ps1:27:5:27:6 | x | provenance | |
|
||||
| test.ps1:27:5:27:6 | x | test.ps1:32:6:32:18 | Call to returnSource2 [element] | provenance | |
|
||||
| test.ps1:27:5:27:6 | x | test.ps1:32:6:32:18 | Call to returnSource2 [unknown index] | provenance | |
|
||||
| test.ps1:28:10:28:19 | Call to Source | test.ps1:29:12:29:13 | y | provenance | |
|
||||
| test.ps1:29:12:29:13 | y | test.ps1:32:6:32:18 | Call to returnSource2 [element] | provenance | |
|
||||
| test.ps1:32:6:32:18 | Call to returnSource2 [element] | test.ps1:33:6:33:7 | x [element] | provenance | |
|
||||
| test.ps1:32:6:32:18 | Call to returnSource2 [element] | test.ps1:34:6:34:7 | x [element] | provenance | |
|
||||
| test.ps1:33:6:33:7 | x [element] | test.ps1:33:6:33:10 | ...[...] | provenance | |
|
||||
| test.ps1:34:6:34:7 | x [element] | test.ps1:34:6:34:10 | ...[...] | provenance | |
|
||||
| test.ps1:38:9:38:18 | Call to Source | test.ps1:42:6:42:21 | Call to callSourceInLoop [element] | provenance | |
|
||||
| test.ps1:42:6:42:21 | Call to callSourceInLoop [element] | test.ps1:43:6:43:7 | x [element] | provenance | |
|
||||
| test.ps1:42:6:42:21 | Call to callSourceInLoop [element] | test.ps1:44:6:44:7 | x [element] | provenance | |
|
||||
| test.ps1:43:6:43:7 | x [element] | test.ps1:43:6:43:10 | ...[...] | provenance | |
|
||||
| test.ps1:44:6:44:7 | x [element] | test.ps1:44:6:44:10 | ...[...] | provenance | |
|
||||
| test.ps1:29:12:29:13 | y | test.ps1:32:6:32:18 | Call to returnSource2 [unknown index] | provenance | |
|
||||
| test.ps1:32:6:32:18 | Call to returnSource2 [unknown index] | test.ps1:33:6:33:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:32:6:32:18 | Call to returnSource2 [unknown index] | test.ps1:34:6:34:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:33:6:33:7 | x [unknown index] | test.ps1:33:6:33:10 | ...[...] | provenance | |
|
||||
| test.ps1:34:6:34:7 | x [unknown index] | test.ps1:34:6:34:10 | ...[...] | provenance | |
|
||||
| test.ps1:38:9:38:18 | Call to Source | test.ps1:42:6:42:21 | Call to callSourceInLoop [unknown index] | provenance | |
|
||||
| test.ps1:42:6:42:21 | Call to callSourceInLoop [unknown index] | test.ps1:43:6:43:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:42:6:42:21 | Call to callSourceInLoop [unknown index] | test.ps1:44:6:44:7 | x [unknown index] | provenance | |
|
||||
| test.ps1:43:6:43:7 | x [unknown index] | test.ps1:43:6:43:10 | ...[...] | provenance | |
|
||||
| test.ps1:44:6:44:7 | x [unknown index] | test.ps1:44:6:44:10 | ...[...] | provenance | |
|
||||
nodes
|
||||
| test.ps1:2:5:2:14 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:5:6:5:19 | Call to callSourceOnce | semmle.label | Call to callSourceOnce |
|
||||
| test.ps1:6:6:6:7 | x | semmle.label | x |
|
||||
| test.ps1:9:5:9:14 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:10:5:10:14 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:13:6:13:20 | Call to callSourceTwice [element] | semmle.label | Call to callSourceTwice [element] |
|
||||
| test.ps1:15:6:15:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:13:6:13:20 | Call to callSourceTwice [unknown index] | semmle.label | Call to callSourceTwice [unknown index] |
|
||||
| test.ps1:15:6:15:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:15:6:15:10 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:16:6:16:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:16:6:16:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:16:6:16:10 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:19:12:19:21 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:22:6:22:18 | Call to returnSource1 | semmle.label | Call to returnSource1 |
|
||||
@@ -41,16 +41,16 @@ nodes
|
||||
| test.ps1:27:5:27:6 | x | semmle.label | x |
|
||||
| test.ps1:28:10:28:19 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:29:12:29:13 | y | semmle.label | y |
|
||||
| test.ps1:32:6:32:18 | Call to returnSource2 [element] | semmle.label | Call to returnSource2 [element] |
|
||||
| test.ps1:33:6:33:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:32:6:32:18 | Call to returnSource2 [unknown index] | semmle.label | Call to returnSource2 [unknown index] |
|
||||
| test.ps1:33:6:33:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:33:6:33:10 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:34:6:34:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:34:6:34:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:34:6:34:10 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:38:9:38:18 | Call to Source | semmle.label | Call to Source |
|
||||
| test.ps1:42:6:42:21 | Call to callSourceInLoop [element] | semmle.label | Call to callSourceInLoop [element] |
|
||||
| test.ps1:43:6:43:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:42:6:42:21 | Call to callSourceInLoop [unknown index] | semmle.label | Call to callSourceInLoop [unknown index] |
|
||||
| test.ps1:43:6:43:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:43:6:43:10 | ...[...] | semmle.label | ...[...] |
|
||||
| test.ps1:44:6:44:7 | x [element] | semmle.label | x [element] |
|
||||
| test.ps1:44:6:44:7 | x [unknown index] | semmle.label | x [unknown index] |
|
||||
| test.ps1:44:6:44:10 | ...[...] | semmle.label | ...[...] |
|
||||
subpaths
|
||||
testFailures
|
||||
|
||||
Reference in New Issue
Block a user