mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge branch 'main' into criemen/pytest-ruby
This commit is contained in:
11
ruby/ql/lib/codeql/ruby/controlflow/internal/Guards.qll
Normal file
11
ruby/ql/lib/codeql/ruby/controlflow/internal/Guards.qll
Normal file
@@ -0,0 +1,11 @@
|
||||
private import codeql.ruby.CFG
|
||||
|
||||
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
|
||||
pragma[nomagic]
|
||||
predicate guardControlsBlock(CfgNodes::AstCfgNode guard, BasicBlock bb, boolean branch) {
|
||||
exists(ConditionBlock conditionBlock, SuccessorTypes::ConditionalSuccessor s |
|
||||
guard = conditionBlock.getLastNode() and
|
||||
s.getValue() = branch and
|
||||
conditionBlock.controls(bb, s)
|
||||
)
|
||||
}
|
||||
@@ -202,8 +202,17 @@ module Ssa {
|
||||
final VariableWriteAccessCfgNode getWriteAccess() { result = write }
|
||||
|
||||
/**
|
||||
* Holds if this SSA definition represents a direct assignment of `value`
|
||||
* to the underlying variable.
|
||||
* Holds if this SSA definition assigns `value` to the underlying variable.
|
||||
*
|
||||
* This is either a direct assignment, `x = value`, or an assignment via
|
||||
* simple pattern matching
|
||||
*
|
||||
* ```rb
|
||||
* case value
|
||||
* in Foo => x then ...
|
||||
* in y => then ...
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
predicate assigns(CfgNodes::ExprCfgNode value) {
|
||||
exists(CfgNodes::ExprNodes::AssignExprCfgNode a, BasicBlock bb, int i |
|
||||
@@ -211,6 +220,14 @@ module Ssa {
|
||||
a = bb.getNode(i) and
|
||||
value = a.getRhs()
|
||||
)
|
||||
or
|
||||
exists(CfgNodes::ExprNodes::CaseExprCfgNode case, CfgNodes::AstCfgNode pattern |
|
||||
case.getValue() = value and
|
||||
pattern = case.getBranch(_).(CfgNodes::ExprNodes::InClauseCfgNode).getPattern()
|
||||
|
|
||||
this.getWriteAccess() =
|
||||
[pattern, pattern.(CfgNodes::ExprNodes::AsPatternCfgNode).getVariableAccess()]
|
||||
)
|
||||
}
|
||||
|
||||
final override string toString() { result = write.toString() }
|
||||
|
||||
@@ -1073,8 +1073,7 @@ private module TrackSingletonMethodOnInstanceInput implements CallGraphConstruct
|
||||
singletonMethodOnInstance(_, _, nodeFromPreExpr.getExpr())
|
||||
)
|
||||
|
|
||||
nodeFromPreExpr =
|
||||
LocalFlow::getParameterDefNode(p.getParameter()).getDefinitionExt().getARead()
|
||||
nodeFromPreExpr = getParameterDef(p.getParameter()).getARead()
|
||||
or
|
||||
nodeFromPreExpr = p.(SelfParameterNodeImpl).getSelfDefinition().getARead()
|
||||
)
|
||||
|
||||
@@ -72,134 +72,48 @@ CfgNodes::ExprCfgNode getAPostUpdateNodeForArg(Argument arg) {
|
||||
not exists(getALastEvalNode(result))
|
||||
}
|
||||
|
||||
/** An SSA definition into which another SSA definition may flow. */
|
||||
class SsaInputDefinitionExt extends SsaImpl::DefinitionExt {
|
||||
SsaInputDefinitionExt() {
|
||||
this instanceof Ssa::PhiNode
|
||||
/** Gets the SSA definition node corresponding to parameter `p`. */
|
||||
pragma[nomagic]
|
||||
SsaImpl::DefinitionExt getParameterDef(NamedParameter p) {
|
||||
exists(BasicBlock bb, int i |
|
||||
bb.getNode(i).getAstNode() = p.getDefiningAccess() and
|
||||
result.definesAt(_, bb, i, _)
|
||||
)
|
||||
}
|
||||
|
||||
/** Provides logic related to SSA. */
|
||||
module SsaFlow {
|
||||
private module Impl = SsaImpl::DataFlowIntegration;
|
||||
|
||||
private ParameterNodeImpl toParameterNode(SsaImpl::ParameterExt p) {
|
||||
result = TNormalParameterNode(p.asParameter())
|
||||
or
|
||||
this instanceof SsaImpl::PhiReadNode
|
||||
result = TSelfMethodParameterNode(p.asMethodSelf())
|
||||
or
|
||||
result = TSelfToplevelParameterNode(p.asToplevelSelf())
|
||||
}
|
||||
|
||||
predicate hasInputFromBlock(SsaImpl::DefinitionExt def, BasicBlock bb, int i, BasicBlock input) {
|
||||
SsaImpl::lastRefBeforeRedefExt(def, bb, i, input, this)
|
||||
Impl::Node asNode(Node n) {
|
||||
n = TSsaNode(result)
|
||||
or
|
||||
result.(Impl::ExprNode).getExpr() = n.asExpr()
|
||||
or
|
||||
result.(Impl::ExprPostUpdateNode).getExpr() = n.(PostUpdateNode).getPreUpdateNode().asExpr()
|
||||
or
|
||||
n = toParameterNode(result.(Impl::ParameterNode).getParameter())
|
||||
}
|
||||
|
||||
predicate localFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
|
||||
Impl::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep)
|
||||
}
|
||||
|
||||
predicate localMustFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
Impl::localMustFlowStep(def, asNode(nodeFrom), asNode(nodeTo))
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides predicates related to local data flow. */
|
||||
module LocalFlow {
|
||||
/**
|
||||
* Holds if `nodeFrom` is a node for SSA definition `def`, which can reach `next`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate localFlowSsaInputFromDef(
|
||||
SsaDefinitionExtNode nodeFrom, SsaImpl::DefinitionExt def, SsaInputNode nodeTo
|
||||
) {
|
||||
exists(BasicBlock bb, int i, BasicBlock input, SsaInputDefinitionExt next |
|
||||
next.hasInputFromBlock(def, bb, i, input) and
|
||||
def = nodeFrom.getDefinitionExt() and
|
||||
def.definesAt(_, bb, i, _) and
|
||||
nodeTo = TSsaInputNode(next, input)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` is a last read of SSA definition `def`, which
|
||||
* can reach `nodeTo`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate localFlowSsaInputFromRead(SsaImpl::DefinitionExt def, Node nodeFrom, SsaInputNode nodeTo) {
|
||||
exists(
|
||||
BasicBlock bb, int i, CfgNodes::ExprCfgNode exprFrom, BasicBlock input,
|
||||
SsaInputDefinitionExt next
|
||||
|
|
||||
next.hasInputFromBlock(def, bb, i, input) and
|
||||
exprFrom = bb.getNode(i) and
|
||||
exprFrom.getExpr() instanceof VariableReadAccess and
|
||||
exprFrom = [nodeFrom.asExpr(), nodeFrom.(PostUpdateNodeImpl).getPreUpdateNode().asExpr()] and
|
||||
nodeTo = TSsaInputNode(next, input)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the SSA definition node corresponding to parameter `p`. */
|
||||
pragma[nomagic]
|
||||
SsaDefinitionExtNode getParameterDefNode(NamedParameter p) {
|
||||
exists(BasicBlock bb, int i |
|
||||
bb.getNode(i).getAstNode() = p.getDefiningAccess() and
|
||||
result.getDefinitionExt().definesAt(_, bb, i, _)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` is a parameter node, and `nodeTo` is a corresponding SSA node.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate localFlowSsaParamInput(ParameterNodeImpl nodeFrom, SsaDefinitionExtNode nodeTo) {
|
||||
nodeTo = getParameterDefNode(nodeFrom.getParameter())
|
||||
or
|
||||
nodeTo.getDefinitionExt() = nodeFrom.(SelfParameterNodeImpl).getSelfDefinition()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo`
|
||||
* involving SSA definition `def`.
|
||||
*/
|
||||
predicate localSsaFlowStepUseUse(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
SsaImpl::adjacentReadPairExt(def, nodeFrom.asExpr(), nodeTo.asExpr())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if SSA definition `def` assigns `value` to the underlying variable.
|
||||
*
|
||||
* This is either a direct assignment, `x = value`, or an assignment via
|
||||
* simple pattern matching
|
||||
*
|
||||
* ```rb
|
||||
* case value
|
||||
* in Foo => x then ...
|
||||
* in y => then ...
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
predicate ssaDefAssigns(Ssa::WriteDefinition def, CfgNodes::ExprCfgNode value) {
|
||||
def.assigns(value)
|
||||
or
|
||||
exists(CfgNodes::ExprNodes::CaseExprCfgNode case, CfgNodes::AstCfgNode pattern |
|
||||
case.getValue() = value and
|
||||
pattern = case.getBranch(_).(CfgNodes::ExprNodes::InClauseCfgNode).getPattern()
|
||||
|
|
||||
def.getWriteAccess() = pattern
|
||||
or
|
||||
def.getWriteAccess() = pattern.(CfgNodes::ExprNodes::AsPatternCfgNode).getVariableAccess()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
|
||||
* SSA definition `def`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate localSsaFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
// Flow from assignment into SSA definition
|
||||
ssaDefAssigns(def, nodeFrom.asExpr()) and
|
||||
nodeTo.(SsaDefinitionExtNode).getDefinitionExt() = def
|
||||
or
|
||||
// Flow from SSA definition to first read
|
||||
def = nodeFrom.(SsaDefinitionExtNode).getDefinitionExt() and
|
||||
SsaImpl::firstReadExt(def, nodeTo.asExpr())
|
||||
or
|
||||
// Flow from post-update read to next read
|
||||
localSsaFlowStepUseUse(def, nodeFrom.(PostUpdateNodeImpl).getPreUpdateNode(), nodeTo)
|
||||
or
|
||||
// Flow into phi (read) SSA definition node from def
|
||||
localFlowSsaInputFromDef(nodeFrom, def, nodeTo)
|
||||
or
|
||||
nodeTo.(SsaDefinitionExtNode).getDefinitionExt() = def and
|
||||
def = nodeFrom.(SsaInputNode).getDefinitionExt()
|
||||
or
|
||||
localFlowSsaParamInput(nodeFrom, nodeTo) and
|
||||
def = nodeTo.(SsaDefinitionExtNode).getDefinitionExt()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
|
||||
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::BlockArgumentCfgNode).getValue()
|
||||
@@ -240,7 +154,7 @@ module LocalFlow {
|
||||
p.(KeywordParameter).getDefaultValue() = nodeFrom.asExpr().getExpr()
|
||||
)
|
||||
or
|
||||
nodeTo.(BlockArgumentNode).getParameterNode(true) = nodeFrom
|
||||
nodeTo.(ImplicitBlockArgumentNode).getParameterNode(true) = nodeFrom
|
||||
}
|
||||
|
||||
predicate flowSummaryLocalStep(
|
||||
@@ -253,21 +167,13 @@ module LocalFlow {
|
||||
}
|
||||
|
||||
predicate localMustFlowStep(Node node1, Node node2) {
|
||||
LocalFlow::localFlowSsaParamInput(node1, node2)
|
||||
or
|
||||
exists(SsaImpl::Definition def |
|
||||
def.(Ssa::WriteDefinition).assigns(node1.asExpr()) and
|
||||
node2.(SsaDefinitionExtNode).getDefinitionExt() = def
|
||||
or
|
||||
def = node1.(SsaDefinitionExtNode).getDefinitionExt() and
|
||||
node2.asExpr() = SsaImpl::getARead(def)
|
||||
)
|
||||
SsaFlow::localMustFlowStep(_, node1, node2)
|
||||
or
|
||||
node1.asExpr() = node2.asExpr().(CfgNodes::ExprNodes::AssignExprCfgNode).getRhs()
|
||||
or
|
||||
node1.asExpr() = node2.asExpr().(CfgNodes::ExprNodes::BlockArgumentCfgNode).getValue()
|
||||
or
|
||||
node1 = node2.(BlockArgumentNode).getParameterNode(true)
|
||||
node1 = node2.(ImplicitBlockArgumentNode).getParameterNode(true)
|
||||
or
|
||||
node1 =
|
||||
unique(FlowSummaryNode n1 |
|
||||
@@ -347,7 +253,7 @@ module VariableCapture {
|
||||
or
|
||||
exists(Ssa::Definition def |
|
||||
def.getARead() = e2 and
|
||||
LocalFlow::ssaDefAssigns(def.getAnUltimateDefinition(), e1)
|
||||
def.getAnUltimateDefinition().(Ssa::WriteDefinition).assigns(e1)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -538,23 +444,14 @@ private module Cached {
|
||||
newtype TNode =
|
||||
TExprNode(CfgNodes::ExprCfgNode n) or
|
||||
TReturningNode(CfgNodes::ReturningCfgNode n) { exists(n.getReturnedValueNode()) } or
|
||||
TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) or
|
||||
TSsaInputNode(SsaInputDefinitionExt def, BasicBlock input) {
|
||||
def.hasInputFromBlock(_, _, _, input)
|
||||
} or
|
||||
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) or
|
||||
TCapturedVariableNode(VariableCapture::CapturedVariable v) or
|
||||
TNormalParameterNode(Parameter p) {
|
||||
p instanceof SimpleParameter or
|
||||
p instanceof OptionalParameter or
|
||||
p instanceof KeywordParameter or
|
||||
p instanceof HashSplatParameter or
|
||||
p instanceof SplatParameter
|
||||
} or
|
||||
TNormalParameterNode(SsaImpl::NormalParameter p) or
|
||||
TSelfMethodParameterNode(MethodBase m) or
|
||||
TSelfToplevelParameterNode(Toplevel t) or
|
||||
TLambdaSelfReferenceNode(Callable c) { lambdaCreationExpr(_, _, c) } or
|
||||
TBlockParameterNode(MethodBase m) or
|
||||
TBlockArgumentNode(CfgNodes::ExprNodes::CallCfgNode yield) {
|
||||
TImplicitBlockParameterNode(MethodBase m) { not m.getAParameter() instanceof BlockParameter } or
|
||||
TImplicitBlockArgumentNode(CfgNodes::ExprNodes::CallCfgNode yield) {
|
||||
yield = any(BlockParameterNode b).getAYieldCall()
|
||||
} or
|
||||
TSynthHashSplatParameterNode(DataFlowCallable c) {
|
||||
@@ -600,7 +497,7 @@ private module Cached {
|
||||
class TSelfParameterNode = TSelfMethodParameterNode or TSelfToplevelParameterNode;
|
||||
|
||||
class TSourceParameterNode =
|
||||
TNormalParameterNode or TBlockParameterNode or TSelfParameterNode or
|
||||
TNormalParameterNode or TImplicitBlockParameterNode or TSelfParameterNode or
|
||||
TSynthHashSplatParameterNode or TSynthSplatParameterNode;
|
||||
|
||||
cached
|
||||
@@ -618,16 +515,13 @@ private module Cached {
|
||||
(
|
||||
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
||||
or
|
||||
exists(SsaImpl::DefinitionExt def |
|
||||
exists(SsaImpl::DefinitionExt def, boolean isUseStep |
|
||||
SsaFlow::localFlowStep(def, nodeFrom, nodeTo, isUseStep) and
|
||||
// captured variables are handled by the shared `VariableCapture` library
|
||||
not def instanceof VariableCapture::CapturedSsaDefinitionExt
|
||||
|
|
||||
LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo)
|
||||
isUseStep = false
|
||||
or
|
||||
LocalFlow::localSsaFlowStepUseUse(def, nodeFrom, nodeTo) and
|
||||
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _)
|
||||
or
|
||||
LocalFlow::localFlowSsaInputFromRead(def, nodeFrom, nodeTo) and
|
||||
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _)
|
||||
)
|
||||
or
|
||||
@@ -643,11 +537,7 @@ private module Cached {
|
||||
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) {
|
||||
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
||||
or
|
||||
LocalFlow::localSsaFlowStep(_, nodeFrom, nodeTo)
|
||||
or
|
||||
LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo)
|
||||
or
|
||||
LocalFlow::localFlowSsaInputFromRead(_, nodeFrom, nodeTo)
|
||||
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
|
||||
or
|
||||
// Simple flow through library code is included in the exposed local
|
||||
// step relation, even though flow is technically inter-procedural
|
||||
@@ -661,11 +551,7 @@ private module Cached {
|
||||
predicate localFlowStepTypeTracker(Node nodeFrom, Node nodeTo) {
|
||||
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
||||
or
|
||||
LocalFlow::localSsaFlowStep(_, nodeFrom, nodeTo)
|
||||
or
|
||||
LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo)
|
||||
or
|
||||
LocalFlow::localFlowSsaInputFromRead(_, nodeFrom, nodeTo)
|
||||
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
|
||||
or
|
||||
VariableCapture::flowInsensitiveStep(nodeFrom, nodeTo)
|
||||
or
|
||||
@@ -675,7 +561,8 @@ private module Cached {
|
||||
|
||||
/** Holds if `n` wraps an SSA definition without ingoing flow. */
|
||||
private predicate entrySsaDefinition(SsaDefinitionExtNode n) {
|
||||
n.getDefinitionExt() = any(SsaImpl::WriteDefinition def | not LocalFlow::ssaDefAssigns(def, _))
|
||||
n.getDefinitionExt() =
|
||||
any(SsaImpl::WriteDefinition def | not def.(Ssa::WriteDefinition).assigns(_))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -715,13 +602,15 @@ private module Cached {
|
||||
// Ensure all entry SSA definitions are local sources, except those that correspond
|
||||
// to parameters (which are themselves local sources)
|
||||
entrySsaDefinition(n) and
|
||||
not LocalFlow::localFlowSsaParamInput(_, n)
|
||||
not exists(SsaImpl::ParameterExt p |
|
||||
p.isInitializedBy(n.(SsaDefinitionExtNode).getDefinitionExt())
|
||||
)
|
||||
or
|
||||
isStoreTargetNode(n)
|
||||
or
|
||||
TypeTrackingInput::loadStep(_, n, _)
|
||||
or
|
||||
n instanceof BlockArgumentNode
|
||||
n instanceof ImplicitBlockArgumentNode
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -825,11 +714,7 @@ import Cached
|
||||
|
||||
/** Holds if `n` should be hidden from path explanations. */
|
||||
predicate nodeIsHidden(Node n) {
|
||||
n.(SsaDefinitionExtNode).isHidden()
|
||||
or
|
||||
n instanceof SsaInputNode
|
||||
or
|
||||
n = LocalFlow::getParameterDefNode(_)
|
||||
n.(SsaNode).isHidden()
|
||||
or
|
||||
exists(AstNode desug |
|
||||
isDesugarNode(desug) and
|
||||
@@ -861,33 +746,55 @@ predicate nodeIsHidden(Node n) {
|
||||
or
|
||||
n instanceof CaptureNode
|
||||
or
|
||||
n instanceof BlockArgumentNode
|
||||
n instanceof ImplicitBlockArgumentNode
|
||||
}
|
||||
|
||||
/** An SSA definition, viewed as a node in a data flow graph. */
|
||||
class SsaDefinitionExtNode extends NodeImpl, TSsaDefinitionExtNode {
|
||||
/** An SSA node. */
|
||||
abstract class SsaNode extends NodeImpl, TSsaNode {
|
||||
SsaImpl::DataFlowIntegration::SsaNode node;
|
||||
SsaImpl::DefinitionExt def;
|
||||
|
||||
SsaDefinitionExtNode() { this = TSsaDefinitionExtNode(def) }
|
||||
SsaNode() {
|
||||
this = TSsaNode(node) and
|
||||
def = node.getDefinitionExt()
|
||||
}
|
||||
|
||||
/** Gets the underlying SSA definition. */
|
||||
SsaImpl::DefinitionExt getDefinitionExt() { result = def }
|
||||
|
||||
/** Holds if this node should be hidden from path explanations. */
|
||||
abstract predicate isHidden();
|
||||
|
||||
override Location getLocationImpl() { result = node.getLocation() }
|
||||
|
||||
override string toStringImpl() { result = node.toString() }
|
||||
}
|
||||
|
||||
/** An (extended) SSA definition, viewed as a node in a data flow graph. */
|
||||
class SsaDefinitionExtNode extends SsaNode {
|
||||
override SsaImpl::DataFlowIntegration::SsaDefinitionExtNode node;
|
||||
|
||||
/** Gets the underlying variable. */
|
||||
Variable getVariable() { result = def.getSourceVariable() }
|
||||
|
||||
/** Holds if this node should be hidden from path explanations. */
|
||||
predicate isHidden() {
|
||||
override predicate isHidden() {
|
||||
not def instanceof Ssa::WriteDefinition
|
||||
or
|
||||
isDesugarNode(def.(Ssa::WriteDefinition).getWriteAccess().getExpr())
|
||||
or
|
||||
def = getParameterDef(_)
|
||||
}
|
||||
|
||||
override CfgScope getCfgScope() { result = def.getBasicBlock().getScope() }
|
||||
}
|
||||
|
||||
override Location getLocationImpl() { result = def.getLocation() }
|
||||
class SsaDefinitionNodeImpl extends SsaDefinitionExtNode {
|
||||
Ssa::Definition ssaDef;
|
||||
|
||||
override string toStringImpl() { result = def.toString() }
|
||||
SsaDefinitionNodeImpl() { ssaDef = def }
|
||||
|
||||
override Location getLocationImpl() { result = ssaDef.getLocation() }
|
||||
|
||||
override string toStringImpl() { result = ssaDef.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -925,20 +832,12 @@ class SsaDefinitionExtNode extends NodeImpl, TSsaDefinitionExtNode {
|
||||
*
|
||||
* both inputs into the phi read node after the outer condition are guarded.
|
||||
*/
|
||||
class SsaInputNode extends NodeImpl, TSsaInputNode {
|
||||
SsaImpl::DefinitionExt def;
|
||||
BasicBlock input;
|
||||
class SsaInputNode extends SsaNode {
|
||||
override SsaImpl::DataFlowIntegration::SsaInputNode node;
|
||||
|
||||
SsaInputNode() { this = TSsaInputNode(def, input) }
|
||||
override predicate isHidden() { any() }
|
||||
|
||||
/** Gets the underlying SSA definition. */
|
||||
SsaImpl::DefinitionExt getDefinitionExt() { result = def }
|
||||
|
||||
override CfgScope getCfgScope() { result = input.getScope() }
|
||||
|
||||
override Location getLocationImpl() { result = input.getLastNode().getLocation() }
|
||||
|
||||
override string toStringImpl() { result = "[input] " + def }
|
||||
override CfgScope getCfgScope() { result = node.getDefinitionExt().getBasicBlock().getScope() }
|
||||
}
|
||||
|
||||
/** An SSA definition for a `self` variable. */
|
||||
@@ -1026,7 +925,7 @@ private module ParameterNodes {
|
||||
* flow graph.
|
||||
*/
|
||||
class NormalParameterNode extends ParameterNodeImpl, TNormalParameterNode {
|
||||
private Parameter parameter;
|
||||
Parameter parameter;
|
||||
|
||||
NormalParameterNode() { this = TNormalParameterNode(parameter) }
|
||||
|
||||
@@ -1055,6 +954,9 @@ private module ParameterNodes {
|
||||
// There are no positional parameters after the splat
|
||||
not exists(SimpleParameter p, int m | m > n | p = callable.getParameter(m))
|
||||
)
|
||||
or
|
||||
parameter = callable.getAParameter().(BlockParameter) and
|
||||
pos.isBlock()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1162,24 +1064,32 @@ private module ParameterNodes {
|
||||
* The value of a block parameter at function entry, viewed as a node in a data
|
||||
* flow graph.
|
||||
*/
|
||||
class BlockParameterNode extends ParameterNodeImpl, TBlockParameterNode {
|
||||
private MethodBase method;
|
||||
|
||||
BlockParameterNode() { this = TBlockParameterNode(method) }
|
||||
|
||||
final MethodBase getMethod() { result = method }
|
||||
|
||||
override Parameter getParameter() {
|
||||
result = method.getAParameter() and result instanceof BlockParameter
|
||||
}
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
|
||||
c.asCfgScope() = method and pos.isBlock()
|
||||
}
|
||||
abstract class BlockParameterNode extends ParameterNodeImpl {
|
||||
abstract MethodBase getMethod();
|
||||
|
||||
CfgNodes::ExprNodes::CallCfgNode getAYieldCall() {
|
||||
this.getMethod() = result.getExpr().(YieldCall).getEnclosingMethod()
|
||||
}
|
||||
}
|
||||
|
||||
private class ExplicitBlockParameterNode extends BlockParameterNode, NormalParameterNode {
|
||||
override BlockParameter parameter;
|
||||
|
||||
final override MethodBase getMethod() { result.getAParameter() = parameter }
|
||||
}
|
||||
|
||||
private class ImplicitBlockParameterNode extends BlockParameterNode, TImplicitBlockParameterNode {
|
||||
private MethodBase method;
|
||||
|
||||
ImplicitBlockParameterNode() { this = TImplicitBlockParameterNode(method) }
|
||||
|
||||
final override MethodBase getMethod() { result = method }
|
||||
|
||||
override Parameter getParameter() { none() }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
|
||||
c.asCfgScope() = method and pos.isBlock()
|
||||
}
|
||||
|
||||
override CfgScope getCfgScope() { result = method }
|
||||
|
||||
@@ -1452,10 +1362,10 @@ module ArgumentNodes {
|
||||
}
|
||||
}
|
||||
|
||||
class BlockArgumentNode extends NodeImpl, ArgumentNode, TBlockArgumentNode {
|
||||
class ImplicitBlockArgumentNode extends NodeImpl, ArgumentNode, TImplicitBlockArgumentNode {
|
||||
CfgNodes::ExprNodes::CallCfgNode yield;
|
||||
|
||||
BlockArgumentNode() { this = TBlockArgumentNode(yield) }
|
||||
ImplicitBlockArgumentNode() { this = TImplicitBlockArgumentNode(yield) }
|
||||
|
||||
CfgNodes::ExprNodes::CallCfgNode getYieldCall() { result = yield }
|
||||
|
||||
@@ -1893,7 +1803,7 @@ predicate jumpStep(Node pred, Node succ) {
|
||||
or
|
||||
any(AdditionalJumpStep s).step(pred, succ)
|
||||
or
|
||||
succ.(BlockArgumentNode).getParameterNode(false) = pred
|
||||
succ.(ImplicitBlockArgumentNode).getParameterNode(false) = pred
|
||||
}
|
||||
|
||||
private ContentSet getArrayContent(int n) {
|
||||
@@ -2236,7 +2146,7 @@ private predicate lambdaCallExpr(
|
||||
*/
|
||||
predicate lambdaSourceCall(CfgNodes::ExprNodes::CallCfgNode call, LambdaCallKind kind, Node receiver) {
|
||||
kind = TYieldCallKind() and
|
||||
call = receiver.(BlockArgumentNode).getYieldCall()
|
||||
call = receiver.(ImplicitBlockArgumentNode).getYieldCall()
|
||||
or
|
||||
kind = TLambdaCallKind() and
|
||||
lambdaCallExpr(call, receiver.asExpr())
|
||||
|
||||
@@ -6,6 +6,7 @@ private import codeql.ruby.typetracking.internal.TypeTrackingImpl
|
||||
private import codeql.ruby.dataflow.SSA
|
||||
private import FlowSummaryImpl as FlowSummaryImpl
|
||||
private import codeql.ruby.ApiGraphs
|
||||
private import SsaImpl as SsaImpl
|
||||
|
||||
/**
|
||||
* An element, viewed as a node in a data flow graph. Either an expression
|
||||
@@ -360,16 +361,12 @@ class PostUpdateNode extends Node {
|
||||
}
|
||||
|
||||
/** An SSA definition, viewed as a node in a data flow graph. */
|
||||
class SsaDefinitionNode extends Node instanceof SsaDefinitionExtNode {
|
||||
Ssa::Definition def;
|
||||
|
||||
SsaDefinitionNode() { this = TSsaDefinitionExtNode(def) }
|
||||
|
||||
class SsaDefinitionNode extends Node instanceof SsaDefinitionNodeImpl {
|
||||
/** Gets the underlying SSA definition. */
|
||||
Ssa::Definition getDefinition() { result = def }
|
||||
Ssa::Definition getDefinition() { result = super.getDefinitionExt() }
|
||||
|
||||
/** Gets the underlying variable. */
|
||||
Variable getVariable() { result = def.getSourceVariable() }
|
||||
Variable getVariable() { result = this.getDefinition().getSourceVariable() }
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -870,56 +867,7 @@ private predicate sameSourceVariable(Ssa::Definition def1, Ssa::Definition def2)
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
private import SsaImpl as SsaImpl
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate guardChecksSsaDef(CfgNodes::AstCfgNode g, boolean branch, Ssa::Definition def) {
|
||||
guardChecks(g, def.getARead(), branch)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate guardControlsSsaRead(
|
||||
CfgNodes::AstCfgNode g, boolean branch, Ssa::Definition def, Node n
|
||||
) {
|
||||
def.getARead() = n.asExpr() and
|
||||
guardControlsBlock(g, n.asExpr().getBasicBlock(), branch)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate guardControlsPhiInput(
|
||||
CfgNodes::AstCfgNode g, boolean branch, Ssa::Definition def, BasicBlock input,
|
||||
SsaInputDefinitionExt phi
|
||||
) {
|
||||
phi.hasInputFromBlock(def, _, _, input) and
|
||||
(
|
||||
guardControlsBlock(g, input, branch)
|
||||
or
|
||||
exists(SuccessorTypes::ConditionalSuccessor s |
|
||||
g = input.getLastNode() and
|
||||
s.getValue() = branch and
|
||||
input.getASuccessor(s) = phi.getBasicBlock()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a node that is safely guarded by the given guard check. */
|
||||
Node getABarrierNode() {
|
||||
exists(CfgNodes::AstCfgNode g, boolean branch, Ssa::Definition def |
|
||||
guardChecksSsaDef(g, branch, def) and
|
||||
guardControlsSsaRead(g, branch, def, result)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
CfgNodes::AstCfgNode g, boolean branch, Ssa::Definition def, BasicBlock input,
|
||||
SsaInputDefinitionExt phi
|
||||
|
|
||||
guardChecksSsaDef(g, branch, def) and
|
||||
guardControlsPhiInput(g, branch, def, input, phi) and
|
||||
result = TSsaInputNode(phi, input)
|
||||
)
|
||||
or
|
||||
result.asExpr() = getAMaybeGuardedCapturedDef().getARead()
|
||||
}
|
||||
private import codeql.ruby.controlflow.internal.Guards
|
||||
|
||||
/**
|
||||
* Gets an implicit entry definition for a captured variable that
|
||||
@@ -928,6 +876,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
* This is restricted to calls where the variable is captured inside a
|
||||
* block.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private Ssa::CapturedEntryDefinition getAMaybeGuardedCapturedDef() {
|
||||
exists(
|
||||
CfgNodes::ExprCfgNode g, boolean branch, CfgNodes::ExprCfgNode testedNode,
|
||||
@@ -940,15 +889,14 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
sameSourceVariable(def, result)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
|
||||
private predicate guardControlsBlock(CfgNodes::AstCfgNode guard, BasicBlock bb, boolean branch) {
|
||||
exists(ConditionBlock conditionBlock, SuccessorTypes::ConditionalSuccessor s |
|
||||
guard = conditionBlock.getLastNode() and
|
||||
s.getValue() = branch and
|
||||
conditionBlock.controls(bb, s)
|
||||
)
|
||||
/** Gets a node that is safely guarded by the given guard check. */
|
||||
Node getABarrierNode() {
|
||||
SsaFlow::asNode(result) =
|
||||
SsaImpl::DataFlowIntegration::BarrierGuard<guardChecks/3>::getABarrierNode()
|
||||
or
|
||||
result.asExpr() = getAMaybeGuardedCapturedDef().getARead()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@ private import codeql.ruby.dataflow.SSA
|
||||
private import codeql.ruby.ast.Variable
|
||||
private import Cfg::CfgNodes::ExprNodes
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
private import codeql.ruby.controlflow.ControlFlowGraph as Cfg
|
||||
private import codeql.ruby.controlflow.BasicBlocks as BasicBlocks
|
||||
|
||||
@@ -65,7 +65,7 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
}
|
||||
}
|
||||
|
||||
private import SsaImplCommon::Make<Location, SsaInput> as Impl
|
||||
import SsaImplCommon::Make<Location, SsaInput> as Impl
|
||||
|
||||
class Definition = Impl::Definition;
|
||||
|
||||
@@ -283,15 +283,6 @@ private predicate adjacentDefSkipUncertainReads(
|
||||
SsaInput::variableRead(bb2, i2, _, true)
|
||||
}
|
||||
|
||||
/** Same as `adjacentDefReadExt`, but skips uncertain reads. */
|
||||
pragma[nomagic]
|
||||
private predicate adjacentDefSkipUncertainReadsExt(
|
||||
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
|
||||
) {
|
||||
adjacentDefReachesReadExt(def, bb1, i1, bb2, i2) and
|
||||
SsaInput::variableRead(bb2, i2, _, true)
|
||||
}
|
||||
|
||||
private predicate adjacentDefReachesUncertainReadExt(
|
||||
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
|
||||
) {
|
||||
@@ -393,19 +384,6 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the value defined at SSA definition `def` can reach a read at `read`,
|
||||
* without passing through any other non-pseudo read.
|
||||
*/
|
||||
cached
|
||||
predicate firstReadExt(DefinitionExt def, VariableReadAccessCfgNode read) {
|
||||
exists(Cfg::BasicBlock bb1, int i1, Cfg::BasicBlock bb2, int i2 |
|
||||
def.definesAt(_, bb1, i1, _) and
|
||||
adjacentDefSkipUncertainReadsExt(def, bb1, i1, bb2, i2) and
|
||||
read = bb2.getNode(i2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the read at `read2` is a read of the same SSA definition `def`
|
||||
* as the read at `read1`, and `read2` can be reached from `read1` without
|
||||
@@ -423,23 +401,6 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the read at `read2` is a read of the same SSA definition `def`
|
||||
* as the read at `read1`, and `read2` can be reached from `read1` without
|
||||
* passing through another non-pseudo read.
|
||||
*/
|
||||
cached
|
||||
predicate adjacentReadPairExt(
|
||||
DefinitionExt def, VariableReadAccessCfgNode read1, VariableReadAccessCfgNode read2
|
||||
) {
|
||||
exists(Cfg::BasicBlock bb1, int i1, Cfg::BasicBlock bb2, int i2 |
|
||||
read1 = bb1.getNode(i1) and
|
||||
variableReadActual(bb1, i1, _) and
|
||||
adjacentDefSkipUncertainReadsExt(def, bb1, i1, bb2, i2) and
|
||||
read2 = bb2.getNode(i2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the read of `def` at `read` may be a last read. That is, `read`
|
||||
* can either reach another definition of the underlying source variable or
|
||||
@@ -454,32 +415,42 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the reference to `def` at index `i` in basic block `bb` can reach
|
||||
* another definition `next` of the same underlying source variable, without
|
||||
* passing through another write or non-pseudo read.
|
||||
*
|
||||
* The reference is either a read of `def` or `def` itself.
|
||||
*/
|
||||
cached
|
||||
predicate lastRefBeforeRedefExt(
|
||||
DefinitionExt def, Cfg::BasicBlock bb, int i, Cfg::BasicBlock input, DefinitionExt next
|
||||
) {
|
||||
exists(LocalVariable v |
|
||||
Impl::lastRefRedefExt(def, v, bb, i, input, next) and
|
||||
not SsaInput::variableRead(bb, i, v, false)
|
||||
)
|
||||
or
|
||||
exists(SsaInput::BasicBlock bb0, int i0 |
|
||||
Impl::lastRefRedefExt(def, _, bb0, i0, input, next) and
|
||||
adjacentDefReachesUncertainReadExt(def, bb, i, bb0, i0)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
|
||||
Impl::uncertainWriteDefinitionInput(def, result)
|
||||
}
|
||||
|
||||
cached
|
||||
module DataFlowIntegration {
|
||||
import DataFlowIntegrationImpl
|
||||
|
||||
cached
|
||||
predicate localFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
|
||||
DataFlowIntegrationImpl::localFlowStep(def, nodeFrom, nodeTo, isUseStep)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate localMustFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
DataFlowIntegrationImpl::localMustFlowStep(def, nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
signature predicate guardChecksSig(Cfg::CfgNodes::AstCfgNode g, Cfg::CfgNode e, boolean branch);
|
||||
|
||||
cached // nothing is actually cached
|
||||
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
private predicate guardChecksAdjTypes(
|
||||
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
|
||||
) {
|
||||
guardChecks(g, e, branch)
|
||||
}
|
||||
|
||||
private Node getABarrierNodeImpl() {
|
||||
result = DataFlowIntegrationImpl::BarrierGuard<guardChecksAdjTypes/3>::getABarrierNode()
|
||||
}
|
||||
|
||||
predicate getABarrierNode = getABarrierNodeImpl/0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
@@ -510,3 +481,97 @@ class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
|
||||
|
||||
override Location getLocation() { result = Impl::PhiReadNode.super.getLocation() }
|
||||
}
|
||||
|
||||
class NormalParameter extends Parameter {
|
||||
NormalParameter() {
|
||||
this instanceof SimpleParameter or
|
||||
this instanceof OptionalParameter or
|
||||
this instanceof KeywordParameter or
|
||||
this instanceof HashSplatParameter or
|
||||
this instanceof SplatParameter or
|
||||
this instanceof BlockParameter
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the SSA definition node corresponding to parameter `p`. */
|
||||
pragma[nomagic]
|
||||
DefinitionExt getParameterDef(NamedParameter p) {
|
||||
exists(Cfg::BasicBlock bb, int i |
|
||||
bb.getNode(i).getAstNode() = p.getDefiningAccess() and
|
||||
result.definesAt(_, bb, i, _)
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TParameterExt =
|
||||
TNormalParameter(NormalParameter p) or
|
||||
TSelfMethodParameter(MethodBase m) or
|
||||
TSelfToplevelParameter(Toplevel t)
|
||||
|
||||
/** A normal parameter or an implicit `self` parameter. */
|
||||
class ParameterExt extends TParameterExt {
|
||||
NormalParameter asParameter() { this = TNormalParameter(result) }
|
||||
|
||||
MethodBase asMethodSelf() { this = TSelfMethodParameter(result) }
|
||||
|
||||
Toplevel asToplevelSelf() { this = TSelfToplevelParameter(result) }
|
||||
|
||||
predicate isInitializedBy(WriteDefinition def) {
|
||||
def = getParameterDef(this.asParameter())
|
||||
or
|
||||
def.(Ssa::SelfDefinition).getSourceVariable().getDeclaringScope() =
|
||||
[this.asMethodSelf().(Scope), this.asToplevelSelf()]
|
||||
}
|
||||
|
||||
string toString() {
|
||||
result =
|
||||
[
|
||||
this.asParameter().toString(), this.asMethodSelf().toString(),
|
||||
this.asToplevelSelf().toString()
|
||||
]
|
||||
}
|
||||
|
||||
Location getLocation() {
|
||||
result =
|
||||
[
|
||||
this.asParameter().getLocation(), this.asMethodSelf().getLocation(),
|
||||
this.asToplevelSelf().getLocation()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
|
||||
private import codeql.ruby.controlflow.internal.Guards as Guards
|
||||
|
||||
class Parameter = ParameterExt;
|
||||
|
||||
class Expr extends Cfg::CfgNodes::ExprCfgNode {
|
||||
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
|
||||
}
|
||||
|
||||
Expr getARead(Definition def) { result = Cached::getARead(def) }
|
||||
|
||||
predicate ssaDefAssigns(WriteDefinition def, Expr value) {
|
||||
def.(Ssa::WriteDefinition).assigns(value)
|
||||
}
|
||||
|
||||
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { p.isInitializedBy(def) }
|
||||
|
||||
class Guard extends Cfg::CfgNodes::AstCfgNode {
|
||||
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
|
||||
}
|
||||
|
||||
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
|
||||
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
Guards::guardControlsBlock(guard, bb, branch)
|
||||
}
|
||||
|
||||
/** Gets an immediate conditional successor of basic block `bb`, if any. */
|
||||
SsaInput::BasicBlock getAConditionalBasicBlockSuccessor(SsaInput::BasicBlock bb, boolean branch) {
|
||||
exists(Cfg::SuccessorTypes::ConditionalSuccessor s |
|
||||
result = bb.getASuccessor(s) and
|
||||
s.getValue() = branch
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;
|
||||
|
||||
@@ -5,6 +5,7 @@ private import codeql.ruby.CFG
|
||||
private import codeql.ruby.DataFlow
|
||||
private import FlowSummaryImpl as FlowSummaryImpl
|
||||
private import codeql.ruby.dataflow.SSA
|
||||
private import SsaImpl as SsaImpl
|
||||
|
||||
/**
|
||||
* Holds if `node` should be a sanitizer in all global taint flow configurations
|
||||
@@ -89,7 +90,7 @@ private module Cached {
|
||||
clause = case.getBranch(_) and
|
||||
def = nodeTo.(SsaDefinitionExtNode).getDefinitionExt() and
|
||||
def.getControlFlowNode() = variablesInPattern(clause.getPattern()) and
|
||||
not LocalFlow::ssaDefAssigns(def, value)
|
||||
not def.(Ssa::WriteDefinition).assigns(value)
|
||||
)
|
||||
or
|
||||
// operation involving `nodeFrom`
|
||||
|
||||
@@ -29,7 +29,7 @@ class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode {
|
||||
this = request
|
||||
|
|
||||
// Net::HTTP.get(...)
|
||||
method = "get" and
|
||||
method in ["get", "get_response"] and
|
||||
requestNode = API::getTopLevelMember("Net").getMember("HTTP").getReturn(method) and
|
||||
returnsResponseBody = true
|
||||
or
|
||||
|
||||
@@ -10,14 +10,14 @@ edges
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:26:31:26:37 | tainted | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:30:24:30:30 | tainted | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:31:27:31:33 | tainted | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:34:16:34:22 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:34:16:34:22 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:35:16:35:22 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:35:16:35:22 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:36:21:36:27 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:36:21:36:27 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:37:36:37:42 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:37:36:37:42 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:34:16:34:22 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:34:16:34:22 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:35:16:35:22 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:35:16:35:22 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:36:21:36:27 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:36:21:36:27 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:37:36:37:42 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:37:36:37:42 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:51:24:51:30 | tainted | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:56:22:56:28 | tainted | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:57:17:57:23 | tainted | provenance | |
|
||||
@@ -27,30 +27,30 @@ edges
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:122:16:122:22 | tainted | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:128:14:128:20 | tainted | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:131:16:131:22 | tainted | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:131:16:131:22 | tainted | provenance | Sink:MaD:3 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:131:16:131:22 | tainted | provenance | Sink:MaD:3 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:132:21:132:27 | tainted | provenance | Sink:MaD:3 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:132:21:132:27 | tainted | provenance | Sink:MaD:3 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:135:26:135:32 | tainted | provenance | Sink:MaD:4 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:135:26:135:32 | tainted | provenance | Sink:MaD:4 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:137:23:137:29 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:137:23:137:29 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:140:19:140:25 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:140:19:140:25 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:141:19:141:25 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:141:19:141:25 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:145:26:145:32 | tainted | provenance | Sink:MaD:1 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:145:26:145:32 | tainted | provenance | Sink:MaD:1 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:147:16:147:22 | tainted | provenance | Sink:MaD:0 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:147:16:147:22 | tainted | provenance | Sink:MaD:0 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:150:39:150:45 | tainted | provenance | Sink:MaD:2 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:150:39:150:45 | tainted | provenance | Sink:MaD:2 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:154:20:154:26 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:154:20:154:26 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:155:28:155:34 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:155:28:155:34 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:156:27:156:33 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:156:27:156:33 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:131:16:131:22 | tainted | provenance | Sink:MaD:65 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:131:16:131:22 | tainted | provenance | Sink:MaD:65 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:132:21:132:27 | tainted | provenance | Sink:MaD:65 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:132:21:132:27 | tainted | provenance | Sink:MaD:65 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:135:26:135:32 | tainted | provenance | Sink:MaD:66 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:135:26:135:32 | tainted | provenance | Sink:MaD:66 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:137:23:137:29 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:137:23:137:29 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:140:19:140:25 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:140:19:140:25 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:141:19:141:25 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:141:19:141:25 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:145:26:145:32 | tainted | provenance | Sink:MaD:63 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:145:26:145:32 | tainted | provenance | Sink:MaD:63 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:147:16:147:22 | tainted | provenance | Sink:MaD:62 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:147:16:147:22 | tainted | provenance | Sink:MaD:62 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:150:39:150:45 | tainted | provenance | Sink:MaD:64 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:150:39:150:45 | tainted | provenance | Sink:MaD:64 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:154:20:154:26 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:154:20:154:26 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:155:28:155:34 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:155:28:155:34 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:156:27:156:33 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:156:27:156:33 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:157:14:160:3 | do ... end [captured tainted] | provenance | |
|
||||
| summaries.rb:1:11:1:36 | call to identity | summaries.rb:157:14:160:3 | do ... end [captured tainted] | provenance | |
|
||||
| summaries.rb:1:20:1:36 | call to source | summaries.rb:1:11:1:36 | call to identity | provenance | |
|
||||
@@ -81,34 +81,34 @@ edges
|
||||
| summaries.rb:16:36:16:42 | tainted | summaries.rb:16:12:16:43 | call to apply_lambda | provenance | |
|
||||
| summaries.rb:20:1:20:8 | tainted4 | summaries.rb:21:6:21:13 | tainted4 | provenance | |
|
||||
| summaries.rb:20:12:20:32 | call to firstArg | summaries.rb:20:1:20:8 | tainted4 | provenance | |
|
||||
| summaries.rb:20:25:20:31 | tainted | summaries.rb:20:12:20:32 | call to firstArg | provenance | MaD:11 |
|
||||
| summaries.rb:20:25:20:31 | tainted | summaries.rb:20:12:20:32 | call to firstArg | provenance | MaD:73 |
|
||||
| summaries.rb:26:1:26:8 | tainted5 | summaries.rb:27:6:27:13 | tainted5 | provenance | |
|
||||
| summaries.rb:26:12:26:38 | call to secondArg | summaries.rb:26:1:26:8 | tainted5 | provenance | |
|
||||
| summaries.rb:26:31:26:37 | tainted | summaries.rb:26:12:26:38 | call to secondArg | provenance | MaD:17 |
|
||||
| summaries.rb:30:24:30:30 | tainted | summaries.rb:30:6:30:42 | call to onlyWithBlock | provenance | MaD:15 |
|
||||
| summaries.rb:31:27:31:33 | tainted | summaries.rb:31:6:31:34 | call to onlyWithoutBlock | provenance | MaD:16 |
|
||||
| summaries.rb:26:31:26:37 | tainted | summaries.rb:26:12:26:38 | call to secondArg | provenance | MaD:79 |
|
||||
| summaries.rb:30:24:30:30 | tainted | summaries.rb:30:6:30:42 | call to onlyWithBlock | provenance | MaD:77 |
|
||||
| summaries.rb:31:27:31:33 | tainted | summaries.rb:31:6:31:34 | call to onlyWithoutBlock | provenance | MaD:78 |
|
||||
| summaries.rb:40:3:40:3 | t | summaries.rb:41:24:41:24 | t | provenance | |
|
||||
| summaries.rb:40:3:40:3 | t | summaries.rb:42:24:42:24 | t | provenance | |
|
||||
| summaries.rb:40:3:40:3 | t | summaries.rb:44:8:44:8 | t | provenance | |
|
||||
| summaries.rb:40:7:40:17 | call to source | summaries.rb:40:3:40:3 | t | provenance | |
|
||||
| summaries.rb:41:24:41:24 | t | summaries.rb:41:8:41:25 | call to matchedByName | provenance | MaD:24 |
|
||||
| summaries.rb:42:24:42:24 | t | summaries.rb:42:8:42:25 | call to matchedByName | provenance | MaD:24 |
|
||||
| summaries.rb:44:8:44:8 | t | summaries.rb:44:8:44:27 | call to matchedByNameRcv | provenance | MaD:23 |
|
||||
| summaries.rb:48:24:48:41 | call to source | summaries.rb:48:8:48:42 | call to preserveTaint | provenance | MaD:10 |
|
||||
| summaries.rb:51:24:51:30 | tainted | summaries.rb:51:6:51:31 | call to namedArg | provenance | MaD:14 |
|
||||
| summaries.rb:41:24:41:24 | t | summaries.rb:41:8:41:25 | call to matchedByName | provenance | MaD:86 |
|
||||
| summaries.rb:42:24:42:24 | t | summaries.rb:42:8:42:25 | call to matchedByName | provenance | MaD:86 |
|
||||
| summaries.rb:44:8:44:8 | t | summaries.rb:44:8:44:27 | call to matchedByNameRcv | provenance | MaD:85 |
|
||||
| summaries.rb:48:24:48:41 | call to source | summaries.rb:48:8:48:42 | call to preserveTaint | provenance | MaD:72 |
|
||||
| summaries.rb:51:24:51:30 | tainted | summaries.rb:51:6:51:31 | call to namedArg | provenance | MaD:76 |
|
||||
| summaries.rb:53:1:53:4 | args [element :foo] | summaries.rb:54:21:54:24 | args [element :foo] | provenance | |
|
||||
| summaries.rb:53:8:53:33 | call to [] [element :foo] | summaries.rb:53:1:53:4 | args [element :foo] | provenance | |
|
||||
| summaries.rb:53:15:53:31 | call to source | summaries.rb:53:8:53:33 | call to [] [element :foo] | provenance | |
|
||||
| summaries.rb:54:19:54:24 | ** ... [element :foo] | summaries.rb:54:6:54:25 | call to namedArg | provenance | MaD:14 |
|
||||
| summaries.rb:54:19:54:24 | ** ... [element :foo] | summaries.rb:54:6:54:25 | call to namedArg | provenance | MaD:76 |
|
||||
| summaries.rb:54:21:54:24 | args [element :foo] | summaries.rb:54:19:54:24 | ** ... [element :foo] | provenance | |
|
||||
| summaries.rb:56:22:56:28 | tainted | summaries.rb:56:6:56:29 | call to anyArg | provenance | MaD:7 |
|
||||
| summaries.rb:57:17:57:23 | tainted | summaries.rb:57:6:57:24 | call to anyArg | provenance | MaD:7 |
|
||||
| summaries.rb:59:27:59:33 | tainted | summaries.rb:59:6:59:34 | call to anyNamedArg | provenance | MaD:8 |
|
||||
| summaries.rb:63:32:63:38 | tainted | summaries.rb:63:6:63:39 | call to anyPositionFromOne | provenance | MaD:9 |
|
||||
| summaries.rb:65:23:65:29 | tainted | summaries.rb:65:40:65:40 | x | provenance | MaD:12 |
|
||||
| summaries.rb:56:22:56:28 | tainted | summaries.rb:56:6:56:29 | call to anyArg | provenance | MaD:69 |
|
||||
| summaries.rb:57:17:57:23 | tainted | summaries.rb:57:6:57:24 | call to anyArg | provenance | MaD:69 |
|
||||
| summaries.rb:59:27:59:33 | tainted | summaries.rb:59:6:59:34 | call to anyNamedArg | provenance | MaD:70 |
|
||||
| summaries.rb:63:32:63:38 | tainted | summaries.rb:63:6:63:39 | call to anyPositionFromOne | provenance | MaD:71 |
|
||||
| summaries.rb:65:23:65:29 | tainted | summaries.rb:65:40:65:40 | x | provenance | MaD:74 |
|
||||
| summaries.rb:65:40:65:40 | x | summaries.rb:66:8:66:8 | x | provenance | |
|
||||
| summaries.rb:73:24:73:53 | call to source | summaries.rb:73:8:73:54 | call to preserveTaint | provenance | MaD:18 |
|
||||
| summaries.rb:76:26:76:56 | call to source | summaries.rb:76:8:76:57 | call to preserveTaint | provenance | MaD:19 |
|
||||
| summaries.rb:73:24:73:53 | call to source | summaries.rb:73:8:73:54 | call to preserveTaint | provenance | MaD:80 |
|
||||
| summaries.rb:76:26:76:56 | call to source | summaries.rb:76:8:76:57 | call to preserveTaint | provenance | MaD:81 |
|
||||
| summaries.rb:79:1:79:1 | a [element 1] | summaries.rb:82:6:82:6 | a [element 1] | provenance | |
|
||||
| summaries.rb:79:1:79:1 | a [element 1] | summaries.rb:82:6:82:6 | a [element 1] | provenance | |
|
||||
| summaries.rb:79:1:79:1 | a [element 1] | summaries.rb:83:6:83:6 | a [element 1] | provenance | |
|
||||
@@ -145,12 +145,12 @@ edges
|
||||
| summaries.rb:81:1:81:1 | [post] a [element] | summaries.rb:95:1:95:1 | a [element] | provenance | |
|
||||
| summaries.rb:81:13:81:27 | call to source | summaries.rb:81:1:81:1 | [post] a [element] | provenance | |
|
||||
| summaries.rb:81:13:81:27 | call to source | summaries.rb:81:1:81:1 | [post] a [element] | provenance | |
|
||||
| summaries.rb:82:6:82:6 | a [element 1] | summaries.rb:82:6:82:24 | call to readElementOne | provenance | MaD:25 |
|
||||
| summaries.rb:82:6:82:6 | a [element 1] | summaries.rb:82:6:82:24 | call to readElementOne | provenance | MaD:25 |
|
||||
| summaries.rb:82:6:82:6 | a [element] | summaries.rb:82:6:82:24 | call to readElementOne | provenance | MaD:25 |
|
||||
| summaries.rb:82:6:82:6 | a [element] | summaries.rb:82:6:82:24 | call to readElementOne | provenance | MaD:25 |
|
||||
| summaries.rb:83:6:83:6 | a [element 1] | summaries.rb:83:6:83:31 | call to readExactlyElementOne | provenance | MaD:26 |
|
||||
| summaries.rb:83:6:83:6 | a [element 1] | summaries.rb:83:6:83:31 | call to readExactlyElementOne | provenance | MaD:26 |
|
||||
| summaries.rb:82:6:82:6 | a [element 1] | summaries.rb:82:6:82:24 | call to readElementOne | provenance | MaD:87 |
|
||||
| summaries.rb:82:6:82:6 | a [element 1] | summaries.rb:82:6:82:24 | call to readElementOne | provenance | MaD:87 |
|
||||
| summaries.rb:82:6:82:6 | a [element] | summaries.rb:82:6:82:24 | call to readElementOne | provenance | MaD:87 |
|
||||
| summaries.rb:82:6:82:6 | a [element] | summaries.rb:82:6:82:24 | call to readElementOne | provenance | MaD:87 |
|
||||
| summaries.rb:83:6:83:6 | a [element 1] | summaries.rb:83:6:83:31 | call to readExactlyElementOne | provenance | MaD:88 |
|
||||
| summaries.rb:83:6:83:6 | a [element 1] | summaries.rb:83:6:83:31 | call to readExactlyElementOne | provenance | MaD:88 |
|
||||
| summaries.rb:84:6:84:6 | a [element] | summaries.rb:84:6:84:9 | ...[...] | provenance | |
|
||||
| summaries.rb:84:6:84:6 | a [element] | summaries.rb:84:6:84:9 | ...[...] | provenance | |
|
||||
| summaries.rb:85:6:85:6 | a [element 1] | summaries.rb:85:6:85:9 | ...[...] | provenance | |
|
||||
@@ -169,10 +169,10 @@ edges
|
||||
| summaries.rb:87:1:87:1 | b [element] | summaries.rb:89:6:89:6 | b [element] | provenance | |
|
||||
| summaries.rb:87:1:87:1 | b [element] | summaries.rb:90:6:90:6 | b [element] | provenance | |
|
||||
| summaries.rb:87:1:87:1 | b [element] | summaries.rb:90:6:90:6 | b [element] | provenance | |
|
||||
| summaries.rb:87:5:87:5 | a [element 1] | summaries.rb:87:5:87:22 | call to withElementOne [element 1] | provenance | MaD:28 |
|
||||
| summaries.rb:87:5:87:5 | a [element 1] | summaries.rb:87:5:87:22 | call to withElementOne [element 1] | provenance | MaD:28 |
|
||||
| summaries.rb:87:5:87:5 | a [element] | summaries.rb:87:5:87:22 | call to withElementOne [element] | provenance | MaD:28 |
|
||||
| summaries.rb:87:5:87:5 | a [element] | summaries.rb:87:5:87:22 | call to withElementOne [element] | provenance | MaD:28 |
|
||||
| summaries.rb:87:5:87:5 | a [element 1] | summaries.rb:87:5:87:22 | call to withElementOne [element 1] | provenance | MaD:90 |
|
||||
| summaries.rb:87:5:87:5 | a [element 1] | summaries.rb:87:5:87:22 | call to withElementOne [element 1] | provenance | MaD:90 |
|
||||
| summaries.rb:87:5:87:5 | a [element] | summaries.rb:87:5:87:22 | call to withElementOne [element] | provenance | MaD:90 |
|
||||
| summaries.rb:87:5:87:5 | a [element] | summaries.rb:87:5:87:22 | call to withElementOne [element] | provenance | MaD:90 |
|
||||
| summaries.rb:87:5:87:22 | call to withElementOne [element 1] | summaries.rb:87:1:87:1 | b [element 1] | provenance | |
|
||||
| summaries.rb:87:5:87:22 | call to withElementOne [element 1] | summaries.rb:87:1:87:1 | b [element 1] | provenance | |
|
||||
| summaries.rb:87:5:87:22 | call to withElementOne [element] | summaries.rb:87:1:87:1 | b [element] | provenance | |
|
||||
@@ -187,8 +187,8 @@ edges
|
||||
| summaries.rb:90:6:90:6 | b [element] | summaries.rb:90:6:90:9 | ...[...] | provenance | |
|
||||
| summaries.rb:91:1:91:1 | c [element 1] | summaries.rb:93:6:93:6 | c [element 1] | provenance | |
|
||||
| summaries.rb:91:1:91:1 | c [element 1] | summaries.rb:93:6:93:6 | c [element 1] | provenance | |
|
||||
| summaries.rb:91:5:91:5 | a [element 1] | summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] | provenance | MaD:29 |
|
||||
| summaries.rb:91:5:91:5 | a [element 1] | summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] | provenance | MaD:29 |
|
||||
| summaries.rb:91:5:91:5 | a [element 1] | summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] | provenance | MaD:91 |
|
||||
| summaries.rb:91:5:91:5 | a [element 1] | summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] | provenance | MaD:91 |
|
||||
| summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] | summaries.rb:91:1:91:1 | c [element 1] | provenance | |
|
||||
| summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] | summaries.rb:91:1:91:1 | c [element 1] | provenance | |
|
||||
| summaries.rb:93:6:93:6 | c [element 1] | summaries.rb:93:6:93:9 | ...[...] | provenance | |
|
||||
@@ -203,10 +203,10 @@ edges
|
||||
| summaries.rb:95:1:95:1 | [post] a [element] | summaries.rb:97:6:97:6 | a [element] | provenance | |
|
||||
| summaries.rb:95:1:95:1 | [post] a [element] | summaries.rb:98:6:98:6 | a [element] | provenance | |
|
||||
| summaries.rb:95:1:95:1 | [post] a [element] | summaries.rb:98:6:98:6 | a [element] | provenance | |
|
||||
| summaries.rb:95:1:95:1 | a [element 2] | summaries.rb:95:1:95:1 | [post] a [element 2] | provenance | MaD:32 |
|
||||
| summaries.rb:95:1:95:1 | a [element 2] | summaries.rb:95:1:95:1 | [post] a [element 2] | provenance | MaD:32 |
|
||||
| summaries.rb:95:1:95:1 | a [element] | summaries.rb:95:1:95:1 | [post] a [element] | provenance | MaD:32 |
|
||||
| summaries.rb:95:1:95:1 | a [element] | summaries.rb:95:1:95:1 | [post] a [element] | provenance | MaD:32 |
|
||||
| summaries.rb:95:1:95:1 | a [element 2] | summaries.rb:95:1:95:1 | [post] a [element 2] | provenance | MaD:94 |
|
||||
| summaries.rb:95:1:95:1 | a [element 2] | summaries.rb:95:1:95:1 | [post] a [element 2] | provenance | MaD:94 |
|
||||
| summaries.rb:95:1:95:1 | a [element] | summaries.rb:95:1:95:1 | [post] a [element] | provenance | MaD:94 |
|
||||
| summaries.rb:95:1:95:1 | a [element] | summaries.rb:95:1:95:1 | [post] a [element] | provenance | MaD:94 |
|
||||
| summaries.rb:96:6:96:6 | a [element] | summaries.rb:96:6:96:9 | ...[...] | provenance | |
|
||||
| summaries.rb:96:6:96:6 | a [element] | summaries.rb:96:6:96:9 | ...[...] | provenance | |
|
||||
| summaries.rb:97:6:97:6 | a [element] | summaries.rb:97:6:97:9 | ...[...] | provenance | |
|
||||
@@ -217,8 +217,8 @@ edges
|
||||
| summaries.rb:98:6:98:6 | a [element] | summaries.rb:98:6:98:9 | ...[...] | provenance | |
|
||||
| summaries.rb:99:1:99:1 | [post] a [element 2] | summaries.rb:102:6:102:6 | a [element 2] | provenance | |
|
||||
| summaries.rb:99:1:99:1 | [post] a [element 2] | summaries.rb:102:6:102:6 | a [element 2] | provenance | |
|
||||
| summaries.rb:99:1:99:1 | a [element 2] | summaries.rb:99:1:99:1 | [post] a [element 2] | provenance | MaD:31 |
|
||||
| summaries.rb:99:1:99:1 | a [element 2] | summaries.rb:99:1:99:1 | [post] a [element 2] | provenance | MaD:31 |
|
||||
| summaries.rb:99:1:99:1 | a [element 2] | summaries.rb:99:1:99:1 | [post] a [element 2] | provenance | MaD:93 |
|
||||
| summaries.rb:99:1:99:1 | a [element 2] | summaries.rb:99:1:99:1 | [post] a [element 2] | provenance | MaD:93 |
|
||||
| summaries.rb:102:6:102:6 | a [element 2] | summaries.rb:102:6:102:9 | ...[...] | provenance | |
|
||||
| summaries.rb:102:6:102:6 | a [element 2] | summaries.rb:102:6:102:9 | ...[...] | provenance | |
|
||||
| summaries.rb:103:1:103:1 | [post] d [element 3] | summaries.rb:104:1:104:1 | d [element 3] | provenance | |
|
||||
@@ -227,39 +227,39 @@ edges
|
||||
| summaries.rb:103:8:103:22 | call to source | summaries.rb:103:1:103:1 | [post] d [element 3] | provenance | |
|
||||
| summaries.rb:104:1:104:1 | [post] d [element 3] | summaries.rb:108:6:108:6 | d [element 3] | provenance | |
|
||||
| summaries.rb:104:1:104:1 | [post] d [element 3] | summaries.rb:108:6:108:6 | d [element 3] | provenance | |
|
||||
| summaries.rb:104:1:104:1 | d [element 3] | summaries.rb:104:1:104:1 | [post] d [element 3] | provenance | MaD:30 |
|
||||
| summaries.rb:104:1:104:1 | d [element 3] | summaries.rb:104:1:104:1 | [post] d [element 3] | provenance | MaD:30 |
|
||||
| summaries.rb:104:1:104:1 | d [element 3] | summaries.rb:104:1:104:1 | [post] d [element 3] | provenance | MaD:92 |
|
||||
| summaries.rb:104:1:104:1 | d [element 3] | summaries.rb:104:1:104:1 | [post] d [element 3] | provenance | MaD:92 |
|
||||
| summaries.rb:108:6:108:6 | d [element 3] | summaries.rb:108:6:108:9 | ...[...] | provenance | |
|
||||
| summaries.rb:108:6:108:6 | d [element 3] | summaries.rb:108:6:108:9 | ...[...] | provenance | |
|
||||
| summaries.rb:111:1:111:1 | [post] x [@value] | summaries.rb:112:6:112:6 | x [@value] | provenance | |
|
||||
| summaries.rb:111:1:111:1 | [post] x [@value] | summaries.rb:112:6:112:6 | x [@value] | provenance | |
|
||||
| summaries.rb:111:13:111:26 | call to source | summaries.rb:111:1:111:1 | [post] x [@value] | provenance | MaD:27 |
|
||||
| summaries.rb:111:13:111:26 | call to source | summaries.rb:111:1:111:1 | [post] x [@value] | provenance | MaD:27 |
|
||||
| summaries.rb:112:6:112:6 | x [@value] | summaries.rb:112:6:112:16 | call to get_value | provenance | MaD:22 |
|
||||
| summaries.rb:112:6:112:6 | x [@value] | summaries.rb:112:6:112:16 | call to get_value | provenance | MaD:22 |
|
||||
| summaries.rb:111:13:111:26 | call to source | summaries.rb:111:1:111:1 | [post] x [@value] | provenance | MaD:89 |
|
||||
| summaries.rb:111:13:111:26 | call to source | summaries.rb:111:1:111:1 | [post] x [@value] | provenance | MaD:89 |
|
||||
| summaries.rb:112:6:112:6 | x [@value] | summaries.rb:112:6:112:16 | call to get_value | provenance | MaD:84 |
|
||||
| summaries.rb:112:6:112:6 | x [@value] | summaries.rb:112:6:112:16 | call to get_value | provenance | MaD:84 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:128:14:128:20 | tainted | provenance | |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:131:16:131:22 | tainted | provenance | |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:131:16:131:22 | tainted | provenance | Sink:MaD:3 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:132:21:132:27 | tainted | provenance | Sink:MaD:3 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:135:26:135:32 | tainted | provenance | Sink:MaD:4 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:137:23:137:29 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:140:19:140:25 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:141:19:141:25 | tainted | provenance | Sink:MaD:6 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:145:26:145:32 | tainted | provenance | Sink:MaD:1 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:147:16:147:22 | tainted | provenance | Sink:MaD:0 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:150:39:150:45 | tainted | provenance | Sink:MaD:2 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:154:20:154:26 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:155:28:155:34 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:156:27:156:33 | tainted | provenance | Sink:MaD:5 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:131:16:131:22 | tainted | provenance | Sink:MaD:65 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:132:21:132:27 | tainted | provenance | Sink:MaD:65 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:135:26:135:32 | tainted | provenance | Sink:MaD:66 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:137:23:137:29 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:140:19:140:25 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:141:19:141:25 | tainted | provenance | Sink:MaD:68 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:145:26:145:32 | tainted | provenance | Sink:MaD:63 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:147:16:147:22 | tainted | provenance | Sink:MaD:62 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:150:39:150:45 | tainted | provenance | Sink:MaD:64 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:154:20:154:26 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:155:28:155:34 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:156:27:156:33 | tainted | provenance | Sink:MaD:67 |
|
||||
| summaries.rb:122:16:122:22 | [post] tainted | summaries.rb:157:14:160:3 | do ... end [captured tainted] | provenance | |
|
||||
| summaries.rb:122:16:122:22 | tainted | summaries.rb:122:16:122:22 | [post] tainted | provenance | MaD:20 |
|
||||
| summaries.rb:122:16:122:22 | tainted | summaries.rb:122:25:122:25 | [post] y | provenance | MaD:20 |
|
||||
| summaries.rb:122:16:122:22 | tainted | summaries.rb:122:33:122:33 | [post] z | provenance | MaD:20 |
|
||||
| summaries.rb:122:16:122:22 | tainted | summaries.rb:122:16:122:22 | [post] tainted | provenance | MaD:82 |
|
||||
| summaries.rb:122:16:122:22 | tainted | summaries.rb:122:25:122:25 | [post] y | provenance | MaD:82 |
|
||||
| summaries.rb:122:16:122:22 | tainted | summaries.rb:122:33:122:33 | [post] z | provenance | MaD:82 |
|
||||
| summaries.rb:122:25:122:25 | [post] y | summaries.rb:124:6:124:6 | y | provenance | |
|
||||
| summaries.rb:122:33:122:33 | [post] z | summaries.rb:125:6:125:6 | z | provenance | |
|
||||
| summaries.rb:128:1:128:1 | [post] x | summaries.rb:129:6:129:6 | x | provenance | |
|
||||
| summaries.rb:128:14:128:20 | tainted | summaries.rb:128:1:128:1 | [post] x | provenance | MaD:21 |
|
||||
| summaries.rb:131:16:131:22 | tainted | summaries.rb:131:1:131:23 | synthetic splat argument | provenance | Sink:MaD:3 |
|
||||
| summaries.rb:128:14:128:20 | tainted | summaries.rb:128:1:128:1 | [post] x | provenance | MaD:83 |
|
||||
| summaries.rb:131:16:131:22 | tainted | summaries.rb:131:1:131:23 | synthetic splat argument | provenance | Sink:MaD:65 |
|
||||
| summaries.rb:157:14:160:3 | do ... end [captured tainted] | summaries.rb:158:15:158:21 | tainted | provenance | heuristic-callback |
|
||||
| summaries.rb:157:14:160:3 | do ... end [captured tainted] | summaries.rb:158:15:158:21 | tainted | provenance | heuristic-callback |
|
||||
nodes
|
||||
|
||||
Reference in New Issue
Block a user