C#: Teach data flow library about CFG splitting

Data flow nodes for expressions do not take CFG splitting into account. Example:

```
if (b)
    x = tainted;
x = x.ToLower();
if (!b)
    Use(x);
```

Flow is incorrectly reported from `tainted` to `x` in `Use(x)`, because the step
from `tainted` to `x.ToLower()` throws away the information that `b = true`.

The solution is to remember the splitting in data flow expression nodes, that is,
to represent the exact control flow node instead of just the expression. With that
we get flow from `tainted` to `[b = true] x.ToLower()`, but not from `tainted` to
`[b = false] x.ToLower()`.

The data flow API remains unchanged, but in order for analyses to fully benefit from
CFG splitting, sanitizers in particular should be CFG-based instead of expression-based:

```
if (b)
   x = tainted;
   if (IsInvalid(x))
       return;
Use(x);
```

If the call to `IsInvalid()` is a sanitizer, then defining an expression node to be
a sanitizer using `GuardedExpr` will be too conservative (`x` in `Use(x)` is in fact
not guarded). However, `[b = true] x` in `[b = true] Use(x)` is guarded, and to help
defining guard-based sanitizers, the class `GuardedDataFlowNode` has been introduced.
This commit is contained in:
Tom Hvitved
2019-01-03 15:28:15 +01:00
parent f768abb0e6
commit b2f99dbbc7
27 changed files with 811 additions and 344 deletions

View File

@@ -39,6 +39,12 @@ class AssignableMemberAccess extends MemberAccess, AssignableAccess {
override AssignableMember getTarget() { result = AssignableAccess.super.getTarget() }
}
private predicate nameOfChild(NameOfExpr noe, Expr child) {
child = noe
or
exists(Expr mid | nameOfChild(noe, mid) | child = mid.getAChildExpr())
}
/**
* An access to an assignable that reads the underlying value. Either a
* variable read (`VariableRead`), a property read (`PropertyRead`), an
@@ -67,7 +73,7 @@ class AssignableRead extends AssignableAccess {
or
this = any(AssignableDefinitions::AddressOfDefinition def).getTargetAccess()
) and
not this = any(NameOfExpr noe).getAChildExpr*()
not nameOfChild(_, this)
}
/**
@@ -669,6 +675,9 @@ module AssignableDefinitions {
IsPatternDefinition() { this = TIsPatternDefinition(ipe) }
/** Gets the underlying `is` expression. */
IsPatternExpr getIsPatternExpr() { result = ipe }
/** Gets the underlying local variable declaration. */
LocalVariableDeclExpr getDeclaration() { result = ipe.getVariableDeclExpr() }
@@ -696,6 +705,9 @@ module AssignableDefinitions {
TypeCasePatternDefinition() { this = TTypeCasePatternDefinition(tc) }
/** Gets the underlying `case` statement. */
TypeCase getTypeCase() { result = tc }
/** Gets the underlying local variable declaration. */
LocalVariableDeclExpr getDeclaration() { result = tc.getVariableDeclExpr() }

View File

@@ -262,6 +262,9 @@ class CaseStmt extends Stmt, @case {
* ```
*/
Expr getCondition() { result = this.getChild(2) }
/** Gets the `switch` statement that this `case` statement belongs to. */
SwitchStmt getSwitchStmt() { result.getACase() = this }
}
/**

View File

@@ -581,6 +581,63 @@ class GuardedControlFlowNode extends ControlFlow::Nodes::ElementNode {
}
}
/**
* A guarded data flow node. A guarded data flow node is like a guarded expression
* (`GuardedExpr`), except control flow graph splitting is taken into account. That
* is, one data flow node belonging to an expression may be guarded, while another
* split need not be guarded:
*
* ```
* if (b)
* if (x == null)
* return;
* x.ToString();
* if (b)
* ...
* ```
*
* In the example above, the node for `x.ToString()` is null-guarded in the
* split `b == true`, but not in the split `b == false`.
*/
class GuardedDataFlowNode extends DataFlow::ExprNode {
private Guard g;
private AccessOrCallExpr sub0;
private AbstractValue v0;
GuardedDataFlowNode() {
exists(ControlFlow::Nodes::ElementNode cfn |
exists(this.getExprAtNode(cfn)) |
isGuardedByNode(cfn, g, sub0, v0)
)
}
/**
* Gets an expression that guards this data flow node. That is, this data flow
* node is only reached when the returned expression has abstract value `v`.
*
* The expression `sub` is a sub expression of the guarding expression that is
* structurally equal to the expression belonging to this data flow node.
*
* In case this data flow node or `sub` accesses an SSA variable in its
* left-most qualifier, then so must the other (accessing the same SSA
* variable).
*/
Expr getAGuard(Expr sub, AbstractValue v) {
result = g and
sub = sub0 and
v = v0
}
/**
* Holds if this data flow node must have abstract value `v`. That is, this
* data flow node is guarded by a structurally equal expression having
* abstract value `v`.
*/
predicate mustHaveValue(AbstractValue v) {
exists(Expr e | e = this.getAGuard(e, v))
}
}
/** An expression guarded by a `null` check. */
class NullGuardedExpr extends GuardedExpr {
NullGuardedExpr() {
@@ -588,6 +645,13 @@ class NullGuardedExpr extends GuardedExpr {
}
}
/** A data flow node guarded by a `null` check. */
class NullGuardedDataFlowNode extends GuardedDataFlowNode {
NullGuardedDataFlowNode() {
this.mustHaveValue(any(NullValue v | not v.isNull()))
}
}
/** INTERNAL: Do not use. */
module Internal {
private import ControlFlow::Internal

View File

@@ -21,6 +21,12 @@ module DataFlow {
/** Gets the expression corresponding to this node, if any. */
DotNet::Expr asExpr() { result = this.(ExprNode).getExpr() }
/** Gets the expression corresponding to this node, at control flow node `cfn`, if any. */
Expr asExprAtNode(ControlFlow::Nodes::ElementNode cfn) {
this = TExprNode(cfn) and
result = cfn.getElement()
}
/** Gets the parameter corresponding to this node, if any. */
DotNet::Parameter asParameter() { result = this.(ParameterNode).getParameter() }
@@ -41,30 +47,47 @@ module DataFlow {
/**
* An expression, viewed as a node in a data flow graph.
*/
class ExprNode extends Node, TExprNode {
DotNet::Expr expr;
ExprNode() { this = TExprNode(expr) }
class ExprNode extends Node {
ExprNode() { this = TExprNode(_) or this = TCilExprNode(_) }
/** Gets the expression corresponding to this node. */
DotNet::Expr getExpr() { result = expr }
DotNet::Expr getExpr() {
result = this.getExprAtNode(_)
or
this = TCilExprNode(result)
}
override DotNet::Type getType() { result = expr.getType() }
/** Gets the expression corresponding to this node, at control flow node `cfn`. */
Expr getExprAtNode(ControlFlow::Nodes::ElementNode cfn) {
this = TExprNode(cfn) and
result = cfn.getElement()
}
override DotNet::Callable getEnclosingCallable() { result = expr.getEnclosingCallable() }
override DotNet::Type getType() { result = this.getExpr().getType() }
override DotNet::Callable getEnclosingCallable() { result = this.getExpr().getEnclosingCallable() }
override string toString() {
result = expr.(Expr).toString()
exists(ControlFlow::Nodes::ElementNode cfn |
this = TExprNode(cfn) |
result = cfn.toString()
)
or
expr instanceof CIL::Expr and
this = TCilExprNode(_) and
result = "CIL expression"
}
override Location getLocation() {
result = expr.(Expr).getLocation()
exists(ControlFlow::Nodes::ElementNode cfn |
this = TExprNode(cfn) |
result = cfn.getLocation()
)
or
result.getFile().isPdbSourceFile() and
result = expr.(CIL::Expr).getALocation()
exists(CIL::Expr e |
this = TCilExprNode(e) |
result = e.getALocation()
)
}
}
@@ -83,9 +106,7 @@ module DataFlow {
DotNet::Parameter getParameter() { none() }
}
/**
* Gets the node corresponding to expression `e`.
*/
/** Gets a node corresponding to expression `e`. */
ExprNode exprNode(DotNet::Expr e) { result.getExpr() = e }
/**
@@ -258,9 +279,7 @@ module DataFlow {
}
}
/**
* INTERNAL: Do not use.
*/
/** INTERNAL: Do not use. */
module Internal {
private import semmle.code.csharp.dataflow.DelegateDataFlow
private import semmle.code.csharp.dispatch.Dispatch
@@ -473,6 +492,9 @@ module DataFlow {
/** Gets the context corresponding to this argument node. */
bindingset [config]
abstract ArgumentContext getContext(Configuration config);
/** Holds if this argument node does not have an associated control flow node. */
abstract predicate hasNoControlFlowNode();
}
/** A data flow node that represents an explicit call argument. */
@@ -511,6 +533,11 @@ module DataFlow {
override ExplicitArgumentContext getContext(Configuration config) {
result.getCallContext() = this.getArgumentCallContext(config)
}
override predicate hasNoControlFlowNode() {
this.asExpr() instanceof CIL::Expr or
this instanceof ImplicitDelegateCallNode
}
}
/**
@@ -558,6 +585,8 @@ module DataFlow {
exists(config) // eliminate warning
}
override predicate hasNoControlFlowNode() { any() }
override Type getType() { result = v.getType() }
override Callable getEnclosingCallable() { result = c.getEnclosingCallable() }
@@ -699,9 +728,181 @@ module DataFlow {
}
/**
* Provides predicates related to local data flow.
* A helper class for defining expression-based data flow steps, while properly
* taking control flow into account.
*/
abstract class ExprStep extends string {
bindingset[this]
ExprStep() { any() }
/**
* Holds if data can flow from expression `exprFrom` to expression `exprTo`,
* but only by following control flow successors (resp. predecessors, as
* specified by `isSuccesor`) inside the scope `scope`. The Boolean `exactScope`
* indicates whether a transitive child of `scope` is allowed
* (`exactScope = false`).
*/
predicate stepsToExpr(Expr exprFrom, Expr exprTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor) { none() }
/**
* Holds if data can flow from expression `exprFrom` to definition `defTo`,
* but only by following control flow successors (resp. predecessors, as
* specified by `isSuccesor`) inside the scope `scope`. The Bolean `exactScope`
* indicates whether a transitive child of `scope` is allowed (`exactScope = false`).
*/
predicate stepsToDefinition(Expr exprFrom, AssignableDefinition defTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor) { none() }
private predicate reachesBasicBlockExprRec(Expr exprFrom, Expr exprTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfnFrom, ControlFlow::BasicBlock bb) {
exists(ControlFlow::BasicBlock mid |
this.reachesBasicBlockExpr(exprFrom, exprTo, scope, exactScope, isSuccessor, cfnFrom, mid) |
isSuccessor = true and
bb = mid.getASuccessor()
or
isSuccessor = false and
bb = mid.getAPredecessor()
)
}
pragma[nomagic]
private predicate reachesBasicBlockExpr(Expr exprFrom, Expr exprTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfnFrom, ControlFlow::BasicBlock bb) {
this.stepsToExpr(exprFrom, exprTo, scope, exactScope, isSuccessor) and
cfnFrom = exprFrom.getAControlFlowNode() and
bb = cfnFrom.getBasicBlock()
or
exists(ControlFlowElement scope0, boolean exactScope0 |
this.reachesBasicBlockExprRec(exprFrom, exprTo, scope0, exactScope0, isSuccessor, cfnFrom, bb) and
this.stepsToExpr(exprFrom, exprTo, scope, exactScope, isSuccessor)
|
exactScope0 = false and
bb.getANode().getElement() = scope0.getAChild*()
or
exactScope0 = true and
bb.getANode().getElement() = scope0
)
}
private predicate reachesBasicBlockDefinitionRec(Expr exprFrom, AssignableDefinition defTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfnFrom, ControlFlow::BasicBlock bb) {
exists(ControlFlow::BasicBlock mid |
this.reachesBasicBlockDefinition(exprFrom, defTo, scope, exactScope, isSuccessor, cfnFrom, mid) |
isSuccessor = true and
bb = mid.getASuccessor()
or
isSuccessor = false and
bb = mid.getAPredecessor()
)
}
pragma[nomagic]
private predicate reachesBasicBlockDefinition(Expr exprFrom, AssignableDefinition defTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfnFrom, ControlFlow::BasicBlock bb) {
this.stepsToDefinition(exprFrom, defTo, scope, exactScope, isSuccessor) and
cfnFrom = exprFrom.getAControlFlowNode() and
bb = cfnFrom.getBasicBlock()
or
exists(ControlFlowElement scope0, boolean exactScope0 |
this.reachesBasicBlockDefinitionRec(exprFrom, defTo, scope0, exactScope0, isSuccessor, cfnFrom, bb) and
this.stepsToDefinition(exprFrom, defTo, scope, exactScope, isSuccessor)
|
exactScope0 = false and
bb.getANode().getElement() = scope0.getAChild*()
or
exactScope0 = true and
bb.getANode().getElement() = scope0
)
}
private predicate hasExprStep(ExprNode nodeFrom, ExprNode nodeTo) {
exists(Expr exprFrom, Expr exprTo, ControlFlow::Nodes::ElementNode cfnFrom, ControlFlow::BasicBlock bb |
this.reachesBasicBlockExpr(exprFrom, exprTo, _, _, _, cfnFrom, bb) |
exprFrom = nodeFrom.asExprAtNode(cfnFrom) and
exprTo = nodeTo.asExprAtNode(bb.getANode())
)
}
private predicate hasSsaDefinitionStep(ExprNode nodeFrom, SsaDefinitionNode nodeTo) {
exists(Expr exprFrom, AssignableDefinition defTo, Ssa::ExplicitDefinition ssaDef, ControlFlow::Nodes::ElementNode cfnFrom, ControlFlow::BasicBlock bb |
this.reachesBasicBlockDefinition(exprFrom, defTo, _, _, _, cfnFrom, bb) |
exprFrom = nodeFrom.asExprAtNode(cfnFrom) and
ssaDef.getADefinition() = defTo and
ssaDef.getBasicBlock() = bb and
nodeTo.getDefinition() = ssaDef
)
}
/**
* Holds if `stepsTo(Expr|SsaDefintion)()` induce a data flow step from
* `nodeFrom` to `nodeTo`.
*/
predicate hasStep(ExprNode nodeFrom, Node nodeTo) {
this.hasExprStep(nodeFrom, nodeTo) or
this.hasSsaDefinitionStep(nodeFrom, nodeTo)
}
}
/** Provides predicates related to local data flow. */
module LocalFlow {
private class LocalExprStep extends ExprStep {
LocalExprStep() { this = "LocalExprStep" }
override predicate stepsToExpr(Expr exprFrom, Expr exprTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor) {
exactScope = false and
(
// Flow using library code
libraryFlow(exprFrom, exprTo, scope, true) and
(isSuccessor = false or isSuccessor = true)
or
exprFrom = exprTo.(ParenthesizedExpr).getExpr() and
scope = exprTo and
isSuccessor = true
or
exprTo = any(ConditionalExpr ce |
exprFrom = ce.getThen() or
exprFrom = ce.getElse()
) and
scope = exprTo and
isSuccessor = false
or
exprFrom = exprTo.(Cast).getExpr() and
scope = exprTo and
isSuccessor = true
or
exprFrom = exprTo.(AwaitExpr).getExpr() and
scope = exprTo and
isSuccessor = true
or
// An `=` expression, where the result of the expression is used
exprTo = any(AssignExpr ae |
ae.getParent() instanceof Expr and
exprFrom = ae.getRValue()
) and
scope = exprTo and
isSuccessor = true
)
}
override predicate stepsToDefinition(Expr exprFrom, AssignableDefinition def, ControlFlowElement scope, boolean exactScope, boolean isSuccessor) {
// Flow from source to definition
exactScope = false and
def.getSource() = exprFrom and
(
scope = def.getExpr() and
isSuccessor = true
or
scope = def.(AssignableDefinitions::IsPatternDefinition).getIsPatternExpr() and
isSuccessor = false
or
exists(SwitchStmt ss |
ss = def.(AssignableDefinitions::TypeCasePatternDefinition).getTypeCase().getSwitchStmt() and
isSuccessor = true
|
scope = ss.getCondition()
or
scope = ss.getACase()
)
)
}
}
/**
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
* (intra-procedural) step.
@@ -709,18 +910,20 @@ module DataFlow {
cached
predicate step(Node nodeFrom, Node nodeTo) {
forceCachingInSameStage() and
localFlowStepExpr(nodeFrom.asExpr(), nodeTo.asExpr())
or
// Flow from source to SSA definition
exists(Ssa::ExplicitDefinition def |
def.getADefinition().getSource() = nodeFrom.asExpr() |
nodeTo.(SsaDefinitionNode).getDefinition() = def
)
TaintTracking::Internal::Cached::forceCachingInSameStage() and
any(LocalExprStep x).hasStep(nodeFrom, nodeTo)
or
// Flow from SSA definition to first read
exists(Ssa::Definition def |
exists(Ssa::Definition def, ControlFlow::Node cfn |
def = nodeFrom.(SsaDefinitionNode).getDefinition() |
nodeTo.asExpr() = def.getAFirstRead()
nodeTo.asExprAtNode(cfn) = def.getAFirstReadAtNode(cfn)
)
or
// Flow from read to next read
exists(ControlFlow::Node cfnFrom, ControlFlow::Node cfnTo |
Ssa::Internal::adjacentReadPairSameVar(cfnFrom, cfnTo) |
nodeFrom = TExprNode(cfnFrom) and
nodeTo = TExprNode(cfnTo)
)
or
// Flow into SSA pseudo definition
@@ -779,9 +982,9 @@ module DataFlow {
def = nodeFrom.(SsaDefinitionNode).getDefinition() and
not exists(def.getARead())
or
exists(AssignableRead read |
read = nodeFrom.asExpr() |
def.getALastRead() = read
exists(AssignableRead read, ControlFlow::Node cfn |
read = nodeFrom.asExprAtNode(cfn) |
def.getALastReadAtNode(cfn) = read
)
}
@@ -794,34 +997,25 @@ module DataFlow {
)
}
private predicate localFlowStepExpr(Expr exprFrom, Expr exprTo) {
// Flow using library code
libraryFlow(exprFrom, exprTo, true)
private Expr getALibraryFlowParent(Expr exprFrom, Expr exprTo, boolean preservesValue) {
libraryFlow(exprFrom, exprTo, preservesValue) and
result = exprFrom
or
// Flow from read to next read
exprTo = exprFrom.(AssignableRead).getANextRead()
or
exprFrom = exprTo.(ParenthesizedExpr).getExpr()
or
exprTo = any(ConditionalExpr ce |
exprFrom = ce.getThen() or
exprFrom = ce.getElse()
)
or
exprFrom = exprTo.(Cast).getExpr()
or
exprFrom = exprTo.(AwaitExpr).getExpr()
or
// An `=` expression, where the result of the expression is used
exprTo = any(AssignExpr ae |
ae.getParent() instanceof Expr and
exprFrom = ae.getRValue()
exists(Expr mid |
mid = getALibraryFlowParent(exprFrom, exprTo, preservesValue) |
result.getAChildExpr() = mid and
not mid.getAChildExpr*() = exprTo
)
}
predicate libraryFlow(Expr exprFrom, Expr exprTo, Expr scope, boolean preservesValue) {
scope = getALibraryFlowParent(exprFrom, exprTo, preservesValue) and
scope.getAChildExpr*() = exprTo
}
predicate localFlowStepNoConfig(Node pred, Node succ) {
localFlowStep(pred, succ) or
flowThroughCallableLibraryOutRef(_, pred.asExpr(), succ, true)
flowThroughCallableLibraryOutRef(_, pred, succ, true)
}
/**
@@ -1135,7 +1329,9 @@ module DataFlow {
cached predicate forceCachingInSameStage() { any() }
cached newtype TNode =
TExprNode(DotNet::Expr e)
TExprNode(ControlFlow::Nodes::ElementNode cfn) {
cfn.getElement() instanceof Expr
}
or
TSsaDefinitionNode(Ssa::Definition def)
or
@@ -1143,6 +1339,8 @@ module DataFlow {
p.getMethod().hasBody()
}
or
TCilExprNode(CIL::Expr e)
or
TImplicitDelegateCallNode(DelegateArgumentToLibraryCallable arg)
or
TImplicitCapturedArgumentNode(Call c, LocalScopeVariable v) {
@@ -1554,8 +1752,8 @@ module DataFlow {
* Holds if data may flow from argument `mid` of a call, back out from the
* call to `out`. The context after the call is `ctx`.
*/
pragma [noinline]
private predicate flowThroughCallable(FlowGraphNode mid, OutNode out, Context ctx) {
pragma[nomagic]
private predicate flowThroughCallable0(FlowGraphNode mid, OutNode out, Context ctx) {
exists(CallNode call, ParameterNode p, ArgumentContext innerctx, CallContext cc |
flowIntoCallable(mid, p, innerctx) and
paramFlowsThrough(call, p, out, innerctx, cc) |
@@ -1579,6 +1777,44 @@ module DataFlow {
)
}
private predicate flowThroughCallable1Scope(OutNode out, Expr e) {
flowThroughCallable0(_, out, _) and
e = out.asExpr().(Expr).getAChildExpr*()
}
pragma[nomagic]
private predicate flowThroughCallable1(FlowGraphNode mid, OutNode out, ControlFlow::Nodes::ElementNode cfn, Context ctx) {
flowThroughCallable0(mid, out, ctx) and
exists(mid.getNode().asExprAtNode(cfn))
or
exists(ControlFlow::Nodes::ElementNode cfnMid |
flowThroughCallable1(mid, out, cfnMid, ctx) |
cfn = cfnMid.getASuccessor() and
flowThroughCallable1Scope(out, cfn.getElement())
)
}
/**
* Holds if data may flow from argument `mid` of a call, back out from the
* call to `out`. The context after the call is `ctx`.
*/
pragma[nomagic]
private predicate flowThroughCallable(FlowGraphNode mid, OutNode out, Context ctx) {
// If both `mid` and `out` have associated control flow nodes, the latter
// must be reachable from the former
exists(ControlFlow::Node cfn |
flowThroughCallable1(mid, out, cfn, ctx) |
exists(out.asExprAtNode(cfn))
)
or
flowThroughCallable0(mid, out, ctx) and
(
mid.getNode().(ArgumentNode).hasNoControlFlowNode()
or
not out.asExpr() instanceof Expr
)
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*
@@ -1592,6 +1828,23 @@ module DataFlow {
flowsink.getNode() = sink
}
private class FlowThroughCallableLibraryOutRefStep extends ExprStep {
FlowThroughCallableLibraryOutRefStep() {
this = "FlowThroughCallableLibraryOutRefStep"
}
override predicate stepsToDefinition(Expr exprFrom, AssignableDefinition defTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor) {
exists(MethodCall mc, Parameter outRef |
libraryFlowOutRef(mc, exprFrom, outRef, _) |
defTo.getTargetAccess() = mc.getArgumentForParameter(outRef) and
defTo instanceof AssignableDefinitions::OutRefDefinition and
scope = mc and
isSuccessor = true and
exactScope = false
)
}
}
/**
* Holds if `arg` is an argument of the method call `mc`, where the target
* of `mc` is a library callable that forwards `arg` to an `out`/`ref` argument
@@ -1605,12 +1858,9 @@ module DataFlow {
* `mc = Int32.TryParse("42", out i)`, `arg = "42"`, and `node` is the access
* to `i` in `out i`.
*/
predicate flowThroughCallableLibraryOutRef(MethodCall mc, Expr arg, SsaDefinitionNode node, boolean preservesValue) {
exists(Parameter outRef, AssignableDefinitions::OutRefDefinition def |
libraryFlowOutRef(mc, arg, outRef, preservesValue) |
def = node.getDefinition().(Ssa::ExplicitDefinition).getADefinition() and
def.getTargetAccess() = mc.getArgumentForParameter(outRef)
)
predicate flowThroughCallableLibraryOutRef(MethodCall mc, ExprNode arg, SsaDefinitionNode node, boolean preservesValue) {
libraryFlowOutRef(mc, arg.getExpr(), _, preservesValue) and
any(FlowThroughCallableLibraryOutRefStep x).hasStep(arg, node)
}
/**

View File

@@ -31,87 +31,6 @@ module TaintTracking {
localAdditionalTaintStep(nodeFrom, nodeTo)
}
private CIL::DataFlowNode asCilDataFlowNode(DataFlow::Node node) {
result = node.asParameter() or
result = node.asExpr()
}
private predicate localTaintStepCil(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
asCilDataFlowNode(nodeFrom).getALocalFlowSucc(asCilDataFlowNode(nodeTo), any(CIL::Tainted t))
}
private cached predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
localAdditionalTaintStepExpr(nodeFrom.asExpr(), nodeTo.asExpr())
or
DataFlow::Internal::flowOutOfDelegateLibraryCall(nodeFrom, nodeTo, false)
or
// Taint from `foreach` expression
exists(ForeachStmt fs, AssignableDefinitions::LocalVariableDefinition def, Ssa::ExplicitDefinition ssaDef |
nodeFrom.asExpr() = fs.getIterableExpr() and
def.getTarget() = fs.getVariable() and
ssaDef.getADefinition() = def and
nodeTo.(DataFlow::Internal::SsaDefinitionNode).getDefinition() = ssaDef
)
or
localTaintStepCil(nodeFrom, nodeTo)
}
private predicate localAdditionalTaintStepExpr(Expr exprFrom, Expr exprTo) {
// Taint propagation using library code
libraryFlow(exprFrom, exprTo, false)
or
// Taint from assigned value to element qualifier (`x[i] = 0`)
exists(AssignExpr ae |
exprFrom = ae.getRValue() and
exprTo.(AssignableRead) = getElementAccessQualifier+(ae.getLValue())
)
or
// Taint from array initializer
exprFrom = exprTo.(ArrayCreation).getInitializer().getAnElement()
or
// Taint from object initializer
exists(ElementInitializer ei |
ei = exprTo.(ObjectCreation).getInitializer().(CollectionInitializer).getAnElementInitializer() and
exprFrom = ei.getArgument(ei.getNumberOfArguments() - 1) // assume the last argument is the value (i.e., not a key)
)
or
// Taint from element qualifier
exprFrom = exprTo.(ElementAccess).getQualifier()
or
exprFrom = exprTo.(AddExpr).getAnOperand()
or
// A comparison expression where taint can flow from one of the
// operands if the other operand is a constant value.
exists(ComparisonTest ct, Expr other |
ct.getExpr() = exprTo and
exprFrom = ct.getAnArgument() and
other = ct.getAnArgument() and
other.stripCasts().hasValue() and
exprFrom != other
)
or
exprFrom = exprTo.(LogicalOperation).getAnOperand()
or
// Taint from tuple argument
exprTo = any(TupleExpr te |
exprFrom = te.getAnArgument() and
te.isReadAccess()
)
or
exprFrom = exprTo.(InterpolatedStringExpr).getAChild()
or
// Taint from tuple expression
exprTo = any(MemberAccess ma |
ma.getQualifier().getType() instanceof TupleType and
exprFrom = ma.getQualifier()
)
}
/** Gets the qualifier of element access `ea`. */
private Expr getElementAccessQualifier(ElementAccess ea) {
result = ea.getQualifier()
}
/**
* A taint tracking configuration.
*
@@ -163,7 +82,7 @@ module TaintTracking {
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
isAdditionalTaintStep(pred, succ) or
localAdditionalTaintStep(pred, succ) or
DataFlow::Internal::flowThroughCallableLibraryOutRef(_, pred.asExpr(), succ, false)
DataFlow::Internal::flowThroughCallableLibraryOutRef(_, pred, succ, false)
}
final
@@ -191,7 +110,136 @@ module TaintTracking {
}
}
private predicate canYieldReturn(Callable c, Expr e) {
c.getSourceDeclaration().canYieldReturn(e)
/** INTERNAL: Do not use. */
module Internal {
predicate canYieldReturn(Callable c, Expr e) {
c.getSourceDeclaration().canYieldReturn(e)
}
private CIL::DataFlowNode asCilDataFlowNode(DataFlow::Node node) {
result = node.asParameter() or
result = node.asExpr()
}
private predicate localTaintStepCil(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
asCilDataFlowNode(nodeFrom).getALocalFlowSucc(asCilDataFlowNode(nodeTo), any(CIL::Tainted t))
}
/** Gets the qualifier of element access `ea`. */
private Expr getElementAccessQualifier(ElementAccess ea) {
result = ea.getQualifier()
}
private class LocalTaintExprStep extends DataFlow::Internal::ExprStep {
LocalTaintExprStep() { this = "LocalTaintExprStep" }
override predicate stepsToExpr(Expr exprFrom, Expr exprTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor) {
exactScope = false and
(
// Taint propagation using library code
DataFlow::Internal::LocalFlow::libraryFlow(exprFrom, exprTo, scope, false) and
(isSuccessor = false or isSuccessor = true)
or
// Taint from assigned value to element qualifier (`x[i] = 0`)
exists(AssignExpr ae |
exprFrom = ae.getRValue() and
exprTo.(AssignableRead) = getElementAccessQualifier+(ae.getLValue()) and
scope = ae and
isSuccessor = false
)
or
// Taint from array initializer
exprFrom = exprTo.(ArrayCreation).getInitializer().getAnElement() and
scope = exprTo and
isSuccessor = false
or
// Taint from object initializer
exists(ElementInitializer ei |
ei = exprTo.(ObjectCreation).getInitializer().(CollectionInitializer).getAnElementInitializer() and
exprFrom = ei.getArgument(ei.getNumberOfArguments() - 1) and // assume the last argument is the value (i.e., not a key)
scope = exprTo and
isSuccessor = false
)
or
// Taint from element qualifier
exprFrom = exprTo.(ElementAccess).getQualifier() and
scope = exprTo and
isSuccessor = true
or
exprFrom = exprTo.(AddExpr).getAnOperand() and
scope = exprTo and
isSuccessor = true
or
// A comparison expression where taint can flow from one of the
// operands if the other operand is a constant value.
exists(ComparisonTest ct, Expr other |
ct.getExpr() = exprTo and
exprFrom = ct.getAnArgument() and
other = ct.getAnArgument() and
other.stripCasts().hasValue() and
exprFrom != other and
scope = exprTo and
isSuccessor = true
)
or
exprFrom = exprTo.(LogicalOperation).getAnOperand() and
scope = exprTo and
isSuccessor = false
or
// Taint from tuple argument
exprTo = any(TupleExpr te |
exprFrom = te.getAnArgument() and
te.isReadAccess() and
scope = exprTo and
isSuccessor = true
)
or
exprFrom = exprTo.(InterpolatedStringExpr).getAChild() and
scope = exprTo and
isSuccessor = true
or
// Taint from tuple expression
exprTo = any(MemberAccess ma |
ma.getQualifier().getType() instanceof TupleType and
exprFrom = ma.getQualifier() and
scope = exprTo and
isSuccessor = true
)
)
}
override predicate stepsToDefinition(Expr exprFrom, AssignableDefinition defTo, ControlFlowElement scope, boolean exactScope, boolean isSuccessor) {
// Taint from `foreach` expression
exists(ForeachStmt fs |
exprFrom = fs.getIterableExpr() and
defTo.(AssignableDefinitions::LocalVariableDefinition).getDeclaration() = fs.getVariableDeclExpr() and
isSuccessor = true
|
scope = fs and
exactScope = true
or
scope = fs.getIterableExpr() and
exactScope = false
or
scope = fs.getVariableDeclExpr() and
exactScope = false
)
}
}
cached module Cached {
cached predicate forceCachingInSameStage() { any() }
cached predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
DataFlow::Internal::Cached::forceCachingInSameStage() and
any(LocalTaintExprStep x).hasStep(nodeFrom, nodeTo)
or
DataFlow::Internal::flowOutOfDelegateLibraryCall(nodeFrom, nodeTo, false)
or
localTaintStepCil(nodeFrom, nodeTo)
}
}
import Cached
}
private import Internal
}

View File

@@ -506,7 +506,7 @@ class DelegateCall extends Call, @delegate_invocation_expr {
)
or
exists(AddEventSource aes, CallContext::CallContext cc2 |
aes = this.getAnAddEventSource() and
aes = this.getAnAddEventSource(_) and
result = aes.getARuntimeTarget(cc2)
|
aes = this.getAnAddEventSourceSameEnclosingCallable() and
@@ -518,18 +518,17 @@ class DelegateCall extends Call, @delegate_invocation_expr {
)
}
private AddEventSource getAnAddEventSource() {
this.getDelegateExpr().(EventAccess).getTarget() = result.getEvent()
private AddEventSource getAnAddEventSource(Callable enclosingCallable) {
this.getDelegateExpr().(EventAccess).getTarget() = result.getEvent() and
enclosingCallable = result.getExpr().getEnclosingCallable()
}
private AddEventSource getAnAddEventSourceSameEnclosingCallable() {
result = getAnAddEventSource() and
result.getExpr().getEnclosingCallable() = this.getEnclosingCallable()
result = getAnAddEventSource(this.getEnclosingCallable())
}
private AddEventSource getAnAddEventSourceDifferentEnclosingCallable() {
result = getAnAddEventSource() and
result.getExpr().getEnclosingCallable() != this.getEnclosingCallable()
exists(Callable c | result = getAnAddEventSource(c) | c != this.getEnclosingCallable())
}
override Callable getARuntimeTarget() { result = getARuntimeTarget(_) }

View File

@@ -670,7 +670,10 @@ class TupleExpr extends Expr, @tuple_expr {
Expr getAnArgument() { result = getArgument(_) }
/** Holds if this tuple is a read access. */
predicate isReadAccess() { not exists(AssignExpr e | this = e.getLValue().getAChildExpr*()) }
predicate isReadAccess() {
not exists(AssignExpr e | this = e.getLValue().getAChildExpr*()) and
not exists(ForeachStmt fs | this = fs.getVariableDeclTuple().getAChildExpr*())
}
}
/**

View File

@@ -123,9 +123,9 @@ module TaintedPath {
*/
class PathCheck extends Sanitizer {
PathCheck() {
// This expression is structurally replicated in a dominating guard which is not a "weak" check.
exists(Expr e |
this.getExpr().(GuardedExpr).isGuardedBy(_, e, _) and
// This expression is structurally replicated in a dominating guard which is not a "weak" check
exists(Expr e, AbstractValues::BooleanValue v |
exists(this.(GuardedDataFlowNode).getAGuard(e, v)) and
not inWeakCheck(e)
)
}

View File

@@ -98,8 +98,9 @@ module UrlRedirect {
*/
class IsLocalUrlSanitizer extends Sanitizer {
IsLocalUrlSanitizer() {
exists(MethodCall mc | mc.getTarget().hasName("IsLocalUrl") |
this.getExpr().(GuardedExpr).isGuardedBy(mc, mc.getArgument(0), true)
exists(MethodCall mc, AbstractValues::BooleanValue v | mc.getTarget().hasName("IsLocalUrl") |
mc = this.(GuardedDataFlowNode).getAGuard(mc.getArgument(0), v) and
v.getValue() = true
)
}
}

View File

@@ -127,10 +127,10 @@ module ZipSlip {
*/
class StringCheckSanitizer extends Sanitizer {
StringCheckSanitizer() {
exists(GuardedExpr ge, MethodCall mc, Expr startsWithQualifier |
ge = this.asExpr() and
ge.isGuardedBy(mc, startsWithQualifier, true)
exists(MethodCall mc, Expr startsWithQualifier, AbstractValues::BooleanValue v |
mc = this.(GuardedDataFlowNode).getAGuard(startsWithQualifier, v)
|
v.getValue() = true and
mc.getTarget().hasQualifiedName("System.String", "StartsWith") and
mc.getQualifier() = startsWithQualifier and
// A StartsWith check against Path.Combine is not sufficient, because the ".." elements have

View File

@@ -185,14 +185,8 @@
| CSharp7.cs:284:41:284:48 | access to property Key | CSharp7.cs:284:40:284:61 | (..., ...) |
| CSharp7.cs:284:51:284:54 | access to parameter item | CSharp7.cs:284:51:284:60 | access to property Value |
| CSharp7.cs:284:51:284:60 | access to property Value | CSharp7.cs:284:40:284:61 | (..., ...) |
| CSharp7.cs:286:23:286:23 | Int32 a | CSharp7.cs:286:18:286:34 | (..., ...) |
| CSharp7.cs:286:33:286:33 | String b | CSharp7.cs:286:18:286:34 | (..., ...) |
| CSharp7.cs:286:39:286:42 | access to local variable list | CSharp7.cs:288:36:288:39 | access to local variable list |
| CSharp7.cs:288:23:288:23 | Int32 a | CSharp7.cs:288:18:288:31 | (..., ...) |
| CSharp7.cs:288:30:288:30 | String b | CSharp7.cs:288:18:288:31 | (..., ...) |
| CSharp7.cs:288:36:288:39 | access to local variable list | CSharp7.cs:290:32:290:35 | access to local variable list |
| CSharp7.cs:290:23:290:23 | Int32 a | CSharp7.cs:290:18:290:27 | (..., ...) |
| CSharp7.cs:290:26:290:26 | String b | CSharp7.cs:290:18:290:27 | (..., ...) |
| CSharp7.cs:298:17:298:19 | SSA def(x) | CSharp7.cs:298:22:298:39 | SSA phi(x) |
| CSharp7.cs:298:19:298:19 | 0 | CSharp7.cs:298:17:298:19 | SSA def(x) |
| CSharp7.cs:298:22:298:22 | access to local variable x | CSharp7.cs:298:22:298:25 | ... < ... |

View File

@@ -40,6 +40,6 @@
| CSharp7.cs:224:9:224:18 | (..., ...) | write |
| CSharp7.cs:225:9:225:18 | (..., ...) | write |
| CSharp7.cs:284:40:284:61 | (..., ...) | read |
| CSharp7.cs:286:18:286:34 | (..., ...) | read |
| CSharp7.cs:288:18:288:31 | (..., ...) | read |
| CSharp7.cs:290:18:290:27 | (..., ...) | read |
| CSharp7.cs:286:18:286:34 | (..., ...) | write |
| CSharp7.cs:288:18:288:31 | (..., ...) | write |
| CSharp7.cs:290:18:290:27 | (..., ...) | write |

View File

@@ -9,8 +9,9 @@ class Configuration extends DataFlow::Configuration {
override predicate isSink(DataFlow::Node sink) { any() }
override predicate isBarrier(DataFlow::Node node) {
exists(EQExpr eq, Expr e |
node.asExpr().(GuardedExpr).isGuardedBy(eq, e, true) and
exists(EQExpr eq, Expr e, AbstractValues::BooleanValue v |
eq = node.(GuardedDataFlowNode).getAGuard(e, v) |
v.getValue() = true and
eq.getAnOperand() = e and
eq.getAnOperand() instanceof NullLiteral
)

View File

@@ -35,5 +35,6 @@
| GlobalDataFlow.cs:263:15:263:24 | access to parameter sinkParam7 |
| GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 |
| GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 |
| Splitting.cs:9:15:9:15 | access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x |

View File

@@ -172,10 +172,18 @@ edges
| GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam |
| GlobalDataFlow.cs:399:9:399:11 | value | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 |
| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | access to parameter tainted |
| Splitting.cs:8:17:8:31 | call to method Return | Splitting.cs:9:15:9:15 | access to local variable x |
| Splitting.cs:8:17:8:31 | call to method Return | Splitting.cs:11:19:11:19 | access to local variable x |
| Splitting.cs:8:24:8:30 | access to parameter tainted | Splitting.cs:8:17:8:31 | call to method Return |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | Splitting.cs:11:19:11:19 | access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | Splitting.cs:11:19:11:19 | access to local variable x |
| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
nodes
| Capture.cs:7:20:7:26 | tainted |
| Capture.cs:9:9:13:9 | SSA capture def(tainted) |
@@ -307,11 +315,23 @@ nodes
| GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 |
| GlobalDataFlow.cs:410:22:410:35 | "taint source" |
| Splitting.cs:3:28:3:34 | tainted |
| Splitting.cs:8:17:8:31 | call to method Return |
| Splitting.cs:8:24:8:30 | access to parameter tainted |
| Splitting.cs:9:15:9:15 | access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted |
| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x |
#select
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | [b (line 3): true] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | [b (line 3): true] access to local variable x |
| GlobalDataFlow.cs:18:15:18:29 | access to field SinkField0 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:18:15:18:29 | access to field SinkField0 | access to field SinkField0 |
| GlobalDataFlow.cs:71:15:71:19 | access to local variable sink0 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:71:15:71:19 | access to local variable sink0 | access to local variable sink0 |
| GlobalDataFlow.cs:73:15:73:19 | access to local variable sink1 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:73:15:73:19 | access to local variable sink1 | access to local variable sink1 |
@@ -340,7 +360,7 @@ nodes
| GlobalDataFlow.cs:153:15:153:19 | access to local variable sink7 | GlobalDataFlow.cs:318:13:318:26 | "taint source" | GlobalDataFlow.cs:153:15:153:19 | access to local variable sink7 | access to local variable sink7 |
| GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | GlobalDataFlow.cs:323:13:323:26 | "taint source" | GlobalDataFlow.cs:156:15:156:19 | access to local variable sink8 | access to local variable sink8 |
| GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | GlobalDataFlow.cs:175:35:175:48 | "taint source" | GlobalDataFlow.cs:177:15:177:19 | access to local variable sink9 | access to local variable sink9 |
| Splitting.cs:9:15:9:15 | access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | access to local variable x | access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:11:19:11:19 | access to local variable x | access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:11:19:11:19 | access to local variable x | access to local variable x |
| GlobalDataFlow.cs:233:15:233:24 | access to parameter sinkParam0 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:233:15:233:24 | access to parameter sinkParam0 | access to parameter sinkParam0 |
| GlobalDataFlow.cs:233:15:233:24 | access to parameter sinkParam0 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:233:15:233:24 | access to parameter sinkParam0 | access to parameter sinkParam0 |

View File

@@ -51,5 +51,6 @@
| GlobalDataFlow.cs:301:15:301:25 | access to parameter sinkParam11 |
| GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 |
| GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 |
| Splitting.cs:9:15:9:15 | access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x |

View File

@@ -215,10 +215,18 @@ edges
| GlobalDataFlow.cs:377:16:377:21 | access to local variable sink11 | GlobalDataFlow.cs:159:22:159:43 | call to method TaintedParam |
| GlobalDataFlow.cs:399:9:399:11 | value | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 |
| GlobalDataFlow.cs:410:22:410:35 | "taint source" | GlobalDataFlow.cs:193:22:193:32 | access to property OutProperty |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | access to parameter tainted |
| Splitting.cs:8:17:8:31 | call to method Return | Splitting.cs:9:15:9:15 | access to local variable x |
| Splitting.cs:8:17:8:31 | call to method Return | Splitting.cs:11:19:11:19 | access to local variable x |
| Splitting.cs:8:24:8:30 | access to parameter tainted | Splitting.cs:8:17:8:31 | call to method Return |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | Splitting.cs:11:19:11:19 | access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | Splitting.cs:11:19:11:19 | access to local variable x |
| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
nodes
| Capture.cs:7:20:7:26 | tainted |
| Capture.cs:9:9:13:9 | SSA capture def(tainted) |
@@ -395,9 +403,17 @@ nodes
| GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 |
| GlobalDataFlow.cs:410:22:410:35 | "taint source" |
| Splitting.cs:3:28:3:34 | tainted |
| Splitting.cs:8:17:8:31 | call to method Return |
| Splitting.cs:8:24:8:30 | access to parameter tainted |
| Splitting.cs:9:15:9:15 | access to local variable x |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted |
| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x |
#select
| Capture.cs:12:19:12:24 | access to local variable sink27 | Capture.cs:7:20:7:26 | tainted | Capture.cs:12:19:12:24 | access to local variable sink27 | access to local variable sink27 |
@@ -454,5 +470,9 @@ nodes
| GlobalDataFlow.cs:301:15:301:25 | access to parameter sinkParam11 | GlobalDataFlow.cs:201:39:201:45 | tainted | GlobalDataFlow.cs:301:15:301:25 | access to parameter sinkParam11 | access to parameter sinkParam11 |
| GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | GlobalDataFlow.cs:373:39:373:45 | tainted | GlobalDataFlow.cs:376:15:376:20 | access to local variable sink11 | access to local variable sink11 |
| GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | GlobalDataFlow.cs:17:27:17:40 | "taint source" | GlobalDataFlow.cs:399:41:399:46 | access to local variable sink20 | access to local variable sink20 |
| Splitting.cs:9:15:9:15 | access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | access to local variable x | access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | [b (line 3): true] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | [b (line 3): true] access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:11:19:11:19 | access to local variable x | access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x | Splitting.cs:3:28:3:34 | tainted | Splitting.cs:11:19:11:19 | access to local variable x | access to local variable x |

View File

@@ -17,8 +17,7 @@
| SSA.cs:98:15:98:22 | access to local variable ssaSink4 |
| SSA.cs:124:15:124:34 | access to field SsaFieldSink1 |
| SSA.cs:180:15:180:22 | access to local variable ssaSink5 |
| Splitting.cs:8:19:8:19 | access to local variable x |
| Splitting.cs:12:15:12:15 | access to local variable x |
| Splitting.cs:25:15:25:15 | access to local variable x |
| Splitting.cs:8:19:8:19 | [b (line 3): true] access to local variable x |
| Splitting.cs:12:15:12:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:25:15:25:15 | [b (line 17): true] access to local variable x |
| Splitting.cs:27:19:27:19 | access to local variable x |
| Splitting.cs:29:19:29:19 | access to local variable x |

View File

@@ -4,7 +4,7 @@ import semmle.code.csharp.controlflow.Guards
predicate step(DataFlow::Node pred, DataFlow::Node succ) {
DataFlow::localFlowStep(pred, succ) and
not succ.asExpr() instanceof NullGuardedExpr
not succ instanceof NullGuardedDataFlowNode
}
from MyFlowSource source, DataFlow::Node sink, Access target

View File

@@ -49,22 +49,25 @@
| LocalDataFlow.cs:85:15:85:22 | access to local variable nonSink0 | LocalDataFlow.cs:92:21:92:28 | access to local variable nonSink0 |
| LocalDataFlow.cs:88:13:88:27 | SSA def(sink6) | LocalDataFlow.cs:89:15:89:19 | access to local variable sink6 |
| LocalDataFlow.cs:88:22:88:26 | access to local variable sink5 | LocalDataFlow.cs:88:13:88:27 | SSA def(sink6) |
| LocalDataFlow.cs:89:15:89:19 | access to local variable sink6 | LocalDataFlow.cs:96:31:96:35 | access to local variable sink6 |
| LocalDataFlow.cs:89:15:89:19 | access to local variable sink6 | LocalDataFlow.cs:96:31:96:35 | [b (line 49): false] access to local variable sink6 |
| LocalDataFlow.cs:92:9:92:29 | SSA def(nonSink0) | LocalDataFlow.cs:93:15:93:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:92:21:92:28 | access to local variable nonSink0 | LocalDataFlow.cs:92:9:92:29 | SSA def(nonSink0) |
| LocalDataFlow.cs:96:13:96:35 | [b (line 49): false] SSA def(sink7) | LocalDataFlow.cs:97:15:97:19 | access to local variable sink7 |
| LocalDataFlow.cs:96:13:96:35 | [b (line 49): true] SSA def(sink7) | LocalDataFlow.cs:97:15:97:19 | access to local variable sink7 |
| LocalDataFlow.cs:96:21:96:21 | access to parameter b | LocalDataFlow.cs:100:20:100:20 | access to parameter b |
| LocalDataFlow.cs:96:13:96:35 | [b (line 49): false] SSA def(sink7) | LocalDataFlow.cs:97:15:97:19 | [b (line 49): false] access to local variable sink7 |
| LocalDataFlow.cs:96:13:96:35 | [b (line 49): true] SSA def(sink7) | LocalDataFlow.cs:97:15:97:19 | [b (line 49): true] access to local variable sink7 |
| LocalDataFlow.cs:96:21:96:21 | access to parameter b | LocalDataFlow.cs:100:20:100:20 | [b (line 49): false] access to parameter b |
| LocalDataFlow.cs:96:21:96:21 | access to parameter b | LocalDataFlow.cs:100:20:100:20 | [b (line 49): true] access to parameter b |
| LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... | LocalDataFlow.cs:96:13:96:35 | [b (line 49): false] SSA def(sink7) |
| LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... | LocalDataFlow.cs:96:13:96:35 | [b (line 49): true] SSA def(sink7) |
| LocalDataFlow.cs:96:25:96:27 | "a" | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:96:31:96:35 | access to local variable sink6 | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:97:15:97:19 | access to local variable sink7 | LocalDataFlow.cs:100:9:100:36 | SSA phi(sink7) |
| LocalDataFlow.cs:96:25:96:27 | [b (line 49): true] "a" | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:96:31:96:35 | [b (line 49): false] access to local variable sink6 | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:97:15:97:19 | [b (line 49): false] access to local variable sink7 | LocalDataFlow.cs:100:9:100:36 | SSA phi(sink7) |
| LocalDataFlow.cs:97:15:97:19 | [b (line 49): true] access to local variable sink7 | LocalDataFlow.cs:100:9:100:36 | SSA phi(sink7) |
| LocalDataFlow.cs:100:9:100:36 | SSA def(nonSink0) | LocalDataFlow.cs:101:15:101:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:100:9:100:36 | SSA phi(sink7) | LocalDataFlow.cs:104:29:104:33 | access to local variable sink7 |
| LocalDataFlow.cs:100:20:100:36 | ... ? ... : ... | LocalDataFlow.cs:100:9:100:36 | SSA def(nonSink0) |
| LocalDataFlow.cs:100:24:100:28 | "abc" | LocalDataFlow.cs:100:20:100:36 | ... ? ... : ... |
| LocalDataFlow.cs:100:32:100:36 | "def" | LocalDataFlow.cs:100:20:100:36 | ... ? ... : ... |
| LocalDataFlow.cs:100:20:100:36 | [b (line 49): false] ... ? ... : ... | LocalDataFlow.cs:100:9:100:36 | SSA def(nonSink0) |
| LocalDataFlow.cs:100:20:100:36 | [b (line 49): true] ... ? ... : ... | LocalDataFlow.cs:100:9:100:36 | SSA def(nonSink0) |
| LocalDataFlow.cs:100:24:100:28 | "abc" | LocalDataFlow.cs:100:20:100:36 | [b (line 49): true] ... ? ... : ... |
| LocalDataFlow.cs:100:32:100:36 | "def" | LocalDataFlow.cs:100:20:100:36 | [b (line 49): false] ... ? ... : ... |
| LocalDataFlow.cs:101:15:101:22 | access to local variable nonSink0 | LocalDataFlow.cs:108:32:108:39 | access to local variable nonSink0 |
| LocalDataFlow.cs:104:13:104:33 | SSA def(sink8) | LocalDataFlow.cs:105:15:105:19 | access to local variable sink8 |
| LocalDataFlow.cs:104:21:104:33 | (...) ... | LocalDataFlow.cs:104:13:104:33 | SSA def(sink8) |
@@ -645,58 +648,72 @@
| SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | SSA.cs:180:15:180:22 | access to local variable ssaSink5 |
| Splitting.cs:3:18:3:18 | b | Splitting.cs:6:13:6:13 | access to parameter b |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:5:17:5:23 | access to parameter tainted |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:8:19:8:19 | access to local variable x |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:12:15:12:15 | access to local variable x |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:8:19:8:19 | [b (line 3): true] access to local variable x |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:12:15:12:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:5:17:5:23 | access to parameter tainted | Splitting.cs:5:13:5:23 | SSA def(x) |
| Splitting.cs:6:13:6:13 | access to parameter b | Splitting.cs:13:13:13:13 | access to parameter b |
| Splitting.cs:8:19:8:19 | access to local variable x | Splitting.cs:9:17:9:17 | access to local variable x |
| Splitting.cs:12:15:12:15 | access to local variable x | Splitting.cs:14:19:14:19 | access to local variable x |
| Splitting.cs:6:13:6:13 | access to parameter b | Splitting.cs:13:13:13:13 | [b (line 3): false] access to parameter b |
| Splitting.cs:6:13:6:13 | access to parameter b | Splitting.cs:13:13:13:13 | [b (line 3): true] access to parameter b |
| Splitting.cs:8:19:8:19 | [b (line 3): true] access to local variable x | Splitting.cs:9:17:9:17 | [b (line 3): true] access to local variable x |
| Splitting.cs:9:17:9:17 | [b (line 3): true] access to local variable x | Splitting.cs:12:15:12:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:12:15:12:15 | [b (line 3): true] access to local variable x | Splitting.cs:14:19:14:19 | access to local variable x |
| Splitting.cs:17:18:17:18 | b | Splitting.cs:20:13:20:13 | access to parameter b |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:22:19:22:19 | access to local variable x |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:25:15:25:15 | access to local variable x |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:22:19:22:19 | [b (line 17): true] access to local variable x |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:25:15:25:15 | [b (line 17): false] access to local variable x |
| Splitting.cs:19:17:19:18 | "" | Splitting.cs:19:13:19:18 | SSA def(x) |
| Splitting.cs:20:13:20:13 | access to parameter b | Splitting.cs:26:13:26:13 | access to parameter b |
| Splitting.cs:23:13:23:30 | [b (line 17): true] SSA def(x) | Splitting.cs:25:15:25:15 | access to local variable x |
| Splitting.cs:23:17:23:30 | "taint source" | Splitting.cs:23:13:23:30 | [b (line 17): true] SSA def(x) |
| Splitting.cs:25:15:25:15 | access to local variable x | Splitting.cs:27:19:27:19 | access to local variable x |
| Splitting.cs:25:15:25:15 | access to local variable x | Splitting.cs:29:19:29:19 | access to local variable x |
| Splitting.cs:20:13:20:13 | access to parameter b | Splitting.cs:26:13:26:13 | [b (line 17): false] access to parameter b |
| Splitting.cs:20:13:20:13 | access to parameter b | Splitting.cs:26:13:26:13 | [b (line 17): true] access to parameter b |
| Splitting.cs:23:13:23:30 | [b (line 17): true] SSA def(x) | Splitting.cs:25:15:25:15 | [b (line 17): true] access to local variable x |
| Splitting.cs:23:17:23:30 | [b (line 17): true] "taint source" | Splitting.cs:23:13:23:30 | [b (line 17): true] SSA def(x) |
| Splitting.cs:25:15:25:15 | [b (line 17): false] access to local variable x | Splitting.cs:29:19:29:19 | access to local variable x |
| Splitting.cs:25:15:25:15 | [b (line 17): true] access to local variable x | Splitting.cs:27:19:27:19 | access to local variable x |
| Splitting.cs:32:18:32:18 | b | Splitting.cs:35:13:35:13 | access to parameter b |
| Splitting.cs:35:13:35:13 | access to parameter b | Splitting.cs:39:15:39:15 | access to parameter b |
| Splitting.cs:37:9:37:15 | [b (line 32): false] SSA def(x) | Splitting.cs:38:15:38:15 | access to local variable x |
| Splitting.cs:37:9:37:15 | [b (line 32): true] SSA def(x) | Splitting.cs:38:15:38:15 | access to local variable x |
| Splitting.cs:37:13:37:15 | "b" | Splitting.cs:37:9:37:15 | [b (line 32): false] SSA def(x) |
| Splitting.cs:37:13:37:15 | "b" | Splitting.cs:37:9:37:15 | [b (line 32): true] SSA def(x) |
| Splitting.cs:38:15:38:15 | access to local variable x | Splitting.cs:39:19:39:19 | access to local variable x |
| Splitting.cs:39:15:39:15 | access to parameter b | Splitting.cs:42:13:42:13 | access to parameter b |
| Splitting.cs:39:19:39:19 | access to local variable x | Splitting.cs:39:15:39:25 | ... ? ... : ... |
| Splitting.cs:39:23:39:25 | "c" | Splitting.cs:39:15:39:25 | ... ? ... : ... |
| Splitting.cs:40:23:40:23 | access to local variable x | Splitting.cs:40:15:40:23 | (...) ... |
| Splitting.cs:41:19:41:21 | "d" | Splitting.cs:41:15:41:21 | ... = ... |
| Splitting.cs:35:13:35:13 | access to parameter b | Splitting.cs:39:15:39:15 | [b (line 32): false] access to parameter b |
| Splitting.cs:35:13:35:13 | access to parameter b | Splitting.cs:39:15:39:15 | [b (line 32): true] access to parameter b |
| Splitting.cs:37:9:37:15 | [b (line 32): false] SSA def(x) | Splitting.cs:38:15:38:15 | [b (line 32): false] access to local variable x |
| Splitting.cs:37:9:37:15 | [b (line 32): true] SSA def(x) | Splitting.cs:38:15:38:15 | [b (line 32): true] access to local variable x |
| Splitting.cs:37:13:37:15 | [b (line 32): false] "b" | Splitting.cs:37:9:37:15 | [b (line 32): false] SSA def(x) |
| Splitting.cs:37:13:37:15 | [b (line 32): true] "b" | Splitting.cs:37:9:37:15 | [b (line 32): true] SSA def(x) |
| Splitting.cs:38:15:38:15 | [b (line 32): false] access to local variable x | Splitting.cs:40:23:40:23 | [b (line 32): false] access to local variable x |
| Splitting.cs:38:15:38:15 | [b (line 32): true] access to local variable x | Splitting.cs:39:19:39:19 | [b (line 32): true] access to local variable x |
| Splitting.cs:39:15:39:15 | [b (line 32): false] access to parameter b | Splitting.cs:42:13:42:13 | [b (line 32): false] access to parameter b |
| Splitting.cs:39:15:39:15 | [b (line 32): true] access to parameter b | Splitting.cs:42:13:42:13 | [b (line 32): true] access to parameter b |
| Splitting.cs:39:19:39:19 | [b (line 32): true] access to local variable x | Splitting.cs:39:15:39:25 | [b (line 32): true] ... ? ... : ... |
| Splitting.cs:39:19:39:19 | [b (line 32): true] access to local variable x | Splitting.cs:40:23:40:23 | [b (line 32): true] access to local variable x |
| Splitting.cs:39:23:39:25 | [b (line 32): false] "c" | Splitting.cs:39:15:39:25 | [b (line 32): false] ... ? ... : ... |
| Splitting.cs:40:23:40:23 | [b (line 32): false] access to local variable x | Splitting.cs:40:15:40:23 | [b (line 32): false] (...) ... |
| Splitting.cs:40:23:40:23 | [b (line 32): true] access to local variable x | Splitting.cs:40:15:40:23 | [b (line 32): true] (...) ... |
| Splitting.cs:41:19:41:21 | [b (line 32): false] "d" | Splitting.cs:41:15:41:21 | [b (line 32): false] ... = ... |
| Splitting.cs:41:19:41:21 | [b (line 32): true] "d" | Splitting.cs:41:15:41:21 | [b (line 32): true] ... = ... |
| Splitting.cs:46:18:46:18 | b | Splitting.cs:49:13:49:13 | access to parameter b |
| Splitting.cs:48:13:48:18 | SSA def(x) | Splitting.cs:53:13:53:13 | access to local variable x |
| Splitting.cs:48:13:48:18 | SSA def(x) | Splitting.cs:53:13:53:13 | [b (line 46): false] access to local variable x |
| Splitting.cs:48:17:48:18 | "" | Splitting.cs:48:13:48:18 | SSA def(x) |
| Splitting.cs:49:13:49:13 | access to parameter b | Splitting.cs:60:13:60:13 | access to parameter b |
| Splitting.cs:50:13:50:21 | [b (line 46): true] SSA def(x) | Splitting.cs:53:13:53:13 | access to local variable x |
| Splitting.cs:50:17:50:21 | "abc" | Splitting.cs:50:13:50:21 | [b (line 46): true] SSA def(x) |
| Splitting.cs:51:13:51:36 | [b (line 46): false] SSA def(y) | Splitting.cs:52:9:52:9 | access to local variable y |
| Splitting.cs:51:13:51:36 | [b (line 46): true] SSA def(y) | Splitting.cs:52:9:52:9 | access to local variable y |
| Splitting.cs:51:17:51:36 | array creation of type String[] | Splitting.cs:51:13:51:36 | [b (line 46): false] SSA def(y) |
| Splitting.cs:51:17:51:36 | array creation of type String[] | Splitting.cs:51:13:51:36 | [b (line 46): true] SSA def(y) |
| Splitting.cs:52:9:52:9 | access to local variable y | Splitting.cs:53:17:53:17 | access to local variable y |
| Splitting.cs:53:9:53:20 | [b (line 46): false] SSA def(x) | Splitting.cs:54:17:54:17 | access to local variable x |
| Splitting.cs:53:9:53:20 | [b (line 46): true] SSA def(x) | Splitting.cs:54:17:54:17 | access to local variable x |
| Splitting.cs:53:13:53:20 | ... + ... | Splitting.cs:53:9:53:20 | [b (line 46): false] SSA def(x) |
| Splitting.cs:53:13:53:20 | ... + ... | Splitting.cs:53:9:53:20 | [b (line 46): true] SSA def(x) |
| Splitting.cs:53:17:53:17 | access to local variable y | Splitting.cs:57:17:57:17 | access to local variable y |
| Splitting.cs:54:13:54:23 | [b (line 46): false] SSA def(z) | Splitting.cs:55:14:55:14 | access to local variable z |
| Splitting.cs:54:13:54:23 | [b (line 46): true] SSA def(z) | Splitting.cs:55:14:55:14 | access to local variable z |
| Splitting.cs:54:17:54:17 | access to local variable x | Splitting.cs:56:17:56:17 | access to local variable x |
| Splitting.cs:54:17:54:23 | ... == ... | Splitting.cs:54:13:54:23 | [b (line 46): false] SSA def(z) |
| Splitting.cs:54:17:54:23 | ... == ... | Splitting.cs:54:13:54:23 | [b (line 46): true] SSA def(z) |
| Splitting.cs:56:9:56:19 | [b (line 46): false] SSA def(x) | Splitting.cs:57:14:57:14 | access to local variable x |
| Splitting.cs:56:9:56:19 | [b (line 46): true] SSA def(x) | Splitting.cs:57:14:57:14 | access to local variable x |
| Splitting.cs:56:13:56:19 | $"..." | Splitting.cs:56:9:56:19 | [b (line 46): false] SSA def(x) |
| Splitting.cs:56:13:56:19 | $"..." | Splitting.cs:56:9:56:19 | [b (line 46): true] SSA def(x) |
| Splitting.cs:57:17:57:17 | access to local variable y | Splitting.cs:58:27:58:27 | access to local variable y |
| Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) | Splitting.cs:59:19:59:19 | access to local variable s |
| Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | Splitting.cs:59:19:59:19 | access to local variable s |
| Splitting.cs:49:13:49:13 | access to parameter b | Splitting.cs:60:13:60:13 | [b (line 46): false] access to parameter b |
| Splitting.cs:49:13:49:13 | access to parameter b | Splitting.cs:60:13:60:13 | [b (line 46): true] access to parameter b |
| Splitting.cs:50:13:50:21 | [b (line 46): true] SSA def(x) | Splitting.cs:53:13:53:13 | [b (line 46): true] access to local variable x |
| Splitting.cs:50:17:50:21 | [b (line 46): true] "abc" | Splitting.cs:50:13:50:21 | [b (line 46): true] SSA def(x) |
| Splitting.cs:51:13:51:36 | [b (line 46): false] SSA def(y) | Splitting.cs:52:9:52:9 | [b (line 46): false] access to local variable y |
| Splitting.cs:51:13:51:36 | [b (line 46): true] SSA def(y) | Splitting.cs:52:9:52:9 | [b (line 46): true] access to local variable y |
| Splitting.cs:51:17:51:36 | [b (line 46): false] array creation of type String[] | Splitting.cs:51:13:51:36 | [b (line 46): false] SSA def(y) |
| Splitting.cs:51:17:51:36 | [b (line 46): true] array creation of type String[] | Splitting.cs:51:13:51:36 | [b (line 46): true] SSA def(y) |
| Splitting.cs:52:9:52:9 | [b (line 46): false] access to local variable y | Splitting.cs:53:17:53:17 | [b (line 46): false] access to local variable y |
| Splitting.cs:52:9:52:9 | [b (line 46): true] access to local variable y | Splitting.cs:53:17:53:17 | [b (line 46): true] access to local variable y |
| Splitting.cs:53:9:53:20 | [b (line 46): false] SSA def(x) | Splitting.cs:54:17:54:17 | [b (line 46): false] access to local variable x |
| Splitting.cs:53:9:53:20 | [b (line 46): true] SSA def(x) | Splitting.cs:54:17:54:17 | [b (line 46): true] access to local variable x |
| Splitting.cs:53:13:53:20 | [b (line 46): false] ... + ... | Splitting.cs:53:9:53:20 | [b (line 46): false] SSA def(x) |
| Splitting.cs:53:13:53:20 | [b (line 46): true] ... + ... | Splitting.cs:53:9:53:20 | [b (line 46): true] SSA def(x) |
| Splitting.cs:53:17:53:17 | [b (line 46): false] access to local variable y | Splitting.cs:57:17:57:17 | [b (line 46): false] access to local variable y |
| Splitting.cs:53:17:53:17 | [b (line 46): true] access to local variable y | Splitting.cs:57:17:57:17 | [b (line 46): true] access to local variable y |
| Splitting.cs:54:13:54:23 | [b (line 46): false] SSA def(z) | Splitting.cs:55:14:55:14 | [b (line 46): false] access to local variable z |
| Splitting.cs:54:13:54:23 | [b (line 46): true] SSA def(z) | Splitting.cs:55:14:55:14 | [b (line 46): true] access to local variable z |
| Splitting.cs:54:17:54:17 | [b (line 46): false] access to local variable x | Splitting.cs:56:17:56:17 | [b (line 46): false] access to local variable x |
| Splitting.cs:54:17:54:17 | [b (line 46): true] access to local variable x | Splitting.cs:56:17:56:17 | [b (line 46): true] access to local variable x |
| Splitting.cs:54:17:54:23 | [b (line 46): false] ... == ... | Splitting.cs:54:13:54:23 | [b (line 46): false] SSA def(z) |
| Splitting.cs:54:17:54:23 | [b (line 46): true] ... == ... | Splitting.cs:54:13:54:23 | [b (line 46): true] SSA def(z) |
| Splitting.cs:56:9:56:19 | [b (line 46): false] SSA def(x) | Splitting.cs:57:14:57:14 | [b (line 46): false] access to local variable x |
| Splitting.cs:56:9:56:19 | [b (line 46): true] SSA def(x) | Splitting.cs:57:14:57:14 | [b (line 46): true] access to local variable x |
| Splitting.cs:56:13:56:19 | [b (line 46): false] $"..." | Splitting.cs:56:9:56:19 | [b (line 46): false] SSA def(x) |
| Splitting.cs:56:13:56:19 | [b (line 46): true] $"..." | Splitting.cs:56:9:56:19 | [b (line 46): true] SSA def(x) |
| Splitting.cs:57:17:57:17 | [b (line 46): false] access to local variable y | Splitting.cs:58:27:58:27 | [b (line 46): false] access to local variable y |
| Splitting.cs:57:17:57:17 | [b (line 46): true] access to local variable y | Splitting.cs:58:27:58:27 | [b (line 46): true] access to local variable y |
| Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): false] access to local variable s |
| Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): true] access to local variable s |

View File

@@ -3,7 +3,8 @@
| LocalDataFlow.cs:71:15:71:19 | access to local variable sink2 |
| LocalDataFlow.cs:81:15:81:19 | access to local variable sink5 |
| LocalDataFlow.cs:89:15:89:19 | access to local variable sink6 |
| LocalDataFlow.cs:97:15:97:19 | access to local variable sink7 |
| LocalDataFlow.cs:97:15:97:19 | [b (line 49): false] access to local variable sink7 |
| LocalDataFlow.cs:97:15:97:19 | [b (line 49): true] access to local variable sink7 |
| LocalDataFlow.cs:105:15:105:19 | access to local variable sink8 |
| LocalDataFlow.cs:113:15:113:19 | access to local variable sink9 |
| LocalDataFlow.cs:121:15:121:20 | access to local variable sink10 |
@@ -70,8 +71,7 @@
| SSA.cs:98:15:98:22 | access to local variable ssaSink4 |
| SSA.cs:124:15:124:34 | access to field SsaFieldSink1 |
| SSA.cs:180:15:180:22 | access to local variable ssaSink5 |
| Splitting.cs:8:19:8:19 | access to local variable x |
| Splitting.cs:12:15:12:15 | access to local variable x |
| Splitting.cs:25:15:25:15 | access to local variable x |
| Splitting.cs:8:19:8:19 | [b (line 3): true] access to local variable x |
| Splitting.cs:12:15:12:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:25:15:25:15 | [b (line 17): true] access to local variable x |
| Splitting.cs:27:19:27:19 | access to local variable x |
| Splitting.cs:29:19:29:19 | access to local variable x |

View File

@@ -4,7 +4,7 @@ import semmle.code.csharp.controlflow.Guards
predicate step(DataFlow::Node pred, DataFlow::Node succ) {
TaintTracking::localTaintStep(pred, succ) and
not succ.asExpr() instanceof NullGuardedExpr
not succ instanceof NullGuardedDataFlowNode
}
from MyFlowSource source, DataFlow::Node sink, Access target

View File

@@ -65,24 +65,28 @@
| LocalDataFlow.cs:85:15:85:22 | access to local variable nonSink0 | LocalDataFlow.cs:92:21:92:28 | access to local variable nonSink0 |
| LocalDataFlow.cs:88:13:88:27 | SSA def(sink6) | LocalDataFlow.cs:89:15:89:19 | access to local variable sink6 |
| LocalDataFlow.cs:88:22:88:26 | access to local variable sink5 | LocalDataFlow.cs:88:13:88:27 | SSA def(sink6) |
| LocalDataFlow.cs:89:15:89:19 | access to local variable sink6 | LocalDataFlow.cs:96:31:96:35 | access to local variable sink6 |
| LocalDataFlow.cs:89:15:89:19 | access to local variable sink6 | LocalDataFlow.cs:96:31:96:35 | [b (line 49): false] access to local variable sink6 |
| LocalDataFlow.cs:92:9:92:29 | SSA def(nonSink0) | LocalDataFlow.cs:93:15:93:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:92:21:92:28 | access to local variable nonSink0 | LocalDataFlow.cs:92:9:92:29 | SSA def(nonSink0) |
| LocalDataFlow.cs:96:13:96:35 | [b (line 49): false] SSA def(sink7) | LocalDataFlow.cs:97:15:97:19 | access to local variable sink7 |
| LocalDataFlow.cs:96:13:96:35 | [b (line 49): true] SSA def(sink7) | LocalDataFlow.cs:97:15:97:19 | access to local variable sink7 |
| LocalDataFlow.cs:96:13:96:35 | [b (line 49): false] SSA def(sink7) | LocalDataFlow.cs:97:15:97:19 | [b (line 49): false] access to local variable sink7 |
| LocalDataFlow.cs:96:13:96:35 | [b (line 49): true] SSA def(sink7) | LocalDataFlow.cs:97:15:97:19 | [b (line 49): true] access to local variable sink7 |
| LocalDataFlow.cs:96:21:96:21 | access to parameter b | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:96:21:96:21 | access to parameter b | LocalDataFlow.cs:100:20:100:20 | access to parameter b |
| LocalDataFlow.cs:96:21:96:21 | access to parameter b | LocalDataFlow.cs:100:20:100:20 | [b (line 49): false] access to parameter b |
| LocalDataFlow.cs:96:21:96:21 | access to parameter b | LocalDataFlow.cs:100:20:100:20 | [b (line 49): true] access to parameter b |
| LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... | LocalDataFlow.cs:96:13:96:35 | [b (line 49): false] SSA def(sink7) |
| LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... | LocalDataFlow.cs:96:13:96:35 | [b (line 49): true] SSA def(sink7) |
| LocalDataFlow.cs:96:25:96:27 | "a" | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:96:31:96:35 | access to local variable sink6 | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:97:15:97:19 | access to local variable sink7 | LocalDataFlow.cs:100:9:100:36 | SSA phi(sink7) |
| LocalDataFlow.cs:96:25:96:27 | [b (line 49): true] "a" | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:96:31:96:35 | [b (line 49): false] access to local variable sink6 | LocalDataFlow.cs:96:21:96:35 | ... ? ... : ... |
| LocalDataFlow.cs:97:15:97:19 | [b (line 49): false] access to local variable sink7 | LocalDataFlow.cs:100:9:100:36 | SSA phi(sink7) |
| LocalDataFlow.cs:97:15:97:19 | [b (line 49): true] access to local variable sink7 | LocalDataFlow.cs:100:9:100:36 | SSA phi(sink7) |
| LocalDataFlow.cs:100:9:100:36 | SSA def(nonSink0) | LocalDataFlow.cs:101:15:101:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:100:9:100:36 | SSA phi(sink7) | LocalDataFlow.cs:104:29:104:33 | access to local variable sink7 |
| LocalDataFlow.cs:100:20:100:20 | access to parameter b | LocalDataFlow.cs:100:20:100:36 | ... ? ... : ... |
| LocalDataFlow.cs:100:20:100:36 | ... ? ... : ... | LocalDataFlow.cs:100:9:100:36 | SSA def(nonSink0) |
| LocalDataFlow.cs:100:24:100:28 | "abc" | LocalDataFlow.cs:100:20:100:36 | ... ? ... : ... |
| LocalDataFlow.cs:100:32:100:36 | "def" | LocalDataFlow.cs:100:20:100:36 | ... ? ... : ... |
| LocalDataFlow.cs:100:20:100:20 | [b (line 49): false] access to parameter b | LocalDataFlow.cs:100:20:100:36 | [b (line 49): false] ... ? ... : ... |
| LocalDataFlow.cs:100:20:100:20 | [b (line 49): true] access to parameter b | LocalDataFlow.cs:100:20:100:36 | [b (line 49): true] ... ? ... : ... |
| LocalDataFlow.cs:100:20:100:36 | [b (line 49): false] ... ? ... : ... | LocalDataFlow.cs:100:9:100:36 | SSA def(nonSink0) |
| LocalDataFlow.cs:100:20:100:36 | [b (line 49): true] ... ? ... : ... | LocalDataFlow.cs:100:9:100:36 | SSA def(nonSink0) |
| LocalDataFlow.cs:100:24:100:28 | "abc" | LocalDataFlow.cs:100:20:100:36 | [b (line 49): true] ... ? ... : ... |
| LocalDataFlow.cs:100:32:100:36 | "def" | LocalDataFlow.cs:100:20:100:36 | [b (line 49): false] ... ? ... : ... |
| LocalDataFlow.cs:101:15:101:22 | access to local variable nonSink0 | LocalDataFlow.cs:108:32:108:39 | access to local variable nonSink0 |
| LocalDataFlow.cs:104:13:104:33 | SSA def(sink8) | LocalDataFlow.cs:105:15:105:19 | access to local variable sink8 |
| LocalDataFlow.cs:104:21:104:33 | (...) ... | LocalDataFlow.cs:104:13:104:33 | SSA def(sink8) |
@@ -805,75 +809,103 @@
| SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | SSA.cs:180:15:180:22 | access to local variable ssaSink5 |
| Splitting.cs:3:18:3:18 | b | Splitting.cs:6:13:6:13 | access to parameter b |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:5:17:5:23 | access to parameter tainted |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:8:19:8:19 | access to local variable x |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:12:15:12:15 | access to local variable x |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:8:19:8:19 | [b (line 3): true] access to local variable x |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:12:15:12:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:5:17:5:23 | access to parameter tainted | Splitting.cs:5:13:5:23 | SSA def(x) |
| Splitting.cs:6:13:6:13 | access to parameter b | Splitting.cs:13:13:13:13 | access to parameter b |
| Splitting.cs:8:19:8:19 | access to local variable x | Splitting.cs:9:17:9:17 | access to local variable x |
| Splitting.cs:9:17:9:17 | access to local variable x | Splitting.cs:9:17:9:25 | ... == ... |
| Splitting.cs:12:15:12:15 | access to local variable x | Splitting.cs:14:19:14:19 | access to local variable x |
| Splitting.cs:6:13:6:13 | access to parameter b | Splitting.cs:13:13:13:13 | [b (line 3): false] access to parameter b |
| Splitting.cs:6:13:6:13 | access to parameter b | Splitting.cs:13:13:13:13 | [b (line 3): true] access to parameter b |
| Splitting.cs:8:19:8:19 | [b (line 3): true] access to local variable x | Splitting.cs:9:17:9:17 | [b (line 3): true] access to local variable x |
| Splitting.cs:9:17:9:17 | [b (line 3): true] access to local variable x | Splitting.cs:9:17:9:25 | [b (line 3): true] ... == ... |
| Splitting.cs:9:17:9:17 | [b (line 3): true] access to local variable x | Splitting.cs:12:15:12:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:12:15:12:15 | [b (line 3): true] access to local variable x | Splitting.cs:14:19:14:19 | access to local variable x |
| Splitting.cs:17:18:17:18 | b | Splitting.cs:20:13:20:13 | access to parameter b |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:22:19:22:19 | access to local variable x |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:25:15:25:15 | access to local variable x |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:22:19:22:19 | [b (line 17): true] access to local variable x |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:25:15:25:15 | [b (line 17): false] access to local variable x |
| Splitting.cs:19:17:19:18 | "" | Splitting.cs:19:13:19:18 | SSA def(x) |
| Splitting.cs:20:13:20:13 | access to parameter b | Splitting.cs:26:13:26:13 | access to parameter b |
| Splitting.cs:23:13:23:30 | [b (line 17): true] SSA def(x) | Splitting.cs:25:15:25:15 | access to local variable x |
| Splitting.cs:23:17:23:30 | "taint source" | Splitting.cs:23:13:23:30 | [b (line 17): true] SSA def(x) |
| Splitting.cs:25:15:25:15 | access to local variable x | Splitting.cs:27:19:27:19 | access to local variable x |
| Splitting.cs:25:15:25:15 | access to local variable x | Splitting.cs:29:19:29:19 | access to local variable x |
| Splitting.cs:20:13:20:13 | access to parameter b | Splitting.cs:26:13:26:13 | [b (line 17): false] access to parameter b |
| Splitting.cs:20:13:20:13 | access to parameter b | Splitting.cs:26:13:26:13 | [b (line 17): true] access to parameter b |
| Splitting.cs:23:13:23:30 | [b (line 17): true] SSA def(x) | Splitting.cs:25:15:25:15 | [b (line 17): true] access to local variable x |
| Splitting.cs:23:17:23:30 | [b (line 17): true] "taint source" | Splitting.cs:23:13:23:30 | [b (line 17): true] SSA def(x) |
| Splitting.cs:25:15:25:15 | [b (line 17): false] access to local variable x | Splitting.cs:29:19:29:19 | access to local variable x |
| Splitting.cs:25:15:25:15 | [b (line 17): true] access to local variable x | Splitting.cs:27:19:27:19 | access to local variable x |
| Splitting.cs:32:18:32:18 | b | Splitting.cs:35:13:35:13 | access to parameter b |
| Splitting.cs:35:13:35:13 | access to parameter b | Splitting.cs:39:15:39:15 | access to parameter b |
| Splitting.cs:37:9:37:15 | [b (line 32): false] SSA def(x) | Splitting.cs:38:15:38:15 | access to local variable x |
| Splitting.cs:37:9:37:15 | [b (line 32): true] SSA def(x) | Splitting.cs:38:15:38:15 | access to local variable x |
| Splitting.cs:37:13:37:15 | "b" | Splitting.cs:37:9:37:15 | [b (line 32): false] SSA def(x) |
| Splitting.cs:37:13:37:15 | "b" | Splitting.cs:37:9:37:15 | [b (line 32): true] SSA def(x) |
| Splitting.cs:38:15:38:15 | access to local variable x | Splitting.cs:39:19:39:19 | access to local variable x |
| Splitting.cs:39:15:39:15 | access to parameter b | Splitting.cs:39:15:39:25 | ... ? ... : ... |
| Splitting.cs:39:15:39:15 | access to parameter b | Splitting.cs:42:13:42:13 | access to parameter b |
| Splitting.cs:39:19:39:19 | access to local variable x | Splitting.cs:39:15:39:25 | ... ? ... : ... |
| Splitting.cs:39:23:39:25 | "c" | Splitting.cs:39:15:39:25 | ... ? ... : ... |
| Splitting.cs:40:23:40:23 | access to local variable x | Splitting.cs:40:15:40:23 | (...) ... |
| Splitting.cs:41:19:41:21 | "d" | Splitting.cs:41:15:41:21 | ... = ... |
| Splitting.cs:35:13:35:13 | access to parameter b | Splitting.cs:39:15:39:15 | [b (line 32): false] access to parameter b |
| Splitting.cs:35:13:35:13 | access to parameter b | Splitting.cs:39:15:39:15 | [b (line 32): true] access to parameter b |
| Splitting.cs:37:9:37:15 | [b (line 32): false] SSA def(x) | Splitting.cs:38:15:38:15 | [b (line 32): false] access to local variable x |
| Splitting.cs:37:9:37:15 | [b (line 32): true] SSA def(x) | Splitting.cs:38:15:38:15 | [b (line 32): true] access to local variable x |
| Splitting.cs:37:13:37:15 | [b (line 32): false] "b" | Splitting.cs:37:9:37:15 | [b (line 32): false] SSA def(x) |
| Splitting.cs:37:13:37:15 | [b (line 32): true] "b" | Splitting.cs:37:9:37:15 | [b (line 32): true] SSA def(x) |
| Splitting.cs:38:15:38:15 | [b (line 32): false] access to local variable x | Splitting.cs:40:23:40:23 | [b (line 32): false] access to local variable x |
| Splitting.cs:38:15:38:15 | [b (line 32): true] access to local variable x | Splitting.cs:39:19:39:19 | [b (line 32): true] access to local variable x |
| Splitting.cs:39:15:39:15 | [b (line 32): false] access to parameter b | Splitting.cs:39:15:39:25 | [b (line 32): false] ... ? ... : ... |
| Splitting.cs:39:15:39:15 | [b (line 32): false] access to parameter b | Splitting.cs:42:13:42:13 | [b (line 32): false] access to parameter b |
| Splitting.cs:39:15:39:15 | [b (line 32): true] access to parameter b | Splitting.cs:39:15:39:25 | [b (line 32): true] ... ? ... : ... |
| Splitting.cs:39:15:39:15 | [b (line 32): true] access to parameter b | Splitting.cs:42:13:42:13 | [b (line 32): true] access to parameter b |
| Splitting.cs:39:19:39:19 | [b (line 32): true] access to local variable x | Splitting.cs:39:15:39:25 | [b (line 32): true] ... ? ... : ... |
| Splitting.cs:39:19:39:19 | [b (line 32): true] access to local variable x | Splitting.cs:40:23:40:23 | [b (line 32): true] access to local variable x |
| Splitting.cs:39:23:39:25 | [b (line 32): false] "c" | Splitting.cs:39:15:39:25 | [b (line 32): false] ... ? ... : ... |
| Splitting.cs:40:23:40:23 | [b (line 32): false] access to local variable x | Splitting.cs:40:15:40:23 | [b (line 32): false] (...) ... |
| Splitting.cs:40:23:40:23 | [b (line 32): true] access to local variable x | Splitting.cs:40:15:40:23 | [b (line 32): true] (...) ... |
| Splitting.cs:41:19:41:21 | [b (line 32): false] "d" | Splitting.cs:41:15:41:21 | [b (line 32): false] ... = ... |
| Splitting.cs:41:19:41:21 | [b (line 32): true] "d" | Splitting.cs:41:15:41:21 | [b (line 32): true] ... = ... |
| Splitting.cs:46:18:46:18 | b | Splitting.cs:49:13:49:13 | access to parameter b |
| Splitting.cs:48:13:48:18 | SSA def(x) | Splitting.cs:53:13:53:13 | access to local variable x |
| Splitting.cs:48:13:48:18 | SSA def(x) | Splitting.cs:53:13:53:13 | [b (line 46): false] access to local variable x |
| Splitting.cs:48:17:48:18 | "" | Splitting.cs:48:13:48:18 | SSA def(x) |
| Splitting.cs:49:13:49:13 | access to parameter b | Splitting.cs:60:13:60:13 | access to parameter b |
| Splitting.cs:50:13:50:21 | [b (line 46): true] SSA def(x) | Splitting.cs:53:13:53:13 | access to local variable x |
| Splitting.cs:50:17:50:21 | "abc" | Splitting.cs:50:13:50:21 | [b (line 46): true] SSA def(x) |
| Splitting.cs:51:13:51:36 | [b (line 46): false] SSA def(y) | Splitting.cs:52:9:52:9 | access to local variable y |
| Splitting.cs:51:13:51:36 | [b (line 46): true] SSA def(y) | Splitting.cs:52:9:52:9 | access to local variable y |
| Splitting.cs:51:17:51:36 | array creation of type String[] | Splitting.cs:51:13:51:36 | [b (line 46): false] SSA def(y) |
| Splitting.cs:51:17:51:36 | array creation of type String[] | Splitting.cs:51:13:51:36 | [b (line 46): true] SSA def(y) |
| Splitting.cs:51:32:51:34 | "a" | Splitting.cs:51:17:51:36 | array creation of type String[] |
| Splitting.cs:52:9:52:9 | access to local variable y | Splitting.cs:52:9:52:12 | access to array element |
| Splitting.cs:52:9:52:9 | access to local variable y | Splitting.cs:53:17:53:17 | access to local variable y |
| Splitting.cs:52:16:52:18 | "b" | Splitting.cs:52:9:52:9 | access to local variable y |
| Splitting.cs:53:9:53:20 | [b (line 46): false] SSA def(x) | Splitting.cs:54:17:54:17 | access to local variable x |
| Splitting.cs:53:9:53:20 | [b (line 46): true] SSA def(x) | Splitting.cs:54:17:54:17 | access to local variable x |
| Splitting.cs:53:13:53:13 | access to local variable x | Splitting.cs:53:13:53:20 | ... + ... |
| Splitting.cs:53:13:53:20 | ... + ... | Splitting.cs:53:9:53:20 | [b (line 46): false] SSA def(x) |
| Splitting.cs:53:13:53:20 | ... + ... | Splitting.cs:53:9:53:20 | [b (line 46): true] SSA def(x) |
| Splitting.cs:53:17:53:17 | access to local variable y | Splitting.cs:53:17:53:20 | access to array element |
| Splitting.cs:53:17:53:17 | access to local variable y | Splitting.cs:57:17:57:17 | access to local variable y |
| Splitting.cs:53:17:53:20 | access to array element | Splitting.cs:53:13:53:20 | ... + ... |
| Splitting.cs:54:13:54:23 | [b (line 46): false] SSA def(z) | Splitting.cs:55:14:55:14 | access to local variable z |
| Splitting.cs:54:13:54:23 | [b (line 46): true] SSA def(z) | Splitting.cs:55:14:55:14 | access to local variable z |
| Splitting.cs:54:17:54:17 | access to local variable x | Splitting.cs:54:17:54:23 | ... == ... |
| Splitting.cs:54:17:54:17 | access to local variable x | Splitting.cs:56:17:56:17 | access to local variable x |
| Splitting.cs:54:17:54:23 | ... == ... | Splitting.cs:54:13:54:23 | [b (line 46): false] SSA def(z) |
| Splitting.cs:54:17:54:23 | ... == ... | Splitting.cs:54:13:54:23 | [b (line 46): true] SSA def(z) |
| Splitting.cs:55:14:55:14 | access to local variable z | Splitting.cs:55:13:55:14 | !... |
| Splitting.cs:56:9:56:19 | [b (line 46): false] SSA def(x) | Splitting.cs:57:14:57:14 | access to local variable x |
| Splitting.cs:56:9:56:19 | [b (line 46): true] SSA def(x) | Splitting.cs:57:14:57:14 | access to local variable x |
| Splitting.cs:56:13:56:19 | $"..." | Splitting.cs:56:9:56:19 | [b (line 46): false] SSA def(x) |
| Splitting.cs:56:13:56:19 | $"..." | Splitting.cs:56:9:56:19 | [b (line 46): true] SSA def(x) |
| Splitting.cs:56:15:56:15 | "c" | Splitting.cs:56:13:56:19 | $"..." |
| Splitting.cs:56:17:56:17 | access to local variable x | Splitting.cs:56:13:56:19 | $"..." |
| Splitting.cs:57:13:57:18 | (..., ...) | Splitting.cs:57:13:57:24 | access to field Item1 |
| Splitting.cs:57:14:57:14 | access to local variable x | Splitting.cs:57:13:57:18 | (..., ...) |
| Splitting.cs:57:17:57:17 | access to local variable y | Splitting.cs:57:13:57:18 | (..., ...) |
| Splitting.cs:57:17:57:17 | access to local variable y | Splitting.cs:58:27:58:27 | access to local variable y |
| Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) | Splitting.cs:59:19:59:19 | access to local variable s |
| Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | Splitting.cs:59:19:59:19 | access to local variable s |
| Splitting.cs:58:27:58:27 | access to local variable y | Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) |
| Splitting.cs:58:27:58:27 | access to local variable y | Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) |
| Splitting.cs:49:13:49:13 | access to parameter b | Splitting.cs:60:13:60:13 | [b (line 46): false] access to parameter b |
| Splitting.cs:49:13:49:13 | access to parameter b | Splitting.cs:60:13:60:13 | [b (line 46): true] access to parameter b |
| Splitting.cs:50:13:50:21 | [b (line 46): true] SSA def(x) | Splitting.cs:53:13:53:13 | [b (line 46): true] access to local variable x |
| Splitting.cs:50:17:50:21 | [b (line 46): true] "abc" | Splitting.cs:50:13:50:21 | [b (line 46): true] SSA def(x) |
| Splitting.cs:51:13:51:36 | [b (line 46): false] SSA def(y) | Splitting.cs:52:9:52:9 | [b (line 46): false] access to local variable y |
| Splitting.cs:51:13:51:36 | [b (line 46): true] SSA def(y) | Splitting.cs:52:9:52:9 | [b (line 46): true] access to local variable y |
| Splitting.cs:51:17:51:36 | [b (line 46): false] array creation of type String[] | Splitting.cs:51:13:51:36 | [b (line 46): false] SSA def(y) |
| Splitting.cs:51:17:51:36 | [b (line 46): true] array creation of type String[] | Splitting.cs:51:13:51:36 | [b (line 46): true] SSA def(y) |
| Splitting.cs:51:32:51:34 | [b (line 46): false] "a" | Splitting.cs:51:17:51:36 | [b (line 46): false] array creation of type String[] |
| Splitting.cs:51:32:51:34 | [b (line 46): true] "a" | Splitting.cs:51:17:51:36 | [b (line 46): true] array creation of type String[] |
| Splitting.cs:52:9:52:9 | [b (line 46): false] access to local variable y | Splitting.cs:52:9:52:12 | [b (line 46): false] access to array element |
| Splitting.cs:52:9:52:9 | [b (line 46): false] access to local variable y | Splitting.cs:53:17:53:17 | [b (line 46): false] access to local variable y |
| Splitting.cs:52:9:52:9 | [b (line 46): true] access to local variable y | Splitting.cs:52:9:52:12 | [b (line 46): true] access to array element |
| Splitting.cs:52:9:52:9 | [b (line 46): true] access to local variable y | Splitting.cs:53:17:53:17 | [b (line 46): true] access to local variable y |
| Splitting.cs:52:16:52:18 | [b (line 46): false] "b" | Splitting.cs:52:9:52:9 | [b (line 46): false] access to local variable y |
| Splitting.cs:52:16:52:18 | [b (line 46): true] "b" | Splitting.cs:52:9:52:9 | [b (line 46): true] access to local variable y |
| Splitting.cs:53:9:53:20 | [b (line 46): false] SSA def(x) | Splitting.cs:54:17:54:17 | [b (line 46): false] access to local variable x |
| Splitting.cs:53:9:53:20 | [b (line 46): true] SSA def(x) | Splitting.cs:54:17:54:17 | [b (line 46): true] access to local variable x |
| Splitting.cs:53:13:53:13 | [b (line 46): false] access to local variable x | Splitting.cs:53:13:53:20 | [b (line 46): false] ... + ... |
| Splitting.cs:53:13:53:13 | [b (line 46): true] access to local variable x | Splitting.cs:53:13:53:20 | [b (line 46): true] ... + ... |
| Splitting.cs:53:13:53:20 | [b (line 46): false] ... + ... | Splitting.cs:53:9:53:20 | [b (line 46): false] SSA def(x) |
| Splitting.cs:53:13:53:20 | [b (line 46): true] ... + ... | Splitting.cs:53:9:53:20 | [b (line 46): true] SSA def(x) |
| Splitting.cs:53:17:53:17 | [b (line 46): false] access to local variable y | Splitting.cs:53:17:53:20 | [b (line 46): false] access to array element |
| Splitting.cs:53:17:53:17 | [b (line 46): false] access to local variable y | Splitting.cs:57:17:57:17 | [b (line 46): false] access to local variable y |
| Splitting.cs:53:17:53:17 | [b (line 46): true] access to local variable y | Splitting.cs:53:17:53:20 | [b (line 46): true] access to array element |
| Splitting.cs:53:17:53:17 | [b (line 46): true] access to local variable y | Splitting.cs:57:17:57:17 | [b (line 46): true] access to local variable y |
| Splitting.cs:53:17:53:20 | [b (line 46): false] access to array element | Splitting.cs:53:13:53:20 | [b (line 46): false] ... + ... |
| Splitting.cs:53:17:53:20 | [b (line 46): true] access to array element | Splitting.cs:53:13:53:20 | [b (line 46): true] ... + ... |
| Splitting.cs:54:13:54:23 | [b (line 46): false] SSA def(z) | Splitting.cs:55:14:55:14 | [b (line 46): false] access to local variable z |
| Splitting.cs:54:13:54:23 | [b (line 46): true] SSA def(z) | Splitting.cs:55:14:55:14 | [b (line 46): true] access to local variable z |
| Splitting.cs:54:17:54:17 | [b (line 46): false] access to local variable x | Splitting.cs:54:17:54:23 | [b (line 46): false] ... == ... |
| Splitting.cs:54:17:54:17 | [b (line 46): false] access to local variable x | Splitting.cs:56:17:56:17 | [b (line 46): false] access to local variable x |
| Splitting.cs:54:17:54:17 | [b (line 46): true] access to local variable x | Splitting.cs:54:17:54:23 | [b (line 46): true] ... == ... |
| Splitting.cs:54:17:54:17 | [b (line 46): true] access to local variable x | Splitting.cs:56:17:56:17 | [b (line 46): true] access to local variable x |
| Splitting.cs:54:17:54:23 | [b (line 46): false] ... == ... | Splitting.cs:54:13:54:23 | [b (line 46): false] SSA def(z) |
| Splitting.cs:54:17:54:23 | [b (line 46): true] ... == ... | Splitting.cs:54:13:54:23 | [b (line 46): true] SSA def(z) |
| Splitting.cs:55:14:55:14 | [b (line 46): false] access to local variable z | Splitting.cs:55:13:55:14 | [b (line 46): false] !... |
| Splitting.cs:55:14:55:14 | [b (line 46): true] access to local variable z | Splitting.cs:55:13:55:14 | [b (line 46): true] !... |
| Splitting.cs:56:9:56:19 | [b (line 46): false] SSA def(x) | Splitting.cs:57:14:57:14 | [b (line 46): false] access to local variable x |
| Splitting.cs:56:9:56:19 | [b (line 46): true] SSA def(x) | Splitting.cs:57:14:57:14 | [b (line 46): true] access to local variable x |
| Splitting.cs:56:13:56:19 | [b (line 46): false] $"..." | Splitting.cs:56:9:56:19 | [b (line 46): false] SSA def(x) |
| Splitting.cs:56:13:56:19 | [b (line 46): true] $"..." | Splitting.cs:56:9:56:19 | [b (line 46): true] SSA def(x) |
| Splitting.cs:56:15:56:15 | [b (line 46): false] "c" | Splitting.cs:56:13:56:19 | [b (line 46): false] $"..." |
| Splitting.cs:56:15:56:15 | [b (line 46): true] "c" | Splitting.cs:56:13:56:19 | [b (line 46): true] $"..." |
| Splitting.cs:56:17:56:17 | [b (line 46): false] access to local variable x | Splitting.cs:56:13:56:19 | [b (line 46): false] $"..." |
| Splitting.cs:56:17:56:17 | [b (line 46): true] access to local variable x | Splitting.cs:56:13:56:19 | [b (line 46): true] $"..." |
| Splitting.cs:57:13:57:18 | [b (line 46): false] (..., ...) | Splitting.cs:57:13:57:24 | [b (line 46): false] access to field Item1 |
| Splitting.cs:57:13:57:18 | [b (line 46): true] (..., ...) | Splitting.cs:57:13:57:24 | [b (line 46): true] access to field Item1 |
| Splitting.cs:57:14:57:14 | [b (line 46): false] access to local variable x | Splitting.cs:57:13:57:18 | [b (line 46): false] (..., ...) |
| Splitting.cs:57:14:57:14 | [b (line 46): true] access to local variable x | Splitting.cs:57:13:57:18 | [b (line 46): true] (..., ...) |
| Splitting.cs:57:17:57:17 | [b (line 46): false] access to local variable y | Splitting.cs:57:13:57:18 | [b (line 46): false] (..., ...) |
| Splitting.cs:57:17:57:17 | [b (line 46): false] access to local variable y | Splitting.cs:58:27:58:27 | [b (line 46): false] access to local variable y |
| Splitting.cs:57:17:57:17 | [b (line 46): true] access to local variable y | Splitting.cs:57:13:57:18 | [b (line 46): true] (..., ...) |
| Splitting.cs:57:17:57:17 | [b (line 46): true] access to local variable y | Splitting.cs:58:27:58:27 | [b (line 46): true] access to local variable y |
| Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): false] access to local variable s |
| Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) | Splitting.cs:59:19:59:19 | [b (line 46): true] access to local variable s |
| Splitting.cs:58:27:58:27 | [b (line 46): false] access to local variable y | Splitting.cs:58:22:58:22 | [b (line 46): false] SSA def(s) |
| Splitting.cs:58:27:58:27 | [b (line 46): true] access to local variable y | Splitting.cs:58:22:58:22 | [b (line 46): true] SSA def(s) |

View File

@@ -175,4 +175,5 @@
| ViableCallable.cs:409:10:409:12 | Run | ViableCallable.cs:403:53:403:57 | M |
| ViableCallable.cs:409:10:409:12 | Run | ViableCallable.cs:405:42:405:46 | M |
| ViableCallable.cs:431:25:431:29 | M2 | ViableCallable.cs:442:17:442:23 | (...) => ... |
| ViableCallable.cs:436:9:436:9 | M | ViableCallable.cs:430:23:430:24 | M1 |
| ViableCallable.cs:436:10:436:10 | M | ViableCallable.cs:430:23:430:24 | M1 |
| ViableCallable.cs:436:10:436:10 | M | ViableCallable.cs:431:25:431:29 | M2 |

View File

@@ -399,5 +399,5 @@
| ViableCallable.cs:422:13:422:37 | call to method Mock | ViableCallable.Mock<A4>() |
| ViableCallable.cs:424:9:424:21 | call to method M | C15.A4.M<T1>() |
| ViableCallable.cs:424:9:424:21 | call to method M | C15.A5.M<T1>() |
| ViableCallable.cs:439:16:439:26 | call to method M1 | C16<String,Int32>.M1(string) |
| ViableCallable.cs:439:9:439:19 | call to method M1 | C16<String,Int32>.M1(string) |
| ViableCallable.cs:442:9:442:24 | call to method M2 | C16<String,Int32>.M2<T>(Func<T>) |

View File

@@ -433,10 +433,10 @@ abstract class C16<T1, T2>
class C17 : C16<string, int>
{
int M(int i)
void M(int i)
{
// Viable callables: C16<string, int>.M1()
return this.M1("");
this.M1("");
// Viable callables: C16<string, int>.M2<int>()
this.M2(() => i);

View File

@@ -5,7 +5,7 @@ using System.Web;
public class StackTraceHandler : IHttpHandler
{
bool b;
public void ProcessRequest(HttpContext ctx)
{
try
@@ -54,7 +54,8 @@ public class StackTraceHandler : IHttpHandler
// Method that may throw an exception
public void doSomeWork()
{
throw new Exception();
if (b)
throw new Exception();
}
public void log(string s, Exception e)