mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge branch 'main' into jcogs33/model-top-jdk-apis
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
## 0.4.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
4
ruby/ql/lib/change-notes/2022-11-30-rails-globalid.md
Normal file
4
ruby/ql/lib/change-notes/2022-11-30-rails-globalid.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Calls to `GlobalID::Locator.locate` and its variants are now recognized as instances of `OrmInstantiation`.
|
||||
14
ruby/ql/lib/change-notes/2022-12-14-constructor-flow.md
Normal file
14
ruby/ql/lib/change-notes/2022-12-14-constructor-flow.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Flow through `initialize` constructors is now taken into account. For example, in
|
||||
```rb
|
||||
class C
|
||||
def initialize(x)
|
||||
@field = x
|
||||
end
|
||||
end
|
||||
|
||||
C.new(y)
|
||||
```
|
||||
there will be flow from `y` to the field `@field` on the constructed `C` object.
|
||||
3
ruby/ql/lib/change-notes/released/0.4.6.md
Normal file
3
ruby/ql/lib/change-notes/released/0.4.6.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.6
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.5
|
||||
lastReleaseVersion: 0.4.6
|
||||
|
||||
@@ -53,9 +53,12 @@ class Call extends Expr instanceof CallImpl {
|
||||
|
||||
/** Gets a potential target of this call, if any. */
|
||||
final Callable getATarget() {
|
||||
exists(DataFlowCall c | this = c.asCall().getExpr() |
|
||||
TCfgScope(result) = [viableCallable(c), viableCallableLambda(c, _)]
|
||||
exists(DataFlowCall c |
|
||||
this = c.asCall().getExpr() and
|
||||
TCfgScope(result) = viableCallableLambda(c, _)
|
||||
)
|
||||
or
|
||||
result = getTarget(this.getAControlFlowNode())
|
||||
}
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
|
||||
@@ -11,7 +11,8 @@ private import codeql.ruby.dataflow.SSA
|
||||
|
||||
newtype TReturnKind =
|
||||
TNormalReturnKind() or
|
||||
TBreakReturnKind()
|
||||
TBreakReturnKind() or
|
||||
TNewReturnKind()
|
||||
|
||||
/**
|
||||
* Gets a node that can read the value returned from `call` with return kind
|
||||
@@ -43,6 +44,15 @@ class BreakReturnKind extends ReturnKind, TBreakReturnKind {
|
||||
override string toString() { result = "break" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A special return kind that is used to represent the value returned
|
||||
* from user-defined `new` methods as well as the effect on `self` in
|
||||
* `initialize` methods.
|
||||
*/
|
||||
class NewReturnKind extends ReturnKind, TNewReturnKind {
|
||||
override string toString() { result = "new" }
|
||||
}
|
||||
|
||||
/** A callable defined in library code, identified by a unique string. */
|
||||
abstract class LibraryCallable extends string {
|
||||
bindingset[this]
|
||||
@@ -275,14 +285,33 @@ private predicate hasAdjacentTypeCheckedReads(
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `new` is a user-defined `self.new` method. */
|
||||
predicate isUserDefinedNew(SingletonMethod new) {
|
||||
exists(Expr object | singletonMethod(new, "new", object) |
|
||||
selfInModule(object.(SelfVariableReadAccess).getVariable(), _)
|
||||
or
|
||||
exists(resolveConstantReadAccess(object))
|
||||
)
|
||||
}
|
||||
|
||||
private Callable viableSourceCallableNonInit(RelevantCall call) {
|
||||
result = getTarget(call) and
|
||||
not call.getExpr() instanceof YieldCall // handled by `lambdaCreation`/`lambdaCall`
|
||||
}
|
||||
|
||||
private Callable viableSourceCallableInit(RelevantCall call) {
|
||||
result = getInitializeTarget(call) and
|
||||
not isUserDefinedNew(getTarget(call))
|
||||
}
|
||||
|
||||
/** Holds if `call` may resolve to the returned source-code method. */
|
||||
private DataFlowCallable viableSourceCallable(DataFlowCall call) {
|
||||
result = TCfgScope(getTarget(call.asCall())) and
|
||||
not call.asCall().getExpr() instanceof YieldCall // handled by `lambdaCreation`/`lambdaCall`
|
||||
private Callable viableSourceCallable(RelevantCall call) {
|
||||
result = viableSourceCallableNonInit(call) or
|
||||
result = viableSourceCallableInit(call)
|
||||
}
|
||||
|
||||
/** Holds if `call` may resolve to the returned summarized library method. */
|
||||
private DataFlowCallable viableLibraryCallable(DataFlowCall call) {
|
||||
DataFlowCallable viableLibraryCallable(DataFlowCall call) {
|
||||
exists(LibraryCallable callable |
|
||||
result = TLibraryCallable(callable) and
|
||||
call.asCall().getExpr() = [callable.getACall(), callable.getACallSimple()]
|
||||
@@ -340,126 +369,22 @@ private module Cached {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Method lookupInstanceMethodCall(RelevantCall call, string method, boolean exact) {
|
||||
exists(Module tp, DataFlow::Node receiver |
|
||||
methodCall(call, pragma[only_bind_into](receiver), pragma[only_bind_into](method)) and
|
||||
receiver = trackInstance(tp, exact) and
|
||||
result = lookupMethod(tp, pragma[only_bind_into](method), exact)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isToplevelMethodInFile(Method m, File f) {
|
||||
m.getEnclosingModule() instanceof Toplevel and
|
||||
f = m.getFile()
|
||||
}
|
||||
|
||||
/** Holds if a `self` access may be the receiver of `call` directly inside module `m`. */
|
||||
pragma[nomagic]
|
||||
private predicate selfInModuleFlowsToMethodCallReceiver(RelevantCall call, Module m, string method) {
|
||||
exists(SsaSelfDefinitionNode self |
|
||||
flowsToMethodCallReceiver(call, self, method) and
|
||||
selfInModule(self.getVariable(), m)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a `self` access may be the receiver of `call` inside some singleton method, where
|
||||
* that method belongs to `m` or one of `m`'s transitive super classes.
|
||||
* Gets the relevant `initialize` method for the `new` call, if any.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate selfInSingletonMethodFlowsToMethodCallReceiver(
|
||||
RelevantCall call, Module m, string method
|
||||
) {
|
||||
exists(SsaSelfDefinitionNode self, MethodBase caller |
|
||||
flowsToMethodCallReceiver(call, self, method) and
|
||||
selfInMethod(self.getVariable(), caller, m) and
|
||||
singletonMethod(caller, _, _)
|
||||
cached
|
||||
Method getInitializeTarget(RelevantCall new) {
|
||||
exists(Module m |
|
||||
moduleFlowsToMethodCallReceiver(new, m, "new") and
|
||||
result = lookupMethod(m, "initialize")
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
CfgScope getTarget(RelevantCall call) {
|
||||
exists(string method |
|
||||
exists(boolean exact |
|
||||
result = lookupInstanceMethodCall(call, method, exact) and
|
||||
(
|
||||
if result.(Method).isPrivate()
|
||||
then
|
||||
call.getReceiver().getExpr() instanceof SelfVariableAccess and
|
||||
// For now, we restrict the scope of top-level declarations to their file.
|
||||
// This may remove some plausible targets, but also removes a lot of
|
||||
// implausible targets
|
||||
(
|
||||
isToplevelMethodInFile(result, call.getFile()) or
|
||||
not isToplevelMethodInFile(result, _)
|
||||
)
|
||||
else any()
|
||||
) and
|
||||
if result.(Method).isProtected()
|
||||
then result = lookupMethod(call.getExpr().getEnclosingModule().getModule(), method, exact)
|
||||
else any()
|
||||
)
|
||||
or
|
||||
// singleton method defined on an instance, e.g.
|
||||
// ```rb
|
||||
// c = C.new
|
||||
// def c.singleton; end # <- result
|
||||
// c.singleton # <- call
|
||||
// ```
|
||||
// or an `extend`ed instance, e.g.
|
||||
// ```rb
|
||||
// c = C.new
|
||||
// module M
|
||||
// def instance; end # <- result
|
||||
// end
|
||||
// c.extend M
|
||||
// c.instance # <- call
|
||||
// ```
|
||||
exists(DataFlow::Node receiver |
|
||||
methodCall(call, receiver, method) and
|
||||
receiver = trackSingletonMethodOnInstance(result, method)
|
||||
)
|
||||
or
|
||||
// singleton method defined on a module
|
||||
// or an `extend`ed module, e.g.
|
||||
// ```rb
|
||||
// module M
|
||||
// def instance; end # <- result
|
||||
// end
|
||||
// M.extend(M)
|
||||
// M.instance # <- call
|
||||
// ```
|
||||
exists(Module m, boolean exact | result = lookupSingletonMethod(m, method, exact) |
|
||||
// ```rb
|
||||
// def C.singleton; end # <- result
|
||||
// C.singleton # <- call
|
||||
// ```
|
||||
moduleFlowsToMethodCallReceiver(call, m, method) and
|
||||
exact = true
|
||||
or
|
||||
// ```rb
|
||||
// class C
|
||||
// def self.singleton; end # <- result
|
||||
// self.singleton # <- call
|
||||
// end
|
||||
// ```
|
||||
selfInModuleFlowsToMethodCallReceiver(call, m, method) and
|
||||
exact = true
|
||||
or
|
||||
// ```rb
|
||||
// class C
|
||||
// def self.singleton; end # <- result
|
||||
// def self.other
|
||||
// self.singleton # <- call
|
||||
// end
|
||||
// end
|
||||
// ```
|
||||
selfInSingletonMethodFlowsToMethodCallReceiver(call, m, method) and
|
||||
exact = false
|
||||
)
|
||||
)
|
||||
result = getTargetInstance(call, _)
|
||||
or
|
||||
result = getTargetSingleton(call, _)
|
||||
or
|
||||
exists(Module cls, string method |
|
||||
superCall(call, cls, method) and
|
||||
@@ -472,7 +397,7 @@ private module Cached {
|
||||
/** Gets a viable run-time target for the call `call`. */
|
||||
cached
|
||||
DataFlowCallable viableCallable(DataFlowCall call) {
|
||||
result = viableSourceCallable(call)
|
||||
result.asCallable() = viableSourceCallable(call.asCall())
|
||||
or
|
||||
result = viableLibraryCallable(call)
|
||||
}
|
||||
@@ -547,6 +472,15 @@ private DataFlow::LocalSourceNode trackModuleAccess(Module m) {
|
||||
result = trackModuleAccess(m, TypeTracker::end())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasUserDefinedNew(Module m) {
|
||||
exists(DataFlow::MethodNode method |
|
||||
// not `getAnAncestor` because singleton methods cannot be included
|
||||
singletonMethodOnModule(method.asCallableAstNode(), "new", m.getSuperClass*()) and
|
||||
not method.getSelfParameter().getAMethodCall("allocate").flowsTo(method.getAReturningNode())
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `n` is an instance of type `tp`. */
|
||||
private predicate isInstance(DataFlow::Node n, Module tp, boolean exact) {
|
||||
n.asExpr().getExpr() instanceof NilLiteral and
|
||||
@@ -603,7 +537,9 @@ private predicate isInstance(DataFlow::Node n, Module tp, boolean exact) {
|
||||
or
|
||||
exists(RelevantCall call, DataFlow::LocalSourceNode sourceNode |
|
||||
flowsToMethodCallReceiver(call, sourceNode, "new") and
|
||||
n.asExpr() = call
|
||||
n.asExpr() = call and
|
||||
// `tp` should not have a user-defined `self.new` method
|
||||
not hasUserDefinedNew(tp)
|
||||
|
|
||||
// `C.new`
|
||||
sourceNode = trackModuleAccess(tp) and
|
||||
@@ -702,6 +638,44 @@ private DataFlow::Node trackInstance(Module tp, boolean exact) {
|
||||
result = trackInstance(tp, exact, TypeTracker::end())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Method lookupInstanceMethodCall(RelevantCall call, string method, boolean exact) {
|
||||
exists(Module tp, DataFlow::Node receiver |
|
||||
methodCall(call, pragma[only_bind_into](receiver), pragma[only_bind_into](method)) and
|
||||
receiver = trackInstance(tp, exact) and
|
||||
result = lookupMethod(tp, pragma[only_bind_into](method), exact)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isToplevelMethodInFile(Method m, File f) {
|
||||
m.getEnclosingModule() instanceof Toplevel and
|
||||
f = m.getFile()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private CfgScope getTargetInstance(RelevantCall call, string method) {
|
||||
exists(boolean exact |
|
||||
result = lookupInstanceMethodCall(call, method, exact) and
|
||||
(
|
||||
if result.(Method).isPrivate()
|
||||
then
|
||||
call.getReceiver().getExpr() instanceof SelfVariableAccess and
|
||||
// For now, we restrict the scope of top-level declarations to their file.
|
||||
// This may remove some plausible targets, but also removes a lot of
|
||||
// implausible targets
|
||||
(
|
||||
isToplevelMethodInFile(result, call.getFile()) or
|
||||
not isToplevelMethodInFile(result, _)
|
||||
)
|
||||
else any()
|
||||
) and
|
||||
if result.(Method).isProtected()
|
||||
then result = lookupMethod(call.getExpr().getEnclosingModule().getModule(), method, exact)
|
||||
else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private DataFlow::LocalSourceNode trackBlock(Block block, TypeTracker t) {
|
||||
t.start() and result.asExpr().getExpr() = block
|
||||
@@ -813,7 +787,7 @@ private MethodBase lookupSingletonMethod(Module m, string name) {
|
||||
// cannot use `lookupSingletonMethodDirect` because it would introduce
|
||||
// negative recursion
|
||||
not singletonMethodOnModule(_, name, m) and
|
||||
result = lookupSingletonMethod(m.getSuperClass(), name)
|
||||
result = lookupSingletonMethod(m.getSuperClass(), name) // not `getAnImmediateAncestor` because singleton methods cannot be included
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -824,7 +798,9 @@ private MethodBase lookupSingletonMethodInSubClasses(Module m, string name) {
|
||||
// being resolved to arbitrary singleton methods.
|
||||
// To remedy this, we do not allow following super-classes all the way to Object.
|
||||
not m = TResolved("Object") and
|
||||
exists(Module sub | sub.getSuperClass() = m |
|
||||
exists(Module sub |
|
||||
sub.getSuperClass() = m // not `getAnImmediateAncestor` because singleton methods cannot be included
|
||||
|
|
||||
result = lookupSingletonMethodDirect(sub, name) or
|
||||
result = lookupSingletonMethodInSubClasses(sub, name)
|
||||
)
|
||||
@@ -972,6 +948,91 @@ private DataFlow::Node trackSingletonMethodOnInstance(MethodBase method, string
|
||||
result = trackSingletonMethodOnInstance(method, name, TypeTracker::end())
|
||||
}
|
||||
|
||||
/** Holds if a `self` access may be the receiver of `call` directly inside module `m`. */
|
||||
pragma[nomagic]
|
||||
private predicate selfInModuleFlowsToMethodCallReceiver(RelevantCall call, Module m, string method) {
|
||||
exists(SsaSelfDefinitionNode self |
|
||||
flowsToMethodCallReceiver(call, self, method) and
|
||||
selfInModule(self.getVariable(), m)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a `self` access may be the receiver of `call` inside some singleton method, where
|
||||
* that method belongs to `m` or one of `m`'s transitive super classes.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate selfInSingletonMethodFlowsToMethodCallReceiver(
|
||||
RelevantCall call, Module m, string method
|
||||
) {
|
||||
exists(SsaSelfDefinitionNode self, MethodBase caller |
|
||||
flowsToMethodCallReceiver(call, self, method) and
|
||||
selfInMethod(self.getVariable(), caller, m) and
|
||||
singletonMethod(caller, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private CfgScope getTargetSingleton(RelevantCall call, string method) {
|
||||
// singleton method defined on an instance, e.g.
|
||||
// ```rb
|
||||
// c = C.new
|
||||
// def c.singleton; end # <- result
|
||||
// c.singleton # <- call
|
||||
// ```
|
||||
// or an `extend`ed instance, e.g.
|
||||
// ```rb
|
||||
// c = C.new
|
||||
// module M
|
||||
// def instance; end # <- result
|
||||
// end
|
||||
// c.extend M
|
||||
// c.instance # <- call
|
||||
// ```
|
||||
exists(DataFlow::Node receiver |
|
||||
methodCall(call, receiver, method) and
|
||||
receiver = trackSingletonMethodOnInstance(result, method)
|
||||
)
|
||||
or
|
||||
// singleton method defined on a module
|
||||
// or an `extend`ed module, e.g.
|
||||
// ```rb
|
||||
// module M
|
||||
// def instance; end # <- result
|
||||
// end
|
||||
// M.extend(M)
|
||||
// M.instance # <- call
|
||||
// ```
|
||||
exists(Module m, boolean exact | result = lookupSingletonMethod(m, method, exact) |
|
||||
// ```rb
|
||||
// def C.singleton; end # <- result
|
||||
// C.singleton # <- call
|
||||
// ```
|
||||
moduleFlowsToMethodCallReceiver(call, m, method) and
|
||||
exact = true
|
||||
or
|
||||
// ```rb
|
||||
// class C
|
||||
// def self.singleton; end # <- result
|
||||
// self.singleton # <- call
|
||||
// end
|
||||
// ```
|
||||
selfInModuleFlowsToMethodCallReceiver(call, m, method) and
|
||||
exact = true
|
||||
or
|
||||
// ```rb
|
||||
// class C
|
||||
// def self.singleton; end # <- result
|
||||
// def self.other
|
||||
// self.singleton # <- call
|
||||
// end
|
||||
// end
|
||||
// ```
|
||||
selfInSingletonMethodFlowsToMethodCallReceiver(call, m, method) and
|
||||
exact = false
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ctx` targets `encl`, which is the enclosing callable of `call`, the receiver
|
||||
* of `call` is a parameter access, where the corresponding argument of `ctx` is `arg`.
|
||||
@@ -982,25 +1043,54 @@ private DataFlow::Node trackSingletonMethodOnInstance(MethodBase method, string
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate argMustFlowToReceiver(
|
||||
RelevantCall ctx, DataFlow::LocalSourceNode source, ArgumentNode arg,
|
||||
RelevantCall ctx, DataFlow::LocalSourceNode source, DataFlow::Node arg,
|
||||
SsaDefinitionExtNode paramDef, RelevantCall call, Callable encl, string name
|
||||
) {
|
||||
exists(ParameterNodeImpl p, ParameterPosition ppos, ArgumentPosition apos |
|
||||
// the receiver of `call` references `p`
|
||||
exists(DataFlow::Node receiver |
|
||||
LocalFlow::localFlowSsaParamInput(p, paramDef) and
|
||||
methodCall(pragma[only_bind_into](call), receiver, pragma[only_bind_into](name)) and
|
||||
methodCall(pragma[only_bind_into](call), pragma[only_bind_into](receiver),
|
||||
pragma[only_bind_into](name)) and
|
||||
receiver.asExpr() = paramDef.getDefinitionExt().(Ssa::Definition).getARead()
|
||||
) and
|
||||
// `p` is a parameter of `encl`,
|
||||
encl = call.getScope() and
|
||||
p.isParameterOf(TCfgScope(encl), ppos) and
|
||||
// `ctx` targets `encl`
|
||||
getTarget(ctx) = encl and
|
||||
// `arg` is the argument for `p` in the call `ctx`
|
||||
arg.sourceArgumentOf(ctx, apos) and
|
||||
parameterMatch(ppos, apos) and
|
||||
source.flowsTo(arg)
|
||||
|
|
||||
encl = viableSourceCallableNonInit(ctx) and
|
||||
arg.(ArgumentNode).sourceArgumentOf(ctx, apos)
|
||||
or
|
||||
encl = viableSourceCallableInit(ctx) and
|
||||
if apos.isSelf()
|
||||
then
|
||||
// when we are targeting an initializer, the type of `self` inside the
|
||||
// initializer will be the type of the `new` call itself, not the receiver
|
||||
// of the `new` call
|
||||
arg.asExpr() = ctx
|
||||
else arg.(ArgumentNode).sourceArgumentOf(ctx, apos)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ctx` targets `encl`, which is the enclosing callable of `new`, and
|
||||
* the receiver of `new` is a parameter access, where the corresponding argument
|
||||
* `arg` of `ctx` has type `tp`.
|
||||
*
|
||||
* `new` calls the object creation `new` method.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate mayBenefitFromCallContextInitialize(
|
||||
RelevantCall ctx, RelevantCall new, DataFlow::Node arg, Callable encl, Module tp, string name
|
||||
) {
|
||||
exists(DataFlow::LocalSourceNode source |
|
||||
argMustFlowToReceiver(ctx, pragma[only_bind_into](source), arg, _, new, encl, "new") and
|
||||
source = trackModuleAccess(tp) and
|
||||
name = "initialize" and
|
||||
exists(lookupMethod(tp, name))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1014,7 +1104,7 @@ private predicate argMustFlowToReceiver(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate mayBenefitFromCallContextInstance(
|
||||
RelevantCall ctx, RelevantCall call, ArgumentNode arg, Callable encl, Module tp, boolean exact,
|
||||
RelevantCall ctx, RelevantCall call, DataFlow::Node arg, Callable encl, Module tp, boolean exact,
|
||||
string name
|
||||
) {
|
||||
exists(DataFlow::LocalSourceNode source |
|
||||
@@ -1035,7 +1125,7 @@ private predicate mayBenefitFromCallContextInstance(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate mayBenefitFromCallContextSingleton(
|
||||
RelevantCall ctx, RelevantCall call, ArgumentNode arg, Callable encl, Module tp, boolean exact,
|
||||
RelevantCall ctx, RelevantCall call, DataFlow::Node arg, Callable encl, Module tp, boolean exact,
|
||||
string name
|
||||
) {
|
||||
exists(DataFlow::LocalSourceNode source |
|
||||
@@ -1066,6 +1156,8 @@ private predicate mayBenefitFromCallContextSingleton(
|
||||
* the implicit `self` parameter).
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) {
|
||||
mayBenefitFromCallContextInitialize(_, call.asCall(), _, c.asCallable(), _, _)
|
||||
or
|
||||
mayBenefitFromCallContextInstance(_, call.asCall(), _, c.asCallable(), _, _, _)
|
||||
or
|
||||
mayBenefitFromCallContextSingleton(_, call.asCall(), _, c.asCallable(), _, _, _)
|
||||
@@ -1083,30 +1175,39 @@ DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
|
||||
exists(RelevantCall call0, Callable res |
|
||||
call0 = call.asCall() and
|
||||
res = result.asCallable() and
|
||||
result = viableSourceCallable(call) and // make sure to not include e.g. private methods
|
||||
exists(Module m, boolean exact, string name |
|
||||
mayBenefitFromCallContextInstance(ctx.asCall(), pragma[only_bind_into](call0), _, _,
|
||||
pragma[only_bind_into](m), exact, pragma[only_bind_into](name)) and
|
||||
res = lookupMethod(m, name, exact)
|
||||
exists(Module m, string name |
|
||||
mayBenefitFromCallContextInitialize(ctx.asCall(), pragma[only_bind_into](call0), _, _,
|
||||
pragma[only_bind_into](m), pragma[only_bind_into](name)) and
|
||||
res = getInitializeTarget(call0) and
|
||||
res = lookupMethod(m, name)
|
||||
or
|
||||
mayBenefitFromCallContextSingleton(ctx.asCall(), pragma[only_bind_into](call0), _, _,
|
||||
pragma[only_bind_into](m), exact, pragma[only_bind_into](name)) and
|
||||
res = lookupSingletonMethod(m, name, exact)
|
||||
exists(boolean exact |
|
||||
mayBenefitFromCallContextInstance(ctx.asCall(), pragma[only_bind_into](call0), _, _,
|
||||
pragma[only_bind_into](m), pragma[only_bind_into](exact), pragma[only_bind_into](name)) and
|
||||
res = getTargetInstance(call0, name) and
|
||||
res = lookupMethod(m, name, exact)
|
||||
or
|
||||
mayBenefitFromCallContextSingleton(ctx.asCall(), pragma[only_bind_into](call0), _, _,
|
||||
pragma[only_bind_into](m), pragma[only_bind_into](exact), pragma[only_bind_into](name)) and
|
||||
res = getTargetSingleton(call0, name) and
|
||||
res = lookupSingletonMethod(m, name, exact)
|
||||
)
|
||||
)
|
||||
)
|
||||
or
|
||||
// `ctx` cannot provide a type bound, and the receiver of the call is `self`;
|
||||
// in this case, still apply an open-world assumption
|
||||
exists(
|
||||
RelevantCall call0, RelevantCall ctx0, ArgumentNode arg, SsaSelfDefinitionNode self,
|
||||
RelevantCall call0, RelevantCall ctx0, DataFlow::Node arg, SsaSelfDefinitionNode self,
|
||||
string name
|
||||
|
|
||||
call0 = call.asCall() and
|
||||
ctx0 = ctx.asCall() and
|
||||
argMustFlowToReceiver(ctx0, _, arg, self, call0, _, name) and
|
||||
not mayBenefitFromCallContextInitialize(ctx0, call0, arg, _, _, _) and
|
||||
not mayBenefitFromCallContextInstance(ctx0, call0, arg, _, _, _, name) and
|
||||
not mayBenefitFromCallContextSingleton(ctx0, call0, arg, _, _, _, name) and
|
||||
result = viableSourceCallable(call)
|
||||
result.asCallable() = viableSourceCallable(call0)
|
||||
)
|
||||
or
|
||||
// library calls should always be able to resolve
|
||||
|
||||
@@ -622,7 +622,11 @@ private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind)
|
||||
}
|
||||
|
||||
private module Stage1 implements StageSig {
|
||||
class Ap = Unit;
|
||||
class Ap extends int {
|
||||
// workaround for bad functionality-induced joins (happens when using `Unit`)
|
||||
pragma[nomagic]
|
||||
Ap() { this in [0 .. 1] and this < 1 }
|
||||
}
|
||||
|
||||
private class Cc = boolean;
|
||||
|
||||
@@ -1327,8 +1331,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and
|
||||
PrevStage::revFlow(node, state, apa, config) and
|
||||
@@ -1337,21 +1341,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[inline]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlow0(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
sourceNode(node, state, config) and
|
||||
(if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and
|
||||
argAp = apNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
or
|
||||
@@ -1372,7 +1376,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone()
|
||||
)
|
||||
or
|
||||
@@ -1380,7 +1384,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1390,7 +1394,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStateStep(mid, state0, node, state, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1414,10 +1418,10 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and
|
||||
if PrevStage::parameterMayFlowThrough(node, apa, config)
|
||||
then (
|
||||
summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and
|
||||
summaryCtx = TParamNodeSome(node.asNode()) and
|
||||
argAp = apSome(ap)
|
||||
) else (
|
||||
summaryCtx = TParameterPositionNone() and argAp = apNone()
|
||||
summaryCtx = TParamNodeNone() and argAp = apNone()
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
@@ -1433,16 +1437,19 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 |
|
||||
fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config)
|
||||
exists(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa
|
||||
|
|
||||
fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowStore(
|
||||
NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
exists(DataFlowType contentType, ApApprox apa1 |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and
|
||||
@@ -1473,8 +1480,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ApNonNil ap, Configuration config
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
@@ -1483,7 +1490,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
@@ -1493,7 +1500,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and
|
||||
@@ -1505,64 +1512,38 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRetFromArg(
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParameterPosition summaryCtx, ParamNodeEx p,
|
||||
Ap argAp, ApApprox argApa, Ap ap, ApApprox apa, Configuration config
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ReturnKindExt kind |
|
||||
exists(ReturnKindExt kind |
|
||||
fwdFlow(pragma[only_bind_into](ret), state, ccc,
|
||||
TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, apa, config) and
|
||||
getApprox(argAp) = argApa and
|
||||
c = ret.getEnclosingCallable() and
|
||||
TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())),
|
||||
pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa),
|
||||
pragma[only_bind_into](config)) and
|
||||
kind = ret.getKind() and
|
||||
p.isParameterOf(c, pragma[only_bind_into](summaryCtx)) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
parameterFlowThroughAllowed(summaryCtx, kind) and
|
||||
argApa = getApprox(argAp) and
|
||||
PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
private predicate fwdFlowInMayFlowThrough(
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx param, Ap ap, ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough0(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx,
|
||||
Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowIn(call, pragma[only_bind_into](param), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(param, apa, config)
|
||||
}
|
||||
|
||||
// dedup before joining with `flowThroughOutOfCall`
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInMayFlowThroughProj(
|
||||
DataFlowCall call, CcCall innerCc, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThrough(call, _, innerCc, _, _, _, _, apa, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughOutOfCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `fwdFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowThroughOutOfCall(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
ApApprox argApa, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThroughProj(call, ccc, argApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config)
|
||||
fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowOutFromArg(
|
||||
DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc, ApApprox argApa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc),
|
||||
summaryCtx, _, argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa),
|
||||
config) and
|
||||
fwdFlowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
)
|
||||
fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa,
|
||||
config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1571,12 +1552,14 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParameterPosition pos, Ap ap, Configuration config
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx p, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx param |
|
||||
fwdFlowInMayFlowThrough(call, cc, _, summaryCtx, argAp, param, ap, _, config) and
|
||||
pos = param.getPosition()
|
||||
exists(ApApprox apa |
|
||||
fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(p, apa, config) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1596,23 +1579,31 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowConsCand(ap1, c, ap2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough0(
|
||||
DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret,
|
||||
ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp,
|
||||
innerArgApa, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough(
|
||||
RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(boolean allowsFieldFlow, ApApprox argApa, ApApprox apa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), _, p,
|
||||
argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa), config) and
|
||||
kind = ret.getKind() and
|
||||
fwdFlowThroughOutOfCall(_, ccc, ret, _, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa |
|
||||
returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
pos = ret.getReturnPosition() and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ApApprox argApa |
|
||||
@@ -1620,7 +1611,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
allowsFieldFlow, argApa, pragma[only_bind_into](config)) and
|
||||
fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa,
|
||||
pragma[only_bind_into](config)) and
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _,
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap,
|
||||
pragma[only_bind_into](config)) and
|
||||
if allowsFieldFlow = false then argAp instanceof ApNil else any()
|
||||
)
|
||||
@@ -1639,12 +1630,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowOutOfCallAp(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ApApprox apa |
|
||||
flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config)
|
||||
flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config) and
|
||||
pos = ret.getReturnPosition()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1739,17 +1731,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnKindExt kind |
|
||||
revFlowOut(_, node, kind, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, kind, state, _, _, _, ap, config)
|
||||
exists(ReturnPosition pos |
|
||||
revFlowOut(_, node, pos, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, pos, state, _, _, _, ap, config)
|
||||
then (
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(kind) and
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(pos) and
|
||||
returnAp = apSome(ap)
|
||||
) else (
|
||||
returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone()
|
||||
@@ -1782,47 +1774,33 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowOut(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx,
|
||||
ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, state, returnCtx, returnAp, ap, config) and
|
||||
flowOutOfCallAp(call, ret, kind, out, allowsFieldFlow, ap, config) and
|
||||
flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughIntoCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `revFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
Configuration config
|
||||
) {
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, argAp, config) and
|
||||
revFlowIsReturned(call, _, _, _, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowParamToReturn(
|
||||
ParamNodeEx p, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, Configuration config
|
||||
ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow(p, state, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp),
|
||||
pragma[only_bind_into](ap), pragma[only_bind_into](config)) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind()) and
|
||||
PrevStage::parameterMayFlowThrough(p, getApprox(ap), config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap,
|
||||
Configuration config
|
||||
private predicate revFlowThrough(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos,
|
||||
ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlowParamToReturn(p, state, kind, returnAp, ap, config) and
|
||||
revFlowThroughIntoCall(call, arg, p, allowsFieldFlow, ap, config)
|
||||
)
|
||||
revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1832,12 +1810,12 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIsReturned(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap,
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, FlowState state, CcCall ccc |
|
||||
revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and
|
||||
revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and
|
||||
matchesCall(ccc, call)
|
||||
)
|
||||
}
|
||||
@@ -1915,17 +1893,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate parameterFlowsThroughRev(
|
||||
ParamNodeEx p, Ap ap, ReturnKindExt kind, Ap returnAp, Configuration config
|
||||
ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config
|
||||
) {
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) {
|
||||
exists(RetNodeEx ret, ReturnKindExt kind |
|
||||
returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, kind, _, config)
|
||||
exists(RetNodeEx ret, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, pos, _, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1933,20 +1911,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate returnMayFlowThrough(
|
||||
RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p |
|
||||
returnFlowsThrough(ret, kind, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, kind, ap, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, pos, ap, config) and
|
||||
kind = pos.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate revFlowInToReturnIsReturned(
|
||||
private predicate revFlowThroughArg(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1954,7 +1933,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) {
|
||||
exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap |
|
||||
revFlow(arg, state, returnCtx, returnAp, ap, config) and
|
||||
revFlowInToReturnIsReturned(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1967,8 +1946,9 @@ private module MkStage<StageSig PrevStage> {
|
||||
conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and
|
||||
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and
|
||||
tuples =
|
||||
count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config))
|
||||
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap |
|
||||
fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)
|
||||
)
|
||||
or
|
||||
fwd = false and
|
||||
nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and
|
||||
@@ -2823,13 +2803,12 @@ private Configuration unbindConf(Configuration conf) {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate nodeMayUseSummary0(
|
||||
NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa,
|
||||
Configuration config
|
||||
NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(AccessPathApprox apa0 |
|
||||
c = n.getEnclosingCallable() and
|
||||
Stage5::parameterMayFlowThrough(p, _, _) and
|
||||
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos),
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()),
|
||||
TAccessPathApproxSome(apa), apa0, config)
|
||||
)
|
||||
}
|
||||
@@ -2838,10 +2817,9 @@ pragma[nomagic]
|
||||
private predicate nodeMayUseSummary(
|
||||
NodeEx n, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p |
|
||||
exists(ParamNodeEx p |
|
||||
Stage5::parameterMayFlowThrough(p, apa, config) and
|
||||
nodeMayUseSummary0(n, c, pos, state, apa, config) and
|
||||
p.isParameterOf(c, pos)
|
||||
nodeMayUseSummary0(n, p, state, apa, config)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -622,7 +622,11 @@ private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind)
|
||||
}
|
||||
|
||||
private module Stage1 implements StageSig {
|
||||
class Ap = Unit;
|
||||
class Ap extends int {
|
||||
// workaround for bad functionality-induced joins (happens when using `Unit`)
|
||||
pragma[nomagic]
|
||||
Ap() { this in [0 .. 1] and this < 1 }
|
||||
}
|
||||
|
||||
private class Cc = boolean;
|
||||
|
||||
@@ -1327,8 +1331,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and
|
||||
PrevStage::revFlow(node, state, apa, config) and
|
||||
@@ -1337,21 +1341,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[inline]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlow0(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
sourceNode(node, state, config) and
|
||||
(if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and
|
||||
argAp = apNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
or
|
||||
@@ -1372,7 +1376,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone()
|
||||
)
|
||||
or
|
||||
@@ -1380,7 +1384,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1390,7 +1394,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStateStep(mid, state0, node, state, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1414,10 +1418,10 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and
|
||||
if PrevStage::parameterMayFlowThrough(node, apa, config)
|
||||
then (
|
||||
summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and
|
||||
summaryCtx = TParamNodeSome(node.asNode()) and
|
||||
argAp = apSome(ap)
|
||||
) else (
|
||||
summaryCtx = TParameterPositionNone() and argAp = apNone()
|
||||
summaryCtx = TParamNodeNone() and argAp = apNone()
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
@@ -1433,16 +1437,19 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 |
|
||||
fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config)
|
||||
exists(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa
|
||||
|
|
||||
fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowStore(
|
||||
NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
exists(DataFlowType contentType, ApApprox apa1 |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and
|
||||
@@ -1473,8 +1480,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ApNonNil ap, Configuration config
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
@@ -1483,7 +1490,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
@@ -1493,7 +1500,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and
|
||||
@@ -1505,64 +1512,38 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRetFromArg(
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParameterPosition summaryCtx, ParamNodeEx p,
|
||||
Ap argAp, ApApprox argApa, Ap ap, ApApprox apa, Configuration config
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ReturnKindExt kind |
|
||||
exists(ReturnKindExt kind |
|
||||
fwdFlow(pragma[only_bind_into](ret), state, ccc,
|
||||
TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, apa, config) and
|
||||
getApprox(argAp) = argApa and
|
||||
c = ret.getEnclosingCallable() and
|
||||
TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())),
|
||||
pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa),
|
||||
pragma[only_bind_into](config)) and
|
||||
kind = ret.getKind() and
|
||||
p.isParameterOf(c, pragma[only_bind_into](summaryCtx)) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
parameterFlowThroughAllowed(summaryCtx, kind) and
|
||||
argApa = getApprox(argAp) and
|
||||
PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
private predicate fwdFlowInMayFlowThrough(
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx param, Ap ap, ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough0(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx,
|
||||
Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowIn(call, pragma[only_bind_into](param), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(param, apa, config)
|
||||
}
|
||||
|
||||
// dedup before joining with `flowThroughOutOfCall`
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInMayFlowThroughProj(
|
||||
DataFlowCall call, CcCall innerCc, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThrough(call, _, innerCc, _, _, _, _, apa, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughOutOfCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `fwdFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowThroughOutOfCall(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
ApApprox argApa, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThroughProj(call, ccc, argApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config)
|
||||
fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowOutFromArg(
|
||||
DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc, ApApprox argApa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc),
|
||||
summaryCtx, _, argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa),
|
||||
config) and
|
||||
fwdFlowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
)
|
||||
fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa,
|
||||
config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1571,12 +1552,14 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParameterPosition pos, Ap ap, Configuration config
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx p, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx param |
|
||||
fwdFlowInMayFlowThrough(call, cc, _, summaryCtx, argAp, param, ap, _, config) and
|
||||
pos = param.getPosition()
|
||||
exists(ApApprox apa |
|
||||
fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(p, apa, config) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1596,23 +1579,31 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowConsCand(ap1, c, ap2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough0(
|
||||
DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret,
|
||||
ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp,
|
||||
innerArgApa, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough(
|
||||
RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(boolean allowsFieldFlow, ApApprox argApa, ApApprox apa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), _, p,
|
||||
argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa), config) and
|
||||
kind = ret.getKind() and
|
||||
fwdFlowThroughOutOfCall(_, ccc, ret, _, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa |
|
||||
returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
pos = ret.getReturnPosition() and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ApApprox argApa |
|
||||
@@ -1620,7 +1611,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
allowsFieldFlow, argApa, pragma[only_bind_into](config)) and
|
||||
fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa,
|
||||
pragma[only_bind_into](config)) and
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _,
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap,
|
||||
pragma[only_bind_into](config)) and
|
||||
if allowsFieldFlow = false then argAp instanceof ApNil else any()
|
||||
)
|
||||
@@ -1639,12 +1630,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowOutOfCallAp(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ApApprox apa |
|
||||
flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config)
|
||||
flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config) and
|
||||
pos = ret.getReturnPosition()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1739,17 +1731,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnKindExt kind |
|
||||
revFlowOut(_, node, kind, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, kind, state, _, _, _, ap, config)
|
||||
exists(ReturnPosition pos |
|
||||
revFlowOut(_, node, pos, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, pos, state, _, _, _, ap, config)
|
||||
then (
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(kind) and
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(pos) and
|
||||
returnAp = apSome(ap)
|
||||
) else (
|
||||
returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone()
|
||||
@@ -1782,47 +1774,33 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowOut(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx,
|
||||
ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, state, returnCtx, returnAp, ap, config) and
|
||||
flowOutOfCallAp(call, ret, kind, out, allowsFieldFlow, ap, config) and
|
||||
flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughIntoCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `revFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
Configuration config
|
||||
) {
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, argAp, config) and
|
||||
revFlowIsReturned(call, _, _, _, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowParamToReturn(
|
||||
ParamNodeEx p, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, Configuration config
|
||||
ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow(p, state, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp),
|
||||
pragma[only_bind_into](ap), pragma[only_bind_into](config)) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind()) and
|
||||
PrevStage::parameterMayFlowThrough(p, getApprox(ap), config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap,
|
||||
Configuration config
|
||||
private predicate revFlowThrough(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos,
|
||||
ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlowParamToReturn(p, state, kind, returnAp, ap, config) and
|
||||
revFlowThroughIntoCall(call, arg, p, allowsFieldFlow, ap, config)
|
||||
)
|
||||
revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1832,12 +1810,12 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIsReturned(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap,
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, FlowState state, CcCall ccc |
|
||||
revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and
|
||||
revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and
|
||||
matchesCall(ccc, call)
|
||||
)
|
||||
}
|
||||
@@ -1915,17 +1893,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate parameterFlowsThroughRev(
|
||||
ParamNodeEx p, Ap ap, ReturnKindExt kind, Ap returnAp, Configuration config
|
||||
ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config
|
||||
) {
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) {
|
||||
exists(RetNodeEx ret, ReturnKindExt kind |
|
||||
returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, kind, _, config)
|
||||
exists(RetNodeEx ret, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, pos, _, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1933,20 +1911,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate returnMayFlowThrough(
|
||||
RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p |
|
||||
returnFlowsThrough(ret, kind, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, kind, ap, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, pos, ap, config) and
|
||||
kind = pos.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate revFlowInToReturnIsReturned(
|
||||
private predicate revFlowThroughArg(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1954,7 +1933,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) {
|
||||
exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap |
|
||||
revFlow(arg, state, returnCtx, returnAp, ap, config) and
|
||||
revFlowInToReturnIsReturned(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1967,8 +1946,9 @@ private module MkStage<StageSig PrevStage> {
|
||||
conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and
|
||||
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and
|
||||
tuples =
|
||||
count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config))
|
||||
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap |
|
||||
fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)
|
||||
)
|
||||
or
|
||||
fwd = false and
|
||||
nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and
|
||||
@@ -2823,13 +2803,12 @@ private Configuration unbindConf(Configuration conf) {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate nodeMayUseSummary0(
|
||||
NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa,
|
||||
Configuration config
|
||||
NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(AccessPathApprox apa0 |
|
||||
c = n.getEnclosingCallable() and
|
||||
Stage5::parameterMayFlowThrough(p, _, _) and
|
||||
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos),
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()),
|
||||
TAccessPathApproxSome(apa), apa0, config)
|
||||
)
|
||||
}
|
||||
@@ -2838,10 +2817,9 @@ pragma[nomagic]
|
||||
private predicate nodeMayUseSummary(
|
||||
NodeEx n, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p |
|
||||
exists(ParamNodeEx p |
|
||||
Stage5::parameterMayFlowThrough(p, apa, config) and
|
||||
nodeMayUseSummary0(n, c, pos, state, apa, config) and
|
||||
p.isParameterOf(c, pos)
|
||||
nodeMayUseSummary0(n, p, state, apa, config)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -916,15 +916,15 @@ private module Cached {
|
||||
TDataFlowCallSome(DataFlowCall call)
|
||||
|
||||
cached
|
||||
newtype TParameterPositionOption =
|
||||
TParameterPositionNone() or
|
||||
TParameterPositionSome(ParameterPosition pos)
|
||||
newtype TParamNodeOption =
|
||||
TParamNodeNone() or
|
||||
TParamNodeSome(ParamNode p)
|
||||
|
||||
cached
|
||||
newtype TReturnCtx =
|
||||
TReturnCtxNone() or
|
||||
TReturnCtxNoFlowThrough() or
|
||||
TReturnCtxMaybeFlowThrough(ReturnKindExt kind)
|
||||
TReturnCtxMaybeFlowThrough(ReturnPosition pos)
|
||||
|
||||
cached
|
||||
newtype TTypedContentApprox =
|
||||
@@ -1343,15 +1343,15 @@ class DataFlowCallOption extends TDataFlowCallOption {
|
||||
}
|
||||
}
|
||||
|
||||
/** An optional `ParameterPosition`. */
|
||||
class ParameterPositionOption extends TParameterPositionOption {
|
||||
/** An optional `ParamNode`. */
|
||||
class ParamNodeOption extends TParamNodeOption {
|
||||
string toString() {
|
||||
this = TParameterPositionNone() and
|
||||
this = TParamNodeNone() and
|
||||
result = "(none)"
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
this = TParameterPositionSome(pos) and
|
||||
result = pos.toString()
|
||||
exists(ParamNode p |
|
||||
this = TParamNodeSome(p) and
|
||||
result = p.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1363,7 +1363,7 @@ class ParameterPositionOption extends TParameterPositionOption {
|
||||
*
|
||||
* - `TReturnCtxNone()`: no return flow.
|
||||
* - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible.
|
||||
* - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and
|
||||
* - `TReturnCtxMaybeFlowThrough(ReturnPosition pos)`: return flow, of kind `pos`, and
|
||||
* flow through may be possible.
|
||||
*/
|
||||
class ReturnCtx extends TReturnCtx {
|
||||
@@ -1374,9 +1374,9 @@ class ReturnCtx extends TReturnCtx {
|
||||
this = TReturnCtxNoFlowThrough() and
|
||||
result = "(no flow through)"
|
||||
or
|
||||
exists(ReturnKindExt kind |
|
||||
this = TReturnCtxMaybeFlowThrough(kind) and
|
||||
result = kind.toString()
|
||||
exists(ReturnPosition pos |
|
||||
this = TReturnCtxMaybeFlowThrough(pos) and
|
||||
result = pos.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,7 +622,11 @@ private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind)
|
||||
}
|
||||
|
||||
private module Stage1 implements StageSig {
|
||||
class Ap = Unit;
|
||||
class Ap extends int {
|
||||
// workaround for bad functionality-induced joins (happens when using `Unit`)
|
||||
pragma[nomagic]
|
||||
Ap() { this in [0 .. 1] and this < 1 }
|
||||
}
|
||||
|
||||
private class Cc = boolean;
|
||||
|
||||
@@ -1327,8 +1331,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and
|
||||
PrevStage::revFlow(node, state, apa, config) and
|
||||
@@ -1337,21 +1341,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[inline]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlow0(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
sourceNode(node, state, config) and
|
||||
(if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and
|
||||
argAp = apNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
or
|
||||
@@ -1372,7 +1376,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone()
|
||||
)
|
||||
or
|
||||
@@ -1380,7 +1384,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1390,7 +1394,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStateStep(mid, state0, node, state, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1414,10 +1418,10 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and
|
||||
if PrevStage::parameterMayFlowThrough(node, apa, config)
|
||||
then (
|
||||
summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and
|
||||
summaryCtx = TParamNodeSome(node.asNode()) and
|
||||
argAp = apSome(ap)
|
||||
) else (
|
||||
summaryCtx = TParameterPositionNone() and argAp = apNone()
|
||||
summaryCtx = TParamNodeNone() and argAp = apNone()
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
@@ -1433,16 +1437,19 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 |
|
||||
fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config)
|
||||
exists(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa
|
||||
|
|
||||
fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowStore(
|
||||
NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
exists(DataFlowType contentType, ApApprox apa1 |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and
|
||||
@@ -1473,8 +1480,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ApNonNil ap, Configuration config
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
@@ -1483,7 +1490,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
@@ -1493,7 +1500,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and
|
||||
@@ -1505,64 +1512,38 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRetFromArg(
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParameterPosition summaryCtx, ParamNodeEx p,
|
||||
Ap argAp, ApApprox argApa, Ap ap, ApApprox apa, Configuration config
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ReturnKindExt kind |
|
||||
exists(ReturnKindExt kind |
|
||||
fwdFlow(pragma[only_bind_into](ret), state, ccc,
|
||||
TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, apa, config) and
|
||||
getApprox(argAp) = argApa and
|
||||
c = ret.getEnclosingCallable() and
|
||||
TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())),
|
||||
pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa),
|
||||
pragma[only_bind_into](config)) and
|
||||
kind = ret.getKind() and
|
||||
p.isParameterOf(c, pragma[only_bind_into](summaryCtx)) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
parameterFlowThroughAllowed(summaryCtx, kind) and
|
||||
argApa = getApprox(argAp) and
|
||||
PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
private predicate fwdFlowInMayFlowThrough(
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx param, Ap ap, ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough0(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx,
|
||||
Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowIn(call, pragma[only_bind_into](param), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(param, apa, config)
|
||||
}
|
||||
|
||||
// dedup before joining with `flowThroughOutOfCall`
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInMayFlowThroughProj(
|
||||
DataFlowCall call, CcCall innerCc, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThrough(call, _, innerCc, _, _, _, _, apa, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughOutOfCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `fwdFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowThroughOutOfCall(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
ApApprox argApa, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThroughProj(call, ccc, argApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config)
|
||||
fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowOutFromArg(
|
||||
DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc, ApApprox argApa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc),
|
||||
summaryCtx, _, argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa),
|
||||
config) and
|
||||
fwdFlowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
)
|
||||
fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa,
|
||||
config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1571,12 +1552,14 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParameterPosition pos, Ap ap, Configuration config
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx p, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx param |
|
||||
fwdFlowInMayFlowThrough(call, cc, _, summaryCtx, argAp, param, ap, _, config) and
|
||||
pos = param.getPosition()
|
||||
exists(ApApprox apa |
|
||||
fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(p, apa, config) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1596,23 +1579,31 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowConsCand(ap1, c, ap2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough0(
|
||||
DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret,
|
||||
ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp,
|
||||
innerArgApa, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough(
|
||||
RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(boolean allowsFieldFlow, ApApprox argApa, ApApprox apa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), _, p,
|
||||
argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa), config) and
|
||||
kind = ret.getKind() and
|
||||
fwdFlowThroughOutOfCall(_, ccc, ret, _, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa |
|
||||
returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
pos = ret.getReturnPosition() and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ApApprox argApa |
|
||||
@@ -1620,7 +1611,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
allowsFieldFlow, argApa, pragma[only_bind_into](config)) and
|
||||
fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa,
|
||||
pragma[only_bind_into](config)) and
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _,
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap,
|
||||
pragma[only_bind_into](config)) and
|
||||
if allowsFieldFlow = false then argAp instanceof ApNil else any()
|
||||
)
|
||||
@@ -1639,12 +1630,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowOutOfCallAp(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ApApprox apa |
|
||||
flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config)
|
||||
flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config) and
|
||||
pos = ret.getReturnPosition()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1739,17 +1731,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnKindExt kind |
|
||||
revFlowOut(_, node, kind, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, kind, state, _, _, _, ap, config)
|
||||
exists(ReturnPosition pos |
|
||||
revFlowOut(_, node, pos, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, pos, state, _, _, _, ap, config)
|
||||
then (
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(kind) and
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(pos) and
|
||||
returnAp = apSome(ap)
|
||||
) else (
|
||||
returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone()
|
||||
@@ -1782,47 +1774,33 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowOut(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx,
|
||||
ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, state, returnCtx, returnAp, ap, config) and
|
||||
flowOutOfCallAp(call, ret, kind, out, allowsFieldFlow, ap, config) and
|
||||
flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughIntoCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `revFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
Configuration config
|
||||
) {
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, argAp, config) and
|
||||
revFlowIsReturned(call, _, _, _, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowParamToReturn(
|
||||
ParamNodeEx p, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, Configuration config
|
||||
ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow(p, state, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp),
|
||||
pragma[only_bind_into](ap), pragma[only_bind_into](config)) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind()) and
|
||||
PrevStage::parameterMayFlowThrough(p, getApprox(ap), config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap,
|
||||
Configuration config
|
||||
private predicate revFlowThrough(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos,
|
||||
ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlowParamToReturn(p, state, kind, returnAp, ap, config) and
|
||||
revFlowThroughIntoCall(call, arg, p, allowsFieldFlow, ap, config)
|
||||
)
|
||||
revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1832,12 +1810,12 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIsReturned(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap,
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, FlowState state, CcCall ccc |
|
||||
revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and
|
||||
revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and
|
||||
matchesCall(ccc, call)
|
||||
)
|
||||
}
|
||||
@@ -1915,17 +1893,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate parameterFlowsThroughRev(
|
||||
ParamNodeEx p, Ap ap, ReturnKindExt kind, Ap returnAp, Configuration config
|
||||
ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config
|
||||
) {
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) {
|
||||
exists(RetNodeEx ret, ReturnKindExt kind |
|
||||
returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, kind, _, config)
|
||||
exists(RetNodeEx ret, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, pos, _, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1933,20 +1911,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate returnMayFlowThrough(
|
||||
RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p |
|
||||
returnFlowsThrough(ret, kind, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, kind, ap, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, pos, ap, config) and
|
||||
kind = pos.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate revFlowInToReturnIsReturned(
|
||||
private predicate revFlowThroughArg(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1954,7 +1933,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) {
|
||||
exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap |
|
||||
revFlow(arg, state, returnCtx, returnAp, ap, config) and
|
||||
revFlowInToReturnIsReturned(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1967,8 +1946,9 @@ private module MkStage<StageSig PrevStage> {
|
||||
conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and
|
||||
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and
|
||||
tuples =
|
||||
count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config))
|
||||
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap |
|
||||
fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)
|
||||
)
|
||||
or
|
||||
fwd = false and
|
||||
nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and
|
||||
@@ -2823,13 +2803,12 @@ private Configuration unbindConf(Configuration conf) {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate nodeMayUseSummary0(
|
||||
NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa,
|
||||
Configuration config
|
||||
NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(AccessPathApprox apa0 |
|
||||
c = n.getEnclosingCallable() and
|
||||
Stage5::parameterMayFlowThrough(p, _, _) and
|
||||
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos),
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()),
|
||||
TAccessPathApproxSome(apa), apa0, config)
|
||||
)
|
||||
}
|
||||
@@ -2838,10 +2817,9 @@ pragma[nomagic]
|
||||
private predicate nodeMayUseSummary(
|
||||
NodeEx n, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p |
|
||||
exists(ParamNodeEx p |
|
||||
Stage5::parameterMayFlowThrough(p, apa, config) and
|
||||
nodeMayUseSummary0(n, c, pos, state, apa, config) and
|
||||
p.isParameterOf(c, pos)
|
||||
nodeMayUseSummary0(n, p, state, apa, config)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -622,7 +622,11 @@ private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind)
|
||||
}
|
||||
|
||||
private module Stage1 implements StageSig {
|
||||
class Ap = Unit;
|
||||
class Ap extends int {
|
||||
// workaround for bad functionality-induced joins (happens when using `Unit`)
|
||||
pragma[nomagic]
|
||||
Ap() { this in [0 .. 1] and this < 1 }
|
||||
}
|
||||
|
||||
private class Cc = boolean;
|
||||
|
||||
@@ -1327,8 +1331,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and
|
||||
PrevStage::revFlow(node, state, apa, config) and
|
||||
@@ -1337,21 +1341,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[inline]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlow0(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
sourceNode(node, state, config) and
|
||||
(if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and
|
||||
argAp = apNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
or
|
||||
@@ -1372,7 +1376,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone()
|
||||
)
|
||||
or
|
||||
@@ -1380,7 +1384,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1390,7 +1394,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStateStep(mid, state0, node, state, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1414,10 +1418,10 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and
|
||||
if PrevStage::parameterMayFlowThrough(node, apa, config)
|
||||
then (
|
||||
summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and
|
||||
summaryCtx = TParamNodeSome(node.asNode()) and
|
||||
argAp = apSome(ap)
|
||||
) else (
|
||||
summaryCtx = TParameterPositionNone() and argAp = apNone()
|
||||
summaryCtx = TParamNodeNone() and argAp = apNone()
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
@@ -1433,16 +1437,19 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 |
|
||||
fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config)
|
||||
exists(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa
|
||||
|
|
||||
fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowStore(
|
||||
NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
exists(DataFlowType contentType, ApApprox apa1 |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and
|
||||
@@ -1473,8 +1480,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ApNonNil ap, Configuration config
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
@@ -1483,7 +1490,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
@@ -1493,7 +1500,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and
|
||||
@@ -1505,64 +1512,38 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRetFromArg(
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParameterPosition summaryCtx, ParamNodeEx p,
|
||||
Ap argAp, ApApprox argApa, Ap ap, ApApprox apa, Configuration config
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ReturnKindExt kind |
|
||||
exists(ReturnKindExt kind |
|
||||
fwdFlow(pragma[only_bind_into](ret), state, ccc,
|
||||
TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, apa, config) and
|
||||
getApprox(argAp) = argApa and
|
||||
c = ret.getEnclosingCallable() and
|
||||
TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())),
|
||||
pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa),
|
||||
pragma[only_bind_into](config)) and
|
||||
kind = ret.getKind() and
|
||||
p.isParameterOf(c, pragma[only_bind_into](summaryCtx)) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
parameterFlowThroughAllowed(summaryCtx, kind) and
|
||||
argApa = getApprox(argAp) and
|
||||
PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
private predicate fwdFlowInMayFlowThrough(
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx param, Ap ap, ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough0(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx,
|
||||
Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowIn(call, pragma[only_bind_into](param), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(param, apa, config)
|
||||
}
|
||||
|
||||
// dedup before joining with `flowThroughOutOfCall`
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInMayFlowThroughProj(
|
||||
DataFlowCall call, CcCall innerCc, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThrough(call, _, innerCc, _, _, _, _, apa, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughOutOfCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `fwdFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowThroughOutOfCall(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
ApApprox argApa, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThroughProj(call, ccc, argApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config)
|
||||
fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowOutFromArg(
|
||||
DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc, ApApprox argApa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc),
|
||||
summaryCtx, _, argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa),
|
||||
config) and
|
||||
fwdFlowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
)
|
||||
fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa,
|
||||
config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1571,12 +1552,14 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParameterPosition pos, Ap ap, Configuration config
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx p, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx param |
|
||||
fwdFlowInMayFlowThrough(call, cc, _, summaryCtx, argAp, param, ap, _, config) and
|
||||
pos = param.getPosition()
|
||||
exists(ApApprox apa |
|
||||
fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(p, apa, config) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1596,23 +1579,31 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowConsCand(ap1, c, ap2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough0(
|
||||
DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret,
|
||||
ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp,
|
||||
innerArgApa, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough(
|
||||
RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(boolean allowsFieldFlow, ApApprox argApa, ApApprox apa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), _, p,
|
||||
argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa), config) and
|
||||
kind = ret.getKind() and
|
||||
fwdFlowThroughOutOfCall(_, ccc, ret, _, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa |
|
||||
returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
pos = ret.getReturnPosition() and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ApApprox argApa |
|
||||
@@ -1620,7 +1611,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
allowsFieldFlow, argApa, pragma[only_bind_into](config)) and
|
||||
fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa,
|
||||
pragma[only_bind_into](config)) and
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _,
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap,
|
||||
pragma[only_bind_into](config)) and
|
||||
if allowsFieldFlow = false then argAp instanceof ApNil else any()
|
||||
)
|
||||
@@ -1639,12 +1630,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowOutOfCallAp(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ApApprox apa |
|
||||
flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config)
|
||||
flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config) and
|
||||
pos = ret.getReturnPosition()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1739,17 +1731,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnKindExt kind |
|
||||
revFlowOut(_, node, kind, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, kind, state, _, _, _, ap, config)
|
||||
exists(ReturnPosition pos |
|
||||
revFlowOut(_, node, pos, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, pos, state, _, _, _, ap, config)
|
||||
then (
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(kind) and
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(pos) and
|
||||
returnAp = apSome(ap)
|
||||
) else (
|
||||
returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone()
|
||||
@@ -1782,47 +1774,33 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowOut(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx,
|
||||
ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, state, returnCtx, returnAp, ap, config) and
|
||||
flowOutOfCallAp(call, ret, kind, out, allowsFieldFlow, ap, config) and
|
||||
flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughIntoCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `revFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
Configuration config
|
||||
) {
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, argAp, config) and
|
||||
revFlowIsReturned(call, _, _, _, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowParamToReturn(
|
||||
ParamNodeEx p, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, Configuration config
|
||||
ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow(p, state, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp),
|
||||
pragma[only_bind_into](ap), pragma[only_bind_into](config)) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind()) and
|
||||
PrevStage::parameterMayFlowThrough(p, getApprox(ap), config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap,
|
||||
Configuration config
|
||||
private predicate revFlowThrough(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos,
|
||||
ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlowParamToReturn(p, state, kind, returnAp, ap, config) and
|
||||
revFlowThroughIntoCall(call, arg, p, allowsFieldFlow, ap, config)
|
||||
)
|
||||
revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1832,12 +1810,12 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIsReturned(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap,
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, FlowState state, CcCall ccc |
|
||||
revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and
|
||||
revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and
|
||||
matchesCall(ccc, call)
|
||||
)
|
||||
}
|
||||
@@ -1915,17 +1893,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate parameterFlowsThroughRev(
|
||||
ParamNodeEx p, Ap ap, ReturnKindExt kind, Ap returnAp, Configuration config
|
||||
ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config
|
||||
) {
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) {
|
||||
exists(RetNodeEx ret, ReturnKindExt kind |
|
||||
returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, kind, _, config)
|
||||
exists(RetNodeEx ret, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, pos, _, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1933,20 +1911,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate returnMayFlowThrough(
|
||||
RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p |
|
||||
returnFlowsThrough(ret, kind, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, kind, ap, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, pos, ap, config) and
|
||||
kind = pos.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate revFlowInToReturnIsReturned(
|
||||
private predicate revFlowThroughArg(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1954,7 +1933,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) {
|
||||
exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap |
|
||||
revFlow(arg, state, returnCtx, returnAp, ap, config) and
|
||||
revFlowInToReturnIsReturned(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1967,8 +1946,9 @@ private module MkStage<StageSig PrevStage> {
|
||||
conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and
|
||||
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and
|
||||
tuples =
|
||||
count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config))
|
||||
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap |
|
||||
fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)
|
||||
)
|
||||
or
|
||||
fwd = false and
|
||||
nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and
|
||||
@@ -2823,13 +2803,12 @@ private Configuration unbindConf(Configuration conf) {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate nodeMayUseSummary0(
|
||||
NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa,
|
||||
Configuration config
|
||||
NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(AccessPathApprox apa0 |
|
||||
c = n.getEnclosingCallable() and
|
||||
Stage5::parameterMayFlowThrough(p, _, _) and
|
||||
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos),
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()),
|
||||
TAccessPathApproxSome(apa), apa0, config)
|
||||
)
|
||||
}
|
||||
@@ -2838,10 +2817,9 @@ pragma[nomagic]
|
||||
private predicate nodeMayUseSummary(
|
||||
NodeEx n, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p |
|
||||
exists(ParamNodeEx p |
|
||||
Stage5::parameterMayFlowThrough(p, apa, config) and
|
||||
nodeMayUseSummary0(n, c, pos, state, apa, config) and
|
||||
p.isParameterOf(c, pos)
|
||||
nodeMayUseSummary0(n, p, state, apa, config)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -622,7 +622,11 @@ private predicate parameterFlowThroughAllowed(ParamNodeEx p, ReturnKindExt kind)
|
||||
}
|
||||
|
||||
private module Stage1 implements StageSig {
|
||||
class Ap = Unit;
|
||||
class Ap extends int {
|
||||
// workaround for bad functionality-induced joins (happens when using `Unit`)
|
||||
pragma[nomagic]
|
||||
Ap() { this in [0 .. 1] and this < 1 }
|
||||
}
|
||||
|
||||
private class Cc = boolean;
|
||||
|
||||
@@ -1327,8 +1331,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, summaryCtx, argAp, ap, apa, config) and
|
||||
PrevStage::revFlow(node, state, apa, config) and
|
||||
@@ -1337,21 +1341,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[inline]
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node, state, cc, summaryCtx, argAp, ap, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlow0(
|
||||
NodeEx node, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
) {
|
||||
sourceNode(node, state, config) and
|
||||
(if hasSourceCallCtx(config) then cc = ccSomeCall() else cc = ccNone()) and
|
||||
argAp = apNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
or
|
||||
@@ -1372,7 +1376,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, pragma[only_bind_into](state), _, _, _, ap, apa, pragma[only_bind_into](config)) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone()
|
||||
)
|
||||
or
|
||||
@@ -1380,7 +1384,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1390,7 +1394,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlow(mid, state0, _, _, _, nil, pragma[only_bind_into](config)) and
|
||||
additionalJumpStateStep(mid, state0, node, state, config) and
|
||||
cc = ccNone() and
|
||||
summaryCtx = TParameterPositionNone() and
|
||||
summaryCtx = TParamNodeNone() and
|
||||
argAp = apNone() and
|
||||
ap = getApNil(node) and
|
||||
apa = getApprox(ap)
|
||||
@@ -1414,10 +1418,10 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowIn(_, node, state, _, cc, _, _, ap, apa, config) and
|
||||
if PrevStage::parameterMayFlowThrough(node, apa, config)
|
||||
then (
|
||||
summaryCtx = TParameterPositionSome(node.(ParamNodeEx).getPosition()) and
|
||||
summaryCtx = TParamNodeSome(node.asNode()) and
|
||||
argAp = apSome(ap)
|
||||
) else (
|
||||
summaryCtx = TParameterPositionNone() and argAp = apNone()
|
||||
summaryCtx = TParamNodeNone() and argAp = apNone()
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
@@ -1433,16 +1437,19 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ParameterPosition summaryCtx0, Ap argAp0 |
|
||||
fwdFlowOutFromArg(call, node, state, summaryCtx0, argAp0, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, summaryCtx, argAp, summaryCtx0, argAp0, config)
|
||||
exists(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa
|
||||
|
|
||||
fwdFlowThrough(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowStore(
|
||||
NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
exists(DataFlowType contentType, ApApprox apa1 |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap1, apa1, config) and
|
||||
@@ -1473,8 +1480,8 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ApNonNil ap, Configuration config
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
@@ -1483,7 +1490,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
@@ -1493,7 +1500,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc,
|
||||
ParameterPositionOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, state, outercc, summaryCtx, argAp, ap, apa, config) and
|
||||
@@ -1505,64 +1512,38 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRetFromArg(
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParameterPosition summaryCtx, ParamNodeEx p,
|
||||
Ap argAp, ApApprox argApa, Ap ap, ApApprox apa, Configuration config
|
||||
RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Ap argAp, ApApprox argApa,
|
||||
Ap ap, ApApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ReturnKindExt kind |
|
||||
exists(ReturnKindExt kind |
|
||||
fwdFlow(pragma[only_bind_into](ret), state, ccc,
|
||||
TParameterPositionSome(pragma[only_bind_into](summaryCtx)), apSome(argAp), ap, apa, config) and
|
||||
getApprox(argAp) = argApa and
|
||||
c = ret.getEnclosingCallable() and
|
||||
TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())),
|
||||
pragma[only_bind_into](apSome(argAp)), ap, pragma[only_bind_into](apa),
|
||||
pragma[only_bind_into](config)) and
|
||||
kind = ret.getKind() and
|
||||
p.isParameterOf(c, pragma[only_bind_into](summaryCtx)) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
parameterFlowThroughAllowed(summaryCtx, kind) and
|
||||
argApa = getApprox(argAp) and
|
||||
PrevStage::returnMayFlowThrough(ret, argApa, apa, kind, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
private predicate fwdFlowInMayFlowThrough(
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx param, Ap ap, ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough0(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ParamNodeEx innerSummaryCtx,
|
||||
Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowIn(call, pragma[only_bind_into](param), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(param, apa, config)
|
||||
}
|
||||
|
||||
// dedup before joining with `flowThroughOutOfCall`
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInMayFlowThroughProj(
|
||||
DataFlowCall call, CcCall innerCc, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThrough(call, _, innerCc, _, _, _, _, apa, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughOutOfCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `fwdFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowThroughOutOfCall(
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
ApApprox argApa, ApApprox apa, Configuration config
|
||||
) {
|
||||
fwdFlowInMayFlowThroughProj(call, ccc, argApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config)
|
||||
fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgAp, innerArgApa, ap, apa, config) and
|
||||
fwdFlowIsEntered(call, cc, ccc, summaryCtx, argAp, innerSummaryCtx, innerArgAp, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowOutFromArg(
|
||||
DataFlowCall call, NodeEx out, FlowState state, ParameterPosition summaryCtx, Ap argAp, Ap ap,
|
||||
ApApprox apa, Configuration config
|
||||
private predicate fwdFlowThrough(
|
||||
DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx,
|
||||
ApOption argAp, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc, ApApprox argApa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc),
|
||||
summaryCtx, _, argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa),
|
||||
config) and
|
||||
fwdFlowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
)
|
||||
fwdFlowThrough0(call, cc, state, ccc, summaryCtx, argAp, ap, apa, ret, _, _, innerArgApa,
|
||||
config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1571,12 +1552,14 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
ParameterPosition pos, Ap ap, Configuration config
|
||||
DataFlowCall call, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, ApOption argAp,
|
||||
ParamNodeEx p, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx param |
|
||||
fwdFlowInMayFlowThrough(call, cc, _, summaryCtx, argAp, param, ap, _, config) and
|
||||
pos = param.getPosition()
|
||||
exists(ApApprox apa |
|
||||
fwdFlowIn(call, pragma[only_bind_into](p), _, cc, innerCc, summaryCtx, argAp, ap,
|
||||
pragma[only_bind_into](apa), pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(p, apa, config) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1596,23 +1579,31 @@ private module MkStage<StageSig PrevStage> {
|
||||
fwdFlowConsCand(ap1, c, ap2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough0(
|
||||
DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret,
|
||||
ParamNodeEx innerSummaryCtx, Ap innerArgAp, ApApprox innerArgApa, Configuration config
|
||||
) {
|
||||
fwdFlowThrough0(call, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgAp,
|
||||
innerArgApa, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnFlowsThrough(
|
||||
RetNodeEx ret, ReturnKindExt kind, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Ap argAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(boolean allowsFieldFlow, ApApprox argApa, ApApprox apa |
|
||||
fwdFlowRetFromArg(pragma[only_bind_into](ret), state, pragma[only_bind_into](ccc), _, p,
|
||||
argAp, pragma[only_bind_into](argApa), ap, pragma[only_bind_into](apa), config) and
|
||||
kind = ret.getKind() and
|
||||
fwdFlowThroughOutOfCall(_, ccc, ret, _, allowsFieldFlow, argApa, apa, config) and
|
||||
(if allowsFieldFlow = false then ap instanceof ApNil else any())
|
||||
exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow, ApApprox innerArgApa |
|
||||
returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argAp, innerArgApa, config) and
|
||||
flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, innerArgApa, apa, config) and
|
||||
pos = ret.getReturnPosition() and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ApApprox argApa |
|
||||
@@ -1620,7 +1611,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
allowsFieldFlow, argApa, pragma[only_bind_into](config)) and
|
||||
fwdFlow(arg, _, _, _, _, pragma[only_bind_into](argAp), argApa,
|
||||
pragma[only_bind_into](config)) and
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), _,
|
||||
returnFlowsThrough(_, _, _, _, p, pragma[only_bind_into](argAp), ap,
|
||||
pragma[only_bind_into](config)) and
|
||||
if allowsFieldFlow = false then argAp instanceof ApNil else any()
|
||||
)
|
||||
@@ -1639,12 +1630,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowOutOfCallAp(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, boolean allowsFieldFlow,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ApApprox apa |
|
||||
flowOutOfCallApa(call, ret, kind, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config)
|
||||
flowOutOfCallApa(call, ret, _, out, allowsFieldFlow, apa, config) and
|
||||
fwdFlow(ret, _, _, _, _, ap, apa, config) and
|
||||
pos = ret.getReturnPosition()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1739,17 +1731,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call, ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, node, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(DataFlowCall call, ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, node, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnKindExt kind |
|
||||
revFlowOut(_, node, kind, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, kind, state, _, _, _, ap, config)
|
||||
exists(ReturnPosition pos |
|
||||
revFlowOut(_, node, pos, state, _, _, ap, config) and
|
||||
if returnFlowsThrough(node, pos, state, _, _, _, ap, config)
|
||||
then (
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(kind) and
|
||||
returnCtx = TReturnCtxMaybeFlowThrough(pos) and
|
||||
returnAp = apSome(ap)
|
||||
) else (
|
||||
returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone()
|
||||
@@ -1782,47 +1774,33 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowOut(
|
||||
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, FlowState state, ReturnCtx returnCtx,
|
||||
DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx,
|
||||
ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, state, returnCtx, returnAp, ap, config) and
|
||||
flowOutOfCallAp(call, ret, kind, out, allowsFieldFlow, ap, config) and
|
||||
flowOutOfCallAp(call, ret, pos, out, allowsFieldFlow, ap, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `flowThroughIntoCall`, but restricted to calls that are reached
|
||||
* in the flow covered by `revFlow`, where data might flow through the target
|
||||
* callable and back out at `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowThroughIntoCall(
|
||||
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow, Ap argAp,
|
||||
Configuration config
|
||||
) {
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, argAp, config) and
|
||||
revFlowIsReturned(call, _, _, _, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowParamToReturn(
|
||||
ParamNodeEx p, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap, Configuration config
|
||||
ParamNodeEx p, FlowState state, ReturnPosition pos, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow(p, state, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(pragma[only_bind_into](p), state, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp),
|
||||
pragma[only_bind_into](ap), pragma[only_bind_into](config)) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind()) and
|
||||
PrevStage::parameterMayFlowThrough(p, getApprox(ap), config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnKindExt kind, Ap returnAp, Ap ap,
|
||||
Configuration config
|
||||
private predicate revFlowThrough(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos,
|
||||
ApOption returnAp, Ap ap, Ap innerReturnAp, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlowParamToReturn(p, state, kind, returnAp, ap, config) and
|
||||
revFlowThroughIntoCall(call, arg, p, allowsFieldFlow, ap, config)
|
||||
)
|
||||
revFlowParamToReturn(p, state, pos, innerReturnAp, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, pos, innerReturnAp, config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1832,12 +1810,12 @@ private module MkStage<StageSig PrevStage> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIsReturned(
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnKindExt kind, Ap ap,
|
||||
DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(RetNodeEx ret, FlowState state, CcCall ccc |
|
||||
revFlowOut(call, ret, kind, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, kind, state, ccc, _, _, ap, config) and
|
||||
revFlowOut(call, ret, pos, state, returnCtx, returnAp, ap, config) and
|
||||
returnFlowsThrough(ret, pos, state, ccc, _, _, ap, config) and
|
||||
matchesCall(ccc, call)
|
||||
)
|
||||
}
|
||||
@@ -1915,17 +1893,17 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate parameterFlowsThroughRev(
|
||||
ParamNodeEx p, Ap ap, ReturnKindExt kind, Ap returnAp, Configuration config
|
||||
ParamNodeEx p, Ap ap, ReturnPosition pos, Ap returnAp, Configuration config
|
||||
) {
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(kind), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, kind)
|
||||
revFlow(p, _, TReturnCtxMaybeFlowThrough(pos), apSome(returnAp), ap, config) and
|
||||
parameterFlowThroughAllowed(p, pos.getKind())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, Ap ap, Configuration config) {
|
||||
exists(RetNodeEx ret, ReturnKindExt kind |
|
||||
returnFlowsThrough(ret, kind, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, kind, _, config)
|
||||
exists(RetNodeEx ret, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, ap, _, config) and
|
||||
parameterFlowsThroughRev(p, ap, pos, _, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1933,20 +1911,21 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate returnMayFlowThrough(
|
||||
RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind, Configuration config
|
||||
) {
|
||||
exists(ParamNodeEx p |
|
||||
returnFlowsThrough(ret, kind, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, kind, ap, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos |
|
||||
returnFlowsThrough(ret, pos, _, _, p, argAp, ap, config) and
|
||||
parameterFlowsThroughRev(p, argAp, pos, ap, config) and
|
||||
kind = pos.getKind()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate revFlowInToReturnIsReturned(
|
||||
private predicate revFlowThroughArg(
|
||||
DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp,
|
||||
Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt returnKind0, Ap returnAp0 |
|
||||
revFlowInToReturn(call, arg, state, returnKind0, returnAp0, ap, config) and
|
||||
revFlowIsReturned(call, returnCtx, returnAp, returnKind0, returnAp0, config)
|
||||
exists(ParamNodeEx p, ReturnPosition pos, Ap innerReturnAp |
|
||||
revFlowThrough(call, returnCtx, p, state, pos, returnAp, ap, innerReturnAp, config) and
|
||||
flowThroughIntoCall(call, arg, p, _, ap, innerReturnAp, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1954,7 +1933,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) {
|
||||
exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap |
|
||||
revFlow(arg, state, returnCtx, returnAp, ap, config) and
|
||||
revFlowInToReturnIsReturned(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1967,8 +1946,9 @@ private module MkStage<StageSig PrevStage> {
|
||||
conscand = count(TypedContent f0, Ap ap | fwdConsCand(f0, ap, config)) and
|
||||
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, config)) and
|
||||
tuples =
|
||||
count(NodeEx n, FlowState state, Cc cc, ParameterPositionOption summaryCtx, ApOption argAp,
|
||||
Ap ap | fwdFlow(n, state, cc, summaryCtx, argAp, ap, config))
|
||||
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, Ap ap |
|
||||
fwdFlow(n, state, cc, summaryCtx, argAp, ap, config)
|
||||
)
|
||||
or
|
||||
fwd = false and
|
||||
nodes = count(NodeEx node | revFlow(node, _, _, _, _, config)) and
|
||||
@@ -2823,13 +2803,12 @@ private Configuration unbindConf(Configuration conf) {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate nodeMayUseSummary0(
|
||||
NodeEx n, DataFlowCallable c, ParameterPosition pos, FlowState state, AccessPathApprox apa,
|
||||
Configuration config
|
||||
NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(AccessPathApprox apa0 |
|
||||
c = n.getEnclosingCallable() and
|
||||
Stage5::parameterMayFlowThrough(p, _, _) and
|
||||
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0, config) and
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParameterPositionSome(pos),
|
||||
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()),
|
||||
TAccessPathApproxSome(apa), apa0, config)
|
||||
)
|
||||
}
|
||||
@@ -2838,10 +2817,9 @@ pragma[nomagic]
|
||||
private predicate nodeMayUseSummary(
|
||||
NodeEx n, FlowState state, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(DataFlowCallable c, ParameterPosition pos, ParamNodeEx p |
|
||||
exists(ParamNodeEx p |
|
||||
Stage5::parameterMayFlowThrough(p, apa, config) and
|
||||
nodeMayUseSummary0(n, c, pos, state, apa, config) and
|
||||
p.isParameterOf(c, pos)
|
||||
nodeMayUseSummary0(n, p, state, apa, config)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -828,8 +828,8 @@ import ParameterNodes
|
||||
|
||||
/** A data-flow node used to model flow summaries. */
|
||||
class SummaryNode extends NodeImpl, TSummaryNode {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private FlowSummaryImpl::Private::SummaryNodeState state;
|
||||
FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
FlowSummaryImpl::Private::SummaryNodeState state;
|
||||
|
||||
SummaryNode() { this = TSummaryNode(c, state) }
|
||||
|
||||
@@ -951,6 +951,11 @@ private module ArgumentNodes {
|
||||
|
||||
import ArgumentNodes
|
||||
|
||||
/** A call to `new`. */
|
||||
private class NewCall extends DataFlowCall {
|
||||
NewCall() { this.asCall().getExpr().(MethodCall).getMethodName() = "new" }
|
||||
}
|
||||
|
||||
/** A data-flow node that represents a value syntactically returned by a callable. */
|
||||
abstract class ReturningNode extends Node {
|
||||
/** Gets the kind of this return node. */
|
||||
@@ -994,7 +999,12 @@ private module ReturnNodes {
|
||||
override ReturnKind getKind() {
|
||||
if n.getNode() instanceof BreakStmt
|
||||
then result instanceof BreakReturnKind
|
||||
else result instanceof NormalReturnKind
|
||||
else
|
||||
exists(CfgScope scope | scope = this.getCfgScope() |
|
||||
if isUserDefinedNew(scope)
|
||||
then result instanceof NewReturnKind
|
||||
else result instanceof NormalReturnKind
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1018,7 +1028,42 @@ private module ReturnNodes {
|
||||
class ExprReturnNode extends ReturningNode, ExprNode {
|
||||
ExprReturnNode() { exists(Callable c | implicitReturn(c, this) = c.getAStmt()) }
|
||||
|
||||
override ReturnKind getKind() { result instanceof NormalReturnKind }
|
||||
override ReturnKind getKind() {
|
||||
exists(CfgScope scope | scope = this.(NodeImpl).getCfgScope() |
|
||||
if isUserDefinedNew(scope)
|
||||
then result instanceof NewReturnKind
|
||||
else result instanceof NormalReturnKind
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `self` node inside an `initialize` method through which data may return.
|
||||
*
|
||||
* For example, in
|
||||
*
|
||||
* ```rb
|
||||
* class C
|
||||
* def initialize(x)
|
||||
* @x = x
|
||||
* end
|
||||
* end
|
||||
* ```
|
||||
*
|
||||
* the implicit `self` reference in `@x` will return data stored in the field
|
||||
* `x` out to the call `C.new`.
|
||||
*/
|
||||
class InitializeReturnNode extends ExprPostUpdateNode, ReturningNode {
|
||||
InitializeReturnNode() {
|
||||
exists(Method initialize |
|
||||
this.getCfgScope() = initialize and
|
||||
initialize.getName() = "initialize" and
|
||||
initialize = any(ClassDeclaration c).getAMethod() and
|
||||
this.getPreUpdateNode().asExpr().getExpr() instanceof SelfVariableReadAccess
|
||||
)
|
||||
}
|
||||
|
||||
override ReturnKind getKind() { result instanceof NewReturnKind }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1054,7 +1099,14 @@ private module ReturnNodes {
|
||||
|
||||
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this, rk) }
|
||||
|
||||
override ReturnKind getKind() { result = rk }
|
||||
override ReturnKind getKind() {
|
||||
result = rk
|
||||
or
|
||||
exists(NewCall new |
|
||||
TLibraryCallable(c) = viableLibraryCallable(new) and
|
||||
result instanceof NewReturnKind
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1078,7 +1130,9 @@ private module OutNodes {
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) {
|
||||
result = call and
|
||||
kind instanceof NormalReturnKind
|
||||
if call instanceof NewCall
|
||||
then kind instanceof NewReturnKind
|
||||
else kind instanceof NormalReturnKind
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ module Public {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the summary is auto generated.
|
||||
* Holds if the summary is auto generated and not manually generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { none() }
|
||||
|
||||
|
||||
125
ruby/ql/lib/codeql/ruby/frameworks/GlobalId.qll
Normal file
125
ruby/ql/lib/codeql/ruby/frameworks/GlobalId.qll
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Provides modeling for `GlobalID`, a library for identifying model instances by URI.
|
||||
* Version: 1.0.0
|
||||
* https://github.com/rails/globalid
|
||||
*/
|
||||
|
||||
private import codeql.ruby.ApiGraphs
|
||||
private import codeql.ruby.Concepts
|
||||
private import codeql.ruby.DataFlow
|
||||
private import codeql.ruby.frameworks.ActiveRecord
|
||||
|
||||
/**
|
||||
* Provides modeling for `GlobalID`, a library for identifying model instances by URI.
|
||||
* Version: 1.0.0
|
||||
* https://github.com/rails/globalid
|
||||
*/
|
||||
module GlobalId {
|
||||
/** A call to `GlobalID::parse` */
|
||||
class ParseCall extends DataFlow::CallNode {
|
||||
ParseCall() { this = API::getTopLevelMember("GlobalID").getAMethodCall("parse") }
|
||||
}
|
||||
|
||||
/** A call to `GlobalID::find` */
|
||||
class FindCall extends DataFlow::CallNode, OrmInstantiation::Range {
|
||||
FindCall() { this = API::getTopLevelMember("GlobalID").getAMethodCall("find") }
|
||||
|
||||
override predicate methodCallMayAccessField(string methodName) { none() }
|
||||
}
|
||||
|
||||
/** `GlobalID::Locator` */
|
||||
module Locator {
|
||||
/** A call to `GlobalID::Locator.locate` */
|
||||
class LocateCall extends DataFlow::CallNode, OrmInstantiation::Range {
|
||||
LocateCall() {
|
||||
this = API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate")
|
||||
}
|
||||
|
||||
override predicate methodCallMayAccessField(string methodName) { none() }
|
||||
}
|
||||
|
||||
/** A call to `GlobalID::Locator.locate_signed` */
|
||||
class LocateSignedCall extends DataFlow::CallNode, OrmInstantiation::Range {
|
||||
LocateSignedCall() {
|
||||
this =
|
||||
API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate_signed")
|
||||
}
|
||||
|
||||
override predicate methodCallMayAccessField(string methodName) { none() }
|
||||
}
|
||||
|
||||
/** A call to `GlobalID::Locator.locate_many` */
|
||||
class LocateManyCall extends DataFlow::CallNode, OrmInstantiation::Range {
|
||||
LocateManyCall() {
|
||||
this = API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate_many")
|
||||
}
|
||||
|
||||
override predicate methodCallMayAccessField(string methodName) { none() }
|
||||
}
|
||||
|
||||
/** A call to `GlobalID::Locator.locate_many_signed` */
|
||||
class LocateManySignedCall extends DataFlow::CallNode, OrmInstantiation::Range {
|
||||
LocateManySignedCall() {
|
||||
this =
|
||||
API::getTopLevelMember("GlobalID")
|
||||
.getMember("Locator")
|
||||
.getAMethodCall("locate_many_signed")
|
||||
}
|
||||
|
||||
override predicate methodCallMayAccessField(string methodName) { none() }
|
||||
}
|
||||
}
|
||||
|
||||
/** `GlobalID::Identification` */
|
||||
module Identification {
|
||||
/** A `DataFlow::CallNode` against an instance of a class that includes the `GlobalID::Identification` module */
|
||||
private class IdentificationInstanceCall extends DataFlow::CallNode {
|
||||
IdentificationInstanceCall() {
|
||||
this =
|
||||
DataFlow::getConstant("GlobalID")
|
||||
.getConstant("Identification")
|
||||
.getADescendentModule()
|
||||
.getAnImmediateReference()
|
||||
.getAMethodCall(["new", "find"])
|
||||
.getAMethodCall()
|
||||
or
|
||||
this instanceof ActiveRecordInstanceMethodCall
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to `GlobalID::Identification.to_global_id` */
|
||||
class ToGlobalIdCall extends IdentificationInstanceCall {
|
||||
ToGlobalIdCall() { this.getMethodName() = ["to_global_id", "to_gid"] }
|
||||
}
|
||||
|
||||
/** A call to `GlobalID::Identification.to_gid_param` */
|
||||
class ToGidParamCall extends DataFlow::CallNode {
|
||||
ToGidParamCall() { this.getMethodName() = "to_gid_param" }
|
||||
}
|
||||
|
||||
/** A call to `GlobalID::Identification.to_signed_global_id` */
|
||||
class ToSignedGlobalIdCall extends DataFlow::CallNode {
|
||||
ToSignedGlobalIdCall() { this.getMethodName() = ["to_signed_global_id", "to_sgid"] }
|
||||
}
|
||||
|
||||
/** A call to `GlobalID::Identification.to_sgid_param` */
|
||||
class ToSgidParamCall extends DataFlow::CallNode {
|
||||
ToSgidParamCall() { this.getMethodName() = "to_sgid_param" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides modeling for `SignedGlobalID`, a module of the `rails/globalid` library. */
|
||||
module SignedGlobalId {
|
||||
/** A call to `SignedGlobalID::parse` */
|
||||
class ParseCall extends DataFlow::CallNode {
|
||||
ParseCall() { this = API::getTopLevelMember("SignedGlobalID").getAMethodCall("parse") }
|
||||
}
|
||||
|
||||
/** A call to `SignedGlobalID::find` */
|
||||
class FindCall extends DataFlow::CallNode, OrmInstantiation::Range {
|
||||
FindCall() { this = API::getTopLevelMember("SignedGlobalID").getAMethodCall("find") }
|
||||
|
||||
override predicate methodCallMayAccessField(string methodName) { none() }
|
||||
}
|
||||
}
|
||||
@@ -79,10 +79,15 @@ predicate jumpStep = DataFlowPrivate::jumpStep/2;
|
||||
/** Holds if there is direct flow from `param` to a return. */
|
||||
pragma[nomagic]
|
||||
private predicate flowThrough(DataFlowPublic::ParameterNode param) {
|
||||
exists(DataFlowPrivate::ReturningNode returnNode |
|
||||
exists(DataFlowPrivate::ReturningNode returnNode, DataFlowDispatch::ReturnKind rk |
|
||||
DataFlowPrivate::LocalFlow::getParameterDefNode(param.getParameter())
|
||||
.(TypeTrackingNode)
|
||||
.flowsTo(returnNode)
|
||||
.flowsTo(returnNode) and
|
||||
rk = returnNode.getKind()
|
||||
|
|
||||
rk instanceof DataFlowDispatch::NormalReturnKind
|
||||
or
|
||||
rk instanceof DataFlowDispatch::BreakReturnKind
|
||||
)
|
||||
}
|
||||
|
||||
@@ -184,7 +189,9 @@ private predicate viableParam(
|
||||
DataFlowDispatch::ParameterPosition ppos
|
||||
) {
|
||||
exists(Cfg::CfgScope callable |
|
||||
DataFlowDispatch::getTarget(call) = callable and
|
||||
DataFlowDispatch::getTarget(call) = callable or
|
||||
DataFlowDispatch::getInitializeTarget(call) = callable
|
||||
|
|
||||
p.isSourceParameterOf(callable, ppos)
|
||||
)
|
||||
}
|
||||
@@ -226,6 +233,9 @@ predicate returnStep(Node nodeFrom, Node nodeTo) {
|
||||
exists(ExprNodes::CallCfgNode call |
|
||||
nodeFrom instanceof DataFlowPrivate::ReturnNode and
|
||||
nodeFrom.(DataFlowPrivate::NodeImpl).getCfgScope() = DataFlowDispatch::getTarget(call) and
|
||||
// deliberately do not include `getInitializeTarget`, since calls to `new` should not
|
||||
// get the return value from `initialize`. Any fields being set in the initializer
|
||||
// will reach all reads via `callStep` and `localFieldStep`.
|
||||
nodeTo.asExpr().getNode() = call.getNode()
|
||||
)
|
||||
or
|
||||
@@ -233,7 +243,8 @@ predicate returnStep(Node nodeFrom, Node nodeTo) {
|
||||
// we model it as a returning flow step, in order to avoid computing a potential
|
||||
// self-cross product of all calls to a function that returns one of its parameters
|
||||
// (only to later filter that flow out using `TypeTracker::append`).
|
||||
nodeTo.(DataFlowPrivate::SynthReturnNode).getAnInput() = nodeFrom
|
||||
nodeTo.(DataFlowPrivate::SynthReturnNode).getAnInput() = nodeFrom and
|
||||
not nodeFrom instanceof DataFlowPrivate::InitializeReturnNode
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/ruby-all
|
||||
version: 0.4.6-dev
|
||||
version: 0.5.0-dev
|
||||
groups: ruby
|
||||
extractor: ruby
|
||||
dbscheme: ruby.dbscheme
|
||||
@@ -8,6 +8,5 @@ library: true
|
||||
dependencies:
|
||||
codeql/ssa: ${workspace}
|
||||
codeql/regex: ${workspace}
|
||||
codeql/ssa: 0.0.1
|
||||
dataExtensions:
|
||||
- codeql/ruby/frameworks/**/model.yml
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.4.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
ruby/ql/src/change-notes/released/0.4.6.md
Normal file
3
ruby/ql/src/change-notes/released/0.4.6.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.6
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.5
|
||||
lastReleaseVersion: 0.4.6
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/ruby-queries
|
||||
version: 0.4.6-dev
|
||||
version: 0.5.0-dev
|
||||
groups:
|
||||
- ruby
|
||||
- queries
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.dataflow.SSA
|
||||
import codeql.ruby.dataflow.internal.DataFlowDispatch
|
||||
|
||||
from DefLoc loc, Expr src, Expr target, string kind
|
||||
where
|
||||
@@ -38,7 +39,12 @@ newtype DefLoc =
|
||||
write = definitionOf(read.getAQualifiedName())
|
||||
} or
|
||||
/** A method call. */
|
||||
MethodLoc(MethodCall call, Method meth) { meth = call.getATarget() } or
|
||||
MethodLoc(MethodCall call, Method meth) {
|
||||
meth = call.getATarget()
|
||||
or
|
||||
// include implicit `initialize` calls
|
||||
meth = getInitializeTarget(call.getAControlFlowNode())
|
||||
} or
|
||||
/** A local variable. */
|
||||
LocalVariableLoc(VariableReadAccess read, VariableWriteAccess write) {
|
||||
exists(Ssa::WriteDefinition w |
|
||||
|
||||
@@ -92,26 +92,54 @@ edges
|
||||
| call_sensitivity.rb:92:35:92:35 | x : | call_sensitivity.rb:93:34:93:34 | x : |
|
||||
| call_sensitivity.rb:93:34:93:34 | x : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:93:34:93:34 | x : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:98:11:98:18 | call to taint : | call_sensitivity.rb:54:15:54:15 | x : |
|
||||
| call_sensitivity.rb:98:11:98:18 | call to taint : | call_sensitivity.rb:54:15:54:15 | x : |
|
||||
| call_sensitivity.rb:99:16:99:23 | call to taint : | call_sensitivity.rb:58:20:58:20 | x : |
|
||||
| call_sensitivity.rb:99:16:99:23 | call to taint : | call_sensitivity.rb:58:20:58:20 | x : |
|
||||
| call_sensitivity.rb:100:14:100:22 | call to taint : | call_sensitivity.rb:62:18:62:18 | y : |
|
||||
| call_sensitivity.rb:100:14:100:22 | call to taint : | call_sensitivity.rb:62:18:62:18 | y : |
|
||||
| call_sensitivity.rb:101:16:101:24 | call to taint : | call_sensitivity.rb:66:20:66:20 | x : |
|
||||
| call_sensitivity.rb:101:16:101:24 | call to taint : | call_sensitivity.rb:66:20:66:20 | x : |
|
||||
| call_sensitivity.rb:102:14:102:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:102:14:102:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:104:21:104:28 | call to taint : | call_sensitivity.rb:80:30:80:30 | x : |
|
||||
| call_sensitivity.rb:104:21:104:28 | call to taint : | call_sensitivity.rb:80:30:80:30 | x : |
|
||||
| call_sensitivity.rb:105:26:105:33 | call to taint : | call_sensitivity.rb:84:35:84:35 | x : |
|
||||
| call_sensitivity.rb:105:26:105:33 | call to taint : | call_sensitivity.rb:84:35:84:35 | x : |
|
||||
| call_sensitivity.rb:106:24:106:32 | call to taint : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:106:24:106:32 | call to taint : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:107:26:107:33 | call to taint : | call_sensitivity.rb:92:35:92:35 | x : |
|
||||
| call_sensitivity.rb:107:26:107:33 | call to taint : | call_sensitivity.rb:92:35:92:35 | x : |
|
||||
| call_sensitivity.rb:140:14:140:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:140:14:140:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:98:13:98:13 | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:98:13:98:13 | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:98:13:98:13 | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:98:13:98:13 | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:102:11:102:20 | ( ... ) : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:102:11:102:20 | ( ... ) : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:102:12:102:19 | call to taint : | call_sensitivity.rb:102:11:102:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:102:12:102:19 | call to taint : | call_sensitivity.rb:102:11:102:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:103:11:103:18 | call to taint : | call_sensitivity.rb:54:15:54:15 | x : |
|
||||
| call_sensitivity.rb:103:11:103:18 | call to taint : | call_sensitivity.rb:54:15:54:15 | x : |
|
||||
| call_sensitivity.rb:104:16:104:23 | call to taint : | call_sensitivity.rb:58:20:58:20 | x : |
|
||||
| call_sensitivity.rb:104:16:104:23 | call to taint : | call_sensitivity.rb:58:20:58:20 | x : |
|
||||
| call_sensitivity.rb:105:14:105:22 | call to taint : | call_sensitivity.rb:62:18:62:18 | y : |
|
||||
| call_sensitivity.rb:105:14:105:22 | call to taint : | call_sensitivity.rb:62:18:62:18 | y : |
|
||||
| call_sensitivity.rb:106:16:106:24 | call to taint : | call_sensitivity.rb:66:20:66:20 | x : |
|
||||
| call_sensitivity.rb:106:16:106:24 | call to taint : | call_sensitivity.rb:66:20:66:20 | x : |
|
||||
| call_sensitivity.rb:107:14:107:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:107:14:107:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:109:21:109:28 | call to taint : | call_sensitivity.rb:80:30:80:30 | x : |
|
||||
| call_sensitivity.rb:109:21:109:28 | call to taint : | call_sensitivity.rb:80:30:80:30 | x : |
|
||||
| call_sensitivity.rb:110:26:110:33 | call to taint : | call_sensitivity.rb:84:35:84:35 | x : |
|
||||
| call_sensitivity.rb:110:26:110:33 | call to taint : | call_sensitivity.rb:84:35:84:35 | x : |
|
||||
| call_sensitivity.rb:111:24:111:32 | call to taint : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:111:24:111:32 | call to taint : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:112:26:112:33 | call to taint : | call_sensitivity.rb:92:35:92:35 | x : |
|
||||
| call_sensitivity.rb:112:26:112:33 | call to taint : | call_sensitivity.rb:92:35:92:35 | x : |
|
||||
| call_sensitivity.rb:149:14:149:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:149:14:149:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:156:19:156:19 | x : | call_sensitivity.rb:157:12:157:12 | x : |
|
||||
| call_sensitivity.rb:156:19:156:19 | x : | call_sensitivity.rb:157:12:157:12 | x : |
|
||||
| call_sensitivity.rb:157:12:157:12 | x : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:157:12:157:12 | x : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:160:11:160:19 | call to taint : | call_sensitivity.rb:156:19:156:19 | x : |
|
||||
| call_sensitivity.rb:160:11:160:19 | call to taint : | call_sensitivity.rb:156:19:156:19 | x : |
|
||||
| call_sensitivity.rb:169:11:169:20 | ( ... ) : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:169:11:169:20 | ( ... ) : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:169:12:169:19 | call to taint : | call_sensitivity.rb:169:11:169:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:169:12:169:19 | call to taint : | call_sensitivity.rb:169:11:169:20 | ( ... ) : |
|
||||
nodes
|
||||
| call_sensitivity.rb:9:6:9:14 | ( ... ) | semmle.label | ( ... ) |
|
||||
| call_sensitivity.rb:9:6:9:14 | ( ... ) | semmle.label | ( ... ) |
|
||||
@@ -219,26 +247,52 @@ nodes
|
||||
| call_sensitivity.rb:92:35:92:35 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:93:34:93:34 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:93:34:93:34 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:98:11:98:18 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:98:11:98:18 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:99:16:99:23 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:99:16:99:23 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:100:14:100:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:100:14:100:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:101:16:101:24 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:101:16:101:24 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:102:14:102:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:102:14:102:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:104:21:104:28 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:104:21:104:28 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:105:26:105:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:105:26:105:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:106:24:106:32 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:106:24:106:32 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:107:26:107:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:107:26:107:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:140:14:140:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:140:14:140:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | semmle.label | x |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | semmle.label | x |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:102:11:102:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:102:11:102:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:102:12:102:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:102:12:102:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:103:11:103:18 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:103:11:103:18 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:104:16:104:23 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:104:16:104:23 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:105:14:105:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:105:14:105:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:106:16:106:24 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:106:16:106:24 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:107:14:107:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:107:14:107:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:109:21:109:28 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:109:21:109:28 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:110:26:110:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:110:26:110:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:111:24:111:32 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:111:24:111:32 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:112:26:112:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:112:26:112:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:149:14:149:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:149:14:149:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:156:19:156:19 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:156:19:156:19 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:157:12:157:12 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:157:12:157:12 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:160:11:160:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:160:11:160:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:169:11:169:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:169:11:169:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:169:12:169:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:169:12:169:19 | call to taint : | semmle.label | call to taint : |
|
||||
subpaths
|
||||
#select
|
||||
| call_sensitivity.rb:9:6:9:14 | ( ... ) | call_sensitivity.rb:9:7:9:13 | call to taint : | call_sensitivity.rb:9:6:9:14 | ( ... ) | $@ | call_sensitivity.rb:9:7:9:13 | call to taint : | call to taint : |
|
||||
@@ -246,16 +300,21 @@ subpaths
|
||||
| call_sensitivity.rb:31:27:31:27 | x | call_sensitivity.rb:32:25:32:32 | call to taint : | call_sensitivity.rb:31:27:31:27 | x | $@ | call_sensitivity.rb:32:25:32:32 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:40:31:40:31 | x | call_sensitivity.rb:41:25:41:32 | call to taint : | call_sensitivity.rb:40:31:40:31 | x | $@ | call_sensitivity.rb:41:25:41:32 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:43:32:43:32 | x | call_sensitivity.rb:44:26:44:33 | call to taint : | call_sensitivity.rb:43:32:43:32 | x | $@ | call_sensitivity.rb:44:26:44:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:98:11:98:18 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:98:11:98:18 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:99:16:99:23 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:99:16:99:23 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:100:14:100:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:100:14:100:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:101:16:101:24 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:101:16:101:24 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:102:14:102:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:102:14:102:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:140:14:140:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:140:14:140:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:104:21:104:28 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:104:21:104:28 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:105:26:105:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:105:26:105:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:106:24:106:32 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:106:24:106:32 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:107:26:107:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:107:26:107:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:102:12:102:19 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:102:12:102:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:103:11:103:18 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:103:11:103:18 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:104:16:104:23 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:104:16:104:23 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:105:14:105:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:105:14:105:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:106:16:106:24 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:106:16:106:24 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:107:14:107:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:107:14:107:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:149:14:149:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:149:14:149:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:160:11:160:19 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:160:11:160:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:109:21:109:28 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:109:21:109:28 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:110:26:110:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:110:26:110:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:111:24:111:32 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:111:24:111:32 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:112:26:112:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:112:26:112:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | call_sensitivity.rb:102:12:102:19 | call to taint : | call_sensitivity.rb:97:10:97:10 | x | $@ | call_sensitivity.rb:102:12:102:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | call_sensitivity.rb:160:11:160:19 | call to taint : | call_sensitivity.rb:97:10:97:10 | x | $@ | call_sensitivity.rb:160:11:160:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | call_sensitivity.rb:169:12:169:19 | call to taint : | call_sensitivity.rb:97:10:97:10 | x | $@ | call_sensitivity.rb:169:12:169:19 | call to taint : | call to taint : |
|
||||
mayBenefitFromCallContext
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
@@ -266,39 +325,54 @@ mayBenefitFromCallContext
|
||||
| call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:84:3:86:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:88:3:90:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:92:3:94:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:119:5:119:18 | call to method2 | call_sensitivity.rb:118:3:120:5 | call_method2 |
|
||||
| call_sensitivity.rb:123:5:123:25 | call to method3 | call_sensitivity.rb:122:3:124:5 | call_method3 |
|
||||
| call_sensitivity.rb:127:5:127:28 | call to singleton_method2 | call_sensitivity.rb:126:3:128:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:131:5:131:35 | call to singleton_method3 | call_sensitivity.rb:130:3:132:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:97:5:97:10 | call to sink | call_sensitivity.rb:96:3:99:5 | initialize |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:96:3:99:5 | initialize |
|
||||
| call_sensitivity.rb:124:5:124:18 | call to method2 | call_sensitivity.rb:123:3:125:5 | call_method2 |
|
||||
| call_sensitivity.rb:128:5:128:25 | call to method3 | call_sensitivity.rb:127:3:129:5 | call_method3 |
|
||||
| call_sensitivity.rb:132:5:132:28 | call to singleton_method2 | call_sensitivity.rb:131:3:133:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:136:5:136:35 | call to singleton_method3 | call_sensitivity.rb:135:3:137:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:156:1:158:3 | create |
|
||||
viableImplInCallContext
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:76:7:76:18 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:110:3:112:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:98:1:98:19 | call to method2 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:119:5:119:18 | call to method2 | call_sensitivity.rb:110:3:112:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:136:1:136:19 | call to method2 | call_sensitivity.rb:110:3:112:5 | method1 |
|
||||
| call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:99:1:99:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:164:3:166:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:103:1:103:19 | call to method2 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:124:5:124:18 | call to method2 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:145:1:145:19 | call to method2 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:104:1:104:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:110:3:112:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:100:1:100:23 | call to method3 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:123:5:123:25 | call to method3 | call_sensitivity.rb:110:3:112:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:138:1:138:23 | call to method3 | call_sensitivity.rb:110:3:112:5 | method1 |
|
||||
| call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:101:1:101:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:164:3:166:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:105:1:105:23 | call to method3 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:128:5:128:25 | call to method3 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:147:1:147:23 | call to method3 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:106:1:106:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:114:3:116:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:104:1:104:29 | call to singleton_method2 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:127:5:127:28 | call to singleton_method2 | call_sensitivity.rb:114:3:116:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:142:1:142:29 | call to singleton_method2 | call_sensitivity.rb:114:3:116:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:105:1:105:34 | call to call_singleton_method2 | call_sensitivity.rb:80:3:82:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:109:1:109:29 | call to singleton_method2 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:132:5:132:28 | call to singleton_method2 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:151:1:151:29 | call to singleton_method2 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:110:1:110:34 | call to call_singleton_method2 | call_sensitivity.rb:80:3:82:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:114:3:116:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:106:1:106:33 | call to singleton_method3 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:131:5:131:35 | call to singleton_method3 | call_sensitivity.rb:114:3:116:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:144:1:144:33 | call to singleton_method3 | call_sensitivity.rb:114:3:116:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:107:1:107:34 | call to call_singleton_method3 | call_sensitivity.rb:88:3:90:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:119:5:119:18 | call to method2 | call_sensitivity.rb:137:1:137:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:123:5:123:25 | call to method3 | call_sensitivity.rb:139:1:139:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:127:5:127:28 | call to singleton_method2 | call_sensitivity.rb:143:1:143:34 | call to call_singleton_method2 | call_sensitivity.rb:80:3:82:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:131:5:131:35 | call to singleton_method3 | call_sensitivity.rb:145:1:145:34 | call to call_singleton_method3 | call_sensitivity.rb:88:3:90:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:111:1:111:33 | call to singleton_method3 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:136:5:136:35 | call to singleton_method3 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:153:1:153:33 | call to singleton_method3 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:112:1:112:34 | call to call_singleton_method3 | call_sensitivity.rb:88:3:90:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:97:5:97:10 | call to sink | call_sensitivity.rb:102:5:102:20 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:97:5:97:10 | call to sink | call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:97:5:97:10 | call to sink | call_sensitivity.rb:169:5:169:20 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:102:5:102:20 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:169:5:169:20 | call to new | call_sensitivity.rb:164:3:166:5 | method1 |
|
||||
| call_sensitivity.rb:124:5:124:18 | call to method2 | call_sensitivity.rb:146:1:146:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:128:5:128:25 | call to method3 | call_sensitivity.rb:148:1:148:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:132:5:132:28 | call to singleton_method2 | call_sensitivity.rb:152:1:152:34 | call to call_singleton_method2 | call_sensitivity.rb:80:3:82:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:136:5:136:35 | call to singleton_method3 | call_sensitivity.rb:154:1:154:34 | call to call_singleton_method3 | call_sensitivity.rb:88:3:90:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:160:1:160:20 | call to create | call_sensitivity.rb:96:3:99:5 | initialize |
|
||||
| call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:161:1:161:20 | call to create | call_sensitivity.rb:139:3:141:5 | initialize |
|
||||
|
||||
@@ -48,7 +48,7 @@ apply_lambda(MY_LAMBDA2, taint(9))
|
||||
|
||||
class A
|
||||
def method1 x
|
||||
sink x # $ hasValueFlow=10 $ hasValueFlow=11 $ hasValueFlow=12 $ hasValueFlow=13 $ hasValueFlow=26 $ SPURIOUS: hasValueFlow=27
|
||||
sink x # $ hasValueFlow=10 $ hasValueFlow=11 $ hasValueFlow=12 $ hasValueFlow=13 $ hasValueFlow=26 $ hasValueFlow=28 $ hasValueFlow=30 $ SPURIOUS: hasValueFlow=27
|
||||
end
|
||||
|
||||
def method2 x
|
||||
@@ -92,9 +92,14 @@ class A
|
||||
def self.call_singleton_method3 x
|
||||
self.singleton_method3(self, x)
|
||||
end
|
||||
|
||||
def initialize(x)
|
||||
sink x # $ hasValueFlow=28 $ hasValueFlow=30 $ hasValueFlow=32
|
||||
method1 x
|
||||
end
|
||||
end
|
||||
|
||||
a = A.new
|
||||
a = A.new (taint 30)
|
||||
a.method2(taint 10)
|
||||
a.call_method2(taint 11)
|
||||
a.method3(a, taint(12))
|
||||
@@ -130,9 +135,13 @@ class B < A
|
||||
def self.call_singleton_method3 x
|
||||
self.singleton_method3(self, x)
|
||||
end
|
||||
|
||||
def initialize(x)
|
||||
puts "NON SINK: #{x}"
|
||||
end
|
||||
end
|
||||
|
||||
b = B.new
|
||||
b = B.new (taint 31)
|
||||
b.method2(taint 18)
|
||||
b.call_method2(taint 19)
|
||||
b.method3(b, taint(20))
|
||||
@@ -143,3 +152,18 @@ B.singleton_method2(taint 22)
|
||||
B.call_singleton_method2(taint 23)
|
||||
B.singleton_method3(B, taint(24))
|
||||
B.call_singleton_method3(taint 25)
|
||||
|
||||
def create (type, x)
|
||||
type.new x
|
||||
end
|
||||
|
||||
create(A, taint(28))
|
||||
create(B, taint(29))
|
||||
|
||||
class C < A
|
||||
def method1 x
|
||||
puts "NON SINK: #{x}"
|
||||
end
|
||||
end
|
||||
|
||||
c = C.new (taint 32)
|
||||
|
||||
@@ -30,139 +30,177 @@ edges
|
||||
| instance_variables.rb:19:12:19:21 | call to taint : | instance_variables.rb:19:5:19:8 | [post] self [@foo] : |
|
||||
| instance_variables.rb:20:10:20:13 | self [@foo] : | instance_variables.rb:20:10:20:13 | @foo |
|
||||
| instance_variables.rb:20:10:20:13 | self [@foo] : | instance_variables.rb:20:10:20:13 | @foo |
|
||||
| instance_variables.rb:24:1:24:3 | [post] foo [@field] : | instance_variables.rb:25:6:25:8 | foo [@field] : |
|
||||
| instance_variables.rb:24:1:24:3 | [post] foo [@field] : | instance_variables.rb:25:6:25:8 | foo [@field] : |
|
||||
| instance_variables.rb:24:15:24:23 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:24:15:24:23 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:24:15:24:23 | call to taint : | instance_variables.rb:24:1:24:3 | [post] foo [@field] : |
|
||||
| instance_variables.rb:24:15:24:23 | call to taint : | instance_variables.rb:24:1:24:3 | [post] foo [@field] : |
|
||||
| instance_variables.rb:25:6:25:8 | foo [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:25:6:25:8 | foo [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:25:6:25:8 | foo [@field] : | instance_variables.rb:25:6:25:18 | call to get_field |
|
||||
| instance_variables.rb:25:6:25:8 | foo [@field] : | instance_variables.rb:25:6:25:18 | call to get_field |
|
||||
| instance_variables.rb:28:1:28:3 | [post] bar [@field] : | instance_variables.rb:29:6:29:8 | bar [@field] : |
|
||||
| instance_variables.rb:28:15:28:22 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:28:15:28:22 | call to taint : | instance_variables.rb:28:1:28:3 | [post] bar [@field] : |
|
||||
| instance_variables.rb:29:6:29:8 | bar [@field] : | instance_variables.rb:16:5:18:7 | self in inc_field [@field] : |
|
||||
| instance_variables.rb:29:6:29:8 | bar [@field] : | instance_variables.rb:29:6:29:18 | call to inc_field |
|
||||
| instance_variables.rb:32:1:32:4 | [post] foo1 [@field] : | instance_variables.rb:33:6:33:9 | foo1 [@field] : |
|
||||
| instance_variables.rb:32:1:32:4 | [post] foo1 [@field] : | instance_variables.rb:33:6:33:9 | foo1 [@field] : |
|
||||
| instance_variables.rb:32:14:32:22 | call to taint : | instance_variables.rb:32:1:32:4 | [post] foo1 [@field] : |
|
||||
| instance_variables.rb:32:14:32:22 | call to taint : | instance_variables.rb:32:1:32:4 | [post] foo1 [@field] : |
|
||||
| instance_variables.rb:33:6:33:9 | foo1 [@field] : | instance_variables.rb:33:6:33:15 | call to field |
|
||||
| instance_variables.rb:33:6:33:9 | foo1 [@field] : | instance_variables.rb:33:6:33:15 | call to field |
|
||||
| instance_variables.rb:36:1:36:4 | [post] foo2 [@field] : | instance_variables.rb:37:6:37:9 | foo2 [@field] : |
|
||||
| instance_variables.rb:36:1:36:4 | [post] foo2 [@field] : | instance_variables.rb:37:6:37:9 | foo2 [@field] : |
|
||||
| instance_variables.rb:36:14:36:22 | call to taint : | instance_variables.rb:36:1:36:4 | [post] foo2 [@field] : |
|
||||
| instance_variables.rb:36:14:36:22 | call to taint : | instance_variables.rb:36:1:36:4 | [post] foo2 [@field] : |
|
||||
| instance_variables.rb:37:6:37:9 | foo2 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:37:6:37:9 | foo2 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:37:6:37:9 | foo2 [@field] : | instance_variables.rb:37:6:37:19 | call to get_field |
|
||||
| instance_variables.rb:37:6:37:9 | foo2 [@field] : | instance_variables.rb:37:6:37:19 | call to get_field |
|
||||
| instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : | instance_variables.rb:41:6:41:9 | foo3 [@field] : |
|
||||
| instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : | instance_variables.rb:41:6:41:9 | foo3 [@field] : |
|
||||
| instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : | instance_variables.rb:53:6:53:9 | foo3 [@field] : |
|
||||
| instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : | instance_variables.rb:53:6:53:9 | foo3 [@field] : |
|
||||
| instance_variables.rb:40:16:40:24 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:40:16:40:24 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:40:16:40:24 | call to taint : | instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:40:16:40:24 | call to taint : | instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:41:6:41:9 | foo3 [@field] : | instance_variables.rb:41:6:41:15 | call to field |
|
||||
| instance_variables.rb:41:6:41:9 | foo3 [@field] : | instance_variables.rb:41:6:41:15 | call to field |
|
||||
| instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : | instance_variables.rb:49:6:49:9 | foo5 [@field] : |
|
||||
| instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : | instance_variables.rb:49:6:49:9 | foo5 [@field] : |
|
||||
| instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : | instance_variables.rb:54:6:54:9 | foo5 [@field] : |
|
||||
| instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : | instance_variables.rb:54:6:54:9 | foo5 [@field] : |
|
||||
| instance_variables.rb:48:18:48:26 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:48:18:48:26 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:48:18:48:26 | call to taint : | instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:48:18:48:26 | call to taint : | instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:49:6:49:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:49:6:49:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:49:6:49:9 | foo5 [@field] : | instance_variables.rb:49:6:49:19 | call to get_field |
|
||||
| instance_variables.rb:49:6:49:9 | foo5 [@field] : | instance_variables.rb:49:6:49:19 | call to get_field |
|
||||
| instance_variables.rb:52:15:52:18 | [post] foo6 [@field] : | instance_variables.rb:55:6:55:9 | foo6 [@field] : |
|
||||
| instance_variables.rb:52:15:52:18 | [post] foo6 [@field] : | instance_variables.rb:55:6:55:9 | foo6 [@field] : |
|
||||
| instance_variables.rb:52:32:52:40 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:52:32:52:40 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:52:32:52:40 | call to taint : | instance_variables.rb:52:15:52:18 | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:52:32:52:40 | call to taint : | instance_variables.rb:52:15:52:18 | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:53:6:53:9 | foo3 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:53:6:53:9 | foo3 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:53:6:53:9 | foo3 [@field] : | instance_variables.rb:53:6:53:19 | call to get_field |
|
||||
| instance_variables.rb:53:6:53:9 | foo3 [@field] : | instance_variables.rb:53:6:53:19 | call to get_field |
|
||||
| instance_variables.rb:54:6:54:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:54:6:54:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:54:6:54:9 | foo5 [@field] : | instance_variables.rb:54:6:54:19 | call to get_field |
|
||||
| instance_variables.rb:54:6:54:9 | foo5 [@field] : | instance_variables.rb:54:6:54:19 | call to get_field |
|
||||
| instance_variables.rb:55:6:55:9 | foo6 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:55:6:55:9 | foo6 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:55:6:55:9 | foo6 [@field] : | instance_variables.rb:55:6:55:19 | call to get_field |
|
||||
| instance_variables.rb:55:6:55:9 | foo6 [@field] : | instance_variables.rb:55:6:55:19 | call to get_field |
|
||||
| instance_variables.rb:59:15:59:18 | [post] foo7 [@field] : | instance_variables.rb:60:6:60:9 | foo7 [@field] : |
|
||||
| instance_variables.rb:59:15:59:18 | [post] foo7 [@field] : | instance_variables.rb:60:6:60:9 | foo7 [@field] : |
|
||||
| instance_variables.rb:59:25:59:28 | [post] foo8 [@field] : | instance_variables.rb:61:6:61:9 | foo8 [@field] : |
|
||||
| instance_variables.rb:59:25:59:28 | [post] foo8 [@field] : | instance_variables.rb:61:6:61:9 | foo8 [@field] : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:59:15:59:18 | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:59:15:59:18 | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:59:25:59:28 | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:59:25:59:28 | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:60:6:60:9 | foo7 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:60:6:60:9 | foo7 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:60:6:60:9 | foo7 [@field] : | instance_variables.rb:60:6:60:19 | call to get_field |
|
||||
| instance_variables.rb:60:6:60:9 | foo7 [@field] : | instance_variables.rb:60:6:60:19 | call to get_field |
|
||||
| instance_variables.rb:61:6:61:9 | foo8 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:61:6:61:9 | foo8 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:61:6:61:9 | foo8 [@field] : | instance_variables.rb:61:6:61:19 | call to get_field |
|
||||
| instance_variables.rb:61:6:61:9 | foo8 [@field] : | instance_variables.rb:61:6:61:19 | call to get_field |
|
||||
| instance_variables.rb:65:22:65:25 | [post] foo9 [@field] : | instance_variables.rb:66:6:66:9 | foo9 [@field] : |
|
||||
| instance_variables.rb:65:22:65:25 | [post] foo9 [@field] : | instance_variables.rb:66:6:66:9 | foo9 [@field] : |
|
||||
| instance_variables.rb:65:32:65:36 | [post] foo10 [@field] : | instance_variables.rb:67:6:67:10 | foo10 [@field] : |
|
||||
| instance_variables.rb:65:32:65:36 | [post] foo10 [@field] : | instance_variables.rb:67:6:67:10 | foo10 [@field] : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:65:22:65:25 | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:65:22:65:25 | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:65:32:65:36 | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:65:32:65:36 | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:66:6:66:9 | foo9 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:66:6:66:9 | foo9 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:66:6:66:9 | foo9 [@field] : | instance_variables.rb:66:6:66:19 | call to get_field |
|
||||
| instance_variables.rb:66:6:66:9 | foo9 [@field] : | instance_variables.rb:66:6:66:19 | call to get_field |
|
||||
| instance_variables.rb:67:6:67:10 | foo10 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:67:6:67:10 | foo10 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:67:6:67:10 | foo10 [@field] : | instance_variables.rb:67:6:67:20 | call to get_field |
|
||||
| instance_variables.rb:67:6:67:10 | foo10 [@field] : | instance_variables.rb:67:6:67:20 | call to get_field |
|
||||
| instance_variables.rb:70:5:70:5 | [post] x [@field] : | instance_variables.rb:74:14:74:18 | [post] foo11 [@field] : |
|
||||
| instance_variables.rb:70:5:70:5 | [post] x [@field] : | instance_variables.rb:74:14:74:18 | [post] foo11 [@field] : |
|
||||
| instance_variables.rb:70:5:70:5 | [post] x [@field] : | instance_variables.rb:78:15:78:19 | [post] foo12 [@field] : |
|
||||
| instance_variables.rb:70:5:70:5 | [post] x [@field] : | instance_variables.rb:78:15:78:19 | [post] foo12 [@field] : |
|
||||
| instance_variables.rb:70:5:70:5 | [post] x [@field] : | instance_variables.rb:83:22:83:26 | [post] foo13 [@field] : |
|
||||
| instance_variables.rb:70:5:70:5 | [post] x [@field] : | instance_variables.rb:83:22:83:26 | [post] foo13 [@field] : |
|
||||
| instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:70:5:70:5 | [post] x [@field] : |
|
||||
| instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:70:5:70:5 | [post] x [@field] : |
|
||||
| instance_variables.rb:74:14:74:18 | [post] foo11 [@field] : | instance_variables.rb:75:6:75:10 | foo11 [@field] : |
|
||||
| instance_variables.rb:74:14:74:18 | [post] foo11 [@field] : | instance_variables.rb:75:6:75:10 | foo11 [@field] : |
|
||||
| instance_variables.rb:75:6:75:10 | foo11 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:75:6:75:10 | foo11 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:75:6:75:10 | foo11 [@field] : | instance_variables.rb:75:6:75:20 | call to get_field |
|
||||
| instance_variables.rb:75:6:75:10 | foo11 [@field] : | instance_variables.rb:75:6:75:20 | call to get_field |
|
||||
| instance_variables.rb:78:15:78:19 | [post] foo12 [@field] : | instance_variables.rb:79:6:79:10 | foo12 [@field] : |
|
||||
| instance_variables.rb:78:15:78:19 | [post] foo12 [@field] : | instance_variables.rb:79:6:79:10 | foo12 [@field] : |
|
||||
| instance_variables.rb:79:6:79:10 | foo12 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:79:6:79:10 | foo12 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:79:6:79:10 | foo12 [@field] : | instance_variables.rb:79:6:79:20 | call to get_field |
|
||||
| instance_variables.rb:79:6:79:10 | foo12 [@field] : | instance_variables.rb:79:6:79:20 | call to get_field |
|
||||
| instance_variables.rb:83:22:83:26 | [post] foo13 [@field] : | instance_variables.rb:84:6:84:10 | foo13 [@field] : |
|
||||
| instance_variables.rb:83:22:83:26 | [post] foo13 [@field] : | instance_variables.rb:84:6:84:10 | foo13 [@field] : |
|
||||
| instance_variables.rb:84:6:84:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:84:6:84:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:84:6:84:10 | foo13 [@field] : | instance_variables.rb:84:6:84:20 | call to get_field |
|
||||
| instance_variables.rb:84:6:84:10 | foo13 [@field] : | instance_variables.rb:84:6:84:20 | call to get_field |
|
||||
| instance_variables.rb:22:20:22:24 | field : | instance_variables.rb:23:18:23:22 | field : |
|
||||
| instance_variables.rb:22:20:22:24 | field : | instance_variables.rb:23:18:23:22 | field : |
|
||||
| instance_variables.rb:23:18:23:22 | field : | instance_variables.rb:23:9:23:14 | [post] self [@field] : |
|
||||
| instance_variables.rb:23:18:23:22 | field : | instance_variables.rb:23:9:23:14 | [post] self [@field] : |
|
||||
| instance_variables.rb:24:9:24:17 | call to taint : | instance_variables.rb:28:9:28:25 | call to initialize : |
|
||||
| instance_variables.rb:24:9:24:17 | call to taint : | instance_variables.rb:28:9:28:25 | call to initialize : |
|
||||
| instance_variables.rb:27:25:27:29 | field : | instance_variables.rb:28:20:28:24 | field : |
|
||||
| instance_variables.rb:27:25:27:29 | field : | instance_variables.rb:28:20:28:24 | field : |
|
||||
| instance_variables.rb:28:9:28:25 | call to initialize : | instance_variables.rb:104:6:104:37 | call to call_initialize |
|
||||
| instance_variables.rb:28:9:28:25 | call to initialize : | instance_variables.rb:104:6:104:37 | call to call_initialize |
|
||||
| instance_variables.rb:28:20:28:24 | field : | instance_variables.rb:22:20:22:24 | field : |
|
||||
| instance_variables.rb:28:20:28:24 | field : | instance_variables.rb:22:20:22:24 | field : |
|
||||
| instance_variables.rb:28:20:28:24 | field : | instance_variables.rb:28:9:28:25 | [post] self [@field] : |
|
||||
| instance_variables.rb:28:20:28:24 | field : | instance_variables.rb:28:9:28:25 | [post] self [@field] : |
|
||||
| instance_variables.rb:34:9:34:17 | call to taint : | instance_variables.rb:106:7:106:24 | call to new : |
|
||||
| instance_variables.rb:34:9:34:17 | call to taint : | instance_variables.rb:106:7:106:24 | call to new : |
|
||||
| instance_variables.rb:39:1:39:3 | [post] foo [@field] : | instance_variables.rb:40:6:40:8 | foo [@field] : |
|
||||
| instance_variables.rb:39:1:39:3 | [post] foo [@field] : | instance_variables.rb:40:6:40:8 | foo [@field] : |
|
||||
| instance_variables.rb:39:15:39:23 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:39:15:39:23 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:39:15:39:23 | call to taint : | instance_variables.rb:39:1:39:3 | [post] foo [@field] : |
|
||||
| instance_variables.rb:39:15:39:23 | call to taint : | instance_variables.rb:39:1:39:3 | [post] foo [@field] : |
|
||||
| instance_variables.rb:40:6:40:8 | foo [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:40:6:40:8 | foo [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:40:6:40:8 | foo [@field] : | instance_variables.rb:40:6:40:18 | call to get_field |
|
||||
| instance_variables.rb:40:6:40:8 | foo [@field] : | instance_variables.rb:40:6:40:18 | call to get_field |
|
||||
| instance_variables.rb:43:1:43:3 | [post] bar [@field] : | instance_variables.rb:44:6:44:8 | bar [@field] : |
|
||||
| instance_variables.rb:43:15:43:22 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:43:15:43:22 | call to taint : | instance_variables.rb:43:1:43:3 | [post] bar [@field] : |
|
||||
| instance_variables.rb:44:6:44:8 | bar [@field] : | instance_variables.rb:16:5:18:7 | self in inc_field [@field] : |
|
||||
| instance_variables.rb:44:6:44:8 | bar [@field] : | instance_variables.rb:44:6:44:18 | call to inc_field |
|
||||
| instance_variables.rb:47:1:47:4 | [post] foo1 [@field] : | instance_variables.rb:48:6:48:9 | foo1 [@field] : |
|
||||
| instance_variables.rb:47:1:47:4 | [post] foo1 [@field] : | instance_variables.rb:48:6:48:9 | foo1 [@field] : |
|
||||
| instance_variables.rb:47:14:47:22 | call to taint : | instance_variables.rb:47:1:47:4 | [post] foo1 [@field] : |
|
||||
| instance_variables.rb:47:14:47:22 | call to taint : | instance_variables.rb:47:1:47:4 | [post] foo1 [@field] : |
|
||||
| instance_variables.rb:48:6:48:9 | foo1 [@field] : | instance_variables.rb:48:6:48:15 | call to field |
|
||||
| instance_variables.rb:48:6:48:9 | foo1 [@field] : | instance_variables.rb:48:6:48:15 | call to field |
|
||||
| instance_variables.rb:51:1:51:4 | [post] foo2 [@field] : | instance_variables.rb:52:6:52:9 | foo2 [@field] : |
|
||||
| instance_variables.rb:51:1:51:4 | [post] foo2 [@field] : | instance_variables.rb:52:6:52:9 | foo2 [@field] : |
|
||||
| instance_variables.rb:51:14:51:22 | call to taint : | instance_variables.rb:51:1:51:4 | [post] foo2 [@field] : |
|
||||
| instance_variables.rb:51:14:51:22 | call to taint : | instance_variables.rb:51:1:51:4 | [post] foo2 [@field] : |
|
||||
| instance_variables.rb:52:6:52:9 | foo2 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:52:6:52:9 | foo2 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:52:6:52:9 | foo2 [@field] : | instance_variables.rb:52:6:52:19 | call to get_field |
|
||||
| instance_variables.rb:52:6:52:9 | foo2 [@field] : | instance_variables.rb:52:6:52:19 | call to get_field |
|
||||
| instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : | instance_variables.rb:56:6:56:9 | foo3 [@field] : |
|
||||
| instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : | instance_variables.rb:56:6:56:9 | foo3 [@field] : |
|
||||
| instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : | instance_variables.rb:68:6:68:9 | foo3 [@field] : |
|
||||
| instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : | instance_variables.rb:68:6:68:9 | foo3 [@field] : |
|
||||
| instance_variables.rb:55:16:55:24 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:55:16:55:24 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:55:16:55:24 | call to taint : | instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:55:16:55:24 | call to taint : | instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:56:6:56:9 | foo3 [@field] : | instance_variables.rb:56:6:56:15 | call to field |
|
||||
| instance_variables.rb:56:6:56:9 | foo3 [@field] : | instance_variables.rb:56:6:56:15 | call to field |
|
||||
| instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : | instance_variables.rb:64:6:64:9 | foo5 [@field] : |
|
||||
| instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : | instance_variables.rb:64:6:64:9 | foo5 [@field] : |
|
||||
| instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : | instance_variables.rb:69:6:69:9 | foo5 [@field] : |
|
||||
| instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : | instance_variables.rb:69:6:69:9 | foo5 [@field] : |
|
||||
| instance_variables.rb:63:18:63:26 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:63:18:63:26 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:63:18:63:26 | call to taint : | instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:63:18:63:26 | call to taint : | instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:64:6:64:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:64:6:64:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:64:6:64:9 | foo5 [@field] : | instance_variables.rb:64:6:64:19 | call to get_field |
|
||||
| instance_variables.rb:64:6:64:9 | foo5 [@field] : | instance_variables.rb:64:6:64:19 | call to get_field |
|
||||
| instance_variables.rb:67:15:67:18 | [post] foo6 [@field] : | instance_variables.rb:70:6:70:9 | foo6 [@field] : |
|
||||
| instance_variables.rb:67:15:67:18 | [post] foo6 [@field] : | instance_variables.rb:70:6:70:9 | foo6 [@field] : |
|
||||
| instance_variables.rb:67:32:67:40 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:67:32:67:40 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:67:32:67:40 | call to taint : | instance_variables.rb:67:15:67:18 | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:67:32:67:40 | call to taint : | instance_variables.rb:67:15:67:18 | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:68:6:68:9 | foo3 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:68:6:68:9 | foo3 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:68:6:68:9 | foo3 [@field] : | instance_variables.rb:68:6:68:19 | call to get_field |
|
||||
| instance_variables.rb:68:6:68:9 | foo3 [@field] : | instance_variables.rb:68:6:68:19 | call to get_field |
|
||||
| instance_variables.rb:69:6:69:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:69:6:69:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:69:6:69:9 | foo5 [@field] : | instance_variables.rb:69:6:69:19 | call to get_field |
|
||||
| instance_variables.rb:69:6:69:9 | foo5 [@field] : | instance_variables.rb:69:6:69:19 | call to get_field |
|
||||
| instance_variables.rb:70:6:70:9 | foo6 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:70:6:70:9 | foo6 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:70:6:70:9 | foo6 [@field] : | instance_variables.rb:70:6:70:19 | call to get_field |
|
||||
| instance_variables.rb:70:6:70:9 | foo6 [@field] : | instance_variables.rb:70:6:70:19 | call to get_field |
|
||||
| instance_variables.rb:74:15:74:18 | [post] foo7 [@field] : | instance_variables.rb:75:6:75:9 | foo7 [@field] : |
|
||||
| instance_variables.rb:74:15:74:18 | [post] foo7 [@field] : | instance_variables.rb:75:6:75:9 | foo7 [@field] : |
|
||||
| instance_variables.rb:74:25:74:28 | [post] foo8 [@field] : | instance_variables.rb:76:6:76:9 | foo8 [@field] : |
|
||||
| instance_variables.rb:74:25:74:28 | [post] foo8 [@field] : | instance_variables.rb:76:6:76:9 | foo8 [@field] : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:74:15:74:18 | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:74:15:74:18 | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:74:25:74:28 | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:74:25:74:28 | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:75:6:75:9 | foo7 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:75:6:75:9 | foo7 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:75:6:75:9 | foo7 [@field] : | instance_variables.rb:75:6:75:19 | call to get_field |
|
||||
| instance_variables.rb:75:6:75:9 | foo7 [@field] : | instance_variables.rb:75:6:75:19 | call to get_field |
|
||||
| instance_variables.rb:76:6:76:9 | foo8 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:76:6:76:9 | foo8 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:76:6:76:9 | foo8 [@field] : | instance_variables.rb:76:6:76:19 | call to get_field |
|
||||
| instance_variables.rb:76:6:76:9 | foo8 [@field] : | instance_variables.rb:76:6:76:19 | call to get_field |
|
||||
| instance_variables.rb:80:22:80:25 | [post] foo9 [@field] : | instance_variables.rb:81:6:81:9 | foo9 [@field] : |
|
||||
| instance_variables.rb:80:22:80:25 | [post] foo9 [@field] : | instance_variables.rb:81:6:81:9 | foo9 [@field] : |
|
||||
| instance_variables.rb:80:32:80:36 | [post] foo10 [@field] : | instance_variables.rb:82:6:82:10 | foo10 [@field] : |
|
||||
| instance_variables.rb:80:32:80:36 | [post] foo10 [@field] : | instance_variables.rb:82:6:82:10 | foo10 [@field] : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:80:22:80:25 | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:80:22:80:25 | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:80:32:80:36 | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:80:32:80:36 | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:81:6:81:9 | foo9 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:81:6:81:9 | foo9 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:81:6:81:9 | foo9 [@field] : | instance_variables.rb:81:6:81:19 | call to get_field |
|
||||
| instance_variables.rb:81:6:81:9 | foo9 [@field] : | instance_variables.rb:81:6:81:19 | call to get_field |
|
||||
| instance_variables.rb:82:6:82:10 | foo10 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:82:6:82:10 | foo10 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:82:6:82:10 | foo10 [@field] : | instance_variables.rb:82:6:82:20 | call to get_field |
|
||||
| instance_variables.rb:82:6:82:10 | foo10 [@field] : | instance_variables.rb:82:6:82:20 | call to get_field |
|
||||
| instance_variables.rb:85:5:85:5 | [post] x [@field] : | instance_variables.rb:89:14:89:18 | [post] foo11 [@field] : |
|
||||
| instance_variables.rb:85:5:85:5 | [post] x [@field] : | instance_variables.rb:89:14:89:18 | [post] foo11 [@field] : |
|
||||
| instance_variables.rb:85:5:85:5 | [post] x [@field] : | instance_variables.rb:93:15:93:19 | [post] foo12 [@field] : |
|
||||
| instance_variables.rb:85:5:85:5 | [post] x [@field] : | instance_variables.rb:93:15:93:19 | [post] foo12 [@field] : |
|
||||
| instance_variables.rb:85:5:85:5 | [post] x [@field] : | instance_variables.rb:98:22:98:26 | [post] foo13 [@field] : |
|
||||
| instance_variables.rb:85:5:85:5 | [post] x [@field] : | instance_variables.rb:98:22:98:26 | [post] foo13 [@field] : |
|
||||
| instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:10:19:10:19 | x : |
|
||||
| instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:85:5:85:5 | [post] x [@field] : |
|
||||
| instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:85:5:85:5 | [post] x [@field] : |
|
||||
| instance_variables.rb:89:14:89:18 | [post] foo11 [@field] : | instance_variables.rb:90:6:90:10 | foo11 [@field] : |
|
||||
| instance_variables.rb:89:14:89:18 | [post] foo11 [@field] : | instance_variables.rb:90:6:90:10 | foo11 [@field] : |
|
||||
| instance_variables.rb:90:6:90:10 | foo11 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:90:6:90:10 | foo11 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:90:6:90:10 | foo11 [@field] : | instance_variables.rb:90:6:90:20 | call to get_field |
|
||||
| instance_variables.rb:90:6:90:10 | foo11 [@field] : | instance_variables.rb:90:6:90:20 | call to get_field |
|
||||
| instance_variables.rb:93:15:93:19 | [post] foo12 [@field] : | instance_variables.rb:94:6:94:10 | foo12 [@field] : |
|
||||
| instance_variables.rb:93:15:93:19 | [post] foo12 [@field] : | instance_variables.rb:94:6:94:10 | foo12 [@field] : |
|
||||
| instance_variables.rb:94:6:94:10 | foo12 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:94:6:94:10 | foo12 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:94:6:94:10 | foo12 [@field] : | instance_variables.rb:94:6:94:20 | call to get_field |
|
||||
| instance_variables.rb:94:6:94:10 | foo12 [@field] : | instance_variables.rb:94:6:94:20 | call to get_field |
|
||||
| instance_variables.rb:98:22:98:26 | [post] foo13 [@field] : | instance_variables.rb:99:6:99:10 | foo13 [@field] : |
|
||||
| instance_variables.rb:98:22:98:26 | [post] foo13 [@field] : | instance_variables.rb:99:6:99:10 | foo13 [@field] : |
|
||||
| instance_variables.rb:99:6:99:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:99:6:99:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:99:6:99:10 | foo13 [@field] : | instance_variables.rb:99:6:99:20 | call to get_field |
|
||||
| instance_variables.rb:99:6:99:10 | foo13 [@field] : | instance_variables.rb:99:6:99:20 | call to get_field |
|
||||
| instance_variables.rb:101:9:101:26 | call to new [@field] : | instance_variables.rb:102:6:102:10 | foo15 [@field] : |
|
||||
| instance_variables.rb:101:9:101:26 | call to new [@field] : | instance_variables.rb:102:6:102:10 | foo15 [@field] : |
|
||||
| instance_variables.rb:101:17:101:25 | call to taint : | instance_variables.rb:22:20:22:24 | field : |
|
||||
| instance_variables.rb:101:17:101:25 | call to taint : | instance_variables.rb:22:20:22:24 | field : |
|
||||
| instance_variables.rb:101:17:101:25 | call to taint : | instance_variables.rb:101:9:101:26 | call to new [@field] : |
|
||||
| instance_variables.rb:101:17:101:25 | call to taint : | instance_variables.rb:101:9:101:26 | call to new [@field] : |
|
||||
| instance_variables.rb:102:6:102:10 | foo15 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:102:6:102:10 | foo15 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:102:6:102:10 | foo15 [@field] : | instance_variables.rb:102:6:102:20 | call to get_field |
|
||||
| instance_variables.rb:102:6:102:10 | foo15 [@field] : | instance_variables.rb:102:6:102:20 | call to get_field |
|
||||
| instance_variables.rb:104:6:104:10 | [post] foo16 [@field] : | instance_variables.rb:105:6:105:10 | foo16 [@field] : |
|
||||
| instance_variables.rb:104:6:104:10 | [post] foo16 [@field] : | instance_variables.rb:105:6:105:10 | foo16 [@field] : |
|
||||
| instance_variables.rb:104:28:104:36 | call to taint : | instance_variables.rb:27:25:27:29 | field : |
|
||||
| instance_variables.rb:104:28:104:36 | call to taint : | instance_variables.rb:27:25:27:29 | field : |
|
||||
| instance_variables.rb:104:28:104:36 | call to taint : | instance_variables.rb:104:6:104:10 | [post] foo16 [@field] : |
|
||||
| instance_variables.rb:104:28:104:36 | call to taint : | instance_variables.rb:104:6:104:10 | [post] foo16 [@field] : |
|
||||
| instance_variables.rb:105:6:105:10 | foo16 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:105:6:105:10 | foo16 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : |
|
||||
| instance_variables.rb:105:6:105:10 | foo16 [@field] : | instance_variables.rb:105:6:105:20 | call to get_field |
|
||||
| instance_variables.rb:105:6:105:10 | foo16 [@field] : | instance_variables.rb:105:6:105:20 | call to get_field |
|
||||
| instance_variables.rb:106:7:106:24 | call to new : | instance_variables.rb:107:6:107:8 | bar |
|
||||
| instance_variables.rb:106:7:106:24 | call to new : | instance_variables.rb:107:6:107:8 | bar |
|
||||
nodes
|
||||
| captured_variables.rb:1:24:1:24 | x : | semmle.label | x : |
|
||||
| captured_variables.rb:1:24:1:24 | x : | semmle.label | x : |
|
||||
@@ -206,182 +244,236 @@ nodes
|
||||
| instance_variables.rb:20:10:20:13 | @foo | semmle.label | @foo |
|
||||
| instance_variables.rb:20:10:20:13 | self [@foo] : | semmle.label | self [@foo] : |
|
||||
| instance_variables.rb:20:10:20:13 | self [@foo] : | semmle.label | self [@foo] : |
|
||||
| instance_variables.rb:24:1:24:3 | [post] foo [@field] : | semmle.label | [post] foo [@field] : |
|
||||
| instance_variables.rb:24:1:24:3 | [post] foo [@field] : | semmle.label | [post] foo [@field] : |
|
||||
| instance_variables.rb:24:15:24:23 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:24:15:24:23 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:25:6:25:8 | foo [@field] : | semmle.label | foo [@field] : |
|
||||
| instance_variables.rb:25:6:25:8 | foo [@field] : | semmle.label | foo [@field] : |
|
||||
| instance_variables.rb:25:6:25:18 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:25:6:25:18 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:28:1:28:3 | [post] bar [@field] : | semmle.label | [post] bar [@field] : |
|
||||
| instance_variables.rb:28:15:28:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:29:6:29:8 | bar [@field] : | semmle.label | bar [@field] : |
|
||||
| instance_variables.rb:29:6:29:18 | call to inc_field | semmle.label | call to inc_field |
|
||||
| instance_variables.rb:32:1:32:4 | [post] foo1 [@field] : | semmle.label | [post] foo1 [@field] : |
|
||||
| instance_variables.rb:32:1:32:4 | [post] foo1 [@field] : | semmle.label | [post] foo1 [@field] : |
|
||||
| instance_variables.rb:32:14:32:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:32:14:32:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:33:6:33:9 | foo1 [@field] : | semmle.label | foo1 [@field] : |
|
||||
| instance_variables.rb:33:6:33:9 | foo1 [@field] : | semmle.label | foo1 [@field] : |
|
||||
| instance_variables.rb:33:6:33:15 | call to field | semmle.label | call to field |
|
||||
| instance_variables.rb:33:6:33:15 | call to field | semmle.label | call to field |
|
||||
| instance_variables.rb:36:1:36:4 | [post] foo2 [@field] : | semmle.label | [post] foo2 [@field] : |
|
||||
| instance_variables.rb:36:1:36:4 | [post] foo2 [@field] : | semmle.label | [post] foo2 [@field] : |
|
||||
| instance_variables.rb:36:14:36:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:36:14:36:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:37:6:37:9 | foo2 [@field] : | semmle.label | foo2 [@field] : |
|
||||
| instance_variables.rb:37:6:37:9 | foo2 [@field] : | semmle.label | foo2 [@field] : |
|
||||
| instance_variables.rb:37:6:37:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:37:6:37:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : | semmle.label | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : | semmle.label | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:40:16:40:24 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:40:16:40:24 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:41:6:41:9 | foo3 [@field] : | semmle.label | foo3 [@field] : |
|
||||
| instance_variables.rb:41:6:41:9 | foo3 [@field] : | semmle.label | foo3 [@field] : |
|
||||
| instance_variables.rb:41:6:41:15 | call to field | semmle.label | call to field |
|
||||
| instance_variables.rb:41:6:41:15 | call to field | semmle.label | call to field |
|
||||
| instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : | semmle.label | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : | semmle.label | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:48:18:48:26 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:48:18:48:26 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:49:6:49:9 | foo5 [@field] : | semmle.label | foo5 [@field] : |
|
||||
| instance_variables.rb:49:6:49:9 | foo5 [@field] : | semmle.label | foo5 [@field] : |
|
||||
| instance_variables.rb:49:6:49:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:49:6:49:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:52:15:52:18 | [post] foo6 [@field] : | semmle.label | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:52:15:52:18 | [post] foo6 [@field] : | semmle.label | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:52:32:52:40 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:52:32:52:40 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:53:6:53:9 | foo3 [@field] : | semmle.label | foo3 [@field] : |
|
||||
| instance_variables.rb:53:6:53:9 | foo3 [@field] : | semmle.label | foo3 [@field] : |
|
||||
| instance_variables.rb:53:6:53:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:53:6:53:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:54:6:54:9 | foo5 [@field] : | semmle.label | foo5 [@field] : |
|
||||
| instance_variables.rb:54:6:54:9 | foo5 [@field] : | semmle.label | foo5 [@field] : |
|
||||
| instance_variables.rb:54:6:54:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:54:6:54:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:55:6:55:9 | foo6 [@field] : | semmle.label | foo6 [@field] : |
|
||||
| instance_variables.rb:55:6:55:9 | foo6 [@field] : | semmle.label | foo6 [@field] : |
|
||||
| instance_variables.rb:55:6:55:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:55:6:55:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:59:15:59:18 | [post] foo7 [@field] : | semmle.label | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:59:15:59:18 | [post] foo7 [@field] : | semmle.label | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:59:25:59:28 | [post] foo8 [@field] : | semmle.label | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:59:25:59:28 | [post] foo8 [@field] : | semmle.label | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:60:6:60:9 | foo7 [@field] : | semmle.label | foo7 [@field] : |
|
||||
| instance_variables.rb:60:6:60:9 | foo7 [@field] : | semmle.label | foo7 [@field] : |
|
||||
| instance_variables.rb:60:6:60:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:60:6:60:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:61:6:61:9 | foo8 [@field] : | semmle.label | foo8 [@field] : |
|
||||
| instance_variables.rb:61:6:61:9 | foo8 [@field] : | semmle.label | foo8 [@field] : |
|
||||
| instance_variables.rb:61:6:61:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:61:6:61:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:65:22:65:25 | [post] foo9 [@field] : | semmle.label | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:65:22:65:25 | [post] foo9 [@field] : | semmle.label | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:65:32:65:36 | [post] foo10 [@field] : | semmle.label | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:65:32:65:36 | [post] foo10 [@field] : | semmle.label | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:66:6:66:9 | foo9 [@field] : | semmle.label | foo9 [@field] : |
|
||||
| instance_variables.rb:66:6:66:9 | foo9 [@field] : | semmle.label | foo9 [@field] : |
|
||||
| instance_variables.rb:66:6:66:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:66:6:66:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:67:6:67:10 | foo10 [@field] : | semmle.label | foo10 [@field] : |
|
||||
| instance_variables.rb:67:6:67:10 | foo10 [@field] : | semmle.label | foo10 [@field] : |
|
||||
| instance_variables.rb:67:6:67:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:67:6:67:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:70:5:70:5 | [post] x [@field] : | semmle.label | [post] x [@field] : |
|
||||
| instance_variables.rb:70:5:70:5 | [post] x [@field] : | semmle.label | [post] x [@field] : |
|
||||
| instance_variables.rb:70:17:70:25 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:70:17:70:25 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:74:14:74:18 | [post] foo11 [@field] : | semmle.label | [post] foo11 [@field] : |
|
||||
| instance_variables.rb:74:14:74:18 | [post] foo11 [@field] : | semmle.label | [post] foo11 [@field] : |
|
||||
| instance_variables.rb:75:6:75:10 | foo11 [@field] : | semmle.label | foo11 [@field] : |
|
||||
| instance_variables.rb:75:6:75:10 | foo11 [@field] : | semmle.label | foo11 [@field] : |
|
||||
| instance_variables.rb:75:6:75:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:75:6:75:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:78:15:78:19 | [post] foo12 [@field] : | semmle.label | [post] foo12 [@field] : |
|
||||
| instance_variables.rb:78:15:78:19 | [post] foo12 [@field] : | semmle.label | [post] foo12 [@field] : |
|
||||
| instance_variables.rb:79:6:79:10 | foo12 [@field] : | semmle.label | foo12 [@field] : |
|
||||
| instance_variables.rb:79:6:79:10 | foo12 [@field] : | semmle.label | foo12 [@field] : |
|
||||
| instance_variables.rb:79:6:79:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:79:6:79:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:83:22:83:26 | [post] foo13 [@field] : | semmle.label | [post] foo13 [@field] : |
|
||||
| instance_variables.rb:83:22:83:26 | [post] foo13 [@field] : | semmle.label | [post] foo13 [@field] : |
|
||||
| instance_variables.rb:84:6:84:10 | foo13 [@field] : | semmle.label | foo13 [@field] : |
|
||||
| instance_variables.rb:84:6:84:10 | foo13 [@field] : | semmle.label | foo13 [@field] : |
|
||||
| instance_variables.rb:84:6:84:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:84:6:84:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:22:20:22:24 | field : | semmle.label | field : |
|
||||
| instance_variables.rb:22:20:22:24 | field : | semmle.label | field : |
|
||||
| instance_variables.rb:23:9:23:14 | [post] self [@field] : | semmle.label | [post] self [@field] : |
|
||||
| instance_variables.rb:23:9:23:14 | [post] self [@field] : | semmle.label | [post] self [@field] : |
|
||||
| instance_variables.rb:23:18:23:22 | field : | semmle.label | field : |
|
||||
| instance_variables.rb:23:18:23:22 | field : | semmle.label | field : |
|
||||
| instance_variables.rb:24:9:24:17 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:24:9:24:17 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:27:25:27:29 | field : | semmle.label | field : |
|
||||
| instance_variables.rb:27:25:27:29 | field : | semmle.label | field : |
|
||||
| instance_variables.rb:28:9:28:25 | [post] self [@field] : | semmle.label | [post] self [@field] : |
|
||||
| instance_variables.rb:28:9:28:25 | [post] self [@field] : | semmle.label | [post] self [@field] : |
|
||||
| instance_variables.rb:28:9:28:25 | call to initialize : | semmle.label | call to initialize : |
|
||||
| instance_variables.rb:28:9:28:25 | call to initialize : | semmle.label | call to initialize : |
|
||||
| instance_variables.rb:28:20:28:24 | field : | semmle.label | field : |
|
||||
| instance_variables.rb:28:20:28:24 | field : | semmle.label | field : |
|
||||
| instance_variables.rb:34:9:34:17 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:34:9:34:17 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:39:1:39:3 | [post] foo [@field] : | semmle.label | [post] foo [@field] : |
|
||||
| instance_variables.rb:39:1:39:3 | [post] foo [@field] : | semmle.label | [post] foo [@field] : |
|
||||
| instance_variables.rb:39:15:39:23 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:39:15:39:23 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:40:6:40:8 | foo [@field] : | semmle.label | foo [@field] : |
|
||||
| instance_variables.rb:40:6:40:8 | foo [@field] : | semmle.label | foo [@field] : |
|
||||
| instance_variables.rb:40:6:40:18 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:40:6:40:18 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:43:1:43:3 | [post] bar [@field] : | semmle.label | [post] bar [@field] : |
|
||||
| instance_variables.rb:43:15:43:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:44:6:44:8 | bar [@field] : | semmle.label | bar [@field] : |
|
||||
| instance_variables.rb:44:6:44:18 | call to inc_field | semmle.label | call to inc_field |
|
||||
| instance_variables.rb:47:1:47:4 | [post] foo1 [@field] : | semmle.label | [post] foo1 [@field] : |
|
||||
| instance_variables.rb:47:1:47:4 | [post] foo1 [@field] : | semmle.label | [post] foo1 [@field] : |
|
||||
| instance_variables.rb:47:14:47:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:47:14:47:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:48:6:48:9 | foo1 [@field] : | semmle.label | foo1 [@field] : |
|
||||
| instance_variables.rb:48:6:48:9 | foo1 [@field] : | semmle.label | foo1 [@field] : |
|
||||
| instance_variables.rb:48:6:48:15 | call to field | semmle.label | call to field |
|
||||
| instance_variables.rb:48:6:48:15 | call to field | semmle.label | call to field |
|
||||
| instance_variables.rb:51:1:51:4 | [post] foo2 [@field] : | semmle.label | [post] foo2 [@field] : |
|
||||
| instance_variables.rb:51:1:51:4 | [post] foo2 [@field] : | semmle.label | [post] foo2 [@field] : |
|
||||
| instance_variables.rb:51:14:51:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:51:14:51:22 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:52:6:52:9 | foo2 [@field] : | semmle.label | foo2 [@field] : |
|
||||
| instance_variables.rb:52:6:52:9 | foo2 [@field] : | semmle.label | foo2 [@field] : |
|
||||
| instance_variables.rb:52:6:52:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:52:6:52:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : | semmle.label | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : | semmle.label | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:55:16:55:24 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:55:16:55:24 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:56:6:56:9 | foo3 [@field] : | semmle.label | foo3 [@field] : |
|
||||
| instance_variables.rb:56:6:56:9 | foo3 [@field] : | semmle.label | foo3 [@field] : |
|
||||
| instance_variables.rb:56:6:56:15 | call to field | semmle.label | call to field |
|
||||
| instance_variables.rb:56:6:56:15 | call to field | semmle.label | call to field |
|
||||
| instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : | semmle.label | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : | semmle.label | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:63:18:63:26 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:63:18:63:26 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:64:6:64:9 | foo5 [@field] : | semmle.label | foo5 [@field] : |
|
||||
| instance_variables.rb:64:6:64:9 | foo5 [@field] : | semmle.label | foo5 [@field] : |
|
||||
| instance_variables.rb:64:6:64:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:64:6:64:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:67:15:67:18 | [post] foo6 [@field] : | semmle.label | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:67:15:67:18 | [post] foo6 [@field] : | semmle.label | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:67:32:67:40 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:67:32:67:40 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:68:6:68:9 | foo3 [@field] : | semmle.label | foo3 [@field] : |
|
||||
| instance_variables.rb:68:6:68:9 | foo3 [@field] : | semmle.label | foo3 [@field] : |
|
||||
| instance_variables.rb:68:6:68:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:68:6:68:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:69:6:69:9 | foo5 [@field] : | semmle.label | foo5 [@field] : |
|
||||
| instance_variables.rb:69:6:69:9 | foo5 [@field] : | semmle.label | foo5 [@field] : |
|
||||
| instance_variables.rb:69:6:69:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:69:6:69:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:70:6:70:9 | foo6 [@field] : | semmle.label | foo6 [@field] : |
|
||||
| instance_variables.rb:70:6:70:9 | foo6 [@field] : | semmle.label | foo6 [@field] : |
|
||||
| instance_variables.rb:70:6:70:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:70:6:70:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:74:15:74:18 | [post] foo7 [@field] : | semmle.label | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:74:15:74:18 | [post] foo7 [@field] : | semmle.label | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:74:25:74:28 | [post] foo8 [@field] : | semmle.label | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:74:25:74:28 | [post] foo8 [@field] : | semmle.label | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:75:6:75:9 | foo7 [@field] : | semmle.label | foo7 [@field] : |
|
||||
| instance_variables.rb:75:6:75:9 | foo7 [@field] : | semmle.label | foo7 [@field] : |
|
||||
| instance_variables.rb:75:6:75:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:75:6:75:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:76:6:76:9 | foo8 [@field] : | semmle.label | foo8 [@field] : |
|
||||
| instance_variables.rb:76:6:76:9 | foo8 [@field] : | semmle.label | foo8 [@field] : |
|
||||
| instance_variables.rb:76:6:76:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:76:6:76:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:80:22:80:25 | [post] foo9 [@field] : | semmle.label | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:80:22:80:25 | [post] foo9 [@field] : | semmle.label | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:80:32:80:36 | [post] foo10 [@field] : | semmle.label | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:80:32:80:36 | [post] foo10 [@field] : | semmle.label | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:81:6:81:9 | foo9 [@field] : | semmle.label | foo9 [@field] : |
|
||||
| instance_variables.rb:81:6:81:9 | foo9 [@field] : | semmle.label | foo9 [@field] : |
|
||||
| instance_variables.rb:81:6:81:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:81:6:81:19 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:82:6:82:10 | foo10 [@field] : | semmle.label | foo10 [@field] : |
|
||||
| instance_variables.rb:82:6:82:10 | foo10 [@field] : | semmle.label | foo10 [@field] : |
|
||||
| instance_variables.rb:82:6:82:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:82:6:82:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:85:5:85:5 | [post] x [@field] : | semmle.label | [post] x [@field] : |
|
||||
| instance_variables.rb:85:5:85:5 | [post] x [@field] : | semmle.label | [post] x [@field] : |
|
||||
| instance_variables.rb:85:17:85:25 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:85:17:85:25 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:89:14:89:18 | [post] foo11 [@field] : | semmle.label | [post] foo11 [@field] : |
|
||||
| instance_variables.rb:89:14:89:18 | [post] foo11 [@field] : | semmle.label | [post] foo11 [@field] : |
|
||||
| instance_variables.rb:90:6:90:10 | foo11 [@field] : | semmle.label | foo11 [@field] : |
|
||||
| instance_variables.rb:90:6:90:10 | foo11 [@field] : | semmle.label | foo11 [@field] : |
|
||||
| instance_variables.rb:90:6:90:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:90:6:90:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:93:15:93:19 | [post] foo12 [@field] : | semmle.label | [post] foo12 [@field] : |
|
||||
| instance_variables.rb:93:15:93:19 | [post] foo12 [@field] : | semmle.label | [post] foo12 [@field] : |
|
||||
| instance_variables.rb:94:6:94:10 | foo12 [@field] : | semmle.label | foo12 [@field] : |
|
||||
| instance_variables.rb:94:6:94:10 | foo12 [@field] : | semmle.label | foo12 [@field] : |
|
||||
| instance_variables.rb:94:6:94:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:94:6:94:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:98:22:98:26 | [post] foo13 [@field] : | semmle.label | [post] foo13 [@field] : |
|
||||
| instance_variables.rb:98:22:98:26 | [post] foo13 [@field] : | semmle.label | [post] foo13 [@field] : |
|
||||
| instance_variables.rb:99:6:99:10 | foo13 [@field] : | semmle.label | foo13 [@field] : |
|
||||
| instance_variables.rb:99:6:99:10 | foo13 [@field] : | semmle.label | foo13 [@field] : |
|
||||
| instance_variables.rb:99:6:99:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:99:6:99:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:101:9:101:26 | call to new [@field] : | semmle.label | call to new [@field] : |
|
||||
| instance_variables.rb:101:9:101:26 | call to new [@field] : | semmle.label | call to new [@field] : |
|
||||
| instance_variables.rb:101:17:101:25 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:101:17:101:25 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:102:6:102:10 | foo15 [@field] : | semmle.label | foo15 [@field] : |
|
||||
| instance_variables.rb:102:6:102:10 | foo15 [@field] : | semmle.label | foo15 [@field] : |
|
||||
| instance_variables.rb:102:6:102:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:102:6:102:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:104:6:104:10 | [post] foo16 [@field] : | semmle.label | [post] foo16 [@field] : |
|
||||
| instance_variables.rb:104:6:104:10 | [post] foo16 [@field] : | semmle.label | [post] foo16 [@field] : |
|
||||
| instance_variables.rb:104:6:104:37 | call to call_initialize | semmle.label | call to call_initialize |
|
||||
| instance_variables.rb:104:6:104:37 | call to call_initialize | semmle.label | call to call_initialize |
|
||||
| instance_variables.rb:104:28:104:36 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:104:28:104:36 | call to taint : | semmle.label | call to taint : |
|
||||
| instance_variables.rb:105:6:105:10 | foo16 [@field] : | semmle.label | foo16 [@field] : |
|
||||
| instance_variables.rb:105:6:105:10 | foo16 [@field] : | semmle.label | foo16 [@field] : |
|
||||
| instance_variables.rb:105:6:105:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:105:6:105:20 | call to get_field | semmle.label | call to get_field |
|
||||
| instance_variables.rb:106:7:106:24 | call to new : | semmle.label | call to new : |
|
||||
| instance_variables.rb:106:7:106:24 | call to new : | semmle.label | call to new : |
|
||||
| instance_variables.rb:107:6:107:8 | bar | semmle.label | bar |
|
||||
| instance_variables.rb:107:6:107:8 | bar | semmle.label | bar |
|
||||
subpaths
|
||||
| instance_variables.rb:24:15:24:23 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:24:1:24:3 | [post] foo [@field] : |
|
||||
| instance_variables.rb:24:15:24:23 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:24:1:24:3 | [post] foo [@field] : |
|
||||
| instance_variables.rb:25:6:25:8 | foo [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:25:6:25:18 | call to get_field |
|
||||
| instance_variables.rb:25:6:25:8 | foo [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:25:6:25:18 | call to get_field |
|
||||
| instance_variables.rb:28:15:28:22 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:28:1:28:3 | [post] bar [@field] : |
|
||||
| instance_variables.rb:29:6:29:8 | bar [@field] : | instance_variables.rb:16:5:18:7 | self in inc_field [@field] : | instance_variables.rb:16:5:18:7 | self in inc_field [@field] : | instance_variables.rb:29:6:29:18 | call to inc_field |
|
||||
| instance_variables.rb:29:6:29:8 | bar [@field] : | instance_variables.rb:16:5:18:7 | self in inc_field [@field] : | instance_variables.rb:17:9:17:14 | [post] self [@field] : | instance_variables.rb:29:6:29:18 | call to inc_field |
|
||||
| instance_variables.rb:37:6:37:9 | foo2 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:37:6:37:19 | call to get_field |
|
||||
| instance_variables.rb:37:6:37:9 | foo2 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:37:6:37:19 | call to get_field |
|
||||
| instance_variables.rb:40:16:40:24 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:40:16:40:24 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:40:1:40:4 | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:48:18:48:26 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:48:18:48:26 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:48:2:48:5 | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:49:6:49:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:49:6:49:19 | call to get_field |
|
||||
| instance_variables.rb:49:6:49:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:49:6:49:19 | call to get_field |
|
||||
| instance_variables.rb:52:32:52:40 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:52:15:52:18 | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:52:32:52:40 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:52:15:52:18 | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:53:6:53:9 | foo3 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:53:6:53:19 | call to get_field |
|
||||
| instance_variables.rb:53:6:53:9 | foo3 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:53:6:53:19 | call to get_field |
|
||||
| instance_variables.rb:54:6:54:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:54:6:54:19 | call to get_field |
|
||||
| instance_variables.rb:54:6:54:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:54:6:54:19 | call to get_field |
|
||||
| instance_variables.rb:55:6:55:9 | foo6 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:55:6:55:19 | call to get_field |
|
||||
| instance_variables.rb:55:6:55:9 | foo6 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:55:6:55:19 | call to get_field |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:59:15:59:18 | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:59:15:59:18 | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:59:25:59:28 | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:59:25:59:28 | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:60:6:60:9 | foo7 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:60:6:60:19 | call to get_field |
|
||||
| instance_variables.rb:60:6:60:9 | foo7 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:60:6:60:19 | call to get_field |
|
||||
| instance_variables.rb:61:6:61:9 | foo8 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:61:6:61:19 | call to get_field |
|
||||
| instance_variables.rb:61:6:61:9 | foo8 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:61:6:61:19 | call to get_field |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:65:22:65:25 | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:65:22:65:25 | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:65:32:65:36 | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:65:32:65:36 | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:66:6:66:9 | foo9 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:66:6:66:19 | call to get_field |
|
||||
| instance_variables.rb:66:6:66:9 | foo9 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:66:6:66:19 | call to get_field |
|
||||
| instance_variables.rb:67:6:67:10 | foo10 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:67:6:67:20 | call to get_field |
|
||||
| instance_variables.rb:67:6:67:10 | foo10 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:67:6:67:20 | call to get_field |
|
||||
| instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:70:5:70:5 | [post] x [@field] : |
|
||||
| instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:70:5:70:5 | [post] x [@field] : |
|
||||
| instance_variables.rb:75:6:75:10 | foo11 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:75:6:75:20 | call to get_field |
|
||||
| instance_variables.rb:75:6:75:10 | foo11 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:75:6:75:20 | call to get_field |
|
||||
| instance_variables.rb:79:6:79:10 | foo12 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:79:6:79:20 | call to get_field |
|
||||
| instance_variables.rb:79:6:79:10 | foo12 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:79:6:79:20 | call to get_field |
|
||||
| instance_variables.rb:84:6:84:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:84:6:84:20 | call to get_field |
|
||||
| instance_variables.rb:84:6:84:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:84:6:84:20 | call to get_field |
|
||||
| instance_variables.rb:28:20:28:24 | field : | instance_variables.rb:22:20:22:24 | field : | instance_variables.rb:23:9:23:14 | [post] self [@field] : | instance_variables.rb:28:9:28:25 | [post] self [@field] : |
|
||||
| instance_variables.rb:28:20:28:24 | field : | instance_variables.rb:22:20:22:24 | field : | instance_variables.rb:23:9:23:14 | [post] self [@field] : | instance_variables.rb:28:9:28:25 | [post] self [@field] : |
|
||||
| instance_variables.rb:39:15:39:23 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:39:1:39:3 | [post] foo [@field] : |
|
||||
| instance_variables.rb:39:15:39:23 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:39:1:39:3 | [post] foo [@field] : |
|
||||
| instance_variables.rb:40:6:40:8 | foo [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:40:6:40:18 | call to get_field |
|
||||
| instance_variables.rb:40:6:40:8 | foo [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:40:6:40:18 | call to get_field |
|
||||
| instance_variables.rb:43:15:43:22 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:43:1:43:3 | [post] bar [@field] : |
|
||||
| instance_variables.rb:44:6:44:8 | bar [@field] : | instance_variables.rb:16:5:18:7 | self in inc_field [@field] : | instance_variables.rb:16:5:18:7 | self in inc_field [@field] : | instance_variables.rb:44:6:44:18 | call to inc_field |
|
||||
| instance_variables.rb:44:6:44:8 | bar [@field] : | instance_variables.rb:16:5:18:7 | self in inc_field [@field] : | instance_variables.rb:17:9:17:14 | [post] self [@field] : | instance_variables.rb:44:6:44:18 | call to inc_field |
|
||||
| instance_variables.rb:52:6:52:9 | foo2 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:52:6:52:19 | call to get_field |
|
||||
| instance_variables.rb:52:6:52:9 | foo2 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:52:6:52:19 | call to get_field |
|
||||
| instance_variables.rb:55:16:55:24 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:55:16:55:24 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:55:1:55:4 | [post] foo3 [@field] : |
|
||||
| instance_variables.rb:63:18:63:26 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:63:18:63:26 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:63:2:63:5 | [post] foo5 [@field] : |
|
||||
| instance_variables.rb:64:6:64:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:64:6:64:19 | call to get_field |
|
||||
| instance_variables.rb:64:6:64:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:64:6:64:19 | call to get_field |
|
||||
| instance_variables.rb:67:32:67:40 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:67:15:67:18 | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:67:32:67:40 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:67:15:67:18 | [post] foo6 [@field] : |
|
||||
| instance_variables.rb:68:6:68:9 | foo3 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:68:6:68:19 | call to get_field |
|
||||
| instance_variables.rb:68:6:68:9 | foo3 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:68:6:68:19 | call to get_field |
|
||||
| instance_variables.rb:69:6:69:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:69:6:69:19 | call to get_field |
|
||||
| instance_variables.rb:69:6:69:9 | foo5 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:69:6:69:19 | call to get_field |
|
||||
| instance_variables.rb:70:6:70:9 | foo6 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:70:6:70:19 | call to get_field |
|
||||
| instance_variables.rb:70:6:70:9 | foo6 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:70:6:70:19 | call to get_field |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:74:15:74:18 | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:74:15:74:18 | [post] foo7 [@field] : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:74:25:74:28 | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:74:25:74:28 | [post] foo8 [@field] : |
|
||||
| instance_variables.rb:75:6:75:9 | foo7 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:75:6:75:19 | call to get_field |
|
||||
| instance_variables.rb:75:6:75:9 | foo7 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:75:6:75:19 | call to get_field |
|
||||
| instance_variables.rb:76:6:76:9 | foo8 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:76:6:76:19 | call to get_field |
|
||||
| instance_variables.rb:76:6:76:9 | foo8 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:76:6:76:19 | call to get_field |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:80:22:80:25 | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:80:22:80:25 | [post] foo9 [@field] : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:80:32:80:36 | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:80:32:80:36 | [post] foo10 [@field] : |
|
||||
| instance_variables.rb:81:6:81:9 | foo9 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:81:6:81:19 | call to get_field |
|
||||
| instance_variables.rb:81:6:81:9 | foo9 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:81:6:81:19 | call to get_field |
|
||||
| instance_variables.rb:82:6:82:10 | foo10 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:82:6:82:20 | call to get_field |
|
||||
| instance_variables.rb:82:6:82:10 | foo10 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:82:6:82:20 | call to get_field |
|
||||
| instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:85:5:85:5 | [post] x [@field] : |
|
||||
| instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : | instance_variables.rb:85:5:85:5 | [post] x [@field] : |
|
||||
| instance_variables.rb:90:6:90:10 | foo11 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:90:6:90:20 | call to get_field |
|
||||
| instance_variables.rb:90:6:90:10 | foo11 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:90:6:90:20 | call to get_field |
|
||||
| instance_variables.rb:94:6:94:10 | foo12 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:94:6:94:20 | call to get_field |
|
||||
| instance_variables.rb:94:6:94:10 | foo12 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:94:6:94:20 | call to get_field |
|
||||
| instance_variables.rb:99:6:99:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:99:6:99:20 | call to get_field |
|
||||
| instance_variables.rb:99:6:99:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:99:6:99:20 | call to get_field |
|
||||
| instance_variables.rb:101:17:101:25 | call to taint : | instance_variables.rb:22:20:22:24 | field : | instance_variables.rb:23:9:23:14 | [post] self [@field] : | instance_variables.rb:101:9:101:26 | call to new [@field] : |
|
||||
| instance_variables.rb:101:17:101:25 | call to taint : | instance_variables.rb:22:20:22:24 | field : | instance_variables.rb:23:9:23:14 | [post] self [@field] : | instance_variables.rb:101:9:101:26 | call to new [@field] : |
|
||||
| instance_variables.rb:102:6:102:10 | foo15 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:102:6:102:20 | call to get_field |
|
||||
| instance_variables.rb:102:6:102:10 | foo15 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:102:6:102:20 | call to get_field |
|
||||
| instance_variables.rb:104:28:104:36 | call to taint : | instance_variables.rb:27:25:27:29 | field : | instance_variables.rb:28:9:28:25 | [post] self [@field] : | instance_variables.rb:104:6:104:10 | [post] foo16 [@field] : |
|
||||
| instance_variables.rb:104:28:104:36 | call to taint : | instance_variables.rb:27:25:27:29 | field : | instance_variables.rb:28:9:28:25 | [post] self [@field] : | instance_variables.rb:104:6:104:10 | [post] foo16 [@field] : |
|
||||
| instance_variables.rb:105:6:105:10 | foo16 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:105:6:105:20 | call to get_field |
|
||||
| instance_variables.rb:105:6:105:10 | foo16 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | instance_variables.rb:14:9:14:21 | return : | instance_variables.rb:105:6:105:20 | call to get_field |
|
||||
#select
|
||||
| captured_variables.rb:2:20:2:20 | x | captured_variables.rb:5:20:5:30 | call to source : | captured_variables.rb:2:20:2:20 | x | $@ | captured_variables.rb:5:20:5:30 | call to source : | call to source : |
|
||||
| captured_variables.rb:23:14:23:14 | x | captured_variables.rb:27:29:27:39 | call to source : | captured_variables.rb:23:14:23:14 | x | $@ | captured_variables.rb:27:29:27:39 | call to source : | call to source : |
|
||||
| captured_variables.rb:34:14:34:14 | x | captured_variables.rb:38:27:38:37 | call to source : | captured_variables.rb:34:14:34:14 | x | $@ | captured_variables.rb:38:27:38:37 | call to source : | call to source : |
|
||||
| instance_variables.rb:20:10:20:13 | @foo | instance_variables.rb:19:12:19:21 | call to taint : | instance_variables.rb:20:10:20:13 | @foo | $@ | instance_variables.rb:19:12:19:21 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:25:6:25:18 | call to get_field | instance_variables.rb:24:15:24:23 | call to taint : | instance_variables.rb:25:6:25:18 | call to get_field | $@ | instance_variables.rb:24:15:24:23 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:29:6:29:18 | call to inc_field | instance_variables.rb:28:15:28:22 | call to taint : | instance_variables.rb:29:6:29:18 | call to inc_field | $@ | instance_variables.rb:28:15:28:22 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:33:6:33:15 | call to field | instance_variables.rb:32:14:32:22 | call to taint : | instance_variables.rb:33:6:33:15 | call to field | $@ | instance_variables.rb:32:14:32:22 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:37:6:37:19 | call to get_field | instance_variables.rb:36:14:36:22 | call to taint : | instance_variables.rb:37:6:37:19 | call to get_field | $@ | instance_variables.rb:36:14:36:22 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:41:6:41:15 | call to field | instance_variables.rb:40:16:40:24 | call to taint : | instance_variables.rb:41:6:41:15 | call to field | $@ | instance_variables.rb:40:16:40:24 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:49:6:49:19 | call to get_field | instance_variables.rb:48:18:48:26 | call to taint : | instance_variables.rb:49:6:49:19 | call to get_field | $@ | instance_variables.rb:48:18:48:26 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:53:6:53:19 | call to get_field | instance_variables.rb:40:16:40:24 | call to taint : | instance_variables.rb:53:6:53:19 | call to get_field | $@ | instance_variables.rb:40:16:40:24 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:54:6:54:19 | call to get_field | instance_variables.rb:48:18:48:26 | call to taint : | instance_variables.rb:54:6:54:19 | call to get_field | $@ | instance_variables.rb:48:18:48:26 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:55:6:55:19 | call to get_field | instance_variables.rb:52:32:52:40 | call to taint : | instance_variables.rb:55:6:55:19 | call to get_field | $@ | instance_variables.rb:52:32:52:40 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:60:6:60:19 | call to get_field | instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:60:6:60:19 | call to get_field | $@ | instance_variables.rb:59:45:59:53 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:61:6:61:19 | call to get_field | instance_variables.rb:59:45:59:53 | call to taint : | instance_variables.rb:61:6:61:19 | call to get_field | $@ | instance_variables.rb:59:45:59:53 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:66:6:66:19 | call to get_field | instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:66:6:66:19 | call to get_field | $@ | instance_variables.rb:65:53:65:61 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:67:6:67:20 | call to get_field | instance_variables.rb:65:53:65:61 | call to taint : | instance_variables.rb:67:6:67:20 | call to get_field | $@ | instance_variables.rb:65:53:65:61 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:75:6:75:20 | call to get_field | instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:75:6:75:20 | call to get_field | $@ | instance_variables.rb:70:17:70:25 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:79:6:79:20 | call to get_field | instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:79:6:79:20 | call to get_field | $@ | instance_variables.rb:70:17:70:25 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:84:6:84:20 | call to get_field | instance_variables.rb:70:17:70:25 | call to taint : | instance_variables.rb:84:6:84:20 | call to get_field | $@ | instance_variables.rb:70:17:70:25 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:40:6:40:18 | call to get_field | instance_variables.rb:39:15:39:23 | call to taint : | instance_variables.rb:40:6:40:18 | call to get_field | $@ | instance_variables.rb:39:15:39:23 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:44:6:44:18 | call to inc_field | instance_variables.rb:43:15:43:22 | call to taint : | instance_variables.rb:44:6:44:18 | call to inc_field | $@ | instance_variables.rb:43:15:43:22 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:48:6:48:15 | call to field | instance_variables.rb:47:14:47:22 | call to taint : | instance_variables.rb:48:6:48:15 | call to field | $@ | instance_variables.rb:47:14:47:22 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:52:6:52:19 | call to get_field | instance_variables.rb:51:14:51:22 | call to taint : | instance_variables.rb:52:6:52:19 | call to get_field | $@ | instance_variables.rb:51:14:51:22 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:56:6:56:15 | call to field | instance_variables.rb:55:16:55:24 | call to taint : | instance_variables.rb:56:6:56:15 | call to field | $@ | instance_variables.rb:55:16:55:24 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:64:6:64:19 | call to get_field | instance_variables.rb:63:18:63:26 | call to taint : | instance_variables.rb:64:6:64:19 | call to get_field | $@ | instance_variables.rb:63:18:63:26 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:68:6:68:19 | call to get_field | instance_variables.rb:55:16:55:24 | call to taint : | instance_variables.rb:68:6:68:19 | call to get_field | $@ | instance_variables.rb:55:16:55:24 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:69:6:69:19 | call to get_field | instance_variables.rb:63:18:63:26 | call to taint : | instance_variables.rb:69:6:69:19 | call to get_field | $@ | instance_variables.rb:63:18:63:26 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:70:6:70:19 | call to get_field | instance_variables.rb:67:32:67:40 | call to taint : | instance_variables.rb:70:6:70:19 | call to get_field | $@ | instance_variables.rb:67:32:67:40 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:75:6:75:19 | call to get_field | instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:75:6:75:19 | call to get_field | $@ | instance_variables.rb:74:45:74:53 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:76:6:76:19 | call to get_field | instance_variables.rb:74:45:74:53 | call to taint : | instance_variables.rb:76:6:76:19 | call to get_field | $@ | instance_variables.rb:74:45:74:53 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:81:6:81:19 | call to get_field | instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:81:6:81:19 | call to get_field | $@ | instance_variables.rb:80:53:80:61 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:82:6:82:20 | call to get_field | instance_variables.rb:80:53:80:61 | call to taint : | instance_variables.rb:82:6:82:20 | call to get_field | $@ | instance_variables.rb:80:53:80:61 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:90:6:90:20 | call to get_field | instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:90:6:90:20 | call to get_field | $@ | instance_variables.rb:85:17:85:25 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:94:6:94:20 | call to get_field | instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:94:6:94:20 | call to get_field | $@ | instance_variables.rb:85:17:85:25 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:99:6:99:20 | call to get_field | instance_variables.rb:85:17:85:25 | call to taint : | instance_variables.rb:99:6:99:20 | call to get_field | $@ | instance_variables.rb:85:17:85:25 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:102:6:102:20 | call to get_field | instance_variables.rb:101:17:101:25 | call to taint : | instance_variables.rb:102:6:102:20 | call to get_field | $@ | instance_variables.rb:101:17:101:25 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:104:6:104:37 | call to call_initialize | instance_variables.rb:24:9:24:17 | call to taint : | instance_variables.rb:104:6:104:37 | call to call_initialize | $@ | instance_variables.rb:24:9:24:17 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:105:6:105:20 | call to get_field | instance_variables.rb:104:28:104:36 | call to taint : | instance_variables.rb:105:6:105:20 | call to get_field | $@ | instance_variables.rb:104:28:104:36 | call to taint : | call to taint : |
|
||||
| instance_variables.rb:107:6:107:8 | bar | instance_variables.rb:34:9:34:17 | call to taint : | instance_variables.rb:107:6:107:8 | bar | $@ | instance_variables.rb:34:9:34:17 | call to taint : | call to taint : |
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
| captured_variables.rb:9:14:9:14 | x | Fixed missing result:hasValueFlow=1.2 |
|
||||
| captured_variables.rb:16:14:16:14 | x | Fixed missing result:hasValueFlow=1.3 |
|
||||
| instance_variables.rb:20:16:20:33 | # $ hasValueFlow=7 | Missing result:hasValueFlow=7 |
|
||||
| instance_variables.rb:25:21:25:39 | # $ hasValueFlow=42 | Missing result:hasValueFlow=42 |
|
||||
| instance_variables.rb:37:22:37:40 | # $ hasValueFlow=21 | Missing result:hasValueFlow=21 |
|
||||
| instance_variables.rb:41:18:41:36 | # $ hasValueFlow=22 | Missing result:hasValueFlow=22 |
|
||||
| instance_variables.rb:49:22:49:40 | # $ hasValueFlow=24 | Missing result:hasValueFlow=24 |
|
||||
| instance_variables.rb:53:22:53:40 | # $ hasValueFlow=22 | Missing result:hasValueFlow=22 |
|
||||
| instance_variables.rb:54:22:54:40 | # $ hasValueFlow=24 | Missing result:hasValueFlow=24 |
|
||||
| instance_variables.rb:55:22:55:40 | # $ hasValueFlow=25 | Missing result:hasValueFlow=25 |
|
||||
| instance_variables.rb:60:22:60:40 | # $ hasValueFlow=26 | Missing result:hasValueFlow=26 |
|
||||
| instance_variables.rb:61:22:61:40 | # $ hasValueFlow=26 | Missing result:hasValueFlow=26 |
|
||||
| instance_variables.rb:66:22:66:40 | # $ hasValueFlow=27 | Missing result:hasValueFlow=27 |
|
||||
| instance_variables.rb:67:23:67:41 | # $ hasValueFlow=27 | Missing result:hasValueFlow=27 |
|
||||
| instance_variables.rb:75:23:75:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:79:23:79:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:84:23:84:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:40:21:40:39 | # $ hasValueFlow=42 | Missing result:hasValueFlow=42 |
|
||||
| instance_variables.rb:52:22:52:40 | # $ hasValueFlow=21 | Missing result:hasValueFlow=21 |
|
||||
| instance_variables.rb:56:18:56:36 | # $ hasValueFlow=22 | Missing result:hasValueFlow=22 |
|
||||
| instance_variables.rb:64:22:64:40 | # $ hasValueFlow=24 | Missing result:hasValueFlow=24 |
|
||||
| instance_variables.rb:68:22:68:40 | # $ hasValueFlow=22 | Missing result:hasValueFlow=22 |
|
||||
| instance_variables.rb:69:22:69:40 | # $ hasValueFlow=24 | Missing result:hasValueFlow=24 |
|
||||
| instance_variables.rb:70:22:70:40 | # $ hasValueFlow=25 | Missing result:hasValueFlow=25 |
|
||||
| instance_variables.rb:75:22:75:40 | # $ hasValueFlow=26 | Missing result:hasValueFlow=26 |
|
||||
| instance_variables.rb:76:22:76:40 | # $ hasValueFlow=26 | Missing result:hasValueFlow=26 |
|
||||
| instance_variables.rb:81:22:81:40 | # $ hasValueFlow=27 | Missing result:hasValueFlow=27 |
|
||||
| instance_variables.rb:82:23:82:41 | # $ hasValueFlow=27 | Missing result:hasValueFlow=27 |
|
||||
| instance_variables.rb:90:23:90:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:94:23:94:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:99:23:99:41 | # $ hasValueFlow=28 | Missing result:hasValueFlow=28 |
|
||||
| instance_variables.rb:102:23:102:41 | # $ hasValueFlow=29 | Missing result:hasValueFlow=29 |
|
||||
| instance_variables.rb:105:23:105:41 | # $ hasValueFlow=30 | Missing result:hasValueFlow=30 |
|
||||
|
||||
@@ -19,7 +19,22 @@ class Foo
|
||||
@foo = taint("7")
|
||||
sink(@foo) # $ hasValueFlow=7
|
||||
|
||||
def initialize(field = nil)
|
||||
@field = field
|
||||
taint(31)
|
||||
end
|
||||
|
||||
def call_initialize(field)
|
||||
initialize(field)
|
||||
end
|
||||
end
|
||||
|
||||
class Bar < Foo
|
||||
def self.new arg
|
||||
taint(32)
|
||||
end
|
||||
end
|
||||
|
||||
foo = Foo.new
|
||||
foo.set_field(taint(42))
|
||||
sink(foo.get_field) # $ hasValueFlow=42
|
||||
@@ -81,4 +96,13 @@ sink(foo12.get_field) # $ hasValueFlow=28
|
||||
foo13 = Foo.new
|
||||
foo14 = Foo.new
|
||||
set_field_on(foo14 = foo13)
|
||||
sink(foo13.get_field) # $ hasValueFlow=28
|
||||
sink(foo13.get_field) # $ hasValueFlow=28
|
||||
|
||||
foo15 = Foo.new(taint(29))
|
||||
sink(foo15.get_field) # $ hasValueFlow=29
|
||||
foo16 = Foo.new
|
||||
sink(foo16.call_initialize(taint(30))) # $ hasValueFlow=31
|
||||
sink(foo16.get_field) # $ hasValueFlow=30
|
||||
bar = Bar.new(taint(33))
|
||||
sink(bar) # $ hasValueFlow=32
|
||||
sink(bar.get_field)
|
||||
@@ -0,0 +1,38 @@
|
||||
locateCalls
|
||||
| globalid.rb:6:3:6:30 | call to locate |
|
||||
| globalid.rb:11:3:11:30 | call to locate |
|
||||
| globalid.rb:70:3:70:30 | call to locate |
|
||||
locateSignedCalls
|
||||
| globalid.rb:16:3:16:38 | call to locate_signed |
|
||||
| globalid.rb:21:3:21:38 | call to locate_signed |
|
||||
| globalid.rb:89:3:89:38 | call to locate_signed |
|
||||
toGlobalIdCalls
|
||||
| globalid.rb:5:9:5:33 | call to to_global_id |
|
||||
| globalid.rb:10:9:10:27 | call to to_gid |
|
||||
| globalid.rb:56:9:56:16 | call to to_gid |
|
||||
| globalid.rb:62:9:62:22 | call to to_global_id |
|
||||
toGidParamCalls
|
||||
| globalid.rb:35:10:35:34 | call to to_gid_param |
|
||||
| globalid.rb:68:10:68:23 | call to to_gid_param |
|
||||
toSignedGlobalIdCalls
|
||||
| globalid.rb:15:10:15:41 | call to to_signed_global_id |
|
||||
| globalid.rb:20:10:20:29 | call to to_sgid |
|
||||
| globalid.rb:75:10:75:18 | call to to_sgid |
|
||||
| globalid.rb:81:10:81:30 | call to to_signed_global_id |
|
||||
toSgidParamCalls
|
||||
| globalid.rb:41:11:41:36 | call to to_sgid_param |
|
||||
| globalid.rb:87:11:87:25 | call to to_sgid_param |
|
||||
globalIdParseCalls
|
||||
| globalid.rb:36:9:36:27 | call to parse |
|
||||
| globalid.rb:69:9:69:27 | call to parse |
|
||||
globalIdFindCalls
|
||||
| globalid.rb:37:3:37:19 | call to find |
|
||||
| globalid.rb:57:3:57:19 | call to find |
|
||||
| globalid.rb:63:3:63:19 | call to find |
|
||||
signedGlobalIdParseCalls
|
||||
| globalid.rb:42:10:42:35 | call to parse |
|
||||
| globalid.rb:88:10:88:35 | call to parse |
|
||||
signedGlobalIdFindCalls
|
||||
| globalid.rb:43:3:43:26 | call to find |
|
||||
| globalid.rb:76:3:76:26 | call to find |
|
||||
| globalid.rb:82:3:82:26 | call to find |
|
||||
21
ruby/ql/test/library-tests/frameworks/globalid/GlobalId.ql
Normal file
21
ruby/ql/test/library-tests/frameworks/globalid/GlobalId.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
import codeql.ruby.frameworks.GlobalId
|
||||
|
||||
query predicate locateCalls(GlobalId::Locator::LocateCall c) { any() }
|
||||
|
||||
query predicate locateSignedCalls(GlobalId::Locator::LocateSignedCall c) { any() }
|
||||
|
||||
query predicate toGlobalIdCalls(GlobalId::Identification::ToGlobalIdCall c) { any() }
|
||||
|
||||
query predicate toGidParamCalls(GlobalId::Identification::ToGidParamCall c) { any() }
|
||||
|
||||
query predicate toSignedGlobalIdCalls(GlobalId::Identification::ToSignedGlobalIdCall c) { any() }
|
||||
|
||||
query predicate toSgidParamCalls(GlobalId::Identification::ToSgidParamCall c) { any() }
|
||||
|
||||
query predicate globalIdParseCalls(GlobalId::ParseCall c) { any() }
|
||||
|
||||
query predicate globalIdFindCalls(GlobalId::FindCall c) { any() }
|
||||
|
||||
query predicate signedGlobalIdParseCalls(SignedGlobalId::ParseCall c) { any() }
|
||||
|
||||
query predicate signedGlobalIdFindCalls(SignedGlobalId::FindCall c) { any() }
|
||||
90
ruby/ql/test/library-tests/frameworks/globalid/globalid.rb
Normal file
90
ruby/ql/test/library-tests/frameworks/globalid/globalid.rb
Normal file
@@ -0,0 +1,90 @@
|
||||
class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def m1
|
||||
gid = User.find(1).to_global_id
|
||||
GlobalID::Locator.locate gid
|
||||
end
|
||||
|
||||
def m2
|
||||
gid = User.find(1).to_gid
|
||||
GlobalID::Locator.locate gid
|
||||
end
|
||||
|
||||
def m3
|
||||
sgid = User.find(1).to_signed_global_id
|
||||
GlobalID::Locator.locate_signed sgid
|
||||
end
|
||||
|
||||
def m4
|
||||
sgid = User.find(1).to_sgid
|
||||
GlobalID::Locator.locate_signed sgid
|
||||
end
|
||||
|
||||
def m5
|
||||
gids = User.all.map(&:to_gid)
|
||||
GlobalID::Locator.locate_many gids
|
||||
end
|
||||
|
||||
def m6
|
||||
sgids = User.all.map(&:to_sgid)
|
||||
GlobalID::Locator.locate_many_signed sgids
|
||||
end
|
||||
|
||||
def m7
|
||||
gidp = User.find(1).to_gid_param
|
||||
gid = GlobalID.parse gidp
|
||||
GlobalID.find gid
|
||||
end
|
||||
|
||||
def m8
|
||||
sgidp = User.find(1).to_sgid_param
|
||||
sgid = SignedGlobalID.parse sgidp
|
||||
SignedGlobalID.find sgid
|
||||
end
|
||||
|
||||
class Person
|
||||
include GlobalID::Identification
|
||||
|
||||
def self.find(id)
|
||||
# implementation goes here
|
||||
end
|
||||
end
|
||||
|
||||
def m9
|
||||
p = Person.find(1)
|
||||
gid = p.to_gid
|
||||
GlobalID.find gid
|
||||
end
|
||||
|
||||
def m10
|
||||
p = Person.find(1)
|
||||
gid = p.to_global_id
|
||||
GlobalID.find gid
|
||||
end
|
||||
|
||||
def m11
|
||||
p = Person.find(1)
|
||||
gidp = p.to_gid_param
|
||||
gid = GlobalID.parse gidp
|
||||
GlobalID::Locator.locate gid
|
||||
end
|
||||
|
||||
def m12
|
||||
p = Person.find(1)
|
||||
sgid = p.to_sgid
|
||||
SignedGlobalID.find sgid
|
||||
end
|
||||
|
||||
def m10
|
||||
p = Person.find(1)
|
||||
sgid = p.to_signed_global_id
|
||||
SignedGlobalID.find sgid
|
||||
end
|
||||
|
||||
def m11
|
||||
p = Person.find(1)
|
||||
sgidp = p.to_sgid_param
|
||||
sgid = SignedGlobalID.parse sgidp
|
||||
GlobalID::Locator.locate_signed sgid
|
||||
end
|
||||
@@ -142,6 +142,12 @@ calls.rb:
|
||||
#-----| super -> Object
|
||||
#-----| include -> Included
|
||||
|
||||
# 633| CustomNew1
|
||||
#-----| super -> Object
|
||||
|
||||
# 641| CustomNew2
|
||||
#-----| super -> Object
|
||||
|
||||
hello.rb:
|
||||
# 1| EnglishWords
|
||||
|
||||
|
||||
@@ -237,6 +237,14 @@ getTarget
|
||||
| calls.rb:620:9:620:16 | call to bar | calls.rb:628:5:630:7 | bar |
|
||||
| calls.rb:627:5:627:20 | call to include | calls.rb:108:5:110:7 | include |
|
||||
| calls.rb:629:9:629:13 | call to super | calls.rb:622:5:623:7 | bar |
|
||||
| calls.rb:635:9:635:14 | call to new | calls.rb:117:5:117:16 | new |
|
||||
| calls.rb:639:1:639:14 | call to new | calls.rb:117:5:117:16 | new |
|
||||
| calls.rb:639:1:639:14 | call to new | calls.rb:634:5:636:7 | new |
|
||||
| calls.rb:639:1:639:23 | call to instance | calls.rb:326:5:328:7 | instance |
|
||||
| calls.rb:647:9:647:34 | call to puts | calls.rb:102:5:102:30 | puts |
|
||||
| calls.rb:651:1:651:14 | call to new | calls.rb:117:5:117:16 | new |
|
||||
| calls.rb:651:1:651:14 | call to new | calls.rb:642:5:644:7 | new |
|
||||
| calls.rb:651:1:651:23 | call to instance | calls.rb:646:5:648:7 | instance |
|
||||
| hello.rb:12:5:12:24 | call to include | calls.rb:108:5:110:7 | include |
|
||||
| hello.rb:14:16:14:20 | call to hello | hello.rb:2:5:4:7 | hello |
|
||||
| hello.rb:20:16:20:20 | call to super | hello.rb:13:5:15:7 | message |
|
||||
@@ -361,6 +369,7 @@ unresolvedCall
|
||||
| calls.rb:562:1:562:13 | call to [] |
|
||||
| calls.rb:562:1:562:39 | call to each |
|
||||
| calls.rb:570:5:570:14 | call to singleton2 |
|
||||
| calls.rb:643:9:643:21 | call to allocate |
|
||||
| hello.rb:20:16:20:26 | ... + ... |
|
||||
| hello.rb:20:16:20:34 | ... + ... |
|
||||
| hello.rb:20:16:20:40 | ... + ... |
|
||||
@@ -483,6 +492,9 @@ publicMethod
|
||||
| calls.rb:619:5:621:7 | foo |
|
||||
| calls.rb:622:5:623:7 | bar |
|
||||
| calls.rb:628:5:630:7 | bar |
|
||||
| calls.rb:634:5:636:7 | new |
|
||||
| calls.rb:642:5:644:7 | new |
|
||||
| calls.rb:646:5:648:7 | instance |
|
||||
| hello.rb:2:5:4:7 | hello |
|
||||
| hello.rb:5:5:7:7 | world |
|
||||
| hello.rb:13:5:15:7 | message |
|
||||
|
||||
@@ -630,3 +630,22 @@ class IncludesIncluded
|
||||
end
|
||||
end
|
||||
|
||||
class CustomNew1
|
||||
def self.new
|
||||
C1.new
|
||||
end
|
||||
end
|
||||
|
||||
CustomNew1.new.instance
|
||||
|
||||
class CustomNew2
|
||||
def self.new
|
||||
self.allocate
|
||||
end
|
||||
|
||||
def instance
|
||||
puts "CustomNew2#instance"
|
||||
end
|
||||
end
|
||||
|
||||
CustomNew2.new.instance
|
||||
|
||||
@@ -48,6 +48,7 @@ getMethod
|
||||
| calls.rb:618:1:624:3 | Included | bar | calls.rb:622:5:623:7 | bar |
|
||||
| calls.rb:618:1:624:3 | Included | foo | calls.rb:619:5:621:7 | foo |
|
||||
| calls.rb:626:1:631:3 | IncludesIncluded | bar | calls.rb:628:5:630:7 | bar |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | instance | calls.rb:646:5:648:7 | instance |
|
||||
| hello.rb:1:1:8:3 | EnglishWords | hello | hello.rb:2:5:4:7 | hello |
|
||||
| hello.rb:1:1:8:3 | EnglishWords | world | hello.rb:5:5:7:7 | world |
|
||||
| hello.rb:11:1:16:3 | Greeting | message | hello.rb:13:5:15:7 | message |
|
||||
@@ -497,6 +498,35 @@ lookupMethod
|
||||
| calls.rb:626:1:631:3 | IncludesIncluded | private_on_main | calls.rb:185:1:186:3 | private_on_main |
|
||||
| calls.rb:626:1:631:3 | IncludesIncluded | puts | calls.rb:102:5:102:30 | puts |
|
||||
| calls.rb:626:1:631:3 | IncludesIncluded | to_s | calls.rb:172:5:173:7 | to_s |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | add_singleton | calls.rb:367:1:371:3 | add_singleton |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | call_block | calls.rb:81:1:83:3 | call_block |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | call_instance_m | calls.rb:39:1:41:3 | call_instance_m |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | create | calls.rb:278:1:286:3 | create |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | foo | calls.rb:1:1:3:3 | foo |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | foo | calls.rb:85:1:89:3 | foo |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | funny | calls.rb:140:1:142:3 | funny |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | indirect | calls.rb:158:1:160:3 | indirect |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | new | calls.rb:117:5:117:16 | new |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | optional_arg | calls.rb:76:1:79:3 | optional_arg |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | private_on_main | calls.rb:185:1:186:3 | private_on_main |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | puts | calls.rb:102:5:102:30 | puts |
|
||||
| calls.rb:633:1:637:3 | CustomNew1 | to_s | calls.rb:172:5:173:7 | to_s |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | add_singleton | calls.rb:367:1:371:3 | add_singleton |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | call_block | calls.rb:81:1:83:3 | call_block |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | call_instance_m | calls.rb:39:1:41:3 | call_instance_m |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | create | calls.rb:278:1:286:3 | create |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | foo | calls.rb:1:1:3:3 | foo |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | foo | calls.rb:85:1:89:3 | foo |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | funny | calls.rb:140:1:142:3 | funny |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | indirect | calls.rb:158:1:160:3 | indirect |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | instance | calls.rb:646:5:648:7 | instance |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | new | calls.rb:117:5:117:16 | new |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | optional_arg | calls.rb:76:1:79:3 | optional_arg |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | private_on_main | calls.rb:185:1:186:3 | private_on_main |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | puts | calls.rb:102:5:102:30 | puts |
|
||||
| calls.rb:641:1:649:3 | CustomNew2 | to_s | calls.rb:172:5:173:7 | to_s |
|
||||
| file://:0:0:0:0 | Class | include | calls.rb:108:5:110:7 | include |
|
||||
| file://:0:0:0:0 | Class | module_eval | calls.rb:107:5:107:24 | module_eval |
|
||||
| file://:0:0:0:0 | Class | new | calls.rb:117:5:117:16 | new |
|
||||
@@ -987,6 +1017,14 @@ enclosingMethod
|
||||
| calls.rb:620:9:620:12 | self | calls.rb:619:5:621:7 | foo |
|
||||
| calls.rb:620:9:620:16 | call to bar | calls.rb:619:5:621:7 | foo |
|
||||
| calls.rb:629:9:629:13 | call to super | calls.rb:628:5:630:7 | bar |
|
||||
| calls.rb:635:9:635:10 | C1 | calls.rb:634:5:636:7 | new |
|
||||
| calls.rb:635:9:635:14 | call to new | calls.rb:634:5:636:7 | new |
|
||||
| calls.rb:643:9:643:12 | self | calls.rb:642:5:644:7 | new |
|
||||
| calls.rb:643:9:643:21 | call to allocate | calls.rb:642:5:644:7 | new |
|
||||
| calls.rb:647:9:647:34 | call to puts | calls.rb:646:5:648:7 | instance |
|
||||
| calls.rb:647:9:647:34 | self | calls.rb:646:5:648:7 | instance |
|
||||
| calls.rb:647:14:647:34 | "CustomNew2#instance" | calls.rb:646:5:648:7 | instance |
|
||||
| calls.rb:647:15:647:33 | CustomNew2#instance | calls.rb:646:5:648:7 | instance |
|
||||
| hello.rb:3:9:3:22 | return | hello.rb:2:5:4:7 | hello |
|
||||
| hello.rb:3:16:3:22 | "hello" | hello.rb:2:5:4:7 | hello |
|
||||
| hello.rb:3:17:3:21 | hello | hello.rb:2:5:4:7 | hello |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -136,6 +136,12 @@ calls.rb:
|
||||
# 626| IncludesIncluded
|
||||
#-----| -> Object
|
||||
|
||||
# 633| CustomNew1
|
||||
#-----| -> Object
|
||||
|
||||
# 641| CustomNew2
|
||||
#-----| -> Object
|
||||
|
||||
hello.rb:
|
||||
# 1| EnglishWords
|
||||
|
||||
|
||||
@@ -12,3 +12,4 @@
|
||||
| Definitions.rb:41:7:41:9 | @@b | Definitions.rb:27:5:27:7 | @@b | class variable |
|
||||
| Definitions.rb:46:1:46:1 | C | Definitions.rb:19:1:44:3 | C | constant |
|
||||
| Definitions.rb:46:1:46:4 | D | Definitions.rb:26:3:43:5 | D | constant |
|
||||
| Definitions.rb:46:1:46:8 | call to new | Definitions.rb:29:5:33:7 | initialize | method |
|
||||
|
||||
Reference in New Issue
Block a user