mirror of
https://github.com/github/codeql.git
synced 2026-07-05 11:35:30 +02:00
Compare commits
46 Commits
codeql-cli
...
rb/data-fl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27e1a8bd7a | ||
|
|
d4b018f242 | ||
|
|
25f0382fce | ||
|
|
af5a378572 | ||
|
|
9a38e31baa | ||
|
|
ff20908bbd | ||
|
|
25dd8db423 | ||
|
|
5fa49b3319 | ||
|
|
8b85744d3e | ||
|
|
4ae90e35d5 | ||
|
|
472a10fd54 | ||
|
|
0f1b3486de | ||
|
|
a195ea942e | ||
|
|
cf4a3e0bbe | ||
|
|
fe8945b5c9 | ||
|
|
bd2a065562 | ||
|
|
2619f3f667 | ||
|
|
ab4e341e65 | ||
|
|
9da5ec79c5 | ||
|
|
e549f15b1c | ||
|
|
056b1e8d63 | ||
|
|
9be2512050 | ||
|
|
b4b34cc994 | ||
|
|
12ce46e4b1 | ||
|
|
38955d1761 | ||
|
|
9f59b6b439 | ||
|
|
0a8f39fe96 | ||
|
|
ff02ba5965 | ||
|
|
017157820a | ||
|
|
b29ac5249e | ||
|
|
4ed61c13f8 | ||
|
|
b632e21ba0 | ||
|
|
06ec03de74 | ||
|
|
046e669c78 | ||
|
|
77d1788619 | ||
|
|
2546d09fe2 | ||
|
|
515b8366d2 | ||
|
|
c8f7519cee | ||
|
|
1f644a9c1d | ||
|
|
436cc60138 | ||
|
|
156964bfc9 | ||
|
|
67772bbc43 | ||
|
|
8976ba5583 | ||
|
|
ac4cac889f | ||
|
|
65add15416 | ||
|
|
aab1e1f5b4 |
@@ -36,6 +36,13 @@ private module Cached {
|
|||||||
not s instanceof ModuleBase and
|
not s instanceof ModuleBase and
|
||||||
result = getEnclosingMethod(s.getOuterScope())
|
result = getEnclosingMethod(s.getOuterScope())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
|
Toplevel getEnclosingToplevel(Scope s) {
|
||||||
|
result = s
|
||||||
|
or
|
||||||
|
result = getEnclosingToplevel(s.getOuterScope())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private import Cached
|
private import Cached
|
||||||
@@ -66,6 +73,9 @@ class AstNode extends TAstNode {
|
|||||||
/** Gets the enclosing method, if any. */
|
/** Gets the enclosing method, if any. */
|
||||||
final MethodBase getEnclosingMethod() { result = getEnclosingMethod(scopeOfInclSynth(this)) }
|
final MethodBase getEnclosingMethod() { result = getEnclosingMethod(scopeOfInclSynth(this)) }
|
||||||
|
|
||||||
|
/** Gets the enclosing top-level. */
|
||||||
|
final Toplevel getEnclosingToplevel() { result = getEnclosingToplevel(scopeOfInclSynth(this)) }
|
||||||
|
|
||||||
/** Gets a textual representation of this node. */
|
/** Gets a textual representation of this node. */
|
||||||
cached
|
cached
|
||||||
string toString() { none() }
|
string toString() { none() }
|
||||||
|
|||||||
@@ -271,10 +271,7 @@ module Http {
|
|||||||
|
|
||||||
/** Gets the URL pattern for this route, if it can be statically determined. */
|
/** Gets the URL pattern for this route, if it can be statically determined. */
|
||||||
string getUrlPattern() {
|
string getUrlPattern() {
|
||||||
exists(CfgNodes::ExprNodes::StringlikeLiteralCfgNode strNode |
|
result = this.getUrlPatternArg().getALocalSource().getConstantValue().getStringlikeValue()
|
||||||
this.getUrlPatternArg().getALocalSource() = DataFlow::exprNode(strNode) and
|
|
||||||
result = strNode.getExpr().getConstantValue().getStringlikeValue()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -538,10 +535,12 @@ module Http {
|
|||||||
|
|
||||||
/** Gets the mimetype of this HTTP response, if it can be statically determined. */
|
/** Gets the mimetype of this HTTP response, if it can be statically determined. */
|
||||||
string getMimetype() {
|
string getMimetype() {
|
||||||
exists(CfgNodes::ExprNodes::StringlikeLiteralCfgNode strNode |
|
result =
|
||||||
this.getMimetypeOrContentTypeArg().getALocalSource() = DataFlow::exprNode(strNode) and
|
this.getMimetypeOrContentTypeArg()
|
||||||
result = strNode.getExpr().getConstantValue().getStringlikeValue().splitAt(";", 0)
|
.getALocalSource()
|
||||||
)
|
.getConstantValue()
|
||||||
|
.getStringlikeValue()
|
||||||
|
.splitAt(";", 0)
|
||||||
or
|
or
|
||||||
not exists(this.getMimetypeOrContentTypeArg()) and
|
not exists(this.getMimetypeOrContentTypeArg()) and
|
||||||
result = this.getMimetypeDefault()
|
result = this.getMimetypeDefault()
|
||||||
|
|||||||
@@ -170,6 +170,24 @@ module ConstantValue {
|
|||||||
|
|
||||||
/** A constant `nil` value. */
|
/** A constant `nil` value. */
|
||||||
class ConstantNilValue extends ConstantValue, TNil { }
|
class ConstantNilValue extends ConstantValue, TNil { }
|
||||||
|
|
||||||
|
/** Gets the integer constant `x`. */
|
||||||
|
ConstantValue fromInt(int x) { result.getInt() = x }
|
||||||
|
|
||||||
|
/** Gets the float constant `x`. */
|
||||||
|
ConstantValue fromFloat(float x) { result.getFloat() = x }
|
||||||
|
|
||||||
|
/** Gets the string constant `x`. */
|
||||||
|
ConstantValue fromString(string x) { result.getString() = x }
|
||||||
|
|
||||||
|
/** Gets the symbol constant `x`. */
|
||||||
|
ConstantValue fromSymbol(string x) { result.getSymbol() = x }
|
||||||
|
|
||||||
|
/** Gets the regexp constant `x`. */
|
||||||
|
ConstantValue fromRegExp(string x) { result.getRegExp() = x }
|
||||||
|
|
||||||
|
/** Gets the string, symbol, or regexp constant `x`. */
|
||||||
|
ConstantValue fromStringlikeValue(string x) { result.getStringlikeValue() = x }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An access to a constant. */
|
/** An access to a constant. */
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ private import codeql.ruby.CFG
|
|||||||
private import internal.AST
|
private import internal.AST
|
||||||
private import internal.Module
|
private import internal.Module
|
||||||
private import internal.TreeSitter
|
private import internal.TreeSitter
|
||||||
|
private import internal.Scope
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of a run-time `module` or `class` value.
|
* A representation of a run-time `module` or `class` value.
|
||||||
@@ -23,6 +24,22 @@ class Module extends TModule {
|
|||||||
/** Gets an `include`d module. */
|
/** Gets an `include`d module. */
|
||||||
Module getAnIncludedModule() { result = getAnIncludedModule(this) }
|
Module getAnIncludedModule() { result = getAnIncludedModule(this) }
|
||||||
|
|
||||||
|
/** Gets the super class or an included or prepended module. */
|
||||||
|
Module getAnImmediateAncestor() {
|
||||||
|
result = [this.getSuperClass(), this.getAPrependedModule(), this.getAnIncludedModule()]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets a direct subclass or module including or prepending this one. */
|
||||||
|
Module getAnImmediateDescendent() { this = result.getAnImmediateAncestor() }
|
||||||
|
|
||||||
|
/** Gets a module that is transitively subclassed, included, or prepended by this module. */
|
||||||
|
pragma[inline]
|
||||||
|
Module getAnAncestor() { result = this.getAnImmediateAncestor*() }
|
||||||
|
|
||||||
|
/** Gets a module that transitively subclasses, includes, or prepends this module. */
|
||||||
|
pragma[inline]
|
||||||
|
Module getADescendent() { result = this.getAnImmediateDescendent*() }
|
||||||
|
|
||||||
/** Holds if this module is a class. */
|
/** Holds if this module is a class. */
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
predicate isClass() {
|
predicate isClass() {
|
||||||
@@ -63,6 +80,99 @@ class Module extends TModule {
|
|||||||
loc.getStartColumn()
|
loc.getStartColumn()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets a constant or `self` access that refers to this module. */
|
||||||
|
private Expr getAnImmediateReferenceBase() {
|
||||||
|
resolveConstantReadAccess(result) = this
|
||||||
|
or
|
||||||
|
result.(SelfVariableAccess).getVariable() = this.getADeclaration().getModuleSelfVariable()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets a singleton class that augments this module object. */
|
||||||
|
SingletonClass getASingletonClass() { result.getValue() = this.getAnImmediateReferenceBase() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a singleton method on this module, either declared as a singleton method
|
||||||
|
* or an instance method on a singleton class.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
MethodBase getAnOwnSingletonMethod() {
|
||||||
|
result.(SingletonMethod).getObject() = this.getAnImmediateReferenceBase()
|
||||||
|
or
|
||||||
|
result = this.getASingletonClass().getAMethod().(Method)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance method named `name` declared in this module.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
Method getOwnInstanceMethod(string name) { result = this.getADeclaration().getMethod(name) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance method declared in this module.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
Method getAnOwnInstanceMethod() { result = this.getADeclaration().getMethod(_) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instance method named `name` available in this module, including methods inherited
|
||||||
|
* from ancestors.
|
||||||
|
*/
|
||||||
|
Method getInstanceMethod(string name) { result = lookupMethod(this, name) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance method available in this module, including methods inherited
|
||||||
|
* from ancestors.
|
||||||
|
*/
|
||||||
|
Method getAnInstanceMethod() { result = lookupMethod(this, _) }
|
||||||
|
|
||||||
|
/** Gets a constant or `self` access that refers to this module. */
|
||||||
|
Expr getAnImmediateReference() {
|
||||||
|
result = this.getAnImmediateReferenceBase()
|
||||||
|
or
|
||||||
|
result.(SelfVariableAccess).getVariable().getDeclaringScope() = this.getAnOwnSingletonMethod()
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private string getEnclosingModuleName() {
|
||||||
|
exists(string qname |
|
||||||
|
qname = this.getQualifiedName() and
|
||||||
|
result = qname.regexpReplaceAll("::[^:]*$", "") and
|
||||||
|
qname != result
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private string getOwnModuleName() {
|
||||||
|
result = this.getQualifiedName().regexpReplaceAll("^.*::", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the enclosing module, as it appears in the qualified name of this module.
|
||||||
|
*
|
||||||
|
* For example, the parent module of `A::B` is `A`, and `A` itself has no parent module.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
Module getParentModule() { result.getQualifiedName() = this.getEnclosingModuleName() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a module named `name` declared inside this one (not aliased), provided
|
||||||
|
* that such a module is defined or reopened in the current codebase.
|
||||||
|
*
|
||||||
|
* For example, for `A::B` the nested module named `C` would be `A::B::C`.
|
||||||
|
*
|
||||||
|
* Note that this is not the same as constant lookup. If `A::B::C` would resolve to a
|
||||||
|
* module whose qualified name is not `A::B::C`, then it will not be found by
|
||||||
|
* this predicate.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
Module getNestedModule(string name) {
|
||||||
|
result.getParentModule() = this and
|
||||||
|
result.getOwnModuleName() = name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,6 +251,46 @@ class ModuleBase extends BodyStmt, Scope, TModuleBase {
|
|||||||
|
|
||||||
/** Gets the representation of the run-time value of this module or class. */
|
/** Gets the representation of the run-time value of this module or class. */
|
||||||
Module getModule() { none() }
|
Module getModule() { none() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the `self` variable in the module-level scope.
|
||||||
|
*
|
||||||
|
* Does not include the `self` variable from any of the methods in the module.
|
||||||
|
*/
|
||||||
|
SelfVariable getModuleSelfVariable() { result.getDeclaringScope() = this }
|
||||||
|
|
||||||
|
/** Gets the nearest enclosing `Namespace` or `Toplevel`, possibly this module itself. */
|
||||||
|
Namespace getNamespaceOrToplevel() {
|
||||||
|
result = this
|
||||||
|
or
|
||||||
|
not this instanceof Namespace and
|
||||||
|
result = this.getEnclosingModule().getNamespaceOrToplevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an expression denoting the super class or an included or prepended module.
|
||||||
|
*
|
||||||
|
* For example, `C` is an ancestor expression of `M` in each of the following examples:
|
||||||
|
* ```rb
|
||||||
|
* class M < C
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* module M
|
||||||
|
* include C
|
||||||
|
* prepend C
|
||||||
|
* end
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
Expr getAnAncestorExpr() {
|
||||||
|
exists(MethodCall call |
|
||||||
|
call.getReceiver().(SelfVariableAccess).getVariable() = this.getModuleSelfVariable() and
|
||||||
|
call.getMethodName() = ["include", "prepend"] and
|
||||||
|
result = call.getArgument(0) and
|
||||||
|
scopeOfInclSynth(call) = this // only permit calls directly in the module scope, not in a block
|
||||||
|
)
|
||||||
|
or
|
||||||
|
result = this.(ClassDeclaration).getSuperclassExpr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ module Ssa {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
final override string toString() { result = "<captured>" }
|
final override string toString() { result = "<captured> " + this.getSourceVariable() }
|
||||||
|
|
||||||
override Location getLocation() { result = this.getBasicBlock().getLocation() }
|
override Location getLocation() { result = this.getBasicBlock().getLocation() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,11 +109,27 @@ module LocalFlow {
|
|||||||
* Holds if `nodeFrom` is a parameter node, and `nodeTo` is a corresponding SSA node.
|
* Holds if `nodeFrom` is a parameter node, and `nodeTo` is a corresponding SSA node.
|
||||||
*/
|
*/
|
||||||
predicate localFlowSsaParamInput(Node nodeFrom, Node nodeTo) {
|
predicate localFlowSsaParamInput(Node nodeFrom, Node nodeTo) {
|
||||||
nodeTo = getParameterDefNode(nodeFrom.(ParameterNode).getParameter())
|
nodeTo = getParameterDefNode(nodeFrom.(ParameterNodeImpl).getParameter())
|
||||||
or
|
or
|
||||||
nodeTo = getSelfParameterDefNode(nodeFrom.(SelfParameterNode).getMethod())
|
nodeTo = getSelfParameterDefNode(nodeFrom.(SelfParameterNode).getMethod())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `nodeFrom -> nodeTo` is a step from a parameter to a capture entry node for
|
||||||
|
* that parameter.
|
||||||
|
*
|
||||||
|
* This is intended to recover from flow not currently recognised by ordinary capture flow.
|
||||||
|
*/
|
||||||
|
predicate localFlowSsaParamCaptureInput(Node nodeFrom, Node nodeTo) {
|
||||||
|
exists(Ssa::CapturedEntryDefinition def |
|
||||||
|
nodeFrom.asParameter().(NamedParameter).getVariable() = def.getSourceVariable()
|
||||||
|
or
|
||||||
|
nodeFrom.(SelfParameterNode).getSelfVariable() = def.getSourceVariable()
|
||||||
|
|
|
||||||
|
nodeTo.(SsaDefinitionNode).getDefinition() = def
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo`
|
* Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo`
|
||||||
* involving SSA definition `def`.
|
* involving SSA definition `def`.
|
||||||
@@ -246,6 +262,9 @@ private module Cached {
|
|||||||
)
|
)
|
||||||
} or
|
} or
|
||||||
TSsaDefinitionNode(Ssa::Definition def) or
|
TSsaDefinitionNode(Ssa::Definition def) or
|
||||||
|
TRawNamespaceSelf(Namespace ns) {
|
||||||
|
not exists(Ssa::SelfDefinition def | def.getSourceVariable() = ns.getModuleSelfVariable())
|
||||||
|
} or
|
||||||
TNormalParameterNode(Parameter p) {
|
TNormalParameterNode(Parameter p) {
|
||||||
p instanceof SimpleParameter or
|
p instanceof SimpleParameter or
|
||||||
p instanceof OptionalParameter or
|
p instanceof OptionalParameter or
|
||||||
@@ -299,7 +318,7 @@ private module Cached {
|
|||||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||||
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
||||||
or
|
or
|
||||||
defaultValueFlow(nodeTo.(ParameterNode).getParameter(), nodeFrom)
|
defaultValueFlow(nodeTo.(ParameterNodeImpl).getParameter(), nodeFrom)
|
||||||
or
|
or
|
||||||
LocalFlow::localFlowSsaParamInput(nodeFrom, nodeTo)
|
LocalFlow::localFlowSsaParamInput(nodeFrom, nodeTo)
|
||||||
or
|
or
|
||||||
@@ -316,7 +335,7 @@ private module Cached {
|
|||||||
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) {
|
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) {
|
||||||
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
||||||
or
|
or
|
||||||
defaultValueFlow(nodeTo.(ParameterNode).getParameter(), nodeFrom)
|
defaultValueFlow(nodeTo.(ParameterNodeImpl).getParameter(), nodeFrom)
|
||||||
or
|
or
|
||||||
LocalFlow::localFlowSsaParamInput(nodeFrom, nodeTo)
|
LocalFlow::localFlowSsaParamInput(nodeFrom, nodeTo)
|
||||||
or
|
or
|
||||||
@@ -327,7 +346,12 @@ private module Cached {
|
|||||||
FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo, _)
|
FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This is the local flow predicate that is used in type tracking. */
|
/**
|
||||||
|
* This is the local flow predicate that is used in type tracking.
|
||||||
|
*
|
||||||
|
* This needs to exclude `localFlowSsaParamInput` due to a performance trick
|
||||||
|
* in type tracking, where such steps are treated as call steps.
|
||||||
|
*/
|
||||||
cached
|
cached
|
||||||
predicate localFlowStepTypeTracker(Node nodeFrom, Node nodeTo) {
|
predicate localFlowStepTypeTracker(Node nodeFrom, Node nodeTo) {
|
||||||
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
||||||
@@ -366,7 +390,7 @@ private module Cached {
|
|||||||
|
|
||||||
cached
|
cached
|
||||||
predicate isLocalSourceNode(Node n) {
|
predicate isLocalSourceNode(Node n) {
|
||||||
n instanceof ParameterNode
|
n instanceof TParameterNode
|
||||||
or
|
or
|
||||||
// Expressions that can't be reached from another entry definition or expression
|
// Expressions that can't be reached from another entry definition or expression
|
||||||
n instanceof ExprNode and
|
n instanceof ExprNode and
|
||||||
@@ -381,6 +405,8 @@ private module Cached {
|
|||||||
or
|
or
|
||||||
// Needed for stores in type tracking
|
// Needed for stores in type tracking
|
||||||
TypeTrackerSpecific::storeStepIntoSourceNode(_, n, _)
|
TypeTrackerSpecific::storeStepIntoSourceNode(_, n, _)
|
||||||
|
or
|
||||||
|
n instanceof TRawNamespaceSelf
|
||||||
}
|
}
|
||||||
|
|
||||||
cached
|
cached
|
||||||
@@ -502,6 +528,38 @@ class SsaSelfDefinitionNode extends LocalSourceNode, SsaDefinitionNode {
|
|||||||
Scope getSelfScope() { result = self.getDeclaringScope() }
|
Scope getSelfScope() { result = self.getDeclaringScope() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A representative for the created or re-opened class/module in a `Namespace` that does
|
||||||
|
* not have an SSA definition for `self`.
|
||||||
|
*/
|
||||||
|
class RawNamespaceSelf extends NodeImpl, TRawNamespaceSelf {
|
||||||
|
private Namespace namespace;
|
||||||
|
|
||||||
|
RawNamespaceSelf() { this = TRawNamespaceSelf(namespace) }
|
||||||
|
|
||||||
|
/** Gets the namespace for which this represents the created or re-opened class/module. */
|
||||||
|
Namespace getNamespace() { result = namespace }
|
||||||
|
|
||||||
|
override CfgScope getCfgScope() { result = namespace.getCfgScope() }
|
||||||
|
|
||||||
|
override Location getLocationImpl() { result = namespace.getLocation() }
|
||||||
|
|
||||||
|
override string toStringImpl() { result = namespace.toString() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a representative for the created or re-opened class/module in a `Namespace`.
|
||||||
|
*
|
||||||
|
* This is usually the SSA definition for `self`, but if this node does not exist due to lack of liveness,
|
||||||
|
* it is the `RawNamespaceSelf` node.
|
||||||
|
*/
|
||||||
|
LocalSourceNode getNamespaceSelf(Namespace namespace) {
|
||||||
|
result.(SsaDefinitionNode).getDefinition().(Ssa::SelfDefinition).getSourceVariable() =
|
||||||
|
namespace.getModuleSelfVariable()
|
||||||
|
or
|
||||||
|
result = TRawNamespaceSelf(namespace)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A value returning statement, viewed as a node in a data flow graph.
|
* A value returning statement, viewed as a node in a data flow graph.
|
||||||
*
|
*
|
||||||
@@ -1242,7 +1300,7 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
|
|||||||
creation.asExpr() =
|
creation.asExpr() =
|
||||||
any(CfgNodes::ExprNodes::MethodCallCfgNode mc |
|
any(CfgNodes::ExprNodes::MethodCallCfgNode mc |
|
||||||
c.asCallable() = mc.getBlock().getExpr() and
|
c.asCallable() = mc.getBlock().getExpr() and
|
||||||
mc.getExpr().getMethodName() = "lambda"
|
mc.getExpr().getMethodName() = ["lambda", "proc"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,30 @@ class Node extends TNode {
|
|||||||
* Gets a data flow node to which data may flow from this node in one local step.
|
* Gets a data flow node to which data may flow from this node in one local step.
|
||||||
*/
|
*/
|
||||||
Node getASuccessor() { localFlowStep(this, result) }
|
Node getASuccessor() { localFlowStep(this, result) }
|
||||||
|
|
||||||
|
/** Gets the constant value of this expression, if any. */
|
||||||
|
ConstantValue getConstantValue() { result = this.asExpr().getConstantValue() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the callable corresponding to this block, lambda expression, or call to `proc` or `lambda`.
|
||||||
|
*
|
||||||
|
* For example, gets the callable in each of the following cases:
|
||||||
|
* ```rb
|
||||||
|
* { |x| x } # block expression
|
||||||
|
* ->(x) { x } # lambda expression
|
||||||
|
* proc { |x| x } # call to 'proc'
|
||||||
|
* lambda { |x| x } # call to 'lambda'
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
pragma[noinline]
|
||||||
|
CallableNode asCallable() {
|
||||||
|
result = this
|
||||||
|
or
|
||||||
|
exists(DataFlowCallable c |
|
||||||
|
lambdaCreation(this, _, c) and
|
||||||
|
result.asCallableAstNode() = c.asCallable()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A data-flow node corresponding to a call in the control-flow graph. */
|
/** A data-flow node corresponding to a call in the control-flow graph. */
|
||||||
@@ -124,6 +148,31 @@ class CallNode extends LocalSourceNode, ExprNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A call to a setter method.
|
||||||
|
*
|
||||||
|
* For example,
|
||||||
|
* ```rb
|
||||||
|
* self.foo = 10
|
||||||
|
* a[0] = 10
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
class SetterCallNode extends CallNode {
|
||||||
|
SetterCallNode() { this.getExprNode().getExpr() instanceof SetterMethodCall }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the method being called without the trailing `=`. For example, in the following
|
||||||
|
* two statements the target name is `value`:
|
||||||
|
* ```rb
|
||||||
|
* foo.value=(1)
|
||||||
|
* foo.value = 1
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
final string getTargetName() {
|
||||||
|
result = this.getExprNode().getExpr().(SetterMethodCall).getTargetName()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An expression, viewed as a node in a data flow graph.
|
* An expression, viewed as a node in a data flow graph.
|
||||||
*
|
*
|
||||||
@@ -144,7 +193,7 @@ class ExprNode extends Node, TExprNode {
|
|||||||
* The value of a parameter at function entry, viewed as a node in a data
|
* The value of a parameter at function entry, viewed as a node in a data
|
||||||
* flow graph.
|
* flow graph.
|
||||||
*/
|
*/
|
||||||
class ParameterNode extends Node, TParameterNode instanceof ParameterNodeImpl {
|
class ParameterNode extends LocalSourceNode, TParameterNode instanceof ParameterNodeImpl {
|
||||||
/** Gets the parameter corresponding to this node, if any. */
|
/** Gets the parameter corresponding to this node, if any. */
|
||||||
final Parameter getParameter() { result = super.getParameter() }
|
final Parameter getParameter() { result = super.getParameter() }
|
||||||
}
|
}
|
||||||
@@ -174,6 +223,80 @@ class LocalSourceNode extends Node {
|
|||||||
*/
|
*/
|
||||||
pragma[inline]
|
pragma[inline]
|
||||||
LocalSourceNode backtrack(TypeBackTracker t2, TypeBackTracker t) { t2 = t.step(result, this) }
|
LocalSourceNode backtrack(TypeBackTracker t2, TypeBackTracker t) { t2 = t.step(result, this) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a node to which data may flow from this node in zero or
|
||||||
|
* more local data-flow steps.
|
||||||
|
*/
|
||||||
|
pragma[inline]
|
||||||
|
Node getALocalUse() { hasLocalSource(result, this) }
|
||||||
|
|
||||||
|
/** Gets a method call where this node flows to the receiver. */
|
||||||
|
CallNode getAMethodCall() { Cached::hasMethodCall(this, result, _) }
|
||||||
|
|
||||||
|
/** Gets a call to a method named `name`, where this node flows to the receiver. */
|
||||||
|
CallNode getAMethodCall(string name) { Cached::hasMethodCall(this, result, name) }
|
||||||
|
|
||||||
|
/** Gets a call `obj.name` with no arguments, where this node flows to `obj`. */
|
||||||
|
CallNode getAnAttributeRead(string name) {
|
||||||
|
result = this.getAMethodCall(name) and
|
||||||
|
result.getNumberOfArguments() = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a value assigned to `name` on this object, such as the `x` in `obj.name = x`.
|
||||||
|
*
|
||||||
|
* Concretely, this gets the argument of any call to `name=` where this node flows to the receiver.
|
||||||
|
*/
|
||||||
|
Node getAnAttributeWriteValue(string name) {
|
||||||
|
result = this.getAMethodCall(name + "=").getArgument(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an access to an element on this node, such as `obj[key]`.
|
||||||
|
*
|
||||||
|
* Concretely this gets a call to `[]` with 1 argument, where this node flows to the receiver.
|
||||||
|
*/
|
||||||
|
CallNode getAnElementRead() {
|
||||||
|
result = this.getAMethodCall("[]") and result.getNumberOfArguments() = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an access to the element `key` on this node, such as `obj[:key]`.
|
||||||
|
*
|
||||||
|
* Concretely this gets a call to `[]` where this node flows to the receiver
|
||||||
|
* and the first and only argument has the constant value `key`.
|
||||||
|
*/
|
||||||
|
CallNode getAnElementRead(ConstantValue key) {
|
||||||
|
result = this.getAnElementRead() and
|
||||||
|
key = result.getArgument(0).getConstantValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
private CallNode getAnElementWriteCall() {
|
||||||
|
result = this.getAMethodCall("[]=") and
|
||||||
|
result.getNumberOfArguments() = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a value stored as an element on this node, such as the `x` in `obj[key] = x`.
|
||||||
|
*
|
||||||
|
* Concretely, this gets the second argument from any call to `[]=` where this node flows to the receiver.
|
||||||
|
*/
|
||||||
|
Node getAnElementWriteValue() { result = this.getAnElementWriteCall().getArgument(1) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the `x` in `obj[key] = x`, where this node flows to `obj`.
|
||||||
|
*
|
||||||
|
* Concretely, this gets the second argument from any call to `[]=` where this node flows to the receiver
|
||||||
|
* and the first argument has constant value `key`.
|
||||||
|
*/
|
||||||
|
Node getAnElementWriteValue(ConstantValue key) {
|
||||||
|
exists(CallNode call |
|
||||||
|
call = this.getAnElementWriteCall() and
|
||||||
|
call.getArgument(0).getConstantValue() = key and
|
||||||
|
result = call.getArgument(1)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,18 +316,74 @@ class PostUpdateNode extends Node instanceof PostUpdateNodeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cached
|
cached
|
||||||
private predicate hasLocalSource(Node sink, Node source) {
|
private module Cached {
|
||||||
|
cached
|
||||||
|
predicate hasLocalSource(Node sink, Node source) {
|
||||||
// Declaring `source` to be a `SourceNode` currently causes a redundant check in the
|
// Declaring `source` to be a `SourceNode` currently causes a redundant check in the
|
||||||
// recursive case, so instead we check it explicitly here.
|
// recursive case, so instead we check it explicitly here.
|
||||||
source = sink and
|
source = sink and
|
||||||
source instanceof LocalSourceNode
|
source instanceof LocalSourceNode
|
||||||
or
|
or
|
||||||
exists(Node mid |
|
exists(Node mid | hasLocalSource(mid, source) |
|
||||||
hasLocalSource(mid, source) and
|
|
||||||
localFlowStepTypeTracker(mid, sink)
|
localFlowStepTypeTracker(mid, sink)
|
||||||
|
or
|
||||||
|
// Explicitly include the SSA param input step as type-tracking omits this step.
|
||||||
|
LocalFlow::localFlowSsaParamInput(mid, sink)
|
||||||
|
or
|
||||||
|
LocalFlow::localFlowSsaParamCaptureInput(mid, sink)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
|
predicate hasMethodCall(LocalSourceNode source, CallNode call, string name) {
|
||||||
|
source.flowsTo(call.getReceiver()) and
|
||||||
|
call.getMethodName() = name
|
||||||
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
|
predicate hasYieldCall(BlockParameterNode block, CallNode yield) {
|
||||||
|
exists(MethodBase method, YieldCall call |
|
||||||
|
block.getMethod() = method and
|
||||||
|
call.getEnclosingMethod() = method and
|
||||||
|
yield.asExpr().getExpr() = call
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A place in which a named constant can be looked up during constant lookup.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
newtype TConstLookupScope =
|
||||||
|
/** Look up in a qualified constant name `base::`. */
|
||||||
|
MkQualifiedLookup(ConstantAccess base) or
|
||||||
|
/** Look up in the ancestors of `mod`. */
|
||||||
|
MkAncestorLookup(Module mod) or
|
||||||
|
/** Look up in a module syntactically nested in a declaration of `mod`. */
|
||||||
|
MkNestedLookup(Module mod) or
|
||||||
|
/** Pseudo-scope for accesses that are known to resolve to `mod`. */
|
||||||
|
MkExactLookup(Module mod)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a `LocalSourceNode` to represent the constant read or written by `access`.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
LocalSourceNode getConstantAccessNode(ConstantAccess access) {
|
||||||
|
// Namespaces don't evaluate to the constant being accessed, they return the value of their last statement.
|
||||||
|
// Use the definition of 'self' in the namespace as the representative in this case.
|
||||||
|
if access instanceof Namespace
|
||||||
|
then result = getNamespaceSelf(access)
|
||||||
|
else result.asExpr().getExpr() = access
|
||||||
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
|
predicate forceCachingInSameStage() { any() }
|
||||||
|
|
||||||
|
cached
|
||||||
|
predicate forceCachingBackref() { exists(any(ConstRef const).getConst(_)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private import Cached
|
||||||
|
|
||||||
/** Gets a node corresponding to expression `e`. */
|
/** Gets a node corresponding to expression `e`. */
|
||||||
ExprNode exprNode(CfgNodes::ExprCfgNode e) { result.getExprNode() = e }
|
ExprNode exprNode(CfgNodes::ExprCfgNode e) { result.getExprNode() = e }
|
||||||
|
|
||||||
@@ -559,3 +738,591 @@ abstract deprecated class BarrierGuard extends CfgNodes::ExprCfgNode {
|
|||||||
result.asExpr() = this.getAMaybeGuardedCapturedDef().getARead()
|
result.asExpr() = this.getAMaybeGuardedCapturedDef().getARead()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A representation of a run-time module or class.
|
||||||
|
*
|
||||||
|
* This is equivalent to the type `Ast::Module` but provides data-flow specific methods.
|
||||||
|
*/
|
||||||
|
class ModuleNode instanceof Module {
|
||||||
|
/** Gets a declaration of this module, if any. */
|
||||||
|
final ModuleBase getADeclaration() { result = super.getADeclaration() }
|
||||||
|
|
||||||
|
/** Gets the super class of this module, if any. */
|
||||||
|
final ModuleNode getSuperClass() { result = super.getSuperClass() }
|
||||||
|
|
||||||
|
/** Gets an immediate sub class of this module, if any. */
|
||||||
|
final ModuleNode getASubClass() { result = super.getASubClass() }
|
||||||
|
|
||||||
|
/** Gets a `prepend`ed module. */
|
||||||
|
final ModuleNode getAPrependedModule() { result = super.getAPrependedModule() }
|
||||||
|
|
||||||
|
/** Gets an `include`d module. */
|
||||||
|
final ModuleNode getAnIncludedModule() { result = super.getAnIncludedModule() }
|
||||||
|
|
||||||
|
/** Gets the super class or an included or prepended module. */
|
||||||
|
final ModuleNode getAnImmediateAncestor() { result = super.getAnImmediateAncestor() }
|
||||||
|
|
||||||
|
/** Gets a direct subclass or module including or prepending this one. */
|
||||||
|
final ModuleNode getAnImmediateDescendent() { result = super.getAnImmediateDescendent() }
|
||||||
|
|
||||||
|
/** Gets a module that is transitively subclassed, included, or prepended by this module. */
|
||||||
|
pragma[inline]
|
||||||
|
final ModuleNode getAnAncestor() { result = super.getAnAncestor() }
|
||||||
|
|
||||||
|
/** Gets a module that transitively subclasses, includes, or prepends this module. */
|
||||||
|
pragma[inline]
|
||||||
|
final ModuleNode getADescendent() { result = super.getADescendent() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the expression node denoting the super class or an included or prepended module.
|
||||||
|
*
|
||||||
|
* For example, `C` is an ancestor expression of `M` in each of the following examples:
|
||||||
|
* ```rb
|
||||||
|
* class M < C
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* module M
|
||||||
|
* include C
|
||||||
|
* prepend C
|
||||||
|
* end
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
final ExprNode getAnAncestorExpr() {
|
||||||
|
result.asExpr().getExpr() = super.getADeclaration().getAnAncestorExpr()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if this module is a class. */
|
||||||
|
predicate isClass() { super.isClass() }
|
||||||
|
|
||||||
|
/** Gets a textual representation of this module. */
|
||||||
|
final string toString() { result = super.toString() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the qualified name of this module, if any.
|
||||||
|
*
|
||||||
|
* Only modules that can be resolved will have a qualified name.
|
||||||
|
*/
|
||||||
|
final string getQualifiedName() { result = super.getQualifiedName() }
|
||||||
|
|
||||||
|
/** Gets the location of this module. */
|
||||||
|
final Location getLocation() { result = super.getLocation() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets `self` in a declaration of this module.
|
||||||
|
*
|
||||||
|
* This only gets `self` at the module level, not inside any (singleton) method.
|
||||||
|
*/
|
||||||
|
LocalSourceNode getModuleLevelSelf() {
|
||||||
|
result.(SsaDefinitionNode).getVariable() = super.getADeclaration().getModuleSelfVariable()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets `self` in the module declaration or in one of its singleton methods.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
LocalSourceNode getAnOwnModuleSelf() {
|
||||||
|
result = this.getModuleLevelSelf()
|
||||||
|
or
|
||||||
|
result = this.getAnOwnSingletonMethod().getSelfParameter()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a call to method `name` on `self` in the module-level scope of this module.
|
||||||
|
*
|
||||||
|
* For example,
|
||||||
|
* ```rb
|
||||||
|
* module M
|
||||||
|
* include A # getAModuleLevelCall("include")
|
||||||
|
* foo :bar # getAModuleLevelCall("foo")
|
||||||
|
* end
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
CallNode getAModuleLevelCall(string name) {
|
||||||
|
result = this.getModuleLevelSelf().getAMethodCall(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets a constant or `self` variable that refers to this module. */
|
||||||
|
LocalSourceNode getAnImmediateReference() {
|
||||||
|
result.asExpr().getExpr() = super.getAnImmediateReference()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a singleton method declared in this module (or in a singleton class
|
||||||
|
* augmenting this module).
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
MethodNode getAnOwnSingletonMethod() {
|
||||||
|
result.asCallableAstNode() = super.getAnOwnSingletonMethod()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the singleton method named `name` declared in this module (or in a singleton class
|
||||||
|
* augmenting this module).
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
MethodNode getOwnSingletonMethod(string name) {
|
||||||
|
result = this.getAnOwnSingletonMethod() and
|
||||||
|
result.getMethodName() = name
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance method declared in this module.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
MethodNode getAnOwnInstanceMethod() {
|
||||||
|
result.asCallableAstNode() = this.getADeclaration().getAMethod().(Method)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance method named `name` declared in this module.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
MethodNode getOwnInstanceMethod(string name) {
|
||||||
|
result = this.getAnOwnInstanceMethod() and
|
||||||
|
result.getMethodName() = name
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the `self` parameter of an instance method declared in this module.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
ParameterNode getAnOwnInstanceSelf() {
|
||||||
|
result = TSelfParameterNode(this.getAnOwnInstanceMethod().asCallableAstNode())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the `self` parameter of an instance method available in this module,
|
||||||
|
* including those inherited from ancestors.
|
||||||
|
*/
|
||||||
|
ParameterNode getAnInstanceSelf() {
|
||||||
|
// Make sure to include the 'self' in overridden instance methods
|
||||||
|
result = this.getAnAncestor().getAnOwnInstanceSelf()
|
||||||
|
}
|
||||||
|
|
||||||
|
private InstanceVariableAccess getAnOwnInstanceVariableAccess(string name) {
|
||||||
|
exists(InstanceVariable v |
|
||||||
|
v.getDeclaringScope() = this.getADeclaration() and
|
||||||
|
v.getName() = name and
|
||||||
|
result.getVariable() = v
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an access to the instance variable `name` in this module.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
LocalSourceNode getAnOwnInstanceVariableRead(string name) {
|
||||||
|
result.asExpr().getExpr() =
|
||||||
|
this.getAnOwnInstanceVariableAccess(name).(InstanceVariableReadAccess)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the right-hand side of an assignment to the instance variable `name` in this module.
|
||||||
|
*
|
||||||
|
* Does not take inheritance into account.
|
||||||
|
*/
|
||||||
|
Node getAnOwnInstanceVariableWriteValue(string name) {
|
||||||
|
exists(AssignExpr assignment |
|
||||||
|
assignment.getLeftOperand() = this.getAnOwnInstanceVariableAccess(name) and
|
||||||
|
result.asExpr().getExpr() = assignment.getRightOperand()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instance method named `name` available in this module, including methods inherited
|
||||||
|
* from ancestors.
|
||||||
|
*
|
||||||
|
* Overridden methods are not included.
|
||||||
|
*/
|
||||||
|
MethodNode getInstanceMethod(string name) {
|
||||||
|
result.asCallableAstNode() = super.getInstanceMethod(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance method available in this module, including methods inherited
|
||||||
|
* from ancestors.
|
||||||
|
*
|
||||||
|
* Overridden methods are not included.
|
||||||
|
*/
|
||||||
|
MethodNode getAnInstanceMethod() { result = this.getInstanceMethod(_) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the enclosing module, as it appears in the qualified name of this module.
|
||||||
|
*
|
||||||
|
* For example, the canonical enclosing module of `A::B` is `A`, and `A` itself has no canonical enclosing module.
|
||||||
|
*/
|
||||||
|
ModuleNode getCanonicalEnclosingModule() { result = super.getParentModule() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a module named `name` declared inside this one (not aliased), provided
|
||||||
|
* that such a module is defined or reopened in the current codebase.
|
||||||
|
*
|
||||||
|
* For example, for `A::B` the canonical nested module named `C` would be `A::B::C`.
|
||||||
|
*
|
||||||
|
* Note that this is not the same as constant lookup. If `A::B::C` would resolve to a
|
||||||
|
* module whose qualified name is not `A::B::C`, then it will not be found by
|
||||||
|
* this predicate.
|
||||||
|
*/
|
||||||
|
ModuleNode getCanonicalNestedModule(string name) { result = super.getNestedModule(name) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A representation of a run-time class.
|
||||||
|
*/
|
||||||
|
class ClassNode extends ModuleNode {
|
||||||
|
ClassNode() { this.isClass() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data flow node corresponding to a method, block, or lambda expression.
|
||||||
|
*/
|
||||||
|
class CallableNode extends ExprNode {
|
||||||
|
private Callable callable;
|
||||||
|
|
||||||
|
CallableNode() { this.asExpr().getExpr() = callable }
|
||||||
|
|
||||||
|
/** Gets the underlying AST node as a `Callable`. */
|
||||||
|
Callable asCallableAstNode() { result = callable }
|
||||||
|
|
||||||
|
private ParameterPosition getParameterPosition(ParameterNodeImpl node) {
|
||||||
|
node.isSourceParameterOf(callable, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the `n`th positional parameter. */
|
||||||
|
ParameterNode getParameter(int n) { this.getParameterPosition(result).isPositional(n) }
|
||||||
|
|
||||||
|
/** Gets the keyword parameter of the given name. */
|
||||||
|
ParameterNode getKeywordParameter(string name) {
|
||||||
|
this.getParameterPosition(result).isKeyword(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the `self` parameter of this callable, if any. */
|
||||||
|
ParameterNode getSelfParameter() { this.getParameterPosition(result).isSelf() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the `hash-splat` parameter. This is a synthetic parameter holding
|
||||||
|
* a hash object with entries for each keyword argument passed to the function.
|
||||||
|
*/
|
||||||
|
ParameterNode getHashSplatParameter() { this.getParameterPosition(result).isHashSplat() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block parameter of this method, if any.
|
||||||
|
*/
|
||||||
|
ParameterNode getBlockParameter() { this.getParameterPosition(result).isBlock() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a `yield` in this method or `.call` on the block parameter.
|
||||||
|
*/
|
||||||
|
CallNode getABlockCall() {
|
||||||
|
hasYieldCall(this.getBlockParameter(), result)
|
||||||
|
or
|
||||||
|
result = this.getBlockParameter().getAMethodCall("call")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the canonical return node from this callable.
|
||||||
|
*
|
||||||
|
* Each callable has exactly one such node, and its location may not correspond
|
||||||
|
* to any particular return site - consider using `getAReturningNode` to get nodes
|
||||||
|
* whose locations correspond to return sites.
|
||||||
|
*/
|
||||||
|
Node getReturn() { result.(SynthReturnNode).getCfgScope() = callable }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a data flow node whose value is about to be returned by this callable.
|
||||||
|
*/
|
||||||
|
Node getAReturningNode() { result = this.getReturn().(SynthReturnNode).getAnInput() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data flow node corresponding to a method (possibly a singleton method).
|
||||||
|
*/
|
||||||
|
class MethodNode extends CallableNode {
|
||||||
|
MethodNode() { super.asCallableAstNode() instanceof MethodBase }
|
||||||
|
|
||||||
|
/** Gets the underlying AST node for this method. */
|
||||||
|
override MethodBase asCallableAstNode() { result = super.asCallableAstNode() }
|
||||||
|
|
||||||
|
/** Gets the name of this method. */
|
||||||
|
string getMethodName() { result = this.asCallableAstNode().getName() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data flow node corresponding to a block argument.
|
||||||
|
*/
|
||||||
|
class BlockNode extends CallableNode {
|
||||||
|
BlockNode() { super.asCallableAstNode() instanceof Block }
|
||||||
|
|
||||||
|
/** Gets the underlying AST node for this block. */
|
||||||
|
override Block asCallableAstNode() { result = super.asCallableAstNode() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A representation of a pair such as `K => V` or `K: V`.
|
||||||
|
*
|
||||||
|
* Unlike most expressions, pairs do not evaluate to actual objects at runtime and their nodes
|
||||||
|
* cannot generally be expected to have meaningful data flow edges.
|
||||||
|
* This node simply provides convenient access to the key and value as data flow nodes.
|
||||||
|
*/
|
||||||
|
class PairNode extends ExprNode {
|
||||||
|
PairNode() { this.getExprNode() instanceof CfgNodes::ExprNodes::PairCfgNode }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this pair is of form `key => value` or `key: value`.
|
||||||
|
*/
|
||||||
|
predicate hasKeyAndValue(Node key, Node value) {
|
||||||
|
exists(CfgNodes::ExprNodes::PairCfgNode n |
|
||||||
|
this.getExprNode() = n and
|
||||||
|
key = TExprNode(n.getKey()) and
|
||||||
|
value = TExprNode(n.getValue())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the key expression of this pair, such as the `K` in `K => V` or `K: V`. */
|
||||||
|
Node getKey() { this.hasKeyAndValue(result, _) }
|
||||||
|
|
||||||
|
/** Gets the value expression of this pair, such as the `V` in `K => V` or `K: V`. */
|
||||||
|
Node getValue() { this.hasKeyAndValue(_, result) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data-flow node that corresponds to a hash literal. Hash literals are desugared
|
||||||
|
* into calls to `Hash.[]`, so this includes both desugared calls as well as
|
||||||
|
* explicit calls.
|
||||||
|
*/
|
||||||
|
class HashLiteralNode extends LocalSourceNode, ExprNode {
|
||||||
|
HashLiteralNode() { super.getExprNode() instanceof CfgNodes::ExprNodes::HashLiteralCfgNode }
|
||||||
|
|
||||||
|
/** Gets a pair in this hash literal. */
|
||||||
|
PairNode getAKeyValuePair() {
|
||||||
|
result.getExprNode() =
|
||||||
|
super.getExprNode().(CfgNodes::ExprNodes::HashLiteralCfgNode).getAKeyValuePair()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the value associated with the constant `key`, if known. */
|
||||||
|
Node getElementFromKey(ConstantValue key) {
|
||||||
|
exists(ExprNode keyNode |
|
||||||
|
this.getAKeyValuePair().hasKeyAndValue(keyNode, result) and
|
||||||
|
keyNode.getConstantValue() = key
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data-flow node corresponding to an array literal. Array literals are desugared
|
||||||
|
* into calls to `Array.[]`, so this includes both desugared calls as well as
|
||||||
|
* explicit calls.
|
||||||
|
*/
|
||||||
|
class ArrayLiteralNode extends LocalSourceNode, ExprNode {
|
||||||
|
ArrayLiteralNode() { super.getExprNode() instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an element of the array.
|
||||||
|
*/
|
||||||
|
Node getAnElement() { result = this.(CallNode).getPositionalArgument(_) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An access to a constant, such as `C`, `C::D`, or a class or module declaration.
|
||||||
|
*
|
||||||
|
* See `DataFlow::getConst` for usage example.
|
||||||
|
*/
|
||||||
|
class ConstRef extends LocalSourceNode {
|
||||||
|
private ConstantAccess access;
|
||||||
|
|
||||||
|
ConstRef() { this = getConstantAccessNode(access) }
|
||||||
|
|
||||||
|
/** Gets the underlying constant access AST node. */
|
||||||
|
ConstantAccess asConstantAccess() { result = access }
|
||||||
|
|
||||||
|
/** Gets the underlying module declaration, if any. */
|
||||||
|
Namespace asNamespaceDeclaration() { result = access }
|
||||||
|
|
||||||
|
/** Gets the module defined or re-opened by this constant access, if any. */
|
||||||
|
ModuleNode asModule() { result.getADeclaration() = access }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the simple name of the constant being referenced, such as
|
||||||
|
* the `B` in `A::B`.
|
||||||
|
*/
|
||||||
|
string getName() { result = access.getName() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this might refer to a top-level constant.
|
||||||
|
*/
|
||||||
|
predicate isPossiblyGlobal() {
|
||||||
|
exists(Module mod |
|
||||||
|
not exists(mod.getParentModule()) and
|
||||||
|
mod.getAnImmediateReference() = access
|
||||||
|
)
|
||||||
|
or
|
||||||
|
not exists(Module mod | mod.getAnImmediateReference() = access) and
|
||||||
|
not exists(access.getScopeExpr())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a module for which this constant is the reference to an ancestor module.
|
||||||
|
*
|
||||||
|
* For example, `M` is the ancestry target of `C` in the following examples:
|
||||||
|
* ```rb
|
||||||
|
* class M < C {}
|
||||||
|
*
|
||||||
|
* module M
|
||||||
|
* include C
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* module M
|
||||||
|
* prepend C
|
||||||
|
* end
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
private ModuleNode getAncestryTarget() { result.getAnAncestorExpr() = this }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the known target module.
|
||||||
|
*
|
||||||
|
* We resolve these differently to prune out infeasible constant lookups.
|
||||||
|
*/
|
||||||
|
private Module getExactTarget() { result.getAnImmediateReference() = access }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a scope in which a constant lookup may access the contents of the module referenced by this constant.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
private TConstLookupScope getATargetScope() {
|
||||||
|
forceCachingInSameStage() and
|
||||||
|
result = MkAncestorLookup(this.getAncestryTarget().getAnImmediateDescendent*())
|
||||||
|
or
|
||||||
|
access = any(ConstantAccess ac).getScopeExpr() and
|
||||||
|
result = MkQualifiedLookup(access)
|
||||||
|
or
|
||||||
|
result = MkNestedLookup(this.getAncestryTarget())
|
||||||
|
or
|
||||||
|
result = MkExactLookup(access.(Namespace).getModule())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the scope expression, or the immediately enclosing `Namespace` (skipping over singleton classes).
|
||||||
|
*
|
||||||
|
* Top-levels are not included, since this is only needed for nested constant lookup, and unqualified constants
|
||||||
|
* at the top-level are handled by `DataFlow::getConst`, never `ConstRef.getConst`.
|
||||||
|
*/
|
||||||
|
private TConstLookupScope getLookupScope() {
|
||||||
|
result = MkQualifiedLookup(access.getScopeExpr())
|
||||||
|
or
|
||||||
|
not exists(this.getExactTarget()) and
|
||||||
|
not exists(access.getScopeExpr()) and
|
||||||
|
not access.hasGlobalScope() and
|
||||||
|
(
|
||||||
|
result = MkAncestorLookup(access.getEnclosingModule().getNamespaceOrToplevel().getModule())
|
||||||
|
or
|
||||||
|
result = MkNestedLookup(access.getEnclosingModule().getEnclosingModule*().getModule())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this can reference a constant named `name` from `scope` using a lookup of `kind`.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
private predicate accesses(TConstLookupScope scope, string name) {
|
||||||
|
forceCachingInSameStage() and
|
||||||
|
scope = this.getLookupScope() and
|
||||||
|
name = this.getName()
|
||||||
|
or
|
||||||
|
exists(Module mod |
|
||||||
|
this.getExactTarget() = mod.getNestedModule(name) and
|
||||||
|
scope = MkExactLookup(mod)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a constant reference that may resolve to a member of this node.
|
||||||
|
*
|
||||||
|
* For example `DataFlow::getConst("A").getConst("B")` finds the following:
|
||||||
|
* ```rb
|
||||||
|
* A::B # simple reference
|
||||||
|
*
|
||||||
|
* module A
|
||||||
|
* B # in scope
|
||||||
|
* module X
|
||||||
|
* B # in nested scope
|
||||||
|
* end
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* module X
|
||||||
|
* include A
|
||||||
|
* B # via inclusion
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* class X < A
|
||||||
|
* B # via subclassing
|
||||||
|
* end
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
pragma[inline]
|
||||||
|
ConstRef getConst(string name) {
|
||||||
|
exists(TConstLookupScope scope |
|
||||||
|
pragma[only_bind_into](scope) = pragma[only_bind_out](this).getATargetScope() and
|
||||||
|
result.accesses(pragma[only_bind_out](scope), name)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a module that transitively subclasses, includes, or prepends the module referred to by
|
||||||
|
* this constant.
|
||||||
|
*
|
||||||
|
* For example, `DataFlow::getConst("A").getADescendentModule()` finds `B`, `C`, and `E`:
|
||||||
|
* ```rb
|
||||||
|
* class B < A
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* class C < B
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* module E
|
||||||
|
* include C
|
||||||
|
* end
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
ModuleNode getADescendentModule() { MkAncestorLookup(result) = this.getATargetScope() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a constant reference that may resolve to the top-level constant `name`.
|
||||||
|
*
|
||||||
|
* To get nested constants, call `getConst()` one or more times on the result.
|
||||||
|
*
|
||||||
|
* For example `DataFlow::getConst("A").getConst("B")` finds the following:
|
||||||
|
* ```rb
|
||||||
|
* A::B # simple reference
|
||||||
|
*
|
||||||
|
* module A
|
||||||
|
* B # in scope
|
||||||
|
* module X
|
||||||
|
* B # in nested scope
|
||||||
|
* end
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* module X
|
||||||
|
* include A
|
||||||
|
* B # via inclusion
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* class X < A
|
||||||
|
* B # via subclassing
|
||||||
|
* end
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
ConstRef getConst(string name) {
|
||||||
|
result.getName() = name and
|
||||||
|
result.isPossiblyGlobal()
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ deprecated class ParamsCall = Rails::ParamsCall;
|
|||||||
deprecated class CookiesCall = Rails::CookiesCall;
|
deprecated class CookiesCall = Rails::CookiesCall;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `ClassDeclaration` for a class that extends `ActionController::Base`.
|
* A class that extends `ActionController::Base`.
|
||||||
* For example,
|
* For example,
|
||||||
*
|
*
|
||||||
* ```rb
|
* ```rb
|
||||||
@@ -36,26 +36,61 @@ deprecated class CookiesCall = Rails::CookiesCall;
|
|||||||
* end
|
* end
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class ActionControllerControllerClass extends ClassDeclaration {
|
class ActionControllerClass extends DataFlow::ClassNode {
|
||||||
ActionControllerControllerClass() {
|
ActionControllerClass() {
|
||||||
this.getSuperclassExpr() =
|
this =
|
||||||
[
|
[
|
||||||
API::getTopLevelMember("ActionController").getMember("Base"),
|
DataFlow::getConst("ActionController").getConst("Base"),
|
||||||
// In Rails applications `ApplicationController` typically extends `ActionController::Base`, but we
|
// In Rails applications `ApplicationController` typically extends `ActionController::Base`, but we
|
||||||
// treat it separately in case the `ApplicationController` definition is not in the database.
|
// treat it separately in case the `ApplicationController` definition is not in the database.
|
||||||
API::getTopLevelMember("ApplicationController"),
|
DataFlow::getConst("ApplicationController"),
|
||||||
// ActionController::Metal technically doesn't contain all of the
|
// ActionController::Metal technically doesn't contain all of the
|
||||||
// methods available in Base, such as those for rendering views.
|
// methods available in Base, such as those for rendering views.
|
||||||
// However we prefer to be over-sensitive in this case in order to find
|
// However we prefer to be over-sensitive in this case in order to find
|
||||||
// more results.
|
// more results.
|
||||||
API::getTopLevelMember("ActionController").getMember("Metal")
|
DataFlow::getConst("ActionController").getConst("Metal")
|
||||||
].getASubclass().getAValueReachableFromSource().asExpr().getExpr()
|
].getADescendentModule()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an `ActionControllerActionMethod` defined in this class.
|
||||||
|
*/
|
||||||
|
ActionControllerActionMethod getAnAction() {
|
||||||
|
result = this.getAnInstanceMethod().asCallableAstNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a `self` that possibly refers to an instance of this class.
|
||||||
|
*/
|
||||||
|
DataFlow::LocalSourceNode getSelf() {
|
||||||
|
result = this.getAnInstanceSelf()
|
||||||
|
or
|
||||||
|
// Include the module-level `self` to recover some cases where a block at the module level
|
||||||
|
// is invoked with an instance as the `self`, which we currently can't model directly.
|
||||||
|
// Concretely this happens in the block passed to `rescue_from`.
|
||||||
|
// TODO: revisit when we have better infrastructure for handling self in a block
|
||||||
|
result = this.getModuleLevelSelf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataFlow::LocalSourceNode actionControllerInstance() {
|
||||||
|
result = any(ActionControllerClass cls).getSelf()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED. Use `ActionControllerClass` instead.
|
||||||
|
*
|
||||||
|
* A `ClassDeclaration` corresponding to an `ActionControllerClass`.
|
||||||
|
*/
|
||||||
|
deprecated class ActionControllerControllerClass extends ClassDeclaration {
|
||||||
|
ActionControllerControllerClass() { this = any(ActionControllerClass cls).getADeclaration() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a `ActionControllerActionMethod` defined in this class.
|
* Gets a `ActionControllerActionMethod` defined in this class.
|
||||||
*/
|
*/
|
||||||
ActionControllerActionMethod getAnAction() { result = this.getAMethod() }
|
ActionControllerActionMethod getAnAction() {
|
||||||
|
result = this.getAMethod().(Method) and result.isPrivate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,9 +98,11 @@ class ActionControllerControllerClass extends ClassDeclaration {
|
|||||||
* This may be the target of a route handler, if such a route is defined.
|
* This may be the target of a route handler, if such a route is defined.
|
||||||
*/
|
*/
|
||||||
class ActionControllerActionMethod extends Method, Http::Server::RequestHandler::Range {
|
class ActionControllerActionMethod extends Method, Http::Server::RequestHandler::Range {
|
||||||
private ActionControllerControllerClass controllerClass;
|
private ActionControllerClass controllerClass;
|
||||||
|
|
||||||
ActionControllerActionMethod() { this = controllerClass.getAMethod() and not this.isPrivate() }
|
ActionControllerActionMethod() {
|
||||||
|
this = controllerClass.getAnInstanceMethod().asCallableAstNode() and not this.isPrivate()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes a mapping between a method within the file
|
* Establishes a mapping between a method within the file
|
||||||
@@ -91,7 +128,7 @@ class ActionControllerActionMethod extends Method, Http::Server::RequestHandler:
|
|||||||
/**
|
/**
|
||||||
* Gets the controller class containing this method.
|
* Gets the controller class containing this method.
|
||||||
*/
|
*/
|
||||||
ActionControllerControllerClass getControllerClass() {
|
ActionControllerClass getControllerClass() {
|
||||||
// TODO: model the implicit render call when a path through the method does
|
// TODO: model the implicit render call when a path through the method does
|
||||||
// not end at an explicit render or redirect
|
// not end at an explicit render or redirect
|
||||||
result = controllerClass
|
result = controllerClass
|
||||||
@@ -102,37 +139,23 @@ class ActionControllerActionMethod extends Method, Http::Server::RequestHandler:
|
|||||||
* May return multiple results.
|
* May return multiple results.
|
||||||
*/
|
*/
|
||||||
ActionDispatch::Routing::Route getARoute() {
|
ActionDispatch::Routing::Route getARoute() {
|
||||||
exists(string name |
|
exists(string name, DataFlow::MethodNode m |
|
||||||
isRoute(result, name, controllerClass) and
|
isRoute(result, name, controllerClass) and
|
||||||
isActionControllerMethod(this, name, controllerClass)
|
m = controllerClass.getInstanceMethod(name) and
|
||||||
|
this = m.asCallableAstNode()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate isRoute(
|
private predicate isRoute(
|
||||||
ActionDispatch::Routing::Route route, string name, ActionControllerControllerClass controllerClass
|
ActionDispatch::Routing::Route route, string name, ActionControllerClass controllerClass
|
||||||
) {
|
) {
|
||||||
route.getController() + "_controller" =
|
route.getController() + "_controller" =
|
||||||
ActionDispatch::Routing::underscore(controllerClass.getAQualifiedName()) and
|
ActionDispatch::Routing::underscore(controllerClass.getQualifiedName()) and
|
||||||
name = route.getAction()
|
name = route.getAction()
|
||||||
}
|
}
|
||||||
|
|
||||||
// A method call with a `self` receiver from within a controller class
|
|
||||||
private class ActionControllerContextCall extends MethodCall {
|
|
||||||
private ActionControllerControllerClass controllerClass;
|
|
||||||
|
|
||||||
ActionControllerContextCall() {
|
|
||||||
this.getReceiver() instanceof SelfVariableAccess and
|
|
||||||
this.getEnclosingModule() = controllerClass
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the controller class containing this method.
|
|
||||||
*/
|
|
||||||
ActionControllerControllerClass getControllerClass() { result = controllerClass }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `RemoteFlowSource::Range` to represent accessing the
|
* A `RemoteFlowSource::Range` to represent accessing the
|
||||||
* ActionController parameters available via the `params` method.
|
* ActionController parameters available via the `params` method.
|
||||||
@@ -158,13 +181,17 @@ class CookiesSource extends Http::Server::RequestInputAccess::Range {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A call to `cookies` from within a controller. */
|
/** A call to `cookies` from within a controller. */
|
||||||
private class ActionControllerCookiesCall extends ActionControllerContextCall, CookiesCallImpl {
|
private class ActionControllerCookiesCall extends CookiesCallImpl {
|
||||||
ActionControllerCookiesCall() { this.getMethodName() = "cookies" }
|
ActionControllerCookiesCall() {
|
||||||
|
this = actionControllerInstance().getAMethodCall("cookies").asExpr().getExpr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A call to `params` from within a controller. */
|
/** A call to `params` from within a controller. */
|
||||||
private class ActionControllerParamsCall extends ActionControllerContextCall, ParamsCallImpl {
|
private class ActionControllerParamsCall extends ParamsCallImpl {
|
||||||
ActionControllerParamsCall() { this.getMethodName() = "params" }
|
ActionControllerParamsCall() {
|
||||||
|
this = actionControllerInstance().getAMethodCall("params").asExpr().getExpr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Modeling for `ActionDispatch::Request`. */
|
/** Modeling for `ActionDispatch::Request`. */
|
||||||
@@ -174,10 +201,7 @@ private module Request {
|
|||||||
* `ActionDispatch::Request`.
|
* `ActionDispatch::Request`.
|
||||||
*/
|
*/
|
||||||
private class RequestNode extends DataFlow::CallNode {
|
private class RequestNode extends DataFlow::CallNode {
|
||||||
RequestNode() {
|
RequestNode() { this = actionControllerInstance().getAMethodCall("request") }
|
||||||
this.asExpr().getExpr() instanceof ActionControllerContextCall and
|
|
||||||
this.getMethodName() = "request"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,7 +258,7 @@ private module Request {
|
|||||||
// Request headers are prefixed with `HTTP_` to distinguish them from
|
// Request headers are prefixed with `HTTP_` to distinguish them from
|
||||||
// "headers" supplied by Rack middleware.
|
// "headers" supplied by Rack middleware.
|
||||||
this.getMethodName() = ["get_header", "fetch_header"] and
|
this.getMethodName() = ["get_header", "fetch_header"] and
|
||||||
this.getArgument(0).asExpr().getExpr().getConstantValue().getString().regexpMatch("^HTTP_.+")
|
this.getArgument(0).getConstantValue().getString().regexpMatch("^HTTP_.+")
|
||||||
}
|
}
|
||||||
|
|
||||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() }
|
override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() }
|
||||||
@@ -290,9 +314,8 @@ private module Request {
|
|||||||
*/
|
*/
|
||||||
private class EnvHttpAccess extends DataFlow::CallNode, Http::Server::RequestInputAccess::Range {
|
private class EnvHttpAccess extends DataFlow::CallNode, Http::Server::RequestInputAccess::Range {
|
||||||
EnvHttpAccess() {
|
EnvHttpAccess() {
|
||||||
any(EnvCall c).(DataFlow::LocalSourceNode).flowsTo(this.getReceiver()) and
|
this = any(EnvCall c).getAMethodCall("[]") and
|
||||||
this.getMethodName() = "[]" and
|
this.getArgument(0).getConstantValue().getString().regexpMatch("^HTTP_.+")
|
||||||
this.getArgument(0).asExpr().getExpr().getConstantValue().getString().regexpMatch("^HTTP_.+")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() }
|
override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() }
|
||||||
@@ -302,21 +325,32 @@ private module Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A call to `render` from within a controller. */
|
/** A call to `render` from within a controller. */
|
||||||
private class ActionControllerRenderCall extends ActionControllerContextCall, RenderCallImpl {
|
private class ActionControllerRenderCall extends RenderCallImpl {
|
||||||
ActionControllerRenderCall() { this.getMethodName() = "render" }
|
ActionControllerRenderCall() {
|
||||||
|
this = actionControllerInstance().getAMethodCall("render").asExpr().getExpr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A call to `render_to` from within a controller. */
|
/** A call to `render_to` from within a controller. */
|
||||||
private class ActionControllerRenderToCall extends ActionControllerContextCall, RenderToCallImpl {
|
private class ActionControllerRenderToCall extends RenderToCallImpl {
|
||||||
ActionControllerRenderToCall() { this.getMethodName() = ["render_to_body", "render_to_string"] }
|
ActionControllerRenderToCall() {
|
||||||
|
this =
|
||||||
|
actionControllerInstance()
|
||||||
|
.getAMethodCall(["render_to_body", "render_to_string"])
|
||||||
|
.asExpr()
|
||||||
|
.getExpr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A call to `html_escape` from within a controller. */
|
/** A call to `html_escape` from within a controller. */
|
||||||
private class ActionControllerHtmlEscapeCall extends HtmlEscapeCallImpl {
|
private class ActionControllerHtmlEscapeCall extends HtmlEscapeCallImpl {
|
||||||
ActionControllerHtmlEscapeCall() {
|
ActionControllerHtmlEscapeCall() {
|
||||||
// "h" is aliased to "html_escape" in ActiveSupport
|
// "h" is aliased to "html_escape" in ActiveSupport
|
||||||
this.getMethodName() = ["html_escape", "html_escape_once", "h", "sanitize"] and
|
this =
|
||||||
this.getEnclosingModule() instanceof ActionControllerControllerClass
|
actionControllerInstance()
|
||||||
|
.getAMethodCall(["html_escape", "html_escape_once", "h", "sanitize"])
|
||||||
|
.asExpr()
|
||||||
|
.getExpr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,9 +358,16 @@ private class ActionControllerHtmlEscapeCall extends HtmlEscapeCallImpl {
|
|||||||
* A call to the `redirect_to` method, used in an action to redirect to a
|
* A call to the `redirect_to` method, used in an action to redirect to a
|
||||||
* specific URL/path or to a different action in this controller.
|
* specific URL/path or to a different action in this controller.
|
||||||
*/
|
*/
|
||||||
class RedirectToCall extends ActionControllerContextCall {
|
class RedirectToCall extends MethodCall {
|
||||||
|
private ActionControllerClass controller;
|
||||||
|
|
||||||
RedirectToCall() {
|
RedirectToCall() {
|
||||||
this.getMethodName() = ["redirect_to", "redirect_back", "redirect_back_or_to"]
|
this =
|
||||||
|
controller
|
||||||
|
.getSelf()
|
||||||
|
.getAMethodCall(["redirect_to", "redirect_back", "redirect_back_or_to"])
|
||||||
|
.asExpr()
|
||||||
|
.getExpr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the `Expr` representing the URL to redirect to, if any */
|
/** Gets the `Expr` representing the URL to redirect to, if any */
|
||||||
@@ -338,8 +379,10 @@ class RedirectToCall extends ActionControllerContextCall {
|
|||||||
|
|
||||||
/** Gets the `ActionControllerActionMethod` to redirect to, if any */
|
/** Gets the `ActionControllerActionMethod` to redirect to, if any */
|
||||||
ActionControllerActionMethod getRedirectActionMethod() {
|
ActionControllerActionMethod getRedirectActionMethod() {
|
||||||
this.getKeywordArgument("action").getConstantValue().isStringlikeValue(result.getName()) and
|
exists(string name |
|
||||||
result.getEnclosingModule() = this.getControllerClass()
|
this.getKeywordArgument("action").getConstantValue().isStringlikeValue(name) and
|
||||||
|
result = controller.getInstanceMethod(name).asCallableAstNode()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -373,18 +416,8 @@ class ActionControllerRedirectResponse extends Http::Server::HttpRedirectRespons
|
|||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate isActionControllerMethod(Method m, string name, ActionControllerControllerClass c) {
|
private predicate actionControllerHasHelperMethodCall(ActionControllerClass c, string name) {
|
||||||
m.getName() = name and
|
c.getAModuleLevelCall("helper_method").getArgument(_).getConstantValue().isStringlikeValue(name)
|
||||||
m.getEnclosingModule() = c
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[nomagic]
|
|
||||||
private predicate actionControllerHasHelperMethodCall(ActionControllerControllerClass c, string name) {
|
|
||||||
exists(MethodCall mc |
|
|
||||||
mc.getMethodName() = "helper_method" and
|
|
||||||
mc.getAnArgument().getConstantValue().isStringlikeValue(name) and
|
|
||||||
mc.getEnclosingModule() = c
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -404,27 +437,28 @@ private predicate actionControllerHasHelperMethodCall(ActionControllerController
|
|||||||
* See also https://api.rubyonrails.org/classes/AbstractController/Helpers/ClassMethods.html#method-i-helper_method
|
* See also https://api.rubyonrails.org/classes/AbstractController/Helpers/ClassMethods.html#method-i-helper_method
|
||||||
*/
|
*/
|
||||||
class ActionControllerHelperMethod extends Method {
|
class ActionControllerHelperMethod extends Method {
|
||||||
private ActionControllerControllerClass controllerClass;
|
private ActionControllerClass controllerClass;
|
||||||
|
|
||||||
ActionControllerHelperMethod() {
|
ActionControllerHelperMethod() {
|
||||||
exists(string name |
|
exists(DataFlow::MethodNode m, string name |
|
||||||
isActionControllerMethod(this, name, controllerClass) and
|
m = controllerClass.getInstanceMethod(name) and
|
||||||
actionControllerHasHelperMethodCall(controllerClass, name)
|
actionControllerHasHelperMethodCall(controllerClass, name) and
|
||||||
|
this = m.asCallableAstNode()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the class containing this helper method. */
|
/** Gets the class containing this helper method. */
|
||||||
ActionControllerControllerClass getControllerClass() { result = controllerClass }
|
ActionControllerClass getControllerClass() { result = controllerClass }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an `ActionControllerControllerClass` associated with the given `ErbFile`
|
* Gets an `ActionControllerClass` associated with the given `ErbFile`
|
||||||
* according to Rails path conventions.
|
* according to Rails path conventions.
|
||||||
* For instance, a template file at `app/views/foo/bar/baz.html.erb` will be
|
* For instance, a template file at `app/views/foo/bar/baz.html.erb` will be
|
||||||
* mapped to a controller class in `app/controllers/foo/bar/baz_controller.rb`,
|
* mapped to a controller class in `app/controllers/foo/bar/baz_controller.rb`,
|
||||||
* if such a controller class exists.
|
* if such a controller class exists.
|
||||||
*/
|
*/
|
||||||
ActionControllerControllerClass getAssociatedControllerClass(ErbFile f) {
|
ActionControllerClass getAssociatedControllerClass(ErbFile f) {
|
||||||
// There is a direct mapping from template file to controller class
|
// There is a direct mapping from template file to controller class
|
||||||
controllerTemplateFile(result, f)
|
controllerTemplateFile(result, f)
|
||||||
or
|
or
|
||||||
@@ -442,13 +476,13 @@ ActionControllerControllerClass getAssociatedControllerClass(ErbFile f) {
|
|||||||
// TODO: improve layout support, e.g. for `layout` method
|
// TODO: improve layout support, e.g. for `layout` method
|
||||||
// https://guides.rubyonrails.org/layouts_and_rendering.html
|
// https://guides.rubyonrails.org/layouts_and_rendering.html
|
||||||
/**
|
/**
|
||||||
* Holds if `templatesFile` is a viable file "belonging" to the given
|
* Holds if `templateFile` is a viable file "belonging" to the given
|
||||||
* `ActionControllerControllerClass`, according to Rails conventions.
|
* `ActionControllerControllerClass`, according to Rails conventions.
|
||||||
*
|
*
|
||||||
* This handles mappings between controllers in `app/controllers/`, and
|
* This handles mappings between controllers in `app/controllers/`, and
|
||||||
* templates in `app/views/` and `app/views/layouts/`.
|
* templates in `app/views/` and `app/views/layouts/`.
|
||||||
*/
|
*/
|
||||||
predicate controllerTemplateFile(ActionControllerControllerClass cls, ErbFile templateFile) {
|
predicate controllerTemplateFile(ActionControllerClass cls, ErbFile templateFile) {
|
||||||
exists(string templatesPath, string sourcePrefix, string subPath, string controllerPath |
|
exists(string templatesPath, string sourcePrefix, string subPath, string controllerPath |
|
||||||
controllerPath = cls.getLocation().getFile().getRelativePath() and
|
controllerPath = cls.getLocation().getFile().getRelativePath() and
|
||||||
templatesPath = templateFile.getParentContainer().getRelativePath() and
|
templatesPath = templateFile.getParentContainer().getRelativePath() and
|
||||||
@@ -484,16 +518,14 @@ class ActionControllerSkipForgeryProtectionCall extends CsrfProtectionSetting::R
|
|||||||
/**
|
/**
|
||||||
* A call to `protect_from_forgery`.
|
* A call to `protect_from_forgery`.
|
||||||
*/
|
*/
|
||||||
private class ActionControllerProtectFromForgeryCall extends CsrfProtectionSetting::Range {
|
private class ActionControllerProtectFromForgeryCall extends CsrfProtectionSetting::Range,
|
||||||
private ActionControllerContextCall callExpr;
|
DataFlow::CallNode {
|
||||||
|
|
||||||
ActionControllerProtectFromForgeryCall() {
|
ActionControllerProtectFromForgeryCall() {
|
||||||
callExpr = this.asExpr().getExpr() and
|
this = actionControllerInstance().getAMethodCall("protect_from_forgery")
|
||||||
callExpr.getMethodName() = "protect_from_forgery"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string getWithValueText() {
|
private string getWithValueText() {
|
||||||
result = callExpr.getKeywordArgument("with").getConstantValue().getSymbol()
|
result = this.getKeywordArgument("with").getConstantValue().getSymbol()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls without `with: :exception` can allow for bypassing CSRF protection
|
// Calls without `with: :exception` can allow for bypassing CSRF protection
|
||||||
@@ -508,11 +540,7 @@ private class ActionControllerProtectFromForgeryCall extends CsrfProtectionSetti
|
|||||||
*/
|
*/
|
||||||
private class SendFile extends FileSystemAccess::Range, DataFlow::CallNode {
|
private class SendFile extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||||
SendFile() {
|
SendFile() {
|
||||||
this.getMethodName() = "send_file" and
|
this = [actionControllerInstance(), Response::response()].getAMethodCall("send_file")
|
||||||
(
|
|
||||||
this.asExpr().getExpr() instanceof ActionControllerContextCall or
|
|
||||||
this.getReceiver().asExpr().getExpr() instanceof Response::ResponseCall
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||||
@@ -522,21 +550,13 @@ private module ParamsSummaries {
|
|||||||
private import codeql.ruby.dataflow.FlowSummary
|
private import codeql.ruby.dataflow.FlowSummary
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of `ActionController::Parameters`, including those returned
|
* Gets an instance of `ActionController::Parameters`, including those returned
|
||||||
* from method calls on other instances.
|
* from method calls on other instances.
|
||||||
*/
|
*/
|
||||||
private class ParamsInstance extends DataFlow::Node {
|
private DataFlow::LocalSourceNode paramsInstance() {
|
||||||
ParamsInstance() {
|
result.asExpr().getExpr() instanceof Rails::ParamsCall
|
||||||
this.asExpr().getExpr() instanceof Rails::ParamsCall
|
|
||||||
or
|
or
|
||||||
this =
|
result = paramsInstance().getAMethodCall(paramsMethodReturningParamsInstance())
|
||||||
any(DataFlow::CallNode call |
|
|
||||||
call.getReceiver() instanceof ParamsInstance and
|
|
||||||
call.getMethodName() = paramsMethodReturningParamsInstance()
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(ParamsInstance prev | prev.(DataFlow::LocalSourceNode).flowsTo(this))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -578,8 +598,7 @@ private module ParamsSummaries {
|
|||||||
MethodsReturningParamsInstanceSummary() { this = "ActionController::Parameters#<various>" }
|
MethodsReturningParamsInstanceSummary() { this = "ActionController::Parameters#<various>" }
|
||||||
|
|
||||||
override MethodCall getACall() {
|
override MethodCall getACall() {
|
||||||
any(ParamsInstance i).asExpr().getExpr() = result.getReceiver() and
|
result = paramsInstance().getAMethodCall(methodReturnsTaintFromSelf()).asExpr().getExpr()
|
||||||
result.getMethodName() = methodReturnsTaintFromSelf()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||||
@@ -601,9 +620,8 @@ private module ParamsSummaries {
|
|||||||
|
|
||||||
override MethodCall getACall() {
|
override MethodCall getACall() {
|
||||||
result.getMethodName() = ["merge", "reverse_merge", "with_defaults"] and
|
result.getMethodName() = ["merge", "reverse_merge", "with_defaults"] and
|
||||||
exists(ParamsInstance i |
|
paramsInstance().getALocalUse().asExpr().getExpr() =
|
||||||
i.asExpr().getExpr() = [result.getReceiver(), result.getArgument(0)]
|
[result.getReceiver(), result.getArgument(0)]
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||||
@@ -625,9 +643,8 @@ private module ParamsSummaries {
|
|||||||
|
|
||||||
override MethodCall getACall() {
|
override MethodCall getACall() {
|
||||||
result.getMethodName() = ["merge!", "reverse_merge!", "with_defaults!"] and
|
result.getMethodName() = ["merge!", "reverse_merge!", "with_defaults!"] and
|
||||||
exists(ParamsInstance i |
|
paramsInstance().getALocalUse().asExpr().getExpr() =
|
||||||
i.asExpr().getExpr() = [result.getReceiver(), result.getArgument(0)]
|
[result.getReceiver(), result.getArgument(0)]
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||||
@@ -643,15 +660,12 @@ private module ParamsSummaries {
|
|||||||
* response.
|
* response.
|
||||||
*/
|
*/
|
||||||
private module Response {
|
private module Response {
|
||||||
class ResponseCall extends ActionControllerContextCall {
|
DataFlow::LocalSourceNode response() {
|
||||||
ResponseCall() { this.getMethodName() = "response" }
|
result = actionControllerInstance().getAMethodCall("response")
|
||||||
}
|
}
|
||||||
|
|
||||||
class BodyWrite extends DataFlow::CallNode, Http::Server::HttpResponse::Range {
|
class BodyWrite extends DataFlow::CallNode, Http::Server::HttpResponse::Range {
|
||||||
BodyWrite() {
|
BodyWrite() { this = response().getAMethodCall("body=") }
|
||||||
this.getReceiver().asExpr().getExpr() instanceof ResponseCall and
|
|
||||||
this.getMethodName() = "body="
|
|
||||||
}
|
|
||||||
|
|
||||||
override DataFlow::Node getBody() { result = this.getArgument(0) }
|
override DataFlow::Node getBody() { result = this.getArgument(0) }
|
||||||
|
|
||||||
@@ -661,10 +675,7 @@ private module Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SendFileCall extends DataFlow::CallNode, Http::Server::HttpResponse::Range {
|
class SendFileCall extends DataFlow::CallNode, Http::Server::HttpResponse::Range {
|
||||||
SendFileCall() {
|
SendFileCall() { this = response().getAMethodCall("send_file") }
|
||||||
this.getReceiver().asExpr().getExpr() instanceof ResponseCall and
|
|
||||||
this.getMethodName() = "send_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
override DataFlow::Node getBody() { result = this.getArgument(0) }
|
override DataFlow::Node getBody() { result = this.getArgument(0) }
|
||||||
|
|
||||||
@@ -677,19 +688,12 @@ private module Response {
|
|||||||
HeaderWrite() {
|
HeaderWrite() {
|
||||||
// response.header[key] = val
|
// response.header[key] = val
|
||||||
// response.headers[key] = val
|
// response.headers[key] = val
|
||||||
exists(MethodCall headerCall |
|
this = response().getAMethodCall(["header", "headers"]).getAMethodCall("[]=")
|
||||||
headerCall.getMethodName() = ["header", "headers"] and
|
|
||||||
headerCall.getReceiver() instanceof ResponseCall
|
|
||||||
|
|
|
||||||
this.getReceiver().asExpr().getExpr() = headerCall and
|
|
||||||
this.getMethodName() = "[]="
|
|
||||||
)
|
|
||||||
or
|
or
|
||||||
// response.set_header(key) = val
|
// response.set_header(key) = val
|
||||||
// response[header] = val
|
// response[header] = val
|
||||||
// response.add_header(key, val)
|
// response.add_header(key, val)
|
||||||
this.getReceiver().asExpr().getExpr() instanceof ResponseCall and
|
this = response().getAMethodCall(["set_header", "[]=", "add_header"])
|
||||||
this.getMethodName() = ["set_header", "[]=", "add_header"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override string getName() {
|
override string getName() {
|
||||||
@@ -702,12 +706,12 @@ private module Response {
|
|||||||
class SpecificHeaderWrite extends DataFlow::CallNode, Http::Server::HeaderWriteAccess::Range {
|
class SpecificHeaderWrite extends DataFlow::CallNode, Http::Server::HeaderWriteAccess::Range {
|
||||||
SpecificHeaderWrite() {
|
SpecificHeaderWrite() {
|
||||||
// response.<method> = val
|
// response.<method> = val
|
||||||
this.getReceiver().asExpr().getExpr() instanceof ResponseCall and
|
this =
|
||||||
this.getMethodName() =
|
response()
|
||||||
[
|
.getAMethodCall([
|
||||||
"location=", "cache_control=", "_cache_control=", "etag=", "charset=", "content_type=",
|
"location=", "cache_control=", "_cache_control=", "etag=", "charset=",
|
||||||
"date=", "last_modified=", "weak_etag=", "strong_etag="
|
"content_type=", "date=", "last_modified=", "weak_etag=", "strong_etag="
|
||||||
]
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
override string getName() {
|
override string getName() {
|
||||||
|
|||||||
@@ -571,9 +571,7 @@ class ActiveRecordAssociation extends DataFlow::CallNode {
|
|||||||
* For example, in `has_many :posts`, this is `post`.
|
* For example, in `has_many :posts`, this is `post`.
|
||||||
*/
|
*/
|
||||||
string getTargetModelName() {
|
string getTargetModelName() {
|
||||||
exists(string s |
|
exists(string s | s = this.getArgument(0).getConstantValue().getStringlikeValue() |
|
||||||
s = this.getArgument(0).asExpr().getExpr().getConstantValue().getStringlikeValue()
|
|
||||||
|
|
|
||||||
// has_one :profile
|
// has_one :profile
|
||||||
// belongs_to :user
|
// belongs_to :user
|
||||||
this.isSingular() and
|
this.isSingular() and
|
||||||
|
|||||||
@@ -92,102 +92,63 @@ module Rails {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to either `Rails::Railtie`, `Rails::Engine`, or `Rails::Application`.
|
* Gets a reference to the `Rails` constant.
|
||||||
|
*/
|
||||||
|
private DataFlow::ConstRef rails() { result = DataFlow::getConst("Rails") }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a reference to either `Rails::Railtie`, `Rails::Engine`, or `Rails::Application`.
|
||||||
* `Engine` and `Application` extend `Railtie`, but may not have definitions present in the database.
|
* `Engine` and `Application` extend `Railtie`, but may not have definitions present in the database.
|
||||||
*/
|
*/
|
||||||
private class RailtieClassAccess extends ConstantReadAccess {
|
private DataFlow::ConstRef railtie() {
|
||||||
RailtieClassAccess() {
|
result = rails().getConst(["Railtie", "Engine", "Application"])
|
||||||
this.getScopeExpr().(ConstantAccess).getName() = "Rails" and
|
|
||||||
this.getName() = ["Railtie", "Engine", "Application"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A `ClassDeclaration` that (transitively) extends `Rails::Railtie`
|
/** Gets a class that transitively extends `Rails::Railtie` */
|
||||||
private class RailtieClass extends ClassDeclaration {
|
private DataFlow::ClassNode railtieClass() { result = railtie().getADescendentModule() }
|
||||||
RailtieClass() {
|
|
||||||
this.getSuperclassExpr() instanceof RailtieClassAccess or
|
|
||||||
exists(RailtieClass other |
|
|
||||||
other.getModule() = this.getSuperclassExpr().(ConstantReadAccess).getModule()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataFlow::CallNode getAConfigureCallNode() {
|
/**
|
||||||
// `Rails.application.configure`
|
* Gets a reference to `Rails::Application` or `Rails.application`.
|
||||||
result = API::getTopLevelMember("Rails").getReturn("application").getAMethodCall("configure")
|
*/
|
||||||
|
private DataFlow::LocalSourceNode railsApp() {
|
||||||
|
result = rails().getAMethodCall("application")
|
||||||
or
|
or
|
||||||
// `Rails::Application.configure`
|
result = rails().getConst("Application")
|
||||||
exists(ConstantReadAccess read, RailtieClass cls |
|
|
||||||
read = result.getReceiver().asExpr().getExpr() and
|
|
||||||
read.getModule() = cls.getModule() and
|
|
||||||
result.asExpr().getExpr().(MethodCall).getMethodName() = "configure"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classes representing accesses to the Rails config object.
|
* Classes representing accesses to the Rails config object.
|
||||||
*/
|
*/
|
||||||
private module Config {
|
private module Config {
|
||||||
/**
|
DataFlow::LocalSourceNode configSource() {
|
||||||
* An access to a Rails config object.
|
|
||||||
*/
|
|
||||||
private class SourceNode extends DataFlow::LocalSourceNode {
|
|
||||||
SourceNode() {
|
|
||||||
// `Foo < Rails::Application ... config ...`
|
// `Foo < Rails::Application ... config ...`
|
||||||
exists(MethodCall configCall | this.asExpr().getExpr() = configCall |
|
result = railtieClass().getAnOwnModuleSelf().getAMethodCall("config")
|
||||||
configCall.getMethodName() = "config" and
|
|
||||||
configCall.getEnclosingModule() instanceof RailtieClass
|
|
||||||
)
|
|
||||||
or
|
or
|
||||||
// `Rails.application.config`
|
// `Rails.application.config`
|
||||||
this = API::getTopLevelMember("Rails").getReturn("application").getReturn("config").asSource()
|
result = railsApp().getAMethodCall("config")
|
||||||
or
|
or
|
||||||
|
// TODO: move away from getParent+() when have better infrastructure for overridden 'self' in blocks
|
||||||
// `Rails.application.configure { ... config ... }`
|
// `Rails.application.configure { ... config ... }`
|
||||||
// `Rails::Application.configure { ... config ... }`
|
// `Rails::Application.configure { ... config ... }`
|
||||||
exists(DataFlow::CallNode configureCallNode, Block block, MethodCall configCall |
|
exists(Block block, MethodCall configCall | configCall = result.asExpr().getExpr() |
|
||||||
configCall = this.asExpr().getExpr()
|
block = railsApp().getAMethodCall("configure").getBlock().asExpr().getExpr() and
|
||||||
|
|
|
||||||
configureCallNode = getAConfigureCallNode() and
|
|
||||||
block = configureCallNode.asExpr().getExpr().(MethodCall).getBlock() and
|
|
||||||
configCall.getParent+() = block and
|
configCall.getParent+() = block and
|
||||||
configCall.getMethodName() = "config"
|
configCall.getMethodName() = "config"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a reference to the ActionController config object.
|
||||||
|
*/
|
||||||
|
DataFlow::LocalSourceNode actionController() {
|
||||||
|
result = configSource().getAMethodCall("action_controller")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the Rails config object.
|
* Gets a reference to the ActionDispatch config object.
|
||||||
*/
|
*/
|
||||||
class Node extends DataFlow::Node {
|
DataFlow::LocalSourceNode actionDispatch() {
|
||||||
Node() { exists(SourceNode src | src.flowsTo(this)) }
|
result = configSource().getAMethodCall("action_dispatch")
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A reference to the ActionController config object.
|
|
||||||
*/
|
|
||||||
class ActionControllerNode extends DataFlow::Node {
|
|
||||||
ActionControllerNode() {
|
|
||||||
exists(DataFlow::CallNode source |
|
|
||||||
source.getReceiver() instanceof Node and
|
|
||||||
source.getMethodName() = "action_controller"
|
|
||||||
|
|
|
||||||
source.flowsTo(this)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A reference to the ActionDispatch config object.
|
|
||||||
*/
|
|
||||||
class ActionDispatchNode extends DataFlow::Node {
|
|
||||||
ActionDispatchNode() {
|
|
||||||
exists(DataFlow::CallNode source |
|
|
||||||
source.getReceiver() instanceof Node and
|
|
||||||
source.getMethodName() = "action_dispatch"
|
|
||||||
|
|
|
||||||
source.flowsTo(this)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,24 +161,18 @@ private module Settings {
|
|||||||
loc.getFile().getStem() = "test"
|
loc.getFile().getStem() = "test"
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Setting extends DataFlow::CallNode {
|
private class Setting extends DataFlow::SetterCallNode {
|
||||||
Setting() {
|
Setting() {
|
||||||
// exclude some test configuration
|
// exclude some test configuration
|
||||||
not isInTestConfiguration(this.getLocation()) and
|
not isInTestConfiguration(this.getLocation()) and
|
||||||
this.getReceiver+() instanceof Config::Node and
|
this = Config::configSource().getAMethodCall+()
|
||||||
this.asExpr().getExpr() instanceof SetterMethodCall
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class LiteralSetting extends Setting {
|
private class LiteralSetting extends Setting {
|
||||||
ConstantValue value;
|
ConstantValue value;
|
||||||
|
|
||||||
LiteralSetting() {
|
LiteralSetting() { value = this.getArgument(0).getALocalSource().getConstantValue() }
|
||||||
exists(DataFlow::LocalSourceNode lsn |
|
|
||||||
lsn.asExpr().getConstantValue() = value and
|
|
||||||
lsn.flowsTo(this.getArgument(0))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
string getValueText() { result = value.toString() }
|
string getValueText() { result = value.toString() }
|
||||||
|
|
||||||
@@ -262,8 +217,7 @@ private module Settings {
|
|||||||
private class AllowForgeryProtectionSetting extends Settings::BooleanSetting,
|
private class AllowForgeryProtectionSetting extends Settings::BooleanSetting,
|
||||||
CsrfProtectionSetting::Range {
|
CsrfProtectionSetting::Range {
|
||||||
AllowForgeryProtectionSetting() {
|
AllowForgeryProtectionSetting() {
|
||||||
this.getReceiver() instanceof Config::ActionControllerNode and
|
this = Config::actionController().getAMethodCall("allow_forgery_protection=")
|
||||||
this.getMethodName() = "allow_forgery_protection="
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override boolean getVerificationSetting() { result = this.getValue() }
|
override boolean getVerificationSetting() { result = this.getValue() }
|
||||||
@@ -277,8 +231,7 @@ private class AllowForgeryProtectionSetting extends Settings::BooleanSetting,
|
|||||||
private class EncryptedCookieCipherSetting extends Settings::StringlikeSetting,
|
private class EncryptedCookieCipherSetting extends Settings::StringlikeSetting,
|
||||||
CookieSecurityConfigurationSetting::Range {
|
CookieSecurityConfigurationSetting::Range {
|
||||||
EncryptedCookieCipherSetting() {
|
EncryptedCookieCipherSetting() {
|
||||||
this.getReceiver() instanceof Config::ActionDispatchNode and
|
this = Config::actionDispatch().getAMethodCall("encrypted_cookie_cipher=")
|
||||||
this.getMethodName() = "encrypted_cookie_cipher="
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenSslCipher getCipher() { this.getValueText() = result.getName() }
|
OpenSslCipher getCipher() { this.getValueText() = result.getName() }
|
||||||
@@ -298,8 +251,7 @@ private class EncryptedCookieCipherSetting extends Settings::StringlikeSetting,
|
|||||||
private class UseAuthenticatedCookieEncryptionSetting extends Settings::BooleanSetting,
|
private class UseAuthenticatedCookieEncryptionSetting extends Settings::BooleanSetting,
|
||||||
CookieSecurityConfigurationSetting::Range {
|
CookieSecurityConfigurationSetting::Range {
|
||||||
UseAuthenticatedCookieEncryptionSetting() {
|
UseAuthenticatedCookieEncryptionSetting() {
|
||||||
this.getReceiver() instanceof Config::ActionDispatchNode and
|
this = Config::actionDispatch().getAMethodCall("use_authenticated_cookie_encryption=")
|
||||||
this.getMethodName() = "use_authenticated_cookie_encryption="
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean getDefaultValue() { result = true }
|
boolean getDefaultValue() { result = true }
|
||||||
@@ -321,8 +273,7 @@ private class UseAuthenticatedCookieEncryptionSetting extends Settings::BooleanS
|
|||||||
private class CookiesSameSiteProtectionSetting extends Settings::NillableStringlikeSetting,
|
private class CookiesSameSiteProtectionSetting extends Settings::NillableStringlikeSetting,
|
||||||
CookieSecurityConfigurationSetting::Range {
|
CookieSecurityConfigurationSetting::Range {
|
||||||
CookiesSameSiteProtectionSetting() {
|
CookiesSameSiteProtectionSetting() {
|
||||||
this.getReceiver() instanceof Config::ActionDispatchNode and
|
this = Config::actionDispatch().getAMethodCall("cookies_same_site_protection=")
|
||||||
this.getMethodName() = "cookies_same_site_protection="
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string getDefaultValue() { result = "lax" }
|
string getDefaultValue() { result = "lax" }
|
||||||
|
|||||||
@@ -12,26 +12,15 @@ private import codeql.ruby.DataFlow
|
|||||||
* Modeling for `railties`.
|
* Modeling for `railties`.
|
||||||
*/
|
*/
|
||||||
module Railties {
|
module Railties {
|
||||||
private class IncludeOrPrependCall extends MethodCall {
|
private DataFlow::ConstRef generatorsActionsConst() {
|
||||||
IncludeOrPrependCall() { this.getMethodName() = ["include", "prepend"] }
|
result = DataFlow::getConst("Rails").getConst("Generators").getConst("Actions")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which `include`s `Rails::Generators::Actions`.
|
* Gets a class which is a descendent of `Rails::Generators::Actions`.
|
||||||
*/
|
*/
|
||||||
private class GeneratorsActionsContext extends ClassDeclaration {
|
private DataFlow::ClassNode generatorsActionsClass() {
|
||||||
GeneratorsActionsContext() {
|
result = generatorsActionsConst().getADescendentModule()
|
||||||
exists(IncludeOrPrependCall i |
|
|
||||||
i.getEnclosingModule() = this and
|
|
||||||
i.getArgument(0) =
|
|
||||||
API::getTopLevelMember("Rails")
|
|
||||||
.getMember("Generators")
|
|
||||||
.getMember("Actions")
|
|
||||||
.getAValueReachableFromSource()
|
|
||||||
.asExpr()
|
|
||||||
.getExpr()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,8 +29,7 @@ module Railties {
|
|||||||
*/
|
*/
|
||||||
private class ExecuteCommandCall extends SystemCommandExecution::Range, DataFlow::CallNode {
|
private class ExecuteCommandCall extends SystemCommandExecution::Range, DataFlow::CallNode {
|
||||||
ExecuteCommandCall() {
|
ExecuteCommandCall() {
|
||||||
this.asExpr().getExpr().getEnclosingModule() instanceof GeneratorsActionsContext and
|
this = generatorsActionsClass().getAnInstanceSelf().getAMethodCall("execute_command")
|
||||||
this.getMethodName() = "execute_command"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override DataFlow::Node getAnArgument() { result = this.getArgument([0, 1]) }
|
override DataFlow::Node getAnArgument() { result = this.getArgument([0, 1]) }
|
||||||
@@ -54,8 +42,10 @@ module Railties {
|
|||||||
*/
|
*/
|
||||||
private class ExecuteCommandWrapperCall extends SystemCommandExecution::Range, DataFlow::CallNode {
|
private class ExecuteCommandWrapperCall extends SystemCommandExecution::Range, DataFlow::CallNode {
|
||||||
ExecuteCommandWrapperCall() {
|
ExecuteCommandWrapperCall() {
|
||||||
this.asExpr().getExpr().getEnclosingModule() instanceof GeneratorsActionsContext and
|
this =
|
||||||
this.getMethodName() = ["rake", "rails_command", "git"]
|
generatorsActionsClass()
|
||||||
|
.getAnInstanceSelf()
|
||||||
|
.getAMethodCall(["rake", "rails_command", "git"])
|
||||||
}
|
}
|
||||||
|
|
||||||
override DataFlow::Node getAnArgument() { result = this.getArgument(0) }
|
override DataFlow::Node getAnArgument() { result = this.getArgument(0) }
|
||||||
|
|||||||
@@ -88,11 +88,7 @@ module UnsafeDeserialization {
|
|||||||
|
|
||||||
private predicate isOjModePair(CfgNodes::ExprNodes::PairCfgNode p, string modeValue) {
|
private predicate isOjModePair(CfgNodes::ExprNodes::PairCfgNode p, string modeValue) {
|
||||||
p.getKey().getConstantValue().isStringlikeValue("mode") and
|
p.getKey().getConstantValue().isStringlikeValue("mode") and
|
||||||
exists(DataFlow::LocalSourceNode symbolLiteral, DataFlow::Node value |
|
DataFlow::exprNode(p.getValue()).getALocalSource().getConstantValue().isSymbol(modeValue)
|
||||||
symbolLiteral.asExpr().getExpr().getConstantValue().isSymbol(modeValue) and
|
|
||||||
symbolLiteral.flowsTo(value) and
|
|
||||||
value.asExpr() = p.getValue()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -180,11 +180,10 @@ private module Shared {
|
|||||||
private predicate isFlowFromLocals0(
|
private predicate isFlowFromLocals0(
|
||||||
CfgNodes::ExprNodes::ElementReferenceCfgNode refNode, string hashKey, ErbFile erb
|
CfgNodes::ExprNodes::ElementReferenceCfgNode refNode, string hashKey, ErbFile erb
|
||||||
) {
|
) {
|
||||||
exists(DataFlow::Node argNode, CfgNodes::ExprNodes::StringlikeLiteralCfgNode strNode |
|
exists(DataFlow::Node argNode |
|
||||||
argNode.asExpr() = refNode.getArgument(0) and
|
argNode.asExpr() = refNode.getArgument(0) and
|
||||||
refNode.getReceiver().getExpr().(MethodCall).getMethodName() = "local_assigns" and
|
refNode.getReceiver().getExpr().(MethodCall).getMethodName() = "local_assigns" and
|
||||||
argNode.getALocalSource() = DataFlow::exprNode(strNode) and
|
argNode.getALocalSource().getConstantValue().isStringlikeValue(hashKey) and
|
||||||
strNode.getExpr().getConstantValue().isStringlikeValue(hashKey) and
|
|
||||||
erb = refNode.getFile()
|
erb = refNode.getFile()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,18 +17,11 @@ import codeql.ruby.frameworks.ActionController
|
|||||||
import DataFlow::PathGraph
|
import DataFlow::PathGraph
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A call to `request` in an ActionController controller class.
|
* Gets a call to `request` in an ActionController controller class.
|
||||||
* This probably refers to the incoming HTTP request object.
|
* This probably refers to the incoming HTTP request object.
|
||||||
*/
|
*/
|
||||||
class ActionControllerRequest extends DataFlow::Node {
|
DataFlow::LocalSourceNode request() {
|
||||||
ActionControllerRequest() {
|
result = any(ActionControllerClass cls).getSelf().getAMethodCall("request")
|
||||||
exists(DataFlow::CallNode c |
|
|
||||||
c.asExpr().getExpr().getEnclosingModule() instanceof ActionControllerControllerClass and
|
|
||||||
c.getMethodName() = "request"
|
|
||||||
|
|
|
||||||
c.flowsTo(this)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,9 +29,11 @@ class ActionControllerRequest extends DataFlow::Node {
|
|||||||
*/
|
*/
|
||||||
class WeakParams extends DataFlow::CallNode {
|
class WeakParams extends DataFlow::CallNode {
|
||||||
WeakParams() {
|
WeakParams() {
|
||||||
this.getReceiver() instanceof ActionControllerRequest and
|
this =
|
||||||
this.getMethodName() =
|
request()
|
||||||
["path_parameters", "query_parameters", "request_parameters", "GET", "POST"]
|
.getAMethodCall([
|
||||||
|
"path_parameters", "query_parameters", "request_parameters", "GET", "POST"
|
||||||
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import codeql.ruby.ast.Literal
|
|||||||
from AmbiguousPathCall call
|
from AmbiguousPathCall call
|
||||||
where
|
where
|
||||||
// there is not a constant string argument
|
// there is not a constant string argument
|
||||||
not exists(call.getPathArgument().asExpr().getExpr().getConstantValue()) and
|
not exists(call.getPathArgument().getConstantValue()) and
|
||||||
// if it's a format string, then the first argument is not a constant string
|
// if it's a format string, then the first argument is not a constant string
|
||||||
not call.getPathArgument().getALocalSource().asExpr().getExpr().(StringLiteral).getComponent(0)
|
not call.getPathArgument().getALocalSource().asExpr().getExpr().(StringLiteral).getComponent(0)
|
||||||
instanceof StringTextComponent
|
instanceof StringTextComponent
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
| array_flow.rb:180:28:180:46 | # $ hasValueFlow=19 | Missing result:hasValueFlow=19 |
|
| array_flow.rb:180:28:180:46 | # $ hasValueFlow=19 | Missing result:hasValueFlow=19 |
|
||||||
| array_flow.rb:226:10:226:13 | ...[...] | Unexpected result: hasValueFlow=25 |
|
| array_flow.rb:226:10:226:13 | ...[...] | Unexpected result: hasValueFlow=25 |
|
||||||
| array_flow.rb:242:14:242:14 | x | Unexpected result: hasValueFlow=27.2 |
|
| array_flow.rb:242:14:242:14 | x | Unexpected result: hasValueFlow=27.2 |
|
||||||
| array_flow.rb:255:16:255:56 | # $ hasValueFlow=28.1 $ hasValueFlow=28.2 | Missing result:hasValueFlow=28.1 |
|
|
||||||
| array_flow.rb:319:10:319:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
| array_flow.rb:319:10:319:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
||||||
| array_flow.rb:320:10:320:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
| array_flow.rb:320:10:320:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
||||||
| array_flow.rb:321:10:321:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
| array_flow.rb:321:10:321:13 | ...[...] | Unexpected result: hasValueFlow=36.1 |
|
||||||
@@ -26,7 +25,6 @@
|
|||||||
| array_flow.rb:490:10:490:13 | ...[...] | Unexpected result: hasValueFlow=54.5 |
|
| array_flow.rb:490:10:490:13 | ...[...] | Unexpected result: hasValueFlow=54.5 |
|
||||||
| array_flow.rb:494:10:494:13 | ...[...] | Unexpected result: hasValueFlow=54.2 |
|
| array_flow.rb:494:10:494:13 | ...[...] | Unexpected result: hasValueFlow=54.2 |
|
||||||
| array_flow.rb:494:10:494:13 | ...[...] | Unexpected result: hasValueFlow=54.3 |
|
| array_flow.rb:494:10:494:13 | ...[...] | Unexpected result: hasValueFlow=54.3 |
|
||||||
| array_flow.rb:564:16:564:56 | # $ hasValueFlow=62.1 $ hasValueFlow=62.2 | Missing result:hasValueFlow=62.1 |
|
|
||||||
| array_flow.rb:575:16:575:34 | # $ hasValueFlow=63 | Missing result:hasValueFlow=63 |
|
| array_flow.rb:575:16:575:34 | # $ hasValueFlow=63 | Missing result:hasValueFlow=63 |
|
||||||
| array_flow.rb:580:19:580:37 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 |
|
| array_flow.rb:580:19:580:37 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 |
|
||||||
| array_flow.rb:582:16:582:34 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 |
|
| array_flow.rb:582:16:582:34 | # $ hasValueFlow=64 | Missing result:hasValueFlow=64 |
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
failures
|
failures
|
||||||
edges
|
edges
|
||||||
|
| captured_variables.rb:1:24:1:24 | x : | captured_variables.rb:2:20:2:20 | x |
|
||||||
|
| captured_variables.rb:1:24:1:24 | x : | captured_variables.rb:2:20:2:20 | x |
|
||||||
|
| captured_variables.rb:5:20:5:30 | call to source : | captured_variables.rb:1:24:1:24 | x : |
|
||||||
|
| captured_variables.rb:5:20:5:30 | call to source : | captured_variables.rb:1:24:1:24 | x : |
|
||||||
|
| captured_variables.rb:21:33:21:33 | x : | captured_variables.rb:23:14:23:14 | x |
|
||||||
|
| captured_variables.rb:21:33:21:33 | x : | captured_variables.rb:23:14:23:14 | x |
|
||||||
|
| captured_variables.rb:27:29:27:39 | call to source : | captured_variables.rb:21:33:21:33 | x : |
|
||||||
|
| captured_variables.rb:27:29:27:39 | call to source : | captured_variables.rb:21:33:21:33 | x : |
|
||||||
|
| captured_variables.rb:32:31:32:31 | x : | captured_variables.rb:34:14:34:14 | x |
|
||||||
|
| captured_variables.rb:32:31:32:31 | x : | captured_variables.rb:34:14:34:14 | x |
|
||||||
|
| captured_variables.rb:38:27:38:37 | call to source : | captured_variables.rb:32:31:32:31 | x : |
|
||||||
|
| captured_variables.rb:38:27:38:37 | call to source : | captured_variables.rb:32:31:32:31 | x : |
|
||||||
| instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:18:11:18 | x : |
|
| instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:18:11:18 | x : |
|
||||||
| instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:18:11:18 | x : |
|
| instance_variables.rb:10:19:10:19 | x : | instance_variables.rb:11:18:11:18 | x : |
|
||||||
| instance_variables.rb:11:18:11:18 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : |
|
| instance_variables.rb:11:18:11:18 | x : | instance_variables.rb:11:9:11:14 | [post] self [@field] : |
|
||||||
@@ -152,6 +164,24 @@ edges
|
|||||||
| 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: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 |
|
||||||
nodes
|
nodes
|
||||||
|
| captured_variables.rb:1:24:1:24 | x : | semmle.label | x : |
|
||||||
|
| captured_variables.rb:1:24:1:24 | x : | semmle.label | x : |
|
||||||
|
| captured_variables.rb:2:20:2:20 | x | semmle.label | x |
|
||||||
|
| captured_variables.rb:2:20:2:20 | x | semmle.label | x |
|
||||||
|
| captured_variables.rb:5:20:5:30 | call to source : | semmle.label | call to source : |
|
||||||
|
| captured_variables.rb:5:20:5:30 | call to source : | semmle.label | call to source : |
|
||||||
|
| captured_variables.rb:21:33:21:33 | x : | semmle.label | x : |
|
||||||
|
| captured_variables.rb:21:33:21:33 | x : | semmle.label | x : |
|
||||||
|
| captured_variables.rb:23:14:23:14 | x | semmle.label | x |
|
||||||
|
| captured_variables.rb:23:14:23:14 | x | semmle.label | x |
|
||||||
|
| captured_variables.rb:27:29:27:39 | call to source : | semmle.label | call to source : |
|
||||||
|
| captured_variables.rb:27:29:27:39 | call to source : | semmle.label | call to source : |
|
||||||
|
| captured_variables.rb:32:31:32:31 | x : | semmle.label | x : |
|
||||||
|
| captured_variables.rb:32:31:32:31 | x : | semmle.label | x : |
|
||||||
|
| captured_variables.rb:34:14:34:14 | x | semmle.label | x |
|
||||||
|
| captured_variables.rb:34:14:34:14 | x | semmle.label | x |
|
||||||
|
| captured_variables.rb:38:27:38:37 | call to source : | semmle.label | call to source : |
|
||||||
|
| captured_variables.rb:38:27:38:37 | call to source : | semmle.label | call to source : |
|
||||||
| instance_variables.rb:10:19:10:19 | x : | semmle.label | x : |
|
| instance_variables.rb:10:19:10:19 | x : | semmle.label | x : |
|
||||||
| instance_variables.rb:10:19:10:19 | x : | semmle.label | x : |
|
| instance_variables.rb:10:19:10:19 | x : | semmle.label | x : |
|
||||||
| instance_variables.rb:11:9:11:14 | [post] self [@field] : | semmle.label | [post] self [@field] : |
|
| instance_variables.rb:11:9:11:14 | [post] self [@field] : | semmle.label | [post] self [@field] : |
|
||||||
@@ -335,6 +365,9 @@ subpaths
|
|||||||
| 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: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 |
|
||||||
#select
|
#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: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: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: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 : |
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
| 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 |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import TestUtilities.InlineTypeTrackingFlowTest
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
def capture_local_call x
|
||||||
|
fn = -> { sink(x) } # $ hasValueFlow=1.1
|
||||||
|
fn.call
|
||||||
|
end
|
||||||
|
capture_local_call source(1.1)
|
||||||
|
|
||||||
|
def capture_escape_return1 x
|
||||||
|
-> {
|
||||||
|
sink(x) # $ MISSING: hasValueFlow=1.2
|
||||||
|
}
|
||||||
|
end
|
||||||
|
(capture_escape_return1 source(1.2)).call
|
||||||
|
|
||||||
|
def capture_escape_return2 x
|
||||||
|
-> {
|
||||||
|
sink(x) # $ MISSING: hasValueFlow=1.3
|
||||||
|
}
|
||||||
|
end
|
||||||
|
Something.unknownMethod(capture_escape_return2 source(1.3))
|
||||||
|
|
||||||
|
def capture_escape_unknown_call x
|
||||||
|
fn = -> {
|
||||||
|
sink(x) # $ hasValueFlow=1.4
|
||||||
|
}
|
||||||
|
Something.unknownMethod(fn)
|
||||||
|
end
|
||||||
|
capture_escape_unknown_call source(1.4)
|
||||||
|
|
||||||
|
def call_it fn
|
||||||
|
fn.call
|
||||||
|
end
|
||||||
|
def capture_escape_known_call x
|
||||||
|
fn = -> {
|
||||||
|
sink(x) # $ hasValueFlow=1.5
|
||||||
|
}
|
||||||
|
call_it fn
|
||||||
|
end
|
||||||
|
capture_escape_known_call source(1.5)
|
||||||
225
ruby/ql/test/library-tests/dataflow/helpers/dataflow.expected
Normal file
225
ruby/ql/test/library-tests/dataflow/helpers/dataflow.expected
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
getAnAncestorExpr
|
||||||
|
| tst.rb:8:1:11:3 | C2 | tst.rb:8:12:8:13 | C1 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:27:12:27:13 | C2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:28:13:28:17 | Mixin |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:29:13:29:18 | Mixin2 |
|
||||||
|
| tst.rb:41:5:42:7 | N1::XY1 | tst.rb:41:17:41:20 | Y |
|
||||||
|
| tst.rb:44:9:45:11 | N1::N2::XY2 | tst.rb:44:21:44:24 | Y |
|
||||||
|
| tst.rb:49:1:51:3 | N2 | tst.rb:50:13:50:13 | X |
|
||||||
|
| tst.rb:53:5:54:7 | N2::XY3 | tst.rb:53:17:53:17 | Y |
|
||||||
|
getAnAncestor
|
||||||
|
| file://:0:0:0:0 | Array | file://:0:0:0:0 | Array |
|
||||||
|
| file://:0:0:0:0 | Array | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Array | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Array | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | BasicObject | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Class | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Class | file://:0:0:0:0 | Class |
|
||||||
|
| file://:0:0:0:0 | Class | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Class | file://:0:0:0:0 | Module |
|
||||||
|
| file://:0:0:0:0 | Class | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Complex | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Complex | file://:0:0:0:0 | Complex |
|
||||||
|
| file://:0:0:0:0 | Complex | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Complex | file://:0:0:0:0 | Numeric |
|
||||||
|
| file://:0:0:0:0 | Complex | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | FalseClass | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | FalseClass | file://:0:0:0:0 | FalseClass |
|
||||||
|
| file://:0:0:0:0 | FalseClass | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | FalseClass | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Float | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Float | file://:0:0:0:0 | Float |
|
||||||
|
| file://:0:0:0:0 | Float | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Float | file://:0:0:0:0 | Numeric |
|
||||||
|
| file://:0:0:0:0 | Float | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Hash | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Hash | file://:0:0:0:0 | Hash |
|
||||||
|
| file://:0:0:0:0 | Hash | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Hash | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Integer | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Integer | file://:0:0:0:0 | Integer |
|
||||||
|
| file://:0:0:0:0 | Integer | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Integer | file://:0:0:0:0 | Numeric |
|
||||||
|
| file://:0:0:0:0 | Integer | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Kernel | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Module | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Module | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Module | file://:0:0:0:0 | Module |
|
||||||
|
| file://:0:0:0:0 | Module | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | NilClass | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | NilClass | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | NilClass | file://:0:0:0:0 | NilClass |
|
||||||
|
| file://:0:0:0:0 | NilClass | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Numeric | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Numeric | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Numeric | file://:0:0:0:0 | Numeric |
|
||||||
|
| file://:0:0:0:0 | Numeric | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Object | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Object | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Object | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Proc | file://:0:0:0:0 | Proc |
|
||||||
|
| file://:0:0:0:0 | Rational | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | Rational | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | Rational | file://:0:0:0:0 | Numeric |
|
||||||
|
| file://:0:0:0:0 | Rational | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | Rational | file://:0:0:0:0 | Rational |
|
||||||
|
| file://:0:0:0:0 | String | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | String | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | String | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | String | file://:0:0:0:0 | String |
|
||||||
|
| file://:0:0:0:0 | Symbol | file://:0:0:0:0 | Symbol |
|
||||||
|
| file://:0:0:0:0 | TrueClass | file://:0:0:0:0 | BasicObject |
|
||||||
|
| file://:0:0:0:0 | TrueClass | file://:0:0:0:0 | Kernel |
|
||||||
|
| file://:0:0:0:0 | TrueClass | file://:0:0:0:0 | Object |
|
||||||
|
| file://:0:0:0:0 | TrueClass | file://:0:0:0:0 | TrueClass |
|
||||||
|
| tst.rb:1:1:6:3 | C1 | file://:0:0:0:0 | BasicObject |
|
||||||
|
| tst.rb:1:1:6:3 | C1 | file://:0:0:0:0 | Kernel |
|
||||||
|
| tst.rb:1:1:6:3 | C1 | file://:0:0:0:0 | Object |
|
||||||
|
| tst.rb:1:1:6:3 | C1 | tst.rb:1:1:6:3 | C1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | file://:0:0:0:0 | BasicObject |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | file://:0:0:0:0 | Kernel |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | file://:0:0:0:0 | Object |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | tst.rb:1:1:6:3 | C1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | tst.rb:8:1:11:3 | C2 |
|
||||||
|
| tst.rb:13:1:18:3 | Mixin | tst.rb:13:1:18:3 | Mixin |
|
||||||
|
| tst.rb:20:1:25:3 | Mixin2 | tst.rb:20:1:25:3 | Mixin2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | file://:0:0:0:0 | BasicObject |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | file://:0:0:0:0 | Kernel |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | file://:0:0:0:0 | Object |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:1:1:6:3 | C1 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:8:1:11:3 | C2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:13:1:18:3 | Mixin |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:20:1:25:3 | Mixin2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:27:1:35:3 | C3 |
|
||||||
|
| tst.rb:40:1:47:3 | N1 | tst.rb:40:1:47:3 | N1 |
|
||||||
|
| tst.rb:41:5:42:7 | N1::XY1 | file://:0:0:0:0 | BasicObject |
|
||||||
|
| tst.rb:41:5:42:7 | N1::XY1 | file://:0:0:0:0 | Kernel |
|
||||||
|
| tst.rb:41:5:42:7 | N1::XY1 | file://:0:0:0:0 | Object |
|
||||||
|
| tst.rb:41:5:42:7 | N1::XY1 | tst.rb:41:5:42:7 | N1::XY1 |
|
||||||
|
| tst.rb:43:5:46:7 | N1::N2 | tst.rb:43:5:46:7 | N1::N2 |
|
||||||
|
| tst.rb:44:9:45:11 | N1::N2::XY2 | file://:0:0:0:0 | BasicObject |
|
||||||
|
| tst.rb:44:9:45:11 | N1::N2::XY2 | file://:0:0:0:0 | Kernel |
|
||||||
|
| tst.rb:44:9:45:11 | N1::N2::XY2 | file://:0:0:0:0 | Object |
|
||||||
|
| tst.rb:44:9:45:11 | N1::N2::XY2 | tst.rb:44:9:45:11 | N1::N2::XY2 |
|
||||||
|
| tst.rb:49:1:51:3 | N2 | tst.rb:49:1:51:3 | N2 |
|
||||||
|
| tst.rb:53:5:54:7 | N2::XY3 | file://:0:0:0:0 | BasicObject |
|
||||||
|
| tst.rb:53:5:54:7 | N2::XY3 | file://:0:0:0:0 | Kernel |
|
||||||
|
| tst.rb:53:5:54:7 | N2::XY3 | file://:0:0:0:0 | Object |
|
||||||
|
| tst.rb:53:5:54:7 | N2::XY3 | tst.rb:53:5:54:7 | N2::XY3 |
|
||||||
|
| tst.rb:57:1:62:3 | Nodes | file://:0:0:0:0 | BasicObject |
|
||||||
|
| tst.rb:57:1:62:3 | Nodes | file://:0:0:0:0 | Kernel |
|
||||||
|
| tst.rb:57:1:62:3 | Nodes | file://:0:0:0:0 | Object |
|
||||||
|
| tst.rb:57:1:62:3 | Nodes | tst.rb:57:1:62:3 | Nodes |
|
||||||
|
getModuleLevelSelf
|
||||||
|
| tst.rb:13:1:18:3 | Mixin | tst.rb:13:1:18:3 | self (Mixin) |
|
||||||
|
| tst.rb:20:1:25:3 | Mixin2 | tst.rb:20:1:25:3 | self (Mixin2) |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:27:1:35:3 | self (C3) |
|
||||||
|
| tst.rb:49:1:51:3 | N2 | tst.rb:49:1:51:3 | self (N2) |
|
||||||
|
getAnImmediateReference
|
||||||
|
| file://:0:0:0:0 | Array | tst.rb:59:15:59:21 | Array |
|
||||||
|
| file://:0:0:0:0 | Hash | tst.rb:60:14:60:45 | Hash |
|
||||||
|
| tst.rb:1:1:6:3 | C1 | tst.rb:8:12:8:13 | C1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | tst.rb:27:12:27:13 | C2 |
|
||||||
|
| tst.rb:13:1:18:3 | Mixin | tst.rb:28:13:28:17 | Mixin |
|
||||||
|
| tst.rb:20:1:25:3 | Mixin2 | tst.rb:29:13:29:18 | Mixin2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:37:5:37:6 | C3 |
|
||||||
|
getOwnInstanceMethod
|
||||||
|
| tst.rb:1:1:6:3 | C1 | c1 | tst.rb:2:5:5:7 | c1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | c2 | tst.rb:9:5:10:7 | c2 |
|
||||||
|
| tst.rb:13:1:18:3 | Mixin | m1 | tst.rb:14:5:15:7 | m1 |
|
||||||
|
| tst.rb:20:1:25:3 | Mixin2 | m2 | tst.rb:21:5:22:7 | m2 |
|
||||||
|
| tst.rb:57:1:62:3 | Nodes | m1 | tst.rb:58:5:61:7 | m1 |
|
||||||
|
getInstanceMethod
|
||||||
|
| tst.rb:1:1:6:3 | C1 | c1 | tst.rb:2:5:5:7 | c1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | c1 | tst.rb:2:5:5:7 | c1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | c2 | tst.rb:9:5:10:7 | c2 |
|
||||||
|
| tst.rb:13:1:18:3 | Mixin | m1 | tst.rb:14:5:15:7 | m1 |
|
||||||
|
| tst.rb:20:1:25:3 | Mixin2 | m2 | tst.rb:21:5:22:7 | m2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | c1 | tst.rb:2:5:5:7 | c1 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | c2 | tst.rb:9:5:10:7 | c2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | m1 | tst.rb:14:5:15:7 | m1 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | m2 | tst.rb:21:5:22:7 | m2 |
|
||||||
|
| tst.rb:57:1:62:3 | Nodes | m1 | tst.rb:58:5:61:7 | m1 |
|
||||||
|
getAnOwnInstanceSelf
|
||||||
|
| tst.rb:1:1:6:3 | C1 | tst.rb:2:5:5:7 | self in c1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | tst.rb:9:5:10:7 | self in c2 |
|
||||||
|
| tst.rb:13:1:18:3 | Mixin | tst.rb:14:5:15:7 | self in m1 |
|
||||||
|
| tst.rb:20:1:25:3 | Mixin2 | tst.rb:21:5:22:7 | self in m2 |
|
||||||
|
| tst.rb:57:1:62:3 | Nodes | tst.rb:58:5:61:7 | self in m1 |
|
||||||
|
getAnInstanceSelf
|
||||||
|
| tst.rb:1:1:6:3 | C1 | tst.rb:2:5:5:7 | self in c1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | tst.rb:2:5:5:7 | self in c1 |
|
||||||
|
| tst.rb:8:1:11:3 | C2 | tst.rb:9:5:10:7 | self in c2 |
|
||||||
|
| tst.rb:13:1:18:3 | Mixin | tst.rb:14:5:15:7 | self in m1 |
|
||||||
|
| tst.rb:20:1:25:3 | Mixin2 | tst.rb:21:5:22:7 | self in m2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:2:5:5:7 | self in c1 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:9:5:10:7 | self in c2 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:14:5:15:7 | self in m1 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | tst.rb:21:5:22:7 | self in m2 |
|
||||||
|
| tst.rb:57:1:62:3 | Nodes | tst.rb:58:5:61:7 | self in m1 |
|
||||||
|
getOwnSingletonMethod
|
||||||
|
| tst.rb:13:1:18:3 | Mixin | m1s | tst.rb:16:5:17:7 | m1s |
|
||||||
|
| tst.rb:20:1:25:3 | Mixin2 | m2s | tst.rb:23:5:24:7 | m2s |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | c3_self1 | tst.rb:32:9:33:11 | c3_self1 |
|
||||||
|
| tst.rb:27:1:35:3 | C3 | c3_self2 | tst.rb:37:1:38:3 | c3_self2 |
|
||||||
|
getAnOwnInstanceVariableRead
|
||||||
|
| tst.rb:1:1:6:3 | C1 | @field | tst.rb:4:9:4:14 | @field |
|
||||||
|
getAnOwnInstanceVariableWriteValue
|
||||||
|
| tst.rb:1:1:6:3 | C1 | @field | tst.rb:3:18:3:18 | 1 |
|
||||||
|
getCanonicalEnclosingModule
|
||||||
|
| tst.rb:41:5:42:7 | N1::XY1 | tst.rb:40:1:47:3 | N1 |
|
||||||
|
| tst.rb:43:5:46:7 | N1::N2 | tst.rb:40:1:47:3 | N1 |
|
||||||
|
| tst.rb:44:9:45:11 | N1::N2::XY2 | tst.rb:43:5:46:7 | N1::N2 |
|
||||||
|
| tst.rb:53:5:54:7 | N2::XY3 | tst.rb:49:1:51:3 | N2 |
|
||||||
|
getCanonicalNestedModule
|
||||||
|
| tst.rb:40:1:47:3 | N1 | N2 | tst.rb:43:5:46:7 | N1::N2 |
|
||||||
|
| tst.rb:40:1:47:3 | N1 | XY1 | tst.rb:41:5:42:7 | N1::XY1 |
|
||||||
|
| tst.rb:43:5:46:7 | N1::N2 | XY2 | tst.rb:44:9:45:11 | N1::N2::XY2 |
|
||||||
|
| tst.rb:49:1:51:3 | N2 | XY3 | tst.rb:53:5:54:7 | N2::XY3 |
|
||||||
|
getTopLevelConst
|
||||||
|
| Array | tst.rb:59:15:59:21 | Array |
|
||||||
|
| C1 | tst.rb:1:1:6:3 | C1 |
|
||||||
|
| C1 | tst.rb:8:12:8:13 | C1 |
|
||||||
|
| C2 | tst.rb:8:1:11:3 | C2 |
|
||||||
|
| C2 | tst.rb:27:12:27:13 | C2 |
|
||||||
|
| C3 | tst.rb:27:1:35:3 | self (C3) |
|
||||||
|
| C3 | tst.rb:37:5:37:6 | C3 |
|
||||||
|
| Hash | tst.rb:60:14:60:45 | Hash |
|
||||||
|
| Mixin | tst.rb:13:1:18:3 | self (Mixin) |
|
||||||
|
| Mixin | tst.rb:28:13:28:17 | Mixin |
|
||||||
|
| Mixin2 | tst.rb:20:1:25:3 | self (Mixin2) |
|
||||||
|
| Mixin2 | tst.rb:29:13:29:18 | Mixin2 |
|
||||||
|
| N1 | tst.rb:40:1:47:3 | N1 |
|
||||||
|
| N2 | tst.rb:43:5:46:7 | N2 |
|
||||||
|
| N2 | tst.rb:49:1:51:3 | self (N2) |
|
||||||
|
| N2 | tst.rb:52:1:55:3 | N2 |
|
||||||
|
| Nodes | tst.rb:57:1:62:3 | Nodes |
|
||||||
|
| X | tst.rb:41:17:41:17 | X |
|
||||||
|
| X | tst.rb:44:21:44:21 | X |
|
||||||
|
| X | tst.rb:50:13:50:13 | X |
|
||||||
|
| XY1 | tst.rb:41:5:42:7 | XY1 |
|
||||||
|
| XY2 | tst.rb:44:9:45:11 | XY2 |
|
||||||
|
| XY3 | tst.rb:53:5:54:7 | XY3 |
|
||||||
|
| Y | tst.rb:53:17:53:17 | Y |
|
||||||
|
getConst
|
||||||
|
| tst.rb:41:17:41:17 | X | Y | tst.rb:41:17:41:20 | Y |
|
||||||
|
| tst.rb:44:21:44:21 | X | Y | tst.rb:44:21:44:24 | Y |
|
||||||
|
| tst.rb:50:13:50:13 | X | X | tst.rb:50:13:50:13 | X |
|
||||||
|
| tst.rb:50:13:50:13 | X | XY3 | tst.rb:53:5:54:7 | XY3 |
|
||||||
|
| tst.rb:50:13:50:13 | X | Y | tst.rb:53:17:53:17 | Y |
|
||||||
|
getXYClasses
|
||||||
|
| tst.rb:41:5:42:7 | N1::XY1 |
|
||||||
|
| tst.rb:44:9:45:11 | N1::N2::XY2 |
|
||||||
|
| tst.rb:53:5:54:7 | N2::XY3 |
|
||||||
|
hashLiteralNode
|
||||||
|
| tst.rb:60:14:60:45 | call to [] |
|
||||||
|
hashLiteralKey
|
||||||
|
| tst.rb:60:14:60:45 | call to [] | bar | tst.rb:60:36:60:36 | 2 |
|
||||||
|
| tst.rb:60:14:60:45 | call to [] | baz | tst.rb:60:44:60:44 | 3 |
|
||||||
|
| tst.rb:60:14:60:45 | call to [] | foo | tst.rb:60:24:60:24 | 1 |
|
||||||
|
arrayLiteralNode
|
||||||
|
| tst.rb:59:15:59:21 | call to [] |
|
||||||
|
arrayLiteralElement
|
||||||
|
| tst.rb:59:15:59:21 | call to [] | tst.rb:59:16:59:16 | 1 |
|
||||||
|
| tst.rb:59:15:59:21 | call to [] | tst.rb:59:18:59:18 | 2 |
|
||||||
|
| tst.rb:59:15:59:21 | call to [] | tst.rb:59:20:59:20 | 3 |
|
||||||
71
ruby/ql/test/library-tests/dataflow/helpers/dataflow.ql
Normal file
71
ruby/ql/test/library-tests/dataflow/helpers/dataflow.ql
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import ruby
|
||||||
|
|
||||||
|
query DataFlow::Node getAnAncestorExpr(DataFlow::ModuleNode mod) {
|
||||||
|
result = mod.getAnAncestorExpr()
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::ModuleNode getAnAncestor(DataFlow::ModuleNode mod) { result = mod.getAnAncestor() }
|
||||||
|
|
||||||
|
query DataFlow::Node getModuleLevelSelf(DataFlow::ModuleNode mod) {
|
||||||
|
result = mod.getModuleLevelSelf()
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::Node getAnImmediateReference(DataFlow::ModuleNode mod) {
|
||||||
|
result = mod.getAnImmediateReference()
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::MethodNode getOwnInstanceMethod(DataFlow::ModuleNode mod, string name) {
|
||||||
|
result = mod.getOwnInstanceMethod(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::MethodNode getInstanceMethod(DataFlow::ModuleNode mod, string name) {
|
||||||
|
result = mod.getInstanceMethod(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::Node getAnOwnInstanceSelf(DataFlow::ModuleNode mod) {
|
||||||
|
result = mod.getAnOwnInstanceSelf()
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::Node getAnInstanceSelf(DataFlow::ModuleNode mod) {
|
||||||
|
result = mod.getAnInstanceSelf()
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::Node getOwnSingletonMethod(DataFlow::ModuleNode mod, string name) {
|
||||||
|
result = mod.getOwnSingletonMethod(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::Node getAnOwnInstanceVariableRead(DataFlow::ModuleNode mod, string name) {
|
||||||
|
result = mod.getAnOwnInstanceVariableRead(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::Node getAnOwnInstanceVariableWriteValue(DataFlow::ModuleNode mod, string name) {
|
||||||
|
result = mod.getAnOwnInstanceVariableWriteValue(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::ModuleNode getCanonicalEnclosingModule(DataFlow::ModuleNode mod) {
|
||||||
|
result = mod.getCanonicalEnclosingModule()
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::ModuleNode getCanonicalNestedModule(DataFlow::ModuleNode mod, string name) {
|
||||||
|
result = mod.getCanonicalNestedModule(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::Node getTopLevelConst(string name) { result = DataFlow::getConst(name) }
|
||||||
|
|
||||||
|
query DataFlow::Node getConst(DataFlow::ConstRef base, string name) { result = base.getConst(name) }
|
||||||
|
|
||||||
|
query DataFlow::ModuleNode getXYClasses() {
|
||||||
|
result = DataFlow::getConst("X").getConst("Y").getADescendentModule()
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::HashLiteralNode hashLiteralNode() { any() }
|
||||||
|
|
||||||
|
query DataFlow::Node hashLiteralKey(DataFlow::HashLiteralNode node, string key) {
|
||||||
|
result = node.getElementFromKey(Ast::ConstantValue::getStringlikeValue(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
query DataFlow::ArrayLiteralNode arrayLiteralNode() { any() }
|
||||||
|
|
||||||
|
query DataFlow::Node arrayLiteralElement(DataFlow::ArrayLiteralNode node) {
|
||||||
|
result = node.getAnElement()
|
||||||
|
}
|
||||||
62
ruby/ql/test/library-tests/dataflow/helpers/tst.rb
Normal file
62
ruby/ql/test/library-tests/dataflow/helpers/tst.rb
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
module C1
|
||||||
|
def c1
|
||||||
|
@field = 1
|
||||||
|
@field
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class C2 < C1
|
||||||
|
def c2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Mixin
|
||||||
|
def m1
|
||||||
|
end
|
||||||
|
def self.m1s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Mixin2
|
||||||
|
def m2
|
||||||
|
end
|
||||||
|
def self.m2s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class C3 < C2
|
||||||
|
include Mixin
|
||||||
|
prepend Mixin2
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def c3_self1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def C3.c3_self2
|
||||||
|
end
|
||||||
|
|
||||||
|
module N1
|
||||||
|
class XY1 < X::Y
|
||||||
|
end
|
||||||
|
module N2
|
||||||
|
class XY2 < X::Y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module N2
|
||||||
|
include X
|
||||||
|
end
|
||||||
|
module N2
|
||||||
|
class XY3 < Y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Nodes
|
||||||
|
def m1
|
||||||
|
array=[1,2,3]
|
||||||
|
hash={'foo' => 1, 'bar' => 2, baz: 3}
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
||||||
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
||||||
| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:12:5:12:5 | x |
|
| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:12:5:12:5 | x |
|
||||||
| local_dataflow.rb:10:5:13:3 | <captured> | local_dataflow.rb:11:1:11:2 | self |
|
| local_dataflow.rb:10:5:13:3 | <captured> self | local_dataflow.rb:11:1:11:2 | self |
|
||||||
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... |
|
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... |
|
||||||
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... |
|
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... |
|
||||||
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 |
|
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 |
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
| local_dataflow.rb:45:10:45:10 | 6 | local_dataflow.rb:45:3:45:10 | return |
|
| local_dataflow.rb:45:10:45:10 | 6 | local_dataflow.rb:45:3:45:10 | return |
|
||||||
| local_dataflow.rb:49:1:53:3 | [post] self | local_dataflow.rb:55:1:55:14 | self |
|
| local_dataflow.rb:49:1:53:3 | [post] self | local_dataflow.rb:55:1:55:14 | self |
|
||||||
| local_dataflow.rb:49:1:53:3 | self | local_dataflow.rb:55:1:55:14 | self |
|
| local_dataflow.rb:49:1:53:3 | self | local_dataflow.rb:55:1:55:14 | self |
|
||||||
| local_dataflow.rb:49:3:53:3 | <captured> | local_dataflow.rb:50:18:50:18 | x |
|
| local_dataflow.rb:49:3:53:3 | <captured> x | local_dataflow.rb:50:18:50:18 | x |
|
||||||
| local_dataflow.rb:50:8:50:13 | "next" | local_dataflow.rb:50:3:50:13 | next |
|
| local_dataflow.rb:50:8:50:13 | "next" | local_dataflow.rb:50:3:50:13 | next |
|
||||||
| local_dataflow.rb:50:18:50:18 | [post] x | local_dataflow.rb:51:20:51:20 | x |
|
| local_dataflow.rb:50:18:50:18 | [post] x | local_dataflow.rb:51:20:51:20 | x |
|
||||||
| local_dataflow.rb:50:18:50:18 | x | local_dataflow.rb:51:20:51:20 | x |
|
| local_dataflow.rb:50:18:50:18 | x | local_dataflow.rb:51:20:51:20 | x |
|
||||||
@@ -264,7 +264,7 @@
|
|||||||
| local_dataflow.rb:118:3:118:11 | [post] self | local_dataflow.rb:119:3:119:31 | self |
|
| local_dataflow.rb:118:3:118:11 | [post] self | local_dataflow.rb:119:3:119:31 | self |
|
||||||
| local_dataflow.rb:118:3:118:11 | call to source | local_dataflow.rb:118:3:118:31 | call to tap |
|
| local_dataflow.rb:118:3:118:11 | call to source | local_dataflow.rb:118:3:118:31 | call to tap |
|
||||||
| local_dataflow.rb:118:3:118:11 | self | local_dataflow.rb:119:3:119:31 | self |
|
| local_dataflow.rb:118:3:118:11 | self | local_dataflow.rb:119:3:119:31 | self |
|
||||||
| local_dataflow.rb:118:17:118:31 | <captured> | local_dataflow.rb:118:23:118:29 | self |
|
| local_dataflow.rb:118:17:118:31 | <captured> self | local_dataflow.rb:118:23:118:29 | self |
|
||||||
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:20:118:20 | x |
|
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:20:118:20 | x |
|
||||||
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:28:118:28 | x |
|
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:28:118:28 | x |
|
||||||
| local_dataflow.rb:119:3:119:31 | [post] self | local_dataflow.rb:119:8:119:16 | self |
|
| local_dataflow.rb:119:3:119:31 | [post] self | local_dataflow.rb:119:8:119:16 | self |
|
||||||
@@ -278,4 +278,4 @@
|
|||||||
| local_dataflow.rb:123:8:123:16 | call to source | local_dataflow.rb:123:8:123:20 | call to dup |
|
| local_dataflow.rb:123:8:123:16 | call to source | local_dataflow.rb:123:8:123:20 | call to dup |
|
||||||
| local_dataflow.rb:123:8:123:20 | call to dup | local_dataflow.rb:123:8:123:45 | call to tap |
|
| local_dataflow.rb:123:8:123:20 | call to dup | local_dataflow.rb:123:8:123:45 | call to tap |
|
||||||
| local_dataflow.rb:123:8:123:45 | call to tap | local_dataflow.rb:123:8:123:49 | call to dup |
|
| local_dataflow.rb:123:8:123:45 | call to tap | local_dataflow.rb:123:8:123:49 | call to dup |
|
||||||
| local_dataflow.rb:123:26:123:45 | <captured> | local_dataflow.rb:123:32:123:43 | self |
|
| local_dataflow.rb:123:26:123:45 | <captured> self | local_dataflow.rb:123:32:123:43 | self |
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
||||||
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
||||||
| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:12:5:12:5 | x |
|
| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:12:5:12:5 | x |
|
||||||
| local_dataflow.rb:10:5:13:3 | <captured> | local_dataflow.rb:11:1:11:2 | self |
|
| local_dataflow.rb:10:5:13:3 | <captured> self | local_dataflow.rb:11:1:11:2 | self |
|
||||||
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... |
|
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... |
|
||||||
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... |
|
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... |
|
||||||
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 |
|
| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 |
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
| local_dataflow.rb:45:10:45:10 | 6 | local_dataflow.rb:45:3:45:10 | return |
|
| local_dataflow.rb:45:10:45:10 | 6 | local_dataflow.rb:45:3:45:10 | return |
|
||||||
| local_dataflow.rb:49:1:53:3 | [post] self | local_dataflow.rb:55:1:55:14 | self |
|
| local_dataflow.rb:49:1:53:3 | [post] self | local_dataflow.rb:55:1:55:14 | self |
|
||||||
| local_dataflow.rb:49:1:53:3 | self | local_dataflow.rb:55:1:55:14 | self |
|
| local_dataflow.rb:49:1:53:3 | self | local_dataflow.rb:55:1:55:14 | self |
|
||||||
| local_dataflow.rb:49:3:53:3 | <captured> | local_dataflow.rb:50:18:50:18 | x |
|
| local_dataflow.rb:49:3:53:3 | <captured> x | local_dataflow.rb:50:18:50:18 | x |
|
||||||
| local_dataflow.rb:50:8:50:13 | "next" | local_dataflow.rb:50:3:50:13 | next |
|
| local_dataflow.rb:50:8:50:13 | "next" | local_dataflow.rb:50:3:50:13 | next |
|
||||||
| local_dataflow.rb:50:18:50:18 | [post] x | local_dataflow.rb:51:20:51:20 | x |
|
| local_dataflow.rb:50:18:50:18 | [post] x | local_dataflow.rb:51:20:51:20 | x |
|
||||||
| local_dataflow.rb:50:18:50:18 | x | local_dataflow.rb:50:18:50:22 | ... < ... |
|
| local_dataflow.rb:50:18:50:18 | x | local_dataflow.rb:50:18:50:22 | ... < ... |
|
||||||
@@ -338,7 +338,7 @@
|
|||||||
| local_dataflow.rb:118:3:118:11 | [post] self | local_dataflow.rb:119:3:119:31 | self |
|
| local_dataflow.rb:118:3:118:11 | [post] self | local_dataflow.rb:119:3:119:31 | self |
|
||||||
| local_dataflow.rb:118:3:118:11 | call to source | local_dataflow.rb:118:3:118:31 | call to tap |
|
| local_dataflow.rb:118:3:118:11 | call to source | local_dataflow.rb:118:3:118:31 | call to tap |
|
||||||
| local_dataflow.rb:118:3:118:11 | self | local_dataflow.rb:119:3:119:31 | self |
|
| local_dataflow.rb:118:3:118:11 | self | local_dataflow.rb:119:3:119:31 | self |
|
||||||
| local_dataflow.rb:118:17:118:31 | <captured> | local_dataflow.rb:118:23:118:29 | self |
|
| local_dataflow.rb:118:17:118:31 | <captured> self | local_dataflow.rb:118:23:118:29 | self |
|
||||||
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:20:118:20 | x |
|
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:20:118:20 | x |
|
||||||
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:28:118:28 | x |
|
| local_dataflow.rb:118:20:118:20 | x | local_dataflow.rb:118:28:118:28 | x |
|
||||||
| local_dataflow.rb:119:3:119:31 | [post] self | local_dataflow.rb:119:8:119:16 | self |
|
| local_dataflow.rb:119:3:119:31 | [post] self | local_dataflow.rb:119:8:119:16 | self |
|
||||||
@@ -352,4 +352,4 @@
|
|||||||
| local_dataflow.rb:123:8:123:16 | call to source | local_dataflow.rb:123:8:123:20 | call to dup |
|
| local_dataflow.rb:123:8:123:16 | call to source | local_dataflow.rb:123:8:123:20 | call to dup |
|
||||||
| local_dataflow.rb:123:8:123:20 | call to dup | local_dataflow.rb:123:8:123:45 | call to tap |
|
| local_dataflow.rb:123:8:123:20 | call to dup | local_dataflow.rb:123:8:123:45 | call to tap |
|
||||||
| local_dataflow.rb:123:8:123:45 | call to tap | local_dataflow.rb:123:8:123:49 | call to dup |
|
| local_dataflow.rb:123:8:123:45 | call to tap | local_dataflow.rb:123:8:123:49 | call to dup |
|
||||||
| local_dataflow.rb:123:26:123:45 | <captured> | local_dataflow.rb:123:32:123:43 | self |
|
| local_dataflow.rb:123:26:123:45 | <captured> self | local_dataflow.rb:123:32:123:43 | self |
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ private class TypeFromCodeQL extends ModelInput::TypeModel {
|
|||||||
override DataFlow::Node getASource(string package, string type) {
|
override DataFlow::Node getASource(string package, string type) {
|
||||||
package = "test" and
|
package = "test" and
|
||||||
type = "FooOrBar" and
|
type = "FooOrBar" and
|
||||||
result.asExpr().getExpr().getConstantValue().getString() = "magic_string"
|
result.getConstantValue().getString() = "magic_string"
|
||||||
}
|
}
|
||||||
|
|
||||||
override API::Node getAnApiNode(string package, string type) {
|
override API::Node getAnApiNode(string package, string type) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
track
|
track
|
||||||
|
| type_tracker.rb:1:1:10:3 | Container | type tracker without call steps | type_tracker.rb:1:1:10:3 | Container |
|
||||||
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:18:1:21:3 | self (positional) |
|
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:18:1:21:3 | self (positional) |
|
||||||
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:18:1:21:3 | self in positional |
|
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:18:1:21:3 | self in positional |
|
||||||
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:25:1:28:3 | self (keyword) |
|
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type tracker with call steps | type_tracker.rb:25:1:28:3 | self (keyword) |
|
||||||
@@ -18,13 +19,19 @@ track
|
|||||||
| type_tracker.rb:2:16:2:18 | val | type tracker with call steps | type_tracker.rb:2:16:2:18 | val |
|
| type_tracker.rb:2:16:2:18 | val | type tracker with call steps | type_tracker.rb:2:16:2:18 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker with call steps | type_tracker.rb:8:9:8:14 | @field |
|
| type_tracker.rb:2:16:2:18 | val | type tracker with call steps | type_tracker.rb:8:9:8:14 | @field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
|
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
|
||||||
| type_tracker.rb:3:9:3:23 | call to puts | type tracker without call steps | type_tracker.rb:3:9:3:23 | call to puts |
|
| type_tracker.rb:3:9:3:23 | call to puts | type tracker without call steps | type_tracker.rb:3:9:3:23 | call to puts |
|
||||||
| type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
|
| type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
|
||||||
@@ -189,20 +196,33 @@ track
|
|||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker with call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:34:18:34:20 | obj |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:36:5:36:10 | ...[...] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:36:5:36:10 | ...[...] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:36:5:36:10 | ...[...] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:40:5:40:12 | ...[...] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:40:5:40:12 | ...[...] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:40:5:40:12 | ...[...] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:38:13:38:25 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:38:13:38:25 | call to [] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:38:13:38:25 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:44:5:44:13 | ...[...] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:44:5:44:13 | ...[...] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:44:5:44:13 | ...[...] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:50:14:50:26 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:50:14:50:26 | call to [] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:50:14:50:26 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element | type_tracker.rb:52:5:52:13 | ...[...] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:35:11:35:15 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:35:11:35:15 | call to [] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:35:11:35:15 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:42:14:42:26 | call to [] |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
|
| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:46:14:46:26 | call to [] |
|
||||||
| type_tracker.rb:34:23:34:23 | y | type tracker with call steps | type_tracker.rb:34:23:34:23 | y |
|
| type_tracker.rb:34:23:34:23 | y | type tracker with call steps | type_tracker.rb:34:23:34:23 | y |
|
||||||
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y |
|
| type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y |
|
||||||
@@ -337,6 +357,7 @@ track
|
|||||||
| type_tracker.rb:52:5:52:13 | ...[...] | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
| type_tracker.rb:52:5:52:13 | ...[...] | type tracker without call steps | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
||||||
| type_tracker.rb:52:5:52:13 | ...[...] | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
|
| type_tracker.rb:52:5:52:13 | ...[...] | type tracker without call steps | type_tracker.rb:52:5:52:13 | ...[...] |
|
||||||
trackEnd
|
trackEnd
|
||||||
|
| type_tracker.rb:1:1:10:3 | Container | type_tracker.rb:1:1:10:3 | Container |
|
||||||
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type_tracker.rb:1:1:10:3 | self (type_tracker.rb) |
|
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type_tracker.rb:1:1:10:3 | self (type_tracker.rb) |
|
||||||
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type_tracker.rb:18:1:21:3 | self (positional) |
|
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type_tracker.rb:18:1:21:3 | self (positional) |
|
||||||
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type_tracker.rb:18:1:21:3 | self in positional |
|
| type_tracker.rb:1:1:10:3 | self (type_tracker.rb) | type_tracker.rb:18:1:21:3 | self in positional |
|
||||||
@@ -370,19 +391,24 @@ trackEnd
|
|||||||
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:7:5:9:7 | self in field |
|
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:7:5:9:7 | self in field |
|
||||||
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:8:9:8:14 | self |
|
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:8:9:8:14 | self |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:5:5:7 | return return in field= |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:3:14:3:23 | call to field |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:3:14:3:23 | call to field |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:3:14:3:23 | call to field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:9:4:20 | ... = ... |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:9:4:20 | ... = ... |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:9:4:20 | ... = ... |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:9:4:20 | ... = ... |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:18:4:20 | val |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:18:4:20 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:18:4:20 | val |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:4:18:4:20 | val |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:7:5:9:7 | return return in field |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:7:5:9:7 | return return in field |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:7:5:9:7 | return return in field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:8:9:8:14 | @field |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:8:9:8:14 | @field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:8:9:8:14 | @field |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:8:9:8:14 | @field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:14:5:14:13 | call to field= |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:14:5:14:13 | call to field= |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:14:5:14:13 | call to field= |
|
||||||
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:15:10:15:18 | call to field |
|
||||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:15:10:15:18 | call to field |
|
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:15:10:15:18 | call to field |
|
||||||
| type_tracker.rb:3:9:3:23 | call to puts | type_tracker.rb:3:9:3:23 | call to puts |
|
| type_tracker.rb:3:9:3:23 | call to puts | type_tracker.rb:3:9:3:23 | call to puts |
|
||||||
| type_tracker.rb:3:14:3:23 | call to field | type_tracker.rb:3:14:3:23 | call to field |
|
| type_tracker.rb:3:14:3:23 | call to field | type_tracker.rb:3:14:3:23 | call to field |
|
||||||
@@ -565,6 +591,7 @@ trackEnd
|
|||||||
| type_tracker.rb:34:1:53:3 | self in throughArray | type_tracker.rb:34:1:53:3 | self in throughArray |
|
| type_tracker.rb:34:1:53:3 | self in throughArray | type_tracker.rb:34:1:53:3 | self in throughArray |
|
||||||
| type_tracker.rb:34:1:53:3 | throughArray | type_tracker.rb:34:1:53:3 | throughArray |
|
| type_tracker.rb:34:1:53:3 | throughArray | type_tracker.rb:34:1:53:3 | throughArray |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
||||||
|
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:1:53:3 | return return in throughArray |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj |
|
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj |
|
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj |
|
||||||
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj |
|
| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:34:18:34:20 | obj |
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ query predicate trackEnd(LocalSourceNode src, DataFlow::Node dst) {
|
|||||||
|
|
||||||
predicate backtrack(LocalSourceNode sink, TypeBackTracker t, LocalSourceNode src) {
|
predicate backtrack(LocalSourceNode sink, TypeBackTracker t, LocalSourceNode src) {
|
||||||
t.start() and
|
t.start() and
|
||||||
sink = src
|
sink.getALocalSource() = src
|
||||||
or
|
or
|
||||||
exists(TypeBackTracker t2, LocalSourceNode mid |
|
exists(TypeBackTracker t2, LocalSourceNode mid |
|
||||||
backtrack(sink, t2, mid) and
|
backtrack(sink, t2, mid) and
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
actionControllerControllerClasses
|
actionControllerControllerClasses
|
||||||
| action_controller/input_access.rb:1:1:50:3 | UsersController |
|
| action_controller/input_access.rb:1:1:50:3 | UsersController |
|
||||||
| action_controller/params_flow.rb:1:1:151:3 | MyController |
|
| action_controller/params_flow.rb:1:1:153:3 | MyController |
|
||||||
|
| action_controller/params_flow.rb:161:1:169:3 | Subclass |
|
||||||
| active_record/ActiveRecord.rb:23:1:39:3 | FooController |
|
| active_record/ActiveRecord.rb:23:1:39:3 | FooController |
|
||||||
| active_record/ActiveRecord.rb:41:1:64:3 | BarController |
|
| active_record/ActiveRecord.rb:41:1:64:3 | BarController |
|
||||||
| active_record/ActiveRecord.rb:66:1:98:3 | BazController |
|
| active_record/ActiveRecord.rb:66:1:98:3 | BazController |
|
||||||
| active_record/ActiveRecord.rb:100:1:108:3 | AnnotatedController |
|
| active_record/ActiveRecord.rb:100:1:108:3 | AnnotatedController |
|
||||||
| active_storage/active_storage.rb:39:1:45:3 | PostsController |
|
| active_storage/active_storage.rb:39:1:45:3 | PostsController2 |
|
||||||
| app/controllers/comments_controller.rb:1:1:40:3 | CommentsController |
|
| app/controllers/comments_controller.rb:1:1:40:3 | CommentsController |
|
||||||
| app/controllers/foo/bars_controller.rb:3:1:46:3 | BarsController |
|
| app/controllers/foo/bars_controller.rb:3:1:46:3 | BarsController |
|
||||||
| app/controllers/photos_controller.rb:1:1:4:3 | PhotosController |
|
| app/controllers/photos_controller.rb:1:1:4:3 | PhotosController |
|
||||||
| app/controllers/posts_controller.rb:1:1:10:3 | PostsController |
|
| app/controllers/posts_controller.rb:1:1:10:3 | PostsController |
|
||||||
| app/controllers/tags_controller.rb:1:1:2:3 | TagsController |
|
| app/controllers/tags_controller.rb:1:1:2:3 | TagsController |
|
||||||
| app/controllers/users/notifications_controller.rb:2:3:5:5 | NotificationsController |
|
| app/controllers/users/notifications_controller.rb:2:3:5:5 | Users::NotificationsController |
|
||||||
actionControllerActionMethods
|
actionControllerActionMethods
|
||||||
| action_controller/input_access.rb:2:3:49:5 | index |
|
| action_controller/input_access.rb:2:3:49:5 | index |
|
||||||
| action_controller/params_flow.rb:2:3:4:5 | m1 |
|
| action_controller/params_flow.rb:2:3:4:5 | m1 |
|
||||||
@@ -47,6 +48,8 @@ actionControllerActionMethods
|
|||||||
| action_controller/params_flow.rb:125:3:132:5 | m30 |
|
| action_controller/params_flow.rb:125:3:132:5 | m30 |
|
||||||
| action_controller/params_flow.rb:134:3:141:5 | m31 |
|
| action_controller/params_flow.rb:134:3:141:5 | m31 |
|
||||||
| action_controller/params_flow.rb:143:3:150:5 | m32 |
|
| action_controller/params_flow.rb:143:3:150:5 | m32 |
|
||||||
|
| action_controller/params_flow.rb:156:3:158:5 | m33 |
|
||||||
|
| action_controller/params_flow.rb:162:3:164:5 | m34 |
|
||||||
| active_record/ActiveRecord.rb:27:3:38:5 | some_request_handler |
|
| active_record/ActiveRecord.rb:27:3:38:5 | some_request_handler |
|
||||||
| active_record/ActiveRecord.rb:42:3:47:5 | some_other_request_handler |
|
| active_record/ActiveRecord.rb:42:3:47:5 | some_other_request_handler |
|
||||||
| active_record/ActiveRecord.rb:49:3:63:5 | safe_paths |
|
| active_record/ActiveRecord.rb:49:3:63:5 | safe_paths |
|
||||||
@@ -117,6 +120,9 @@ paramsCalls
|
|||||||
| action_controller/params_flow.rb:144:10:144:15 | call to params |
|
| action_controller/params_flow.rb:144:10:144:15 | call to params |
|
||||||
| action_controller/params_flow.rb:145:32:145:37 | call to params |
|
| action_controller/params_flow.rb:145:32:145:37 | call to params |
|
||||||
| action_controller/params_flow.rb:148:22:148:27 | call to params |
|
| action_controller/params_flow.rb:148:22:148:27 | call to params |
|
||||||
|
| action_controller/params_flow.rb:157:10:157:15 | call to params |
|
||||||
|
| action_controller/params_flow.rb:163:10:163:15 | call to params |
|
||||||
|
| action_controller/params_flow.rb:167:10:167:15 | call to params |
|
||||||
| action_mailer/mailer.rb:3:10:3:15 | call to params |
|
| action_mailer/mailer.rb:3:10:3:15 | call to params |
|
||||||
| active_record/ActiveRecord.rb:28:30:28:35 | call to params |
|
| active_record/ActiveRecord.rb:28:30:28:35 | call to params |
|
||||||
| active_record/ActiveRecord.rb:29:29:29:34 | call to params |
|
| active_record/ActiveRecord.rb:29:29:29:34 | call to params |
|
||||||
@@ -192,6 +198,9 @@ paramsSources
|
|||||||
| action_controller/params_flow.rb:144:10:144:15 | call to params |
|
| action_controller/params_flow.rb:144:10:144:15 | call to params |
|
||||||
| action_controller/params_flow.rb:145:32:145:37 | call to params |
|
| action_controller/params_flow.rb:145:32:145:37 | call to params |
|
||||||
| action_controller/params_flow.rb:148:22:148:27 | call to params |
|
| action_controller/params_flow.rb:148:22:148:27 | call to params |
|
||||||
|
| action_controller/params_flow.rb:157:10:157:15 | call to params |
|
||||||
|
| action_controller/params_flow.rb:163:10:163:15 | call to params |
|
||||||
|
| action_controller/params_flow.rb:167:10:167:15 | call to params |
|
||||||
| action_mailer/mailer.rb:3:10:3:15 | call to params |
|
| action_mailer/mailer.rb:3:10:3:15 | call to params |
|
||||||
| active_record/ActiveRecord.rb:28:30:28:35 | call to params |
|
| active_record/ActiveRecord.rb:28:30:28:35 | call to params |
|
||||||
| active_record/ActiveRecord.rb:29:29:29:34 | call to params |
|
| active_record/ActiveRecord.rb:29:29:29:34 | call to params |
|
||||||
@@ -306,6 +315,9 @@ httpInputAccesses
|
|||||||
| action_controller/params_flow.rb:144:10:144:15 | call to params | ActionController::Metal#params |
|
| action_controller/params_flow.rb:144:10:144:15 | call to params | ActionController::Metal#params |
|
||||||
| action_controller/params_flow.rb:145:32:145:37 | call to params | ActionController::Metal#params |
|
| action_controller/params_flow.rb:145:32:145:37 | call to params | ActionController::Metal#params |
|
||||||
| action_controller/params_flow.rb:148:22:148:27 | call to params | ActionController::Metal#params |
|
| action_controller/params_flow.rb:148:22:148:27 | call to params | ActionController::Metal#params |
|
||||||
|
| action_controller/params_flow.rb:157:10:157:15 | call to params | ActionController::Metal#params |
|
||||||
|
| action_controller/params_flow.rb:163:10:163:15 | call to params | ActionController::Metal#params |
|
||||||
|
| action_controller/params_flow.rb:167:10:167:15 | call to params | ActionController::Metal#params |
|
||||||
| action_mailer/mailer.rb:3:10:3:15 | call to params | ActionController::Metal#params |
|
| action_mailer/mailer.rb:3:10:3:15 | call to params | ActionController::Metal#params |
|
||||||
| active_record/ActiveRecord.rb:28:30:28:35 | call to params | ActionController::Metal#params |
|
| active_record/ActiveRecord.rb:28:30:28:35 | call to params | ActionController::Metal#params |
|
||||||
| active_record/ActiveRecord.rb:29:29:29:34 | call to params | ActionController::Metal#params |
|
| active_record/ActiveRecord.rb:29:29:29:34 | call to params | ActionController::Metal#params |
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ private import codeql.ruby.frameworks.ActionView
|
|||||||
private import codeql.ruby.Concepts
|
private import codeql.ruby.Concepts
|
||||||
private import codeql.ruby.DataFlow
|
private import codeql.ruby.DataFlow
|
||||||
|
|
||||||
query predicate actionControllerControllerClasses(ActionControllerControllerClass cls) { any() }
|
query predicate actionControllerControllerClasses(ActionControllerClass cls) { any() }
|
||||||
|
|
||||||
query predicate actionControllerActionMethods(ActionControllerActionMethod m) { any() }
|
query predicate actionControllerActionMethods(ActionControllerActionMethod m) { any() }
|
||||||
|
|
||||||
@@ -25,11 +25,11 @@ query predicate redirectToCalls(RedirectToCall c) { any() }
|
|||||||
|
|
||||||
query predicate actionControllerHelperMethods(ActionControllerHelperMethod m) { any() }
|
query predicate actionControllerHelperMethods(ActionControllerHelperMethod m) { any() }
|
||||||
|
|
||||||
query predicate getAssociatedControllerClasses(ActionControllerControllerClass cls, ErbFile f) {
|
query predicate getAssociatedControllerClasses(ActionControllerClass cls, ErbFile f) {
|
||||||
cls = getAssociatedControllerClass(f)
|
cls = getAssociatedControllerClass(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
query predicate controllerTemplateFiles(ActionControllerControllerClass cls, ErbFile templateFile) {
|
query predicate controllerTemplateFiles(ActionControllerClass cls, ErbFile templateFile) {
|
||||||
controllerTemplateFile(cls, templateFile)
|
controllerTemplateFile(cls, templateFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ edges
|
|||||||
| params_flow.rb:145:32:145:37 | call to params : | params_flow.rb:145:10:145:38 | call to with_defaults! |
|
| params_flow.rb:145:32:145:37 | call to params : | params_flow.rb:145:10:145:38 | call to with_defaults! |
|
||||||
| params_flow.rb:148:5:148:5 | [post] p : | params_flow.rb:149:10:149:10 | p |
|
| params_flow.rb:148:5:148:5 | [post] p : | params_flow.rb:149:10:149:10 | p |
|
||||||
| params_flow.rb:148:22:148:27 | call to params : | params_flow.rb:148:5:148:5 | [post] p : |
|
| params_flow.rb:148:22:148:27 | call to params : | params_flow.rb:148:5:148:5 | [post] p : |
|
||||||
|
| params_flow.rb:157:10:157:15 | call to params : | params_flow.rb:157:10:157:19 | ...[...] |
|
||||||
|
| params_flow.rb:163:10:163:15 | call to params : | params_flow.rb:163:10:163:19 | ...[...] |
|
||||||
|
| params_flow.rb:167:10:167:15 | call to params : | params_flow.rb:167:10:167:19 | ...[...] |
|
||||||
nodes
|
nodes
|
||||||
| params_flow.rb:3:10:3:15 | call to params : | semmle.label | call to params : |
|
| params_flow.rb:3:10:3:15 | call to params : | semmle.label | call to params : |
|
||||||
| params_flow.rb:3:10:3:19 | ...[...] | semmle.label | ...[...] |
|
| params_flow.rb:3:10:3:19 | ...[...] | semmle.label | ...[...] |
|
||||||
@@ -130,6 +133,12 @@ nodes
|
|||||||
| params_flow.rb:148:5:148:5 | [post] p : | semmle.label | [post] p : |
|
| params_flow.rb:148:5:148:5 | [post] p : | semmle.label | [post] p : |
|
||||||
| params_flow.rb:148:22:148:27 | call to params : | semmle.label | call to params : |
|
| params_flow.rb:148:22:148:27 | call to params : | semmle.label | call to params : |
|
||||||
| params_flow.rb:149:10:149:10 | p | semmle.label | p |
|
| params_flow.rb:149:10:149:10 | p | semmle.label | p |
|
||||||
|
| params_flow.rb:157:10:157:15 | call to params : | semmle.label | call to params : |
|
||||||
|
| params_flow.rb:157:10:157:19 | ...[...] | semmle.label | ...[...] |
|
||||||
|
| params_flow.rb:163:10:163:15 | call to params : | semmle.label | call to params : |
|
||||||
|
| params_flow.rb:163:10:163:19 | ...[...] | semmle.label | ...[...] |
|
||||||
|
| params_flow.rb:167:10:167:15 | call to params : | semmle.label | call to params : |
|
||||||
|
| params_flow.rb:167:10:167:19 | ...[...] | semmle.label | ...[...] |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| params_flow.rb:3:10:3:19 | ...[...] | params_flow.rb:3:10:3:15 | call to params : | params_flow.rb:3:10:3:19 | ...[...] | $@ | params_flow.rb:3:10:3:15 | call to params : | call to params : |
|
| params_flow.rb:3:10:3:19 | ...[...] | params_flow.rb:3:10:3:15 | call to params : | params_flow.rb:3:10:3:19 | ...[...] | $@ | params_flow.rb:3:10:3:15 | call to params : | call to params : |
|
||||||
@@ -173,3 +182,6 @@ subpaths
|
|||||||
| params_flow.rb:144:10:144:44 | call to with_defaults! | params_flow.rb:144:10:144:15 | call to params : | params_flow.rb:144:10:144:44 | call to with_defaults! | $@ | params_flow.rb:144:10:144:15 | call to params : | call to params : |
|
| params_flow.rb:144:10:144:44 | call to with_defaults! | params_flow.rb:144:10:144:15 | call to params : | params_flow.rb:144:10:144:44 | call to with_defaults! | $@ | params_flow.rb:144:10:144:15 | call to params : | call to params : |
|
||||||
| params_flow.rb:145:10:145:38 | call to with_defaults! | params_flow.rb:145:32:145:37 | call to params : | params_flow.rb:145:10:145:38 | call to with_defaults! | $@ | params_flow.rb:145:32:145:37 | call to params : | call to params : |
|
| params_flow.rb:145:10:145:38 | call to with_defaults! | params_flow.rb:145:32:145:37 | call to params : | params_flow.rb:145:10:145:38 | call to with_defaults! | $@ | params_flow.rb:145:32:145:37 | call to params : | call to params : |
|
||||||
| params_flow.rb:149:10:149:10 | p | params_flow.rb:148:22:148:27 | call to params : | params_flow.rb:149:10:149:10 | p | $@ | params_flow.rb:148:22:148:27 | call to params : | call to params : |
|
| params_flow.rb:149:10:149:10 | p | params_flow.rb:148:22:148:27 | call to params : | params_flow.rb:149:10:149:10 | p | $@ | params_flow.rb:148:22:148:27 | call to params : | call to params : |
|
||||||
|
| params_flow.rb:157:10:157:19 | ...[...] | params_flow.rb:157:10:157:15 | call to params : | params_flow.rb:157:10:157:19 | ...[...] | $@ | params_flow.rb:157:10:157:15 | call to params : | call to params : |
|
||||||
|
| params_flow.rb:163:10:163:19 | ...[...] | params_flow.rb:163:10:163:15 | call to params : | params_flow.rb:163:10:163:19 | ...[...] | $@ | params_flow.rb:163:10:163:15 | call to params : | call to params : |
|
||||||
|
| params_flow.rb:167:10:167:19 | ...[...] | params_flow.rb:167:10:167:15 | call to params : | params_flow.rb:167:10:167:19 | ...[...] | $@ | params_flow.rb:167:10:167:15 | call to params : | call to params : |
|
||||||
|
|||||||
@@ -148,4 +148,22 @@ class MyController < ActionController::Base
|
|||||||
p.with_defaults!(params)
|
p.with_defaults!(params)
|
||||||
sink p # $hasTaintFlow
|
sink p # $hasTaintFlow
|
||||||
end
|
end
|
||||||
|
|
||||||
|
include Mixin
|
||||||
|
end
|
||||||
|
|
||||||
|
module Mixin
|
||||||
|
def m33
|
||||||
|
sink params[:x] # $hasTaintFlow
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Subclass < MyController
|
||||||
|
def m34
|
||||||
|
sink params[:x] # $hasTaintFlow
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue_from 'Foo::Bar' do |err|
|
||||||
|
sink params[:x] # $hasTaintFlow
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ ActiveStorage.video_preview_arguments = custom_preview_args
|
|||||||
|
|
||||||
ActiveStorage.variant_processor = custom_processor
|
ActiveStorage.variant_processor = custom_processor
|
||||||
|
|
||||||
class PostsController < ActionController::Base
|
class PostsController2 < ActionController::Base
|
||||||
def create
|
def create
|
||||||
post = Post.new(params[:post])
|
post = Post.new(params[:post])
|
||||||
post.images.attach(params[:images])
|
post.images.attach(params[:images])
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ definition
|
|||||||
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self |
|
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self |
|
||||||
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self |
|
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self |
|
||||||
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self |
|
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self |
|
||||||
| instance_variables.rb:27:6:29:1 | <captured> | instance_variables.rb:1:1:44:4 | self |
|
| instance_variables.rb:27:6:29:1 | <captured> self | instance_variables.rb:1:1:44:4 | self |
|
||||||
| instance_variables.rb:31:1:33:3 | self (bar) | instance_variables.rb:31:1:33:3 | self |
|
| instance_variables.rb:31:1:33:3 | self (bar) | instance_variables.rb:31:1:33:3 | self |
|
||||||
| instance_variables.rb:32:10:32:21 | <captured> | instance_variables.rb:31:1:33:3 | self |
|
| instance_variables.rb:32:10:32:21 | <captured> self | instance_variables.rb:31:1:33:3 | self |
|
||||||
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self |
|
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self |
|
||||||
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self |
|
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self |
|
||||||
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self |
|
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self |
|
||||||
@@ -32,8 +32,8 @@ definition
|
|||||||
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a |
|
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a |
|
||||||
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a |
|
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a |
|
||||||
| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a |
|
| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a |
|
||||||
| nested_scopes.rb:18:23:18:36 | <captured> | nested_scopes.rb:12:9:21:11 | self |
|
| nested_scopes.rb:18:23:18:36 | <captured> a | nested_scopes.rb:16:29:16:29 | a |
|
||||||
| nested_scopes.rb:18:23:18:36 | <captured> | nested_scopes.rb:16:29:16:29 | a |
|
| nested_scopes.rb:18:23:18:36 | <captured> self | nested_scopes.rb:12:9:21:11 | self |
|
||||||
| nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self |
|
| nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self |
|
||||||
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a |
|
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a |
|
||||||
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self |
|
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self |
|
||||||
@@ -41,7 +41,7 @@ definition
|
|||||||
| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a |
|
| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a |
|
||||||
| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d |
|
| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d |
|
||||||
| parameters.rb:1:1:1:1 | self (parameters.rb) | parameters.rb:1:1:62:1 | self |
|
| parameters.rb:1:1:1:1 | self (parameters.rb) | parameters.rb:1:1:62:1 | self |
|
||||||
| parameters.rb:1:9:5:3 | <captured> | parameters.rb:1:1:62:1 | self |
|
| parameters.rb:1:9:5:3 | <captured> self | parameters.rb:1:1:62:1 | self |
|
||||||
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x |
|
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x |
|
||||||
| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y |
|
| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y |
|
||||||
| parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self |
|
| parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self |
|
||||||
@@ -49,7 +49,7 @@ definition
|
|||||||
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas |
|
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas |
|
||||||
| parameters.rb:15:1:19:3 | self (print_map) | parameters.rb:15:1:19:3 | self |
|
| parameters.rb:15:1:19:3 | self (print_map) | parameters.rb:15:1:19:3 | self |
|
||||||
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map |
|
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map |
|
||||||
| parameters.rb:16:12:18:5 | <captured> | parameters.rb:15:1:19:3 | self |
|
| parameters.rb:16:12:18:5 | <captured> self | parameters.rb:15:1:19:3 | self |
|
||||||
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key |
|
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key |
|
||||||
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value |
|
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value |
|
||||||
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block |
|
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block |
|
||||||
@@ -76,8 +76,8 @@ definition
|
|||||||
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a |
|
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a |
|
||||||
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b |
|
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b |
|
||||||
| parameters.rb:53:1:53:6 | ... = ... | parameters.rb:53:1:53:1 | x |
|
| parameters.rb:53:1:53:6 | ... = ... | parameters.rb:53:1:53:1 | x |
|
||||||
| parameters.rb:54:9:57:3 | <captured> | parameters.rb:1:1:62:1 | self |
|
| parameters.rb:54:9:57:3 | <captured> self | parameters.rb:1:1:62:1 | self |
|
||||||
| parameters.rb:54:9:57:3 | <captured> | parameters.rb:53:1:53:1 | x |
|
| parameters.rb:54:9:57:3 | <captured> x | parameters.rb:53:1:53:1 | x |
|
||||||
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y |
|
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y |
|
||||||
| parameters.rb:54:19:54:23 | ... = ... | parameters.rb:53:1:53:1 | x |
|
| parameters.rb:54:19:54:23 | ... = ... | parameters.rb:53:1:53:1 | x |
|
||||||
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x |
|
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x |
|
||||||
@@ -86,11 +86,11 @@ definition
|
|||||||
| parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b |
|
| parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b |
|
||||||
| parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c |
|
| parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c |
|
||||||
| scopes.rb:1:1:1:15 | self (scopes.rb) | scopes.rb:1:1:49:4 | self |
|
| scopes.rb:1:1:1:15 | self (scopes.rb) | scopes.rb:1:1:49:4 | self |
|
||||||
| scopes.rb:2:9:6:3 | <captured> | scopes.rb:1:1:49:4 | self |
|
| scopes.rb:2:9:6:3 | <captured> self | scopes.rb:1:1:49:4 | self |
|
||||||
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a |
|
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a |
|
||||||
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a |
|
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self |
|
| scopes.rb:9:9:18:3 | <captured> a | scopes.rb:7:1:7:1 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self |
|
||||||
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a |
|
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a |
|
||||||
| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a |
|
| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a |
|
||||||
| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b |
|
| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b |
|
||||||
@@ -120,11 +120,11 @@ definition
|
|||||||
| ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self |
|
| ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self |
|
||||||
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements |
|
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements |
|
||||||
| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem |
|
| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem |
|
||||||
| ssa.rb:26:3:28:5 | <captured> | ssa.rb:25:1:30:3 | self |
|
| ssa.rb:26:3:28:5 | <captured> self | ssa.rb:25:1:30:3 | self |
|
||||||
| ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 |
|
| ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 |
|
||||||
| ssa.rb:26:3:28:5 | call to each | ssa.rb:26:7:26:10 | elem |
|
| ssa.rb:26:3:28:5 | call to each | ssa.rb:26:7:26:10 | elem |
|
||||||
| ssa.rb:32:1:36:3 | self (m3) | ssa.rb:32:1:36:3 | self |
|
| ssa.rb:32:1:36:3 | self (m3) | ssa.rb:32:1:36:3 | self |
|
||||||
| ssa.rb:33:16:35:5 | <captured> | ssa.rb:32:1:36:3 | self |
|
| ssa.rb:33:16:35:5 | <captured> self | ssa.rb:32:1:36:3 | self |
|
||||||
| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x |
|
| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x |
|
||||||
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self |
|
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self |
|
||||||
| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 |
|
| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 |
|
||||||
@@ -147,19 +147,19 @@ definition
|
|||||||
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a |
|
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a |
|
||||||
| ssa.rb:65:3:65:15 | ... = ... | ssa.rb:65:3:65:10 | captured |
|
| ssa.rb:65:3:65:15 | ... = ... | ssa.rb:65:3:65:10 | captured |
|
||||||
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured |
|
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:64:1:72:3 | self |
|
| ssa.rb:66:11:70:5 | <captured> captured | ssa.rb:65:3:65:10 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured |
|
| ssa.rb:66:11:70:5 | <captured> self | ssa.rb:64:1:72:3 | self |
|
||||||
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a |
|
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a |
|
||||||
| ssa.rb:69:5:69:17 | ... = ... | ssa.rb:65:3:65:10 | captured |
|
| ssa.rb:69:5:69:17 | ... = ... | ssa.rb:65:3:65:10 | captured |
|
||||||
| ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self |
|
| ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self |
|
||||||
| ssa.rb:75:3:75:14 | ... = ... | ssa.rb:75:3:75:10 | captured |
|
| ssa.rb:75:3:75:14 | ... = ... | ssa.rb:75:3:75:10 | captured |
|
||||||
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:74:1:79:3 | self |
|
| ssa.rb:76:7:78:5 | <captured> captured | ssa.rb:75:3:75:10 | captured |
|
||||||
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:75:3:75:10 | captured |
|
| ssa.rb:76:7:78:5 | <captured> self | ssa.rb:74:1:79:3 | self |
|
||||||
| ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self |
|
| ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self |
|
||||||
| ssa.rb:82:3:82:14 | ... = ... | ssa.rb:82:3:82:10 | captured |
|
| ssa.rb:82:3:82:14 | ... = ... | ssa.rb:82:3:82:10 | captured |
|
||||||
| ssa.rb:83:7:87:5 | <captured> | ssa.rb:81:1:88:3 | self |
|
| ssa.rb:83:7:87:5 | <captured> self | ssa.rb:81:1:88:3 | self |
|
||||||
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:81:1:88:3 | self |
|
| ssa.rb:84:10:86:8 | <captured> captured | ssa.rb:82:3:82:10 | captured |
|
||||||
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:82:3:82:10 | captured |
|
| ssa.rb:84:10:86:8 | <captured> self | ssa.rb:81:1:88:3 | self |
|
||||||
read
|
read
|
||||||
| class_variables.rb:1:1:1:3 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
|
| class_variables.rb:1:1:1:3 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
|
||||||
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
|
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
|
||||||
@@ -179,8 +179,8 @@ read
|
|||||||
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
|
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
|
||||||
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
|
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
|
||||||
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
|
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
|
||||||
| instance_variables.rb:27:6:29:1 | <captured> | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
|
| instance_variables.rb:27:6:29:1 | <captured> self | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
|
||||||
| instance_variables.rb:32:10:32:21 | <captured> | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
|
| instance_variables.rb:32:10:32:21 | <captured> self | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
|
||||||
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
|
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
|
||||||
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:41:4:41:4 | self |
|
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:41:4:41:4 | self |
|
||||||
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:4:42:7 | self |
|
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:4:42:7 | self |
|
||||||
@@ -202,8 +202,8 @@ read
|
|||||||
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:15:11:15:11 | a |
|
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:15:11:15:11 | a |
|
||||||
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a |
|
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a |
|
||||||
| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a |
|
| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a |
|
||||||
| nested_scopes.rb:18:23:18:36 | <captured> | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self |
|
| nested_scopes.rb:18:23:18:36 | <captured> a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a |
|
||||||
| nested_scopes.rb:18:23:18:36 | <captured> | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a |
|
| nested_scopes.rb:18:23:18:36 | <captured> self | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self |
|
||||||
| nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self |
|
| nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self |
|
||||||
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:23:16:23:16 | a |
|
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:23:16:23:16 | a |
|
||||||
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self |
|
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self |
|
||||||
@@ -211,8 +211,8 @@ read
|
|||||||
| nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self |
|
| nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self |
|
||||||
| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a |
|
| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a |
|
||||||
| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d |
|
| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d |
|
||||||
| parameters.rb:1:9:5:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self |
|
| parameters.rb:1:9:5:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self |
|
||||||
| parameters.rb:1:9:5:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:4:4:4:9 | self |
|
| parameters.rb:1:9:5:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:4:4:4:9 | self |
|
||||||
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x |
|
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x |
|
||||||
| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y |
|
| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y |
|
||||||
| parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self |
|
| parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self |
|
||||||
@@ -222,7 +222,7 @@ read
|
|||||||
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas |
|
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas |
|
||||||
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:11:14:11:19 | pizzas |
|
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:11:14:11:19 | pizzas |
|
||||||
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map | parameters.rb:16:3:16:5 | map |
|
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map | parameters.rb:16:3:16:5 | map |
|
||||||
| parameters.rb:16:12:18:5 | <captured> | parameters.rb:15:1:19:3 | self | parameters.rb:17:5:17:28 | self |
|
| parameters.rb:16:12:18:5 | <captured> self | parameters.rb:15:1:19:3 | self | parameters.rb:17:5:17:28 | self |
|
||||||
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:17:13:17:15 | key |
|
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:17:13:17:15 | key |
|
||||||
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:17:22:17:26 | value |
|
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:17:22:17:26 | value |
|
||||||
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block | parameters.rb:22:3:22:7 | block |
|
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block | parameters.rb:22:3:22:7 | block |
|
||||||
@@ -246,8 +246,8 @@ read
|
|||||||
| parameters.rb:49:1:51:3 | self (tuples) | parameters.rb:49:1:51:3 | self | parameters.rb:50:3:50:18 | self |
|
| parameters.rb:49:1:51:3 | self (tuples) | parameters.rb:49:1:51:3 | self | parameters.rb:50:3:50:18 | self |
|
||||||
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:50:11:50:11 | a |
|
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:50:11:50:11 | a |
|
||||||
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:50:16:50:16 | b |
|
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:50:16:50:16 | b |
|
||||||
| parameters.rb:54:9:57:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:55:4:55:9 | self |
|
| parameters.rb:54:9:57:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:55:4:55:9 | self |
|
||||||
| parameters.rb:54:9:57:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:56:4:56:9 | self |
|
| parameters.rb:54:9:57:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:56:4:56:9 | self |
|
||||||
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:56:9:56:9 | y |
|
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:56:9:56:9 | y |
|
||||||
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:55:9:55:9 | x |
|
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:55:9:55:9 | x |
|
||||||
| parameters.rb:59:1:61:3 | self (tuples_nested) | parameters.rb:59:1:61:3 | self | parameters.rb:60:3:60:23 | self |
|
| parameters.rb:59:1:61:3 | self (tuples_nested) | parameters.rb:59:1:61:3 | self | parameters.rb:60:3:60:23 | self |
|
||||||
@@ -255,19 +255,19 @@ read
|
|||||||
| parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | parameters.rb:60:16:60:16 | b |
|
| parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | parameters.rb:60:16:60:16 | b |
|
||||||
| parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c |
|
| parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c |
|
||||||
| scopes.rb:1:1:1:15 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self |
|
| scopes.rb:1:1:1:15 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self |
|
||||||
| scopes.rb:2:9:6:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self |
|
| scopes.rb:2:9:6:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self |
|
||||||
| scopes.rb:2:9:6:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:3:9:3:9 | self |
|
| scopes.rb:2:9:6:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:3:9:3:9 | self |
|
||||||
| scopes.rb:2:9:6:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:5:4:5:9 | self |
|
| scopes.rb:2:9:6:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:5:4:5:9 | self |
|
||||||
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
|
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
|
||||||
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
|
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> a | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:12:4:12:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> a | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:14:4:14:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:12:4:12:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:14:4:14:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:17:4:17:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:17:4:17:9 | self |
|
||||||
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
|
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
|
||||||
| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
|
| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
|
||||||
| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
|
| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
|
||||||
@@ -308,10 +308,10 @@ read
|
|||||||
| ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self |
|
| ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self |
|
||||||
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements |
|
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements |
|
||||||
| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem |
|
| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem |
|
||||||
| ssa.rb:26:3:28:5 | <captured> | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self |
|
| ssa.rb:26:3:28:5 | <captured> self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self |
|
||||||
| ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 |
|
| ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 |
|
||||||
| ssa.rb:26:3:28:5 | call to each | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem |
|
| ssa.rb:26:3:28:5 | call to each | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem |
|
||||||
| ssa.rb:33:16:35:5 | <captured> | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self |
|
| ssa.rb:33:16:35:5 | <captured> self | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self |
|
||||||
| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x |
|
| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x |
|
||||||
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:3:39:9 | self |
|
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:3:39:9 | self |
|
||||||
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:8:39:9 | self |
|
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:8:39:9 | self |
|
||||||
@@ -331,18 +331,18 @@ read
|
|||||||
| ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self |
|
| ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self |
|
||||||
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
|
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
|
||||||
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
|
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:64:1:72:3 | self | ssa.rb:67:5:67:10 | self |
|
| ssa.rb:66:11:70:5 | <captured> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:64:1:72:3 | self | ssa.rb:68:5:68:17 | self |
|
| ssa.rb:66:11:70:5 | <captured> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:69:5:69:12 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured |
|
| ssa.rb:66:11:70:5 | <captured> self | ssa.rb:64:1:72:3 | self | ssa.rb:67:5:67:10 | self |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:69:5:69:12 | captured |
|
| ssa.rb:66:11:70:5 | <captured> self | ssa.rb:64:1:72:3 | self | ssa.rb:68:5:68:17 | self |
|
||||||
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:67:10:67:10 | a |
|
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:67:10:67:10 | a |
|
||||||
| ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self | ssa.rb:76:3:78:5 | self |
|
| ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self | ssa.rb:76:3:78:5 | self |
|
||||||
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:74:1:79:3 | self | ssa.rb:77:6:77:23 | self |
|
| ssa.rb:76:7:78:5 | <captured> captured | ssa.rb:75:3:75:10 | captured | ssa.rb:77:15:77:22 | captured |
|
||||||
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:75:3:75:10 | captured | ssa.rb:77:15:77:22 | captured |
|
| ssa.rb:76:7:78:5 | <captured> self | ssa.rb:74:1:79:3 | self | ssa.rb:77:6:77:23 | self |
|
||||||
| ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self | ssa.rb:83:3:87:5 | self |
|
| ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self | ssa.rb:83:3:87:5 | self |
|
||||||
| ssa.rb:83:7:87:5 | <captured> | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
|
| ssa.rb:83:7:87:5 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
|
||||||
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
|
| ssa.rb:84:10:86:8 | <captured> captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
|
||||||
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
|
| ssa.rb:84:10:86:8 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
|
||||||
firstRead
|
firstRead
|
||||||
| class_variables.rb:1:1:1:3 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
|
| class_variables.rb:1:1:1:3 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
|
||||||
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
|
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
|
||||||
@@ -358,8 +358,8 @@ firstRead
|
|||||||
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
|
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
|
||||||
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
|
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
|
||||||
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
|
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
|
||||||
| instance_variables.rb:27:6:29:1 | <captured> | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
|
| instance_variables.rb:27:6:29:1 | <captured> self | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
|
||||||
| instance_variables.rb:32:10:32:21 | <captured> | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
|
| instance_variables.rb:32:10:32:21 | <captured> self | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
|
||||||
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
|
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
|
||||||
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:41:4:41:4 | self |
|
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:41:4:41:4 | self |
|
||||||
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self |
|
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self |
|
||||||
@@ -376,15 +376,15 @@ firstRead
|
|||||||
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a |
|
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a |
|
||||||
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a |
|
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a |
|
||||||
| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a |
|
| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a |
|
||||||
| nested_scopes.rb:18:23:18:36 | <captured> | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self |
|
| nested_scopes.rb:18:23:18:36 | <captured> a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a |
|
||||||
| nested_scopes.rb:18:23:18:36 | <captured> | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a |
|
| nested_scopes.rb:18:23:18:36 | <captured> self | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self |
|
||||||
| nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self |
|
| nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self |
|
||||||
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:23:16:23:16 | a |
|
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:23:16:23:16 | a |
|
||||||
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self |
|
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self |
|
||||||
| nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self |
|
| nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self |
|
||||||
| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a |
|
| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a |
|
||||||
| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d |
|
| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d |
|
||||||
| parameters.rb:1:9:5:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self |
|
| parameters.rb:1:9:5:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self |
|
||||||
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x |
|
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x |
|
||||||
| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y |
|
| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y |
|
||||||
| parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self |
|
| parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self |
|
||||||
@@ -393,7 +393,7 @@ firstRead
|
|||||||
| parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | parameters.rb:11:41:11:46 | client |
|
| parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | parameters.rb:11:41:11:46 | client |
|
||||||
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas |
|
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas |
|
||||||
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map | parameters.rb:16:3:16:5 | map |
|
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map | parameters.rb:16:3:16:5 | map |
|
||||||
| parameters.rb:16:12:18:5 | <captured> | parameters.rb:15:1:19:3 | self | parameters.rb:17:5:17:28 | self |
|
| parameters.rb:16:12:18:5 | <captured> self | parameters.rb:15:1:19:3 | self | parameters.rb:17:5:17:28 | self |
|
||||||
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:17:13:17:15 | key |
|
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:17:13:17:15 | key |
|
||||||
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:17:22:17:26 | value |
|
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:17:22:17:26 | value |
|
||||||
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block | parameters.rb:22:3:22:7 | block |
|
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block | parameters.rb:22:3:22:7 | block |
|
||||||
@@ -416,7 +416,7 @@ firstRead
|
|||||||
| parameters.rb:49:1:51:3 | self (tuples) | parameters.rb:49:1:51:3 | self | parameters.rb:50:3:50:18 | self |
|
| parameters.rb:49:1:51:3 | self (tuples) | parameters.rb:49:1:51:3 | self | parameters.rb:50:3:50:18 | self |
|
||||||
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:50:11:50:11 | a |
|
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:50:11:50:11 | a |
|
||||||
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:50:16:50:16 | b |
|
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:50:16:50:16 | b |
|
||||||
| parameters.rb:54:9:57:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:55:4:55:9 | self |
|
| parameters.rb:54:9:57:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:55:4:55:9 | self |
|
||||||
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:56:9:56:9 | y |
|
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:56:9:56:9 | y |
|
||||||
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:55:9:55:9 | x |
|
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:55:9:55:9 | x |
|
||||||
| parameters.rb:59:1:61:3 | self (tuples_nested) | parameters.rb:59:1:61:3 | self | parameters.rb:60:3:60:23 | self |
|
| parameters.rb:59:1:61:3 | self (tuples_nested) | parameters.rb:59:1:61:3 | self | parameters.rb:60:3:60:23 | self |
|
||||||
@@ -424,11 +424,11 @@ firstRead
|
|||||||
| parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | parameters.rb:60:16:60:16 | b |
|
| parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | parameters.rb:60:16:60:16 | b |
|
||||||
| parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c |
|
| parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c |
|
||||||
| scopes.rb:1:1:1:15 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self |
|
| scopes.rb:1:1:1:15 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self |
|
||||||
| scopes.rb:2:9:6:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self |
|
| scopes.rb:2:9:6:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self |
|
||||||
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
|
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
|
||||||
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
|
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> a | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self |
|
||||||
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
|
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
|
||||||
| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
|
| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
|
||||||
| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
|
| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
|
||||||
@@ -451,10 +451,10 @@ firstRead
|
|||||||
| ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self |
|
| ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self |
|
||||||
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements |
|
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements |
|
||||||
| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem |
|
| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem |
|
||||||
| ssa.rb:26:3:28:5 | <captured> | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self |
|
| ssa.rb:26:3:28:5 | <captured> self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self |
|
||||||
| ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 |
|
| ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 |
|
||||||
| ssa.rb:26:3:28:5 | call to each | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem |
|
| ssa.rb:26:3:28:5 | call to each | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem |
|
||||||
| ssa.rb:33:16:35:5 | <captured> | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self |
|
| ssa.rb:33:16:35:5 | <captured> self | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self |
|
||||||
| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x |
|
| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x |
|
||||||
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:3:39:9 | self |
|
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:3:39:9 | self |
|
||||||
| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 |
|
| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 |
|
||||||
@@ -472,16 +472,16 @@ firstRead
|
|||||||
| ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self |
|
| ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self |
|
||||||
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
|
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
|
||||||
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
|
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:64:1:72:3 | self | ssa.rb:67:5:67:10 | self |
|
| ssa.rb:66:11:70:5 | <captured> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured |
|
| ssa.rb:66:11:70:5 | <captured> self | ssa.rb:64:1:72:3 | self | ssa.rb:67:5:67:10 | self |
|
||||||
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:67:10:67:10 | a |
|
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:67:10:67:10 | a |
|
||||||
| ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self | ssa.rb:76:3:78:5 | self |
|
| ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self | ssa.rb:76:3:78:5 | self |
|
||||||
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:74:1:79:3 | self | ssa.rb:77:6:77:23 | self |
|
| ssa.rb:76:7:78:5 | <captured> captured | ssa.rb:75:3:75:10 | captured | ssa.rb:77:15:77:22 | captured |
|
||||||
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:75:3:75:10 | captured | ssa.rb:77:15:77:22 | captured |
|
| ssa.rb:76:7:78:5 | <captured> self | ssa.rb:74:1:79:3 | self | ssa.rb:77:6:77:23 | self |
|
||||||
| ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self | ssa.rb:83:3:87:5 | self |
|
| ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self | ssa.rb:83:3:87:5 | self |
|
||||||
| ssa.rb:83:7:87:5 | <captured> | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
|
| ssa.rb:83:7:87:5 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
|
||||||
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
|
| ssa.rb:84:10:86:8 | <captured> captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
|
||||||
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
|
| ssa.rb:84:10:86:8 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
|
||||||
lastRead
|
lastRead
|
||||||
| class_variables.rb:1:1:1:3 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
|
| class_variables.rb:1:1:1:3 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
|
||||||
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
|
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
|
||||||
@@ -498,8 +498,8 @@ lastRead
|
|||||||
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
|
| instance_variables.rb:15:3:17:5 | self (m) | instance_variables.rb:15:3:17:5 | self | instance_variables.rb:16:5:16:6 | self |
|
||||||
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
|
| instance_variables.rb:20:1:25:3 | self (M) | instance_variables.rb:20:1:25:3 | self | instance_variables.rb:21:2:21:3 | self |
|
||||||
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
|
| instance_variables.rb:22:2:24:4 | self (n) | instance_variables.rb:22:2:24:4 | self | instance_variables.rb:23:4:23:5 | self |
|
||||||
| instance_variables.rb:27:6:29:1 | <captured> | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
|
| instance_variables.rb:27:6:29:1 | <captured> self | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:28:3:28:4 | self |
|
||||||
| instance_variables.rb:32:10:32:21 | <captured> | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
|
| instance_variables.rb:32:10:32:21 | <captured> self | instance_variables.rb:31:1:33:3 | self | instance_variables.rb:32:12:32:13 | self |
|
||||||
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
|
| instance_variables.rb:35:1:44:4 | self (C) | instance_variables.rb:35:1:44:4 | self | instance_variables.rb:36:3:36:4 | self |
|
||||||
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:6:42:7 | self |
|
| instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:6:42:7 | self |
|
||||||
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self |
|
| instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self |
|
||||||
@@ -516,15 +516,15 @@ lastRead
|
|||||||
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:15:11:15:11 | a |
|
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:15:11:15:11 | a |
|
||||||
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a |
|
| nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a |
|
||||||
| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a |
|
| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a |
|
||||||
| nested_scopes.rb:18:23:18:36 | <captured> | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self |
|
| nested_scopes.rb:18:23:18:36 | <captured> a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a |
|
||||||
| nested_scopes.rb:18:23:18:36 | <captured> | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a |
|
| nested_scopes.rb:18:23:18:36 | <captured> self | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self |
|
||||||
| nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self |
|
| nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self |
|
||||||
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:23:16:23:16 | a |
|
| nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:23:16:23:16 | a |
|
||||||
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:16:28:16 | self |
|
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:16:28:16 | self |
|
||||||
| nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self |
|
| nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self |
|
||||||
| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a |
|
| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a |
|
||||||
| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d |
|
| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d |
|
||||||
| parameters.rb:1:9:5:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:4:4:4:9 | self |
|
| parameters.rb:1:9:5:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:4:4:4:9 | self |
|
||||||
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x |
|
| parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x |
|
||||||
| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y |
|
| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y |
|
||||||
| parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self |
|
| parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self |
|
||||||
@@ -534,7 +534,7 @@ lastRead
|
|||||||
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas |
|
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas |
|
||||||
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:11:14:11:19 | pizzas |
|
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:11:14:11:19 | pizzas |
|
||||||
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map | parameters.rb:16:3:16:5 | map |
|
| parameters.rb:15:17:15:19 | map | parameters.rb:15:17:15:19 | map | parameters.rb:16:3:16:5 | map |
|
||||||
| parameters.rb:16:12:18:5 | <captured> | parameters.rb:15:1:19:3 | self | parameters.rb:17:5:17:28 | self |
|
| parameters.rb:16:12:18:5 | <captured> self | parameters.rb:15:1:19:3 | self | parameters.rb:17:5:17:28 | self |
|
||||||
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:17:13:17:15 | key |
|
| parameters.rb:16:16:16:18 | key | parameters.rb:16:16:16:18 | key | parameters.rb:17:13:17:15 | key |
|
||||||
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:17:22:17:26 | value |
|
| parameters.rb:16:21:16:25 | value | parameters.rb:16:21:16:25 | value | parameters.rb:17:22:17:26 | value |
|
||||||
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block | parameters.rb:22:3:22:7 | block |
|
| parameters.rb:21:17:21:21 | block | parameters.rb:21:17:21:21 | block | parameters.rb:22:3:22:7 | block |
|
||||||
@@ -556,7 +556,7 @@ lastRead
|
|||||||
| parameters.rb:49:1:51:3 | self (tuples) | parameters.rb:49:1:51:3 | self | parameters.rb:50:3:50:18 | self |
|
| parameters.rb:49:1:51:3 | self (tuples) | parameters.rb:49:1:51:3 | self | parameters.rb:50:3:50:18 | self |
|
||||||
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:50:11:50:11 | a |
|
| parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | parameters.rb:50:11:50:11 | a |
|
||||||
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:50:16:50:16 | b |
|
| parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | parameters.rb:50:16:50:16 | b |
|
||||||
| parameters.rb:54:9:57:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:56:4:56:9 | self |
|
| parameters.rb:54:9:57:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:56:4:56:9 | self |
|
||||||
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:56:9:56:9 | y |
|
| parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | parameters.rb:56:9:56:9 | y |
|
||||||
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:55:9:55:9 | x |
|
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:55:9:55:9 | x |
|
||||||
| parameters.rb:59:1:61:3 | self (tuples_nested) | parameters.rb:59:1:61:3 | self | parameters.rb:60:3:60:23 | self |
|
| parameters.rb:59:1:61:3 | self (tuples_nested) | parameters.rb:59:1:61:3 | self | parameters.rb:60:3:60:23 | self |
|
||||||
@@ -564,11 +564,11 @@ lastRead
|
|||||||
| parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | parameters.rb:60:16:60:16 | b |
|
| parameters.rb:59:23:59:23 | b | parameters.rb:59:23:59:23 | b | parameters.rb:60:16:60:16 | b |
|
||||||
| parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c |
|
| parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c |
|
||||||
| scopes.rb:1:1:1:15 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self |
|
| scopes.rb:1:1:1:15 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self |
|
||||||
| scopes.rb:2:9:6:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:5:4:5:9 | self |
|
| scopes.rb:2:9:6:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:5:4:5:9 | self |
|
||||||
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
|
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
|
||||||
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
|
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:17:4:17:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> a | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:17:4:17:9 | self |
|
||||||
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
|
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
|
||||||
| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
|
| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
|
||||||
| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
|
| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
|
||||||
@@ -592,10 +592,10 @@ lastRead
|
|||||||
| ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self |
|
| ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self |
|
||||||
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements |
|
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements |
|
||||||
| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem |
|
| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem |
|
||||||
| ssa.rb:26:3:28:5 | <captured> | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self |
|
| ssa.rb:26:3:28:5 | <captured> self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self |
|
||||||
| ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 |
|
| ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 |
|
||||||
| ssa.rb:26:3:28:5 | call to each | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem |
|
| ssa.rb:26:3:28:5 | call to each | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem |
|
||||||
| ssa.rb:33:16:35:5 | <captured> | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self |
|
| ssa.rb:33:16:35:5 | <captured> self | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self |
|
||||||
| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x |
|
| ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x |
|
||||||
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:41:3:41:13 | self |
|
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:41:3:41:13 | self |
|
||||||
| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 |
|
| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 |
|
||||||
@@ -613,16 +613,16 @@ lastRead
|
|||||||
| ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self |
|
| ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self |
|
||||||
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
|
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
|
||||||
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
|
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:64:1:72:3 | self | ssa.rb:68:5:68:17 | self |
|
| ssa.rb:66:11:70:5 | <captured> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:69:5:69:12 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:69:5:69:12 | captured |
|
| ssa.rb:66:11:70:5 | <captured> self | ssa.rb:64:1:72:3 | self | ssa.rb:68:5:68:17 | self |
|
||||||
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:67:10:67:10 | a |
|
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:67:10:67:10 | a |
|
||||||
| ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self | ssa.rb:76:3:78:5 | self |
|
| ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self | ssa.rb:76:3:78:5 | self |
|
||||||
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:74:1:79:3 | self | ssa.rb:77:6:77:23 | self |
|
| ssa.rb:76:7:78:5 | <captured> captured | ssa.rb:75:3:75:10 | captured | ssa.rb:77:15:77:22 | captured |
|
||||||
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:75:3:75:10 | captured | ssa.rb:77:15:77:22 | captured |
|
| ssa.rb:76:7:78:5 | <captured> self | ssa.rb:74:1:79:3 | self | ssa.rb:77:6:77:23 | self |
|
||||||
| ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self | ssa.rb:83:3:87:5 | self |
|
| ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self | ssa.rb:83:3:87:5 | self |
|
||||||
| ssa.rb:83:7:87:5 | <captured> | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
|
| ssa.rb:83:7:87:5 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
|
||||||
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
|
| ssa.rb:84:10:86:8 | <captured> captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
|
||||||
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
|
| ssa.rb:84:10:86:8 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
|
||||||
adjacentReads
|
adjacentReads
|
||||||
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:27:3:27:11 | self | class_variables.rb:28:3:28:7 | self |
|
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:27:3:27:11 | self | class_variables.rb:28:3:28:7 | self |
|
||||||
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self | instance_variables.rb:11:1:11:9 | self |
|
| instance_variables.rb:1:1:1:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self | instance_variables.rb:11:1:11:9 | self |
|
||||||
@@ -636,19 +636,19 @@ adjacentReads
|
|||||||
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:15:11:15:11 | a |
|
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:15:11:15:11 | a |
|
||||||
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self | nested_scopes.rb:28:16:28:16 | self |
|
| nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self | nested_scopes.rb:28:16:28:16 | self |
|
||||||
| nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:30:16:30:19 | self | nested_scopes.rb:32:11:32:16 | self |
|
| nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:30:16:30:19 | self | nested_scopes.rb:32:11:32:16 | self |
|
||||||
| parameters.rb:1:9:5:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self | parameters.rb:4:4:4:9 | self |
|
| parameters.rb:1:9:5:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self | parameters.rb:4:4:4:9 | self |
|
||||||
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas | parameters.rb:11:14:11:19 | pizzas |
|
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas | parameters.rb:11:14:11:19 | pizzas |
|
||||||
| parameters.rb:25:1:28:3 | self (opt_param) | parameters.rb:25:1:28:3 | self | parameters.rb:26:3:26:11 | self | parameters.rb:27:3:27:11 | self |
|
| parameters.rb:25:1:28:3 | self (opt_param) | parameters.rb:25:1:28:3 | self | parameters.rb:26:3:26:11 | self | parameters.rb:27:3:27:11 | self |
|
||||||
| parameters.rb:25:15:25:18 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:40:25:43 | name | parameters.rb:26:8:26:11 | name |
|
| parameters.rb:25:15:25:18 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:40:25:43 | name | parameters.rb:26:8:26:11 | name |
|
||||||
| parameters.rb:54:9:57:3 | <captured> | parameters.rb:1:1:62:1 | self | parameters.rb:55:4:55:9 | self | parameters.rb:56:4:56:9 | self |
|
| parameters.rb:54:9:57:3 | <captured> self | parameters.rb:1:1:62:1 | self | parameters.rb:55:4:55:9 | self | parameters.rb:56:4:56:9 | self |
|
||||||
| scopes.rb:2:9:6:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self | scopes.rb:3:9:3:9 | self |
|
| scopes.rb:2:9:6:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self | scopes.rb:3:9:3:9 | self |
|
||||||
| scopes.rb:2:9:6:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:3:9:3:9 | self | scopes.rb:5:4:5:9 | self |
|
| scopes.rb:2:9:6:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:3:9:3:9 | self | scopes.rb:5:4:5:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self | scopes.rb:12:4:12:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> a | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | scopes.rb:11:4:11:4 | a |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:12:4:12:9 | self | scopes.rb:14:4:14:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self | scopes.rb:12:4:12:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:14:4:14:9 | self | scopes.rb:15:4:15:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:12:4:12:9 | self | scopes.rb:14:4:14:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self | scopes.rb:16:4:16:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:14:4:14:9 | self | scopes.rb:15:4:15:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self | scopes.rb:17:4:17:9 | self |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self | scopes.rb:16:4:16:9 | self |
|
||||||
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | scopes.rb:11:4:11:4 | a |
|
| scopes.rb:9:9:18:3 | <captured> self | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self | scopes.rb:17:4:17:9 | self |
|
||||||
| scopes.rb:13:10:13:15 | ... = ... | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 |
|
| scopes.rb:13:10:13:15 | ... = ... | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 |
|
||||||
| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 |
|
| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 |
|
||||||
| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 |
|
| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 |
|
||||||
@@ -671,14 +671,14 @@ adjacentReads
|
|||||||
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x | ssa.rb:21:5:21:5 | x |
|
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x | ssa.rb:21:5:21:5 | x |
|
||||||
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:3:39:9 | self | ssa.rb:39:8:39:9 | self |
|
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:3:39:9 | self | ssa.rb:39:8:39:9 | self |
|
||||||
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:8:39:9 | self | ssa.rb:41:3:41:13 | self |
|
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:8:39:9 | self | ssa.rb:41:3:41:13 | self |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:64:1:72:3 | self | ssa.rb:67:5:67:10 | self | ssa.rb:68:5:68:17 | self |
|
| ssa.rb:66:11:70:5 | <captured> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured | ssa.rb:69:5:69:12 | captured |
|
||||||
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured | ssa.rb:69:5:69:12 | captured |
|
| ssa.rb:66:11:70:5 | <captured> self | ssa.rb:64:1:72:3 | self | ssa.rb:67:5:67:10 | self | ssa.rb:68:5:68:17 | self |
|
||||||
phi
|
phi
|
||||||
| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | <uninitialized> |
|
| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | <uninitialized> |
|
||||||
| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:20 | ... = ... |
|
| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:20 | ... = ... |
|
||||||
| parameters.rb:42:3:42:18 | phi | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | <uninitialized> |
|
| parameters.rb:42:3:42:18 | phi | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | <uninitialized> |
|
||||||
| parameters.rb:42:3:42:18 | phi | parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:19 | ... = ... |
|
| parameters.rb:42:3:42:18 | phi | parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:19 | ... = ... |
|
||||||
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:54:9:57:3 | <captured> |
|
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:54:9:57:3 | <captured> x |
|
||||||
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:54:19:54:23 | ... = ... |
|
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:54:19:54:23 | ... = ... |
|
||||||
| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:6:5:6:9 | ... = ... |
|
| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:6:5:6:9 | ... = ... |
|
||||||
| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:10:5:10:9 | ... = ... |
|
| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:10:5:10:9 | ... = ... |
|
||||||
|
|||||||
Reference in New Issue
Block a user