mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Merge branch 'main' of github.com:github/codeql into SharedDataflow_ArgumentPassing
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @name Code injection
|
||||
* @description Interpreting unsanitized user input as code allows a malicious user to perform arbitrary
|
||||
* code execution.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @sub-severity high
|
||||
* @precision high
|
||||
* @id py/code-injection
|
||||
* @tags security
|
||||
* external/owasp/owasp-a1
|
||||
* external/cwe/cwe-094
|
||||
* external/cwe/cwe-095
|
||||
* external/cwe/cwe-116
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import experimental.dataflow.TaintTracking
|
||||
import experimental.semmle.python.Concepts
|
||||
import experimental.dataflow.RemoteFlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class CodeInjectionConfiguration extends TaintTracking::Configuration {
|
||||
CodeInjectionConfiguration() { this = "CodeInjectionConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink = any(CodeExecution e).getCode() }
|
||||
}
|
||||
|
||||
from CodeInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to here and is interpreted as code.",
|
||||
source.getNode(), "A user-provided value"
|
||||
@@ -2,6 +2,7 @@ private import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
// Need to import since frameworks can extend `RemoteFlowSource::Range`
|
||||
private import experimental.semmle.python.Frameworks
|
||||
private import experimental.semmle.python.Concepts
|
||||
|
||||
/**
|
||||
* A data flow source of remote user input.
|
||||
|
||||
@@ -6,7 +6,7 @@ private import internal.DataFlowPrivate
|
||||
|
||||
/** Any string that may appear as the name of an attribute or access path. */
|
||||
class AttributeName extends string {
|
||||
AttributeName() { this = any(Attribute a).getName() }
|
||||
AttributeName() { this = any(AttrRef a).getAttributeName() }
|
||||
}
|
||||
|
||||
/** Either an attribute name, or the empty string (representing no attribute). */
|
||||
@@ -71,7 +71,8 @@ module StepSummary {
|
||||
/** Holds if it's reasonable to expect the data flow step from `nodeFrom` to `nodeTo` to preserve types. */
|
||||
private predicate typePreservingStep(Node nodeFrom, Node nodeTo) {
|
||||
EssaFlow::essaFlowStep(nodeFrom, nodeTo) or
|
||||
jumpStep(nodeFrom, nodeTo)
|
||||
jumpStep(nodeFrom, nodeTo) or
|
||||
nodeFrom = nodeTo.(PostUpdateNode).getPreUpdateNode()
|
||||
}
|
||||
|
||||
/** Holds if `nodeFrom` steps to `nodeTo` by being passed as a parameter in a call. */
|
||||
@@ -115,11 +116,10 @@ predicate returnStep(ReturnNode nodeFrom, Node nodeTo) {
|
||||
* assignment to `z` inside `bar`, even though this attribute write happens _after_ `bar` is called.
|
||||
*/
|
||||
predicate basicStoreStep(Node nodeFrom, Node nodeTo, string attr) {
|
||||
exists(AttributeAssignment a, Node var |
|
||||
a.getName() = attr and
|
||||
simpleLocalFlowStep*(nodeTo, var) and
|
||||
var.asVar() = a.getInput() and
|
||||
nodeFrom.asCfgNode() = a.getValue()
|
||||
exists(AttrWrite a |
|
||||
a.mayHaveAttributeName(attr) and
|
||||
nodeFrom = a.getValue() and
|
||||
simpleLocalFlowStep*(nodeTo, a.getObject())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -127,7 +127,11 @@ predicate basicStoreStep(Node nodeFrom, Node nodeTo, string attr) {
|
||||
* Holds if `nodeTo` is the result of accessing the `attr` attribute of `nodeFrom`.
|
||||
*/
|
||||
predicate basicLoadStep(Node nodeFrom, Node nodeTo, string attr) {
|
||||
exists(AttrNode s | nodeTo.asCfgNode() = s and s.getObject(attr) = nodeFrom.asCfgNode())
|
||||
exists(AttrRead a |
|
||||
a.mayHaveAttributeName(attr) and
|
||||
nodeFrom = a.getObject() and
|
||||
nodeTo = a
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
244
python/ql/src/experimental/dataflow/internal/Attributes.qll
Normal file
244
python/ql/src/experimental/dataflow/internal/Attributes.qll
Normal file
@@ -0,0 +1,244 @@
|
||||
/** This module provides an API for attribute reads and writes. */
|
||||
|
||||
import DataFlowUtil
|
||||
import DataFlowPublic
|
||||
private import DataFlowPrivate
|
||||
|
||||
/**
|
||||
* A data flow node that reads or writes an attribute of an object.
|
||||
*
|
||||
* This abstract base class only knows about the base object on which the attribute is being
|
||||
* accessed, and the attribute itself, if it is statically inferrable.
|
||||
*/
|
||||
abstract class AttrRef extends Node {
|
||||
/**
|
||||
* Gets the data flow node corresponding to the object whose attribute is being read or written.
|
||||
*/
|
||||
abstract Node getObject();
|
||||
|
||||
/**
|
||||
* Gets the expression node that defines the attribute being accessed, if any. This is
|
||||
* usually an identifier or literal.
|
||||
*/
|
||||
abstract ExprNode getAttributeNameExpr();
|
||||
|
||||
/**
|
||||
* Holds if this attribute reference may access an attribute named `attrName`.
|
||||
* Uses local data flow to track potential attribute names, which may lead to imprecision. If more
|
||||
* precision is needed, consider using `getAttributeName` instead.
|
||||
*/
|
||||
predicate mayHaveAttributeName(string attrName) {
|
||||
attrName = this.getAttributeName()
|
||||
or
|
||||
exists(Node nodeFrom |
|
||||
localFlow(nodeFrom, this.getAttributeNameExpr()) and
|
||||
attrName = nodeFrom.asExpr().(StrConst).getText()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the attribute being read or written. For dynamic attribute accesses, this
|
||||
* method is not guaranteed to return a result. For such cases, using `mayHaveAttributeName` may yield
|
||||
* better results.
|
||||
*/
|
||||
abstract string getAttributeName();
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that writes an attribute of an object. This includes
|
||||
* - Simple attribute writes: `object.attr = value`
|
||||
* - Dynamic attribute writes: `setattr(object, attr, value)`
|
||||
* - Fields written during class initialization: `class MyClass: attr = value`
|
||||
*/
|
||||
abstract class AttrWrite extends AttrRef {
|
||||
/** Gets the data flow node corresponding to the value that is written to the attribute. */
|
||||
abstract Node getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a control flow node for a simple attribute assignment. That is,
|
||||
* ```python
|
||||
* object.attr = value
|
||||
* ```
|
||||
* Also gives access to the `value` being written, by extending `DefinitionNode`.
|
||||
*/
|
||||
private class AttributeAssignmentNode extends DefinitionNode, AttrNode {
|
||||
override ControlFlowNode getValue() { result = DefinitionNode.super.getValue() }
|
||||
}
|
||||
|
||||
/** A simple attribute assignment: `object.attr = value`. */
|
||||
private class AttributeAssignmentAsAttrWrite extends AttrWrite, CfgNode {
|
||||
override AttributeAssignmentNode node;
|
||||
|
||||
override Node getValue() { result.asCfgNode() = node.getValue() }
|
||||
|
||||
override Node getObject() { result.asCfgNode() = node.getObject() }
|
||||
|
||||
override ExprNode getAttributeNameExpr() {
|
||||
// Attribute names don't exist as `Node`s in the control flow graph, as they can only ever be
|
||||
// identifiers, and are therefore represented directly as strings.
|
||||
// Use `getAttributeName` to access the name of the attribute.
|
||||
none()
|
||||
}
|
||||
|
||||
override string getAttributeName() { result = node.getName() }
|
||||
}
|
||||
|
||||
import semmle.python.types.Builtins
|
||||
|
||||
/** Represents `CallNode`s that may refer to calls to built-in functions or classes. */
|
||||
private class BuiltInCallNode extends CallNode {
|
||||
string name;
|
||||
|
||||
BuiltInCallNode() {
|
||||
// TODO disallow instances where the name of the built-in may refer to an in-scope variable of that name.
|
||||
exists(NameNode id | this.getFunction() = id and id.getId() = name and id.isGlobal()) and
|
||||
name = any(Builtin b).getName()
|
||||
}
|
||||
|
||||
/** Gets the name of the built-in function that is called at this `CallNode` */
|
||||
string getBuiltinName() { result = name }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a call to the built-ins that handle dynamic inspection and modification of
|
||||
* attributes: `getattr`, `setattr`, `hasattr`, and `delattr`.
|
||||
*/
|
||||
private class BuiltinAttrCallNode extends BuiltInCallNode {
|
||||
BuiltinAttrCallNode() { name in ["setattr", "getattr", "hasattr", "delattr"] }
|
||||
|
||||
/** Gets the control flow node for object on which the attribute is accessed. */
|
||||
ControlFlowNode getObject() { result in [this.getArg(0), this.getArgByName("object")] }
|
||||
|
||||
/**
|
||||
* Gets the control flow node for the value that is being written to the attribute.
|
||||
* Only relevant for `setattr` calls.
|
||||
*/
|
||||
ControlFlowNode getValue() {
|
||||
// only valid for `setattr`
|
||||
name = "setattr" and
|
||||
result in [this.getArg(2), this.getArgByName("value")]
|
||||
}
|
||||
|
||||
/** Gets the control flow node that defines the name of the attribute being accessed. */
|
||||
ControlFlowNode getName() { result in [this.getArg(1), this.getArgByName("name")] }
|
||||
}
|
||||
|
||||
/** Represents calls to the built-in `setattr`. */
|
||||
private class SetAttrCallNode extends BuiltinAttrCallNode {
|
||||
SetAttrCallNode() { name = "setattr" }
|
||||
}
|
||||
|
||||
/** Represents calls to the built-in `getattr`. */
|
||||
private class GetAttrCallNode extends BuiltinAttrCallNode {
|
||||
GetAttrCallNode() { name = "getattr" }
|
||||
}
|
||||
|
||||
/** An attribute assignment using `setattr`, e.g. `setattr(object, attr, value)` */
|
||||
private class SetAttrCallAsAttrWrite extends AttrWrite, CfgNode {
|
||||
override SetAttrCallNode node;
|
||||
|
||||
override Node getValue() { result.asCfgNode() = node.getValue() }
|
||||
|
||||
override Node getObject() { result.asCfgNode() = node.getObject() }
|
||||
|
||||
override ExprNode getAttributeNameExpr() { result.asCfgNode() = node.getName() }
|
||||
|
||||
override string getAttributeName() {
|
||||
result = this.getAttributeNameExpr().asExpr().(StrConst).getText()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an attribute of a class that is assigned statically during class definition. For instance
|
||||
* ```python
|
||||
* class MyClass:
|
||||
* attr = value
|
||||
* ...
|
||||
* ```
|
||||
* Instances of this class correspond to the `NameNode` for `attr`, and also gives access to `value` by
|
||||
* virtue of being a `DefinitionNode`.
|
||||
*/
|
||||
private class ClassAttributeAssignmentNode extends DefinitionNode, NameNode { }
|
||||
|
||||
/**
|
||||
* An attribute assignment via a class field, e.g.
|
||||
* ```python
|
||||
* class MyClass:
|
||||
* attr = value
|
||||
* ```
|
||||
* is treated as equivalent to `MyClass.attr = value`.
|
||||
*/
|
||||
private class ClassDefinitionAsAttrWrite extends AttrWrite, CfgNode {
|
||||
ClassExpr cls;
|
||||
override ClassAttributeAssignmentNode node;
|
||||
|
||||
ClassDefinitionAsAttrWrite() { node.getScope() = cls.getInnerScope() }
|
||||
|
||||
override Node getValue() { result.asCfgNode() = node.getValue() }
|
||||
|
||||
override Node getObject() { result.asCfgNode() = cls.getAFlowNode() }
|
||||
|
||||
override ExprNode getAttributeNameExpr() { none() }
|
||||
|
||||
override string getAttributeName() { result = node.getId() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A read of an attribute on an object. This includes
|
||||
* - Simple attribute reads: `object.attr`
|
||||
* - Dynamic attribute reads using `getattr`: `getattr(object, attr)`
|
||||
* - Qualified imports: `from module import attr as name`
|
||||
*/
|
||||
abstract class AttrRead extends AttrRef, Node { }
|
||||
|
||||
/** A simple attribute read, e.g. `object.attr` */
|
||||
private class AttributeReadAsAttrRead extends AttrRead, CfgNode {
|
||||
override AttrNode node;
|
||||
|
||||
override Node getObject() { result.asCfgNode() = node.getObject() }
|
||||
|
||||
override ExprNode getAttributeNameExpr() {
|
||||
// Attribute names don't exist as `Node`s in the control flow graph, as they can only ever be
|
||||
// identifiers, and are therefore represented directly as strings.
|
||||
// Use `getAttributeName` to access the name of the attribute.
|
||||
none()
|
||||
}
|
||||
|
||||
override string getAttributeName() { result = node.getName() }
|
||||
}
|
||||
|
||||
/** An attribute read using `getattr`: `getattr(object, attr)` */
|
||||
private class GetAttrCallAsAttrRead extends AttrRead, CfgNode {
|
||||
override GetAttrCallNode node;
|
||||
|
||||
override Node getObject() { result.asCfgNode() = node.getObject() }
|
||||
|
||||
override ExprNode getAttributeNameExpr() { result.asCfgNode() = node.getName() }
|
||||
|
||||
override string getAttributeName() {
|
||||
result = this.getAttributeNameExpr().asExpr().(StrConst).getText()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a named import as an attribute read. That is,
|
||||
* ```python
|
||||
* from module import attr as attr_ref
|
||||
* ```
|
||||
* is treated as if it is a read of the attribute `module.attr`, even if `module` is not imported directly.
|
||||
*/
|
||||
private class ModuleAttributeImportAsAttrRead extends AttrRead, CfgNode {
|
||||
override ImportMemberNode node;
|
||||
|
||||
override Node getObject() { result.asCfgNode() = node.getModule(_) }
|
||||
|
||||
override ExprNode getAttributeNameExpr() {
|
||||
// The name of an imported attribute doesn't exist as a `Node` in the control flow graph, as it
|
||||
// can only ever be an identifier, and is therefore represented directly as a string.
|
||||
// Use `getAttributeName` to access the name of the attribute.
|
||||
none()
|
||||
}
|
||||
|
||||
override string getAttributeName() { exists(node.getModule(result)) }
|
||||
}
|
||||
@@ -167,4 +167,9 @@ module Consistency {
|
||||
not isImmutableOrUnobservable(n) and
|
||||
msg = "ArgumentNode is missing PostUpdateNode."
|
||||
}
|
||||
|
||||
query predicate postWithInFlow(PostUpdateNode n, string msg) {
|
||||
simpleLocalFlowStep(_, n) and
|
||||
msg = "PostUpdateNode should not be the target of local flow."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,6 @@ private import semmle.python.essa.SsaCompute
|
||||
//--------
|
||||
predicate isExpressionNode(ControlFlowNode node) { node.getNode() instanceof Expr }
|
||||
|
||||
/** A control flow node which is also a dataflow node */
|
||||
class DataFlowCfgNode extends ControlFlowNode {
|
||||
DataFlowCfgNode() { isExpressionNode(this) }
|
||||
}
|
||||
|
||||
/** A data flow node for which we should synthesise an associated pre-update node. */
|
||||
abstract class NeedsSyntheticPreUpdateNode extends Node {
|
||||
/** A label for this kind of node. This will figure in the textual representation of the synthesized pre-update node. */
|
||||
@@ -158,29 +153,6 @@ module EssaFlow {
|
||||
// nodeTo is `y` on second line, cfg node
|
||||
useToNextUse(nodeFrom.asCfgNode(), nodeTo.asCfgNode())
|
||||
or
|
||||
// Refinements
|
||||
exists(EssaEdgeRefinement r |
|
||||
nodeTo.(EssaNode).getVar() = r.getVariable() and
|
||||
nodeFrom.(EssaNode).getVar() = r.getInput()
|
||||
)
|
||||
or
|
||||
exists(EssaNodeRefinement r |
|
||||
nodeTo.(EssaNode).getVar() = r.getVariable() and
|
||||
nodeFrom.(EssaNode).getVar() = r.getInput()
|
||||
)
|
||||
or
|
||||
exists(PhiFunction p |
|
||||
nodeTo.(EssaNode).getVar() = p.getVariable() and
|
||||
nodeFrom.(EssaNode).getVar() = p.getAnInput()
|
||||
)
|
||||
or
|
||||
// Overflow keyword argument
|
||||
exists(CallNode call, CallableValue callable |
|
||||
call = callable.getACall() and
|
||||
nodeTo = TKwOverflowNode(call, callable) and
|
||||
nodeFrom.asCfgNode() = call.getNode().getKwargs().getAFlowNode()
|
||||
)
|
||||
or
|
||||
// If expressions
|
||||
nodeFrom.asCfgNode() = nodeTo.asCfgNode().(IfExprNode).getAnOperand()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
private import python
|
||||
private import DataFlowPrivate
|
||||
import experimental.dataflow.TypeTracker
|
||||
import Attributes
|
||||
private import semmle.python.essa.SsaCompute
|
||||
|
||||
/**
|
||||
@@ -22,8 +23,8 @@ newtype TNode =
|
||||
/** A node corresponding to an SSA variable. */
|
||||
TEssaNode(EssaVariable var) or
|
||||
/** A node corresponding to a control flow node. */
|
||||
TCfgNode(DataFlowCfgNode node) or
|
||||
/** A synthetic node representing the value of an object before a state change. */
|
||||
TCfgNode(ControlFlowNode node) { isExpressionNode(node) } or
|
||||
/** A synthetic node representing the value of an object before a state change */
|
||||
TSyntheticPreUpdateNode(NeedsSyntheticPreUpdateNode post) or
|
||||
/** A synthetic node representing the value of an object after a state change. */
|
||||
TSyntheticPostUpdateNode(NeedsSyntheticPostUpdateNode pre) or
|
||||
@@ -133,7 +134,7 @@ class EssaNode extends Node, TEssaNode {
|
||||
}
|
||||
|
||||
class CfgNode extends Node, TCfgNode {
|
||||
DataFlowCfgNode node;
|
||||
ControlFlowNode node;
|
||||
|
||||
CfgNode() { this = TCfgNode(node) }
|
||||
|
||||
@@ -181,6 +182,9 @@ class ParameterNode extends EssaNode {
|
||||
}
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { this.isParameterOf(result, _) }
|
||||
|
||||
/** Gets the `Parameter` this `ParameterNode` represents. */
|
||||
Parameter getParameter() { result = var.(ParameterDefinition).getParameter() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
|
||||
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
|
||||
|
||||
/**
|
||||
* Gets an EssaNode that holds the module imported by `name`.
|
||||
* Gets a `Node` that refers to the module referenced by `name`.
|
||||
* Note that for the statement `import pkg.mod`, the new variable introduced is `pkg` that is a
|
||||
* reference to the module `pkg`.
|
||||
*
|
||||
@@ -27,16 +27,17 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
|
||||
* 2. `from <package> import <module>` when `<name> = <package> + "." + <module>`
|
||||
* 3. `from <module> import <member>` when `<name> = <module> + "." + <member>`
|
||||
*
|
||||
* Finally, in `from <module> import <member>` we consider the `ImportExpr` corresponding to
|
||||
* `<module>` to be a reference to that module.
|
||||
*
|
||||
* Note:
|
||||
* While it is technically possible that `import mypkg.foo` and `from mypkg import foo` can give different values,
|
||||
* it's highly unlikely that this will be a problem in production level code.
|
||||
* Example: If `mypkg/__init__.py` contains `foo = 42`, then `from mypkg import foo` will not import the module
|
||||
* `mypkg/foo.py` but the variable `foo` containing `42` -- however, `import mypkg.foo` will always cause `mypkg.foo`
|
||||
* to refer to the module.
|
||||
*
|
||||
* Also see `DataFlow::importMember`
|
||||
*/
|
||||
EssaNode importModule(string name) {
|
||||
Node importNode(string name) {
|
||||
exists(Variable var, Import imp, Alias alias |
|
||||
alias = imp.getAName() and
|
||||
alias.getAsname() = var.getAStore() and
|
||||
@@ -45,23 +46,27 @@ EssaNode importModule(string name) {
|
||||
or
|
||||
name = alias.getValue().(ImportExpr).getImportedModuleName()
|
||||
) and
|
||||
result.getVar().(AssignmentDefinition).getSourceVariable() = var
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a EssaNode that holds the value imported by using fully qualified name in
|
||||
*`from <moduleName> import <memberName>`.
|
||||
*
|
||||
* Also see `DataFlow::importModule`.
|
||||
*/
|
||||
EssaNode importMember(string moduleName, string memberName) {
|
||||
exists(Variable var, Import imp, Alias alias, ImportMember member |
|
||||
alias = imp.getAName() and
|
||||
member = alias.getValue() and
|
||||
moduleName = member.getModule().(ImportExpr).getImportedModuleName() and
|
||||
memberName = member.getName() and
|
||||
alias.getAsname() = var.getAStore() and
|
||||
result.getVar().(AssignmentDefinition).getSourceVariable() = var
|
||||
result.(EssaNode).getVar().(AssignmentDefinition).getSourceVariable() = var
|
||||
)
|
||||
or
|
||||
// Although it may seem superfluous to consider the `foo` part of `from foo import bar as baz` to
|
||||
// be a reference to a module (since that reference only makes sense locally within the `import`
|
||||
// statement), it's important for our use of type trackers to consider this local reference to
|
||||
// also refer to the `foo` module. That way, if one wants to track references to the `bar`
|
||||
// attribute using a type tracker, one can simply write
|
||||
//
|
||||
// ```ql
|
||||
// DataFlow::Node bar_attr_tracker(TypeTracker t) {
|
||||
// t.startInAttr("bar") and
|
||||
// result = foo_module_tracker()
|
||||
// or
|
||||
// exists(TypeTracker t2 | result = bar_attr_tracker(t2).track(t2, t))
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// Where `foo_module_tracker` is a type tracker that tracks references to the `foo` module.
|
||||
// Because named imports are modelled as `AttrRead`s, the statement `from foo import bar as baz`
|
||||
// is interpreted as if it was an assignment `baz = foo.bar`, which means `baz` gets tracked as a
|
||||
// reference to `foo.bar`, as desired.
|
||||
result.asCfgNode().getNode() = any(ImportExpr i | i.getName() = name)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.semmle.python.Frameworks
|
||||
private import experimental.dataflow.RemoteFlowSources
|
||||
|
||||
/**
|
||||
* A data-flow node that executes an operating system command,
|
||||
@@ -16,12 +17,12 @@ private import experimental.semmle.python.Frameworks
|
||||
* extend `SystemCommandExecution::Range` instead.
|
||||
*/
|
||||
class SystemCommandExecution extends DataFlow::Node {
|
||||
SystemCommandExecution::Range self;
|
||||
SystemCommandExecution::Range range;
|
||||
|
||||
SystemCommandExecution() { this = self }
|
||||
SystemCommandExecution() { this = range }
|
||||
|
||||
/** Gets the argument that specifies the command to be executed. */
|
||||
DataFlow::Node getCommand() { result = self.getCommand() }
|
||||
DataFlow::Node getCommand() { result = range.getCommand() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new system-command execution APIs. */
|
||||
@@ -38,3 +39,91 @@ module SystemCommandExecution {
|
||||
abstract DataFlow::Node getCommand();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that dynamically executes Python code.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `CodeExecution::Range` instead.
|
||||
*/
|
||||
class CodeExecution extends DataFlow::Node {
|
||||
CodeExecution::Range range;
|
||||
|
||||
CodeExecution() { this = range }
|
||||
|
||||
/** Gets the argument that specifies the code to be executed. */
|
||||
DataFlow::Node getCode() { result = range.getCode() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new dynamic code execution APIs. */
|
||||
module CodeExecution {
|
||||
/**
|
||||
* A data-flow node that dynamically executes Python code.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `CodeExecution` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the argument that specifies the code to be executed. */
|
||||
abstract DataFlow::Node getCode();
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides classes for modeling HTTP-related APIs. */
|
||||
module HTTP {
|
||||
/** Provides classes for modeling HTTP servers. */
|
||||
module Server {
|
||||
/**
|
||||
* An data-flow node that sets up a route on a server.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `RouteSetup::Range` instead.
|
||||
*/
|
||||
class RouteSetup extends DataFlow::Node {
|
||||
RouteSetup::Range range;
|
||||
|
||||
RouteSetup() { this = range }
|
||||
|
||||
/** Gets the URL pattern for this route, if it can be statically determined. */
|
||||
string getUrlPattern() { result = range.getUrlPattern() }
|
||||
|
||||
/** Gets a function that will handle incoming requests for this route, if any. */
|
||||
Function getARouteHandler() { result = range.getARouteHandler() }
|
||||
|
||||
/**
|
||||
* Gets a parameter that will receive parts of the url when handling incoming
|
||||
* requests for this route, if any. These automatically become a `RemoteFlowSource`.
|
||||
*/
|
||||
Parameter getARoutedParameter() { result = range.getARoutedParameter() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new HTTP routing APIs. */
|
||||
module RouteSetup {
|
||||
/**
|
||||
* An data-flow node that sets up a route on a server.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `RouteSetup` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the URL pattern for this route, if it can be statically determined. */
|
||||
abstract string getUrlPattern();
|
||||
|
||||
/** Gets a function that will handle incoming requests for this route, if any. */
|
||||
abstract Function getARouteHandler();
|
||||
|
||||
/**
|
||||
* Gets a parameter that will receive parts of the url when handling incoming
|
||||
* requests for this route, if any. These automatically become a `RemoteFlowSource`.
|
||||
*/
|
||||
abstract Parameter getARoutedParameter();
|
||||
}
|
||||
}
|
||||
|
||||
private class RoutedParameter extends RemoteFlowSource::Range, DataFlow::ParameterNode {
|
||||
RoutedParameter() { this.getParameter() = any(RouteSetup setup).getARoutedParameter() }
|
||||
|
||||
override string getSourceType() { result = "RoutedParameter" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Helper file that imports all framework modeling.
|
||||
*/
|
||||
|
||||
private import experimental.semmle.python.frameworks.Flask
|
||||
private import experimental.semmle.python.frameworks.Django
|
||||
private import experimental.semmle.python.frameworks.Flask
|
||||
private import experimental.semmle.python.frameworks.Invoke
|
||||
private import experimental.semmle.python.frameworks.Stdlib
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `flask` package.
|
||||
* Provides classes modeling security-relevant aspects of the `flask` PyPI package.
|
||||
* See https://flask.palletsprojects.com/en/1.1.x/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
@@ -11,11 +12,15 @@ private import experimental.semmle.python.frameworks.Werkzeug
|
||||
|
||||
// for old improved impl see
|
||||
// https://github.com/github/codeql/blob/9f95212e103c68d0c1dfa4b6f30fb5d53954ccef/python/ql/src/semmle/python/web/flask/Request.qll
|
||||
/**
|
||||
* Provides models for the `flask` PyPI package.
|
||||
* See https://flask.palletsprojects.com/en/1.1.x/.
|
||||
*/
|
||||
private module Flask {
|
||||
/** Gets a reference to the `flask` module. */
|
||||
DataFlow::Node flask(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importModule("flask")
|
||||
result = DataFlow::importNode("flask")
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = flask(t2).track(t2, t))
|
||||
}
|
||||
@@ -23,22 +28,164 @@ private module Flask {
|
||||
/** Gets a reference to the `flask` module. */
|
||||
DataFlow::Node flask() { result = flask(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/** Provides models for the `flask` module. */
|
||||
module flask {
|
||||
/** Gets a reference to the `flask.request` object. */
|
||||
DataFlow::Node request(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importMember("flask", "request")
|
||||
result = DataFlow::importNode("flask.request")
|
||||
or
|
||||
t.startInAttr("request") and
|
||||
result = flask()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = flask::request(t2).track(t2, t))
|
||||
exists(DataFlow::TypeTracker t2 | result = request(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `flask.request` object. */
|
||||
DataFlow::Node request() { result = flask::request(DataFlow::TypeTracker::end()) }
|
||||
DataFlow::Node request() { result = request(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/** Gets a reference to the `flask.Flask` class. */
|
||||
private DataFlow::Node classFlask(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importNode("flask.Flask")
|
||||
or
|
||||
t.startInAttr("Flask") and
|
||||
result = flask()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = classFlask(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `flask.Flask` class. */
|
||||
DataFlow::Node classFlask() { result = classFlask(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/** Gets a reference to an instance of `flask.Flask` (a Flask application). */
|
||||
private DataFlow::Node app(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result.asCfgNode().(CallNode).getFunction() = flask::classFlask().asCfgNode()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = app(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to an instance of `flask.Flask` (a flask application). */
|
||||
DataFlow::Node app() { result = app(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// routing modeling
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* Gets a reference to the attribute `attr_name` of a flask application.
|
||||
* WARNING: Only holds for a few predefined attributes.
|
||||
*/
|
||||
private DataFlow::Node app_attr(DataFlow::TypeTracker t, string attr_name) {
|
||||
attr_name in ["route", "add_url_rule"] and
|
||||
t.startInAttr(attr_name) and
|
||||
result = flask::app()
|
||||
or
|
||||
// Due to bad performance when using normal setup with `app_attr(t2, attr_name).track(t2, t)`
|
||||
// we have inlined that code and forced a join
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
exists(DataFlow::StepSummary summary |
|
||||
app_attr_first_join(t2, attr_name, result, summary) and
|
||||
t = t2.append(summary)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate app_attr_first_join(
|
||||
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res, DataFlow::StepSummary summary
|
||||
) {
|
||||
DataFlow::StepSummary::step(app_attr(t2, attr_name), res, summary)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the attribute `attr_name` of a flask application.
|
||||
* WARNING: Only holds for a few predefined attributes.
|
||||
*/
|
||||
private DataFlow::Node app_attr(string attr_name) {
|
||||
result = app_attr(DataFlow::TypeTracker::end(), attr_name)
|
||||
}
|
||||
|
||||
private string werkzeug_rule_re() {
|
||||
// since flask uses werkzeug internally, we are using its routing rules from
|
||||
// https://github.com/pallets/werkzeug/blob/4dc8d6ab840d4b78cbd5789cef91b01e3bde01d5/src/werkzeug/routing.py#L138-L151
|
||||
result =
|
||||
"(?<static>[^<]*)<(?:(?<converter>[a-zA-Z_][a-zA-Z0-9_]*)(?:\\((?<args>.*?)\\))?\\:)?(?<variable>[a-zA-Z_][a-zA-Z0-9_]*)>"
|
||||
}
|
||||
|
||||
/** A route setup made by flask (sharing handling of URL patterns). */
|
||||
abstract private class FlaskRouteSetup extends HTTP::Server::RouteSetup::Range {
|
||||
override Parameter getARoutedParameter() {
|
||||
// If we don't know the URL pattern, we simply mark all parameters as a routed
|
||||
// parameter. This should give us more RemoteFlowSources but could also lead to
|
||||
// more FPs. If this turns out to be the wrong tradeoff, we can always change our mind.
|
||||
not exists(this.getUrlPattern()) and
|
||||
result = this.getARouteHandler().getArgByName(_)
|
||||
or
|
||||
exists(string name |
|
||||
result = this.getARouteHandler().getArgByName(name) and
|
||||
exists(string match |
|
||||
match = this.getUrlPattern().regexpFind(werkzeug_rule_re(), _, _) and
|
||||
name = match.regexpCapture(werkzeug_rule_re(), 4)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the argument used to pass in the URL pattern. */
|
||||
abstract DataFlow::Node getUrlPatternArg();
|
||||
|
||||
override string getUrlPattern() {
|
||||
exists(StrConst str |
|
||||
DataFlow::localFlow(DataFlow::exprNode(str), this.getUrlPatternArg()) and
|
||||
result = str.getText()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `flask.Flask.route`.
|
||||
*
|
||||
* See https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.route
|
||||
*/
|
||||
private class FlaskAppRouteCall extends FlaskRouteSetup, DataFlow::CfgNode {
|
||||
override CallNode node;
|
||||
|
||||
FlaskAppRouteCall() { node.getFunction() = app_attr("route").asCfgNode() }
|
||||
|
||||
override DataFlow::Node getUrlPatternArg() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("rule")]
|
||||
}
|
||||
|
||||
override Function getARouteHandler() { result.getADecorator().getAFlowNode() = node }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `flask.Flask.add_url_rule`.
|
||||
*
|
||||
* See https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.add_url_rule
|
||||
*/
|
||||
private class FlaskAppAddUrlRule extends FlaskRouteSetup, DataFlow::CfgNode {
|
||||
override CallNode node;
|
||||
|
||||
FlaskAppAddUrlRule() { node.getFunction() = app_attr("add_url_rule").asCfgNode() }
|
||||
|
||||
override DataFlow::Node getUrlPatternArg() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("rule")]
|
||||
}
|
||||
|
||||
override Function getARouteHandler() {
|
||||
exists(DataFlow::Node view_func_arg, DataFlow::Node func_src |
|
||||
view_func_arg.asCfgNode() in [node.getArg(2), node.getArgByName("view_func")] and
|
||||
DataFlow::localFlow(func_src, view_func_arg) and
|
||||
func_src.asExpr().(CallableExpr) = result.getDefinition()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// flask.Request taint modeling
|
||||
// ---------------------------------------------------------------------------
|
||||
// TODO: Do we even need this class? :|
|
||||
/**
|
||||
* A source of remote flow from a flask request.
|
||||
|
||||
149
python/ql/src/experimental/semmle/python/frameworks/Invoke.qll
Normal file
149
python/ql/src/experimental/semmle/python/frameworks/Invoke.qll
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `invoke` PyPI package.
|
||||
* See https://www.pyinvoke.org/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.semmle.python.Concepts
|
||||
|
||||
/**
|
||||
* Provides models for the `invoke` PyPI package.
|
||||
* See https://www.pyinvoke.org/.
|
||||
*/
|
||||
private module Invoke {
|
||||
// ---------------------------------------------------------------------------
|
||||
// invoke
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Gets a reference to the `invoke` module. */
|
||||
private DataFlow::Node invoke(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importNode("invoke")
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = invoke(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `invoke` module. */
|
||||
DataFlow::Node invoke() { result = invoke(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/**
|
||||
* Gets a reference to the attribute `attr_name` of the `invoke` module.
|
||||
* WARNING: Only holds for a few predefined attributes.
|
||||
*/
|
||||
private DataFlow::Node invoke_attr(DataFlow::TypeTracker t, string attr_name) {
|
||||
attr_name in ["run", "sudo", "context", "Context", "task"] and
|
||||
(
|
||||
t.start() and
|
||||
result = DataFlow::importNode("invoke." + attr_name)
|
||||
or
|
||||
t.startInAttr(attr_name) and
|
||||
result = DataFlow::importNode("invoke")
|
||||
)
|
||||
or
|
||||
// Due to bad performance when using normal setup with `invoke_attr(t2, attr_name).track(t2, t)`
|
||||
// we have inlined that code and forced a join
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
exists(DataFlow::StepSummary summary |
|
||||
invoke_attr_first_join(t2, attr_name, result, summary) and
|
||||
t = t2.append(summary)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate invoke_attr_first_join(
|
||||
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res, DataFlow::StepSummary summary
|
||||
) {
|
||||
DataFlow::StepSummary::step(invoke_attr(t2, attr_name), res, summary)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the attribute `attr_name` of the `invoke` module.
|
||||
* WARNING: Only holds for a few predefined attributes.
|
||||
*/
|
||||
private DataFlow::Node invoke_attr(string attr_name) {
|
||||
result = invoke_attr(DataFlow::TypeTracker::end(), attr_name)
|
||||
}
|
||||
|
||||
/** Provides models for the `invoke` module. */
|
||||
module invoke {
|
||||
/** Gets a reference to the `invoke.context` module. */
|
||||
DataFlow::Node context() { result = invoke_attr("context") }
|
||||
|
||||
/** Provides models for the `invoke.context` module */
|
||||
module context {
|
||||
/** Provides models for the `invoke.context.Context` class */
|
||||
module Context {
|
||||
/** Gets a reference to the `invoke.context.Context` class. */
|
||||
private DataFlow::Node classRef(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importNode("invoke.context.Context")
|
||||
or
|
||||
t.startInAttr("Context") and
|
||||
result = invoke::context()
|
||||
or
|
||||
// handle invoke.Context alias
|
||||
t.start() and
|
||||
result = invoke_attr("Context")
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = classRef(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `invoke.context.Context` class. */
|
||||
DataFlow::Node classRef() { result = classRef(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/** Gets a reference to an instance of `invoke.context.Context`. */
|
||||
private DataFlow::Node instance(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result.asCfgNode().(CallNode).getFunction() =
|
||||
invoke::context::Context::classRef().asCfgNode()
|
||||
or
|
||||
t.start() and
|
||||
exists(Function func |
|
||||
func.getADecorator() = invoke_attr("task").asExpr() and
|
||||
result.(DataFlow::ParameterNode).getParameter() = func.getArg(0)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to an instance of `invoke.context.Context`. */
|
||||
DataFlow::Node instance() { result = instance(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/** Gets a reference to the `run` or `sudo` methods on a `invoke.context.Context` instance. */
|
||||
private DataFlow::Node instanceRunMethods(DataFlow::TypeTracker t) {
|
||||
t.startInAttr(["run", "sudo"]) and
|
||||
result = invoke::context::Context::instance()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = instanceRunMethods(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `run` or `sudo` methods on a `invoke.context.Context` instance. */
|
||||
DataFlow::Node instanceRunMethods() {
|
||||
result = instanceRunMethods(DataFlow::TypeTracker::end())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to either
|
||||
* - `invoke.run` or `invoke.sudo` functions (http://docs.pyinvoke.org/en/stable/api/__init__.html)
|
||||
* - `run` or `sudo` methods on a `invoke.context.Context` instance (http://docs.pyinvoke.org/en/stable/api/context.html#invoke.context.Context.run)
|
||||
*/
|
||||
private class InvokeRunCommandCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
|
||||
override CallNode node;
|
||||
|
||||
InvokeRunCommandCall() {
|
||||
exists(DataFlow::Node callFunction | node.getFunction() = callFunction.asCfgNode() |
|
||||
callFunction = invoke_attr(["run", "sudo"])
|
||||
or
|
||||
callFunction = invoke::context::Context::instanceRunMethods()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommand() {
|
||||
result.asCfgNode() in [node.getArg(0), node.getArgByName("command")]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ private module Stdlib {
|
||||
/** Gets a reference to the `os` module. */
|
||||
private DataFlow::Node os(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importModule("os")
|
||||
result = DataFlow::importNode("os")
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = os(t2).track(t2, t))
|
||||
}
|
||||
@@ -42,10 +42,10 @@ private module Stdlib {
|
||||
"path"] and
|
||||
(
|
||||
t.start() and
|
||||
result = DataFlow::importMember("os", attr_name)
|
||||
result = DataFlow::importNode("os." + attr_name)
|
||||
or
|
||||
t.startInAttr(attr_name) and
|
||||
result = DataFlow::importModule("os")
|
||||
result = DataFlow::importNode("os")
|
||||
)
|
||||
or
|
||||
// Due to bad performance when using normal setup with `os_attr(t2, attr_name).track(t2, t)`
|
||||
@@ -85,7 +85,7 @@ private module Stdlib {
|
||||
/** Gets a reference to the `os.path.join` function. */
|
||||
private DataFlow::Node join(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importMember("os.path", "join")
|
||||
result = DataFlow::importNode("os.path.join")
|
||||
or
|
||||
t.startInAttr("join") and
|
||||
result = os::path()
|
||||
@@ -190,7 +190,7 @@ private module Stdlib {
|
||||
/** Gets a reference to the `subprocess` module. */
|
||||
private DataFlow::Node subprocess(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importModule("subprocess")
|
||||
result = DataFlow::importNode("subprocess")
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = subprocess(t2).track(t2, t))
|
||||
}
|
||||
@@ -208,10 +208,10 @@ private module Stdlib {
|
||||
attr_name in ["Popen", "call", "check_call", "check_output", "run"] and
|
||||
(
|
||||
t.start() and
|
||||
result = DataFlow::importMember("subprocess", attr_name)
|
||||
result = DataFlow::importNode("subprocess." + attr_name)
|
||||
or
|
||||
t.startInAttr(attr_name) and
|
||||
result = DataFlow::importModule("subprocess")
|
||||
result = subprocess()
|
||||
)
|
||||
or
|
||||
// Due to bad performance when using normal setup with `subprocess_attr(t2, attr_name).track(t2, t)`
|
||||
@@ -327,4 +327,115 @@ private module Stdlib {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// builtins
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Gets a reference to the `builtins` module (called `__builtin__` in Python 2). */
|
||||
private DataFlow::Node builtins(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importNode(["builtins", "__builtin__"])
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = builtins(t2).track(t2, t))
|
||||
}
|
||||
|
||||
/** Gets a reference to the `builtins` module. */
|
||||
DataFlow::Node builtins() { result = builtins(DataFlow::TypeTracker::end()) }
|
||||
|
||||
/**
|
||||
* Gets a reference to the attribute `attr_name` of the `builtins` module.
|
||||
* WARNING: Only holds for a few predefined attributes.
|
||||
*/
|
||||
private DataFlow::Node builtins_attr(DataFlow::TypeTracker t, string attr_name) {
|
||||
attr_name in ["exec", "eval", "compile"] and
|
||||
(
|
||||
t.start() and
|
||||
result = DataFlow::importNode(["builtins", "__builtin__"] + "." + attr_name)
|
||||
or
|
||||
t.startInAttr(attr_name) and
|
||||
result = DataFlow::importNode(["builtins", "__builtin__"])
|
||||
or
|
||||
// special handling of builtins, that are in scope without any imports
|
||||
// TODO: Take care of overrides, either `def eval: ...`, `eval = ...`, or `builtins.eval = ...`
|
||||
t.start() and
|
||||
exists(NameNode ref | result.asCfgNode() = ref |
|
||||
ref.isGlobal() and
|
||||
ref.getId() = attr_name and
|
||||
ref.isLoad()
|
||||
)
|
||||
)
|
||||
or
|
||||
// Due to bad performance when using normal setup with `builtins_attr(t2, attr_name).track(t2, t)`
|
||||
// we have inlined that code and forced a join
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
exists(DataFlow::StepSummary summary |
|
||||
builtins_attr_first_join(t2, attr_name, result, summary) and
|
||||
t = t2.append(summary)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate builtins_attr_first_join(
|
||||
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res, DataFlow::StepSummary summary
|
||||
) {
|
||||
DataFlow::StepSummary::step(builtins_attr(t2, attr_name), res, summary)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the attribute `attr_name` of the `builtins` module.
|
||||
* WARNING: Only holds for a few predefined attributes.
|
||||
*/
|
||||
private DataFlow::Node builtins_attr(string attr_name) {
|
||||
result = builtins_attr(DataFlow::TypeTracker::end(), attr_name)
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the builtin `exec` function.
|
||||
* See https://docs.python.org/3/library/functions.html#exec
|
||||
*/
|
||||
private class BuiltinsExecCall extends CodeExecution::Range, DataFlow::CfgNode {
|
||||
override CallNode node;
|
||||
|
||||
BuiltinsExecCall() { node.getFunction() = builtins_attr("exec").asCfgNode() }
|
||||
|
||||
override DataFlow::Node getCode() { result.asCfgNode() = node.getArg(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the builtin `eval` function.
|
||||
* See https://docs.python.org/3/library/functions.html#eval
|
||||
*/
|
||||
private class BuiltinsEvalCall extends CodeExecution::Range, DataFlow::CfgNode {
|
||||
override CallNode node;
|
||||
|
||||
BuiltinsEvalCall() { node.getFunction() = builtins_attr("eval").asCfgNode() }
|
||||
|
||||
override DataFlow::Node getCode() { result.asCfgNode() = node.getArg(0) }
|
||||
}
|
||||
|
||||
/** An additional taint step for calls to the builtin function `compile` */
|
||||
private class BuiltinsCompileCallAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
exists(CallNode call |
|
||||
nodeTo.asCfgNode() = call and
|
||||
call.getFunction() = builtins_attr("compile").asCfgNode() and
|
||||
nodeFrom.asCfgNode() in [call.getArg(0), call.getArgByName("source")]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An exec statement (only Python 2).
|
||||
* Se ehttps://docs.python.org/2/reference/simple_stmts.html#the-exec-statement.
|
||||
*/
|
||||
private class ExecStatement extends CodeExecution::Range {
|
||||
ExecStatement() {
|
||||
// since there are no DataFlow::Nodes for a Statement, we can't do anything like
|
||||
// `this = any(Exec exec)`
|
||||
this.asExpr() = any(Exec exec).getBody()
|
||||
}
|
||||
|
||||
override DataFlow::Node getCode() { result = this }
|
||||
}
|
||||
|
||||
@@ -567,6 +567,7 @@ class ParameterDefinition extends EssaNodeDefinition {
|
||||
exists(Function func | func.getKwarg() = this.getDefiningNode().getNode())
|
||||
}
|
||||
|
||||
/** Gets the `Parameter` this `ParameterDefinition` represents. */
|
||||
Parameter getParameter() { result = this.getDefiningNode().getNode() }
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:4:10:4:10 | ControlFlowNode for z |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:1:7:1 | GSSA Variable b |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:1:19:1:19 | SSA variable x |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:2:3:2:3 | SSA variable y |
|
||||
@@ -47,7 +46,6 @@
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:6:1:6:1 | GSSA Variable a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:1:7:1 | GSSA Variable b |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() | test.py:7:1:7:1 | GSSA Variable b |
|
||||
| test.py:7:19:7:19 | ControlFlowNode for a | test.py:1:19:1:19 | SSA variable x |
|
||||
|
||||
@@ -66,14 +66,10 @@
|
||||
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:4:10:4:10 | ControlFlowNode for z |
|
||||
| test.py:4:10:4:10 | ControlFlowNode for z | test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() |
|
||||
| test.py:4:10:4:10 | ControlFlowNode for z | test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:6:1:6:1 | GSSA Variable a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:6:1:6:1 | GSSA Variable a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() | test.py:7:1:7:1 | GSSA Variable b |
|
||||
|
||||
@@ -34,11 +34,9 @@
|
||||
| test.py:4:10:4:10 | ControlFlowNode for z | test.py:4:10:4:10 | ControlFlowNode for z |
|
||||
| test.py:6:1:6:1 | ControlFlowNode for a | test.py:6:1:6:1 | ControlFlowNode for a |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:6:1:6:1 | GSSA Variable a |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:6:1:6:1 | GSSA Variable a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:7:1:7:1 | ControlFlowNode for b | test.py:7:1:7:1 | ControlFlowNode for b |
|
||||
| test.py:7:1:7:1 | GSSA Variable b | test.py:7:1:7:1 | GSSA Variable b |
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:2:3:2:3 | SSA variable y |
|
||||
| test.py:3:3:3:3 | SSA variable z | test.py:4:10:4:10 | ControlFlowNode for z |
|
||||
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:3:3:3:3 | SSA variable z |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:5:7:20 | GSSA Variable a |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:19:7:19 | ControlFlowNode for a |
|
||||
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:6:1:6:1 | GSSA Variable a |
|
||||
| test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() | test.py:7:1:7:1 | GSSA Variable b |
|
||||
|
||||
@@ -6,4 +6,3 @@
|
||||
| test.py:3:3:3:3 | SSA variable z | test.py:7:1:7:1 | GSSA Variable b |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:4:10:4:10 | ControlFlowNode for z |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:1:7:1 | GSSA Variable b |
|
||||
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:5:7:20 | GSSA Variable a |
|
||||
|
||||
@@ -15,3 +15,4 @@ uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
|
||||
@@ -4,5 +4,4 @@
|
||||
| argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c |
|
||||
| argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c |
|
||||
| argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:126:11:126:11 | ControlFlowNode for c |
|
||||
| argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | argumentPassing.py:155:11:155:13 | ControlFlowNode for baz |
|
||||
| classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:571:15:571:19 | ControlFlowNode for value |
|
||||
|
||||
@@ -3,34 +3,13 @@
|
||||
| test.py:41:1:41:33 | GSSA Variable SOURCE | test.py:42:21:42:26 | ControlFlowNode for SOURCE |
|
||||
| test.py:42:5:42:5 | SSA variable x | test.py:43:9:43:9 | ControlFlowNode for x |
|
||||
| test.py:42:10:42:26 | ControlFlowNode for Tuple | test.py:42:5:42:5 | SSA variable x |
|
||||
| test.py:43:5:43:5 | SSA variable y | test.py:44:5:44:11 | SSA variable y |
|
||||
| test.py:43:5:43:5 | SSA variable y | test.py:44:10:44:10 | ControlFlowNode for y |
|
||||
| test.py:43:9:43:12 | ControlFlowNode for Subscript | test.py:43:5:43:5 | SSA variable y |
|
||||
| test.py:187:1:187:53 | GSSA Variable SINK | test.py:189:5:189:8 | ControlFlowNode for SINK |
|
||||
| test.py:187:1:187:53 | GSSA Variable SOURCE | test.py:188:25:188:30 | ControlFlowNode for SOURCE |
|
||||
| test.py:188:5:188:5 | SSA variable x | test.py:189:10:189:10 | ControlFlowNode for x |
|
||||
| test.py:188:9:188:68 | ControlFlowNode for ListComp | test.py:188:5:188:5 | SSA variable x |
|
||||
| test.py:188:9:188:68 | SSA variable u | test.py:188:9:188:68 | SSA variable u |
|
||||
| test.py:188:9:188:68 | SSA variable u | test.py:188:9:188:68 | SSA variable u |
|
||||
| test.py:188:9:188:68 | SSA variable u | test.py:188:9:188:68 | SSA variable u |
|
||||
| test.py:188:9:188:68 | SSA variable v | test.py:188:9:188:68 | SSA variable v |
|
||||
| test.py:188:9:188:68 | SSA variable y | test.py:188:9:188:68 | SSA variable y |
|
||||
| test.py:188:9:188:68 | SSA variable y | test.py:188:9:188:68 | SSA variable y |
|
||||
| test.py:188:9:188:68 | SSA variable y | test.py:188:9:188:68 | SSA variable y |
|
||||
| test.py:188:9:188:68 | SSA variable y | test.py:188:9:188:68 | SSA variable y |
|
||||
| test.py:188:9:188:68 | SSA variable y | test.py:188:9:188:68 | SSA variable y |
|
||||
| test.py:188:9:188:68 | SSA variable y | test.py:188:9:188:68 | SSA variable y |
|
||||
| test.py:188:9:188:68 | SSA variable y | test.py:188:9:188:68 | SSA variable y |
|
||||
| test.py:188:9:188:68 | SSA variable z | test.py:188:9:188:68 | SSA variable z |
|
||||
| test.py:188:9:188:68 | SSA variable z | test.py:188:9:188:68 | SSA variable z |
|
||||
| test.py:188:9:188:68 | SSA variable z | test.py:188:9:188:68 | SSA variable z |
|
||||
| test.py:188:9:188:68 | SSA variable z | test.py:188:9:188:68 | SSA variable z |
|
||||
| test.py:188:9:188:68 | SSA variable z | test.py:188:9:188:68 | SSA variable z |
|
||||
| test.py:188:16:188:16 | SSA variable v | test.py:188:9:188:68 | SSA variable v |
|
||||
| test.py:188:16:188:16 | SSA variable v | test.py:188:45:188:45 | ControlFlowNode for v |
|
||||
| test.py:188:40:188:40 | SSA variable u | test.py:188:9:188:68 | SSA variable u |
|
||||
| test.py:188:40:188:40 | SSA variable u | test.py:188:56:188:56 | ControlFlowNode for u |
|
||||
| test.py:188:51:188:51 | SSA variable z | test.py:188:9:188:68 | SSA variable z |
|
||||
| test.py:188:51:188:51 | SSA variable z | test.py:188:67:188:67 | ControlFlowNode for z |
|
||||
| test.py:188:62:188:62 | SSA variable y | test.py:188:9:188:68 | SSA variable y |
|
||||
| test.py:188:62:188:62 | SSA variable y | test.py:188:10:188:10 | ControlFlowNode for y |
|
||||
|
||||
@@ -1,44 +1,26 @@
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:1:1:1:66 | GSSA Variable SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:28:1:28:4 | ControlFlowNode for SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK_F | examples.py:1:1:1:66 | GSSA Variable SINK_F |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:1:1:1:66 | GSSA Variable SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:27:15:27:20 | ControlFlowNode for SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable __name__ | examples.py:1:1:1:66 | GSSA Variable __name__ |
|
||||
| examples.py:0:0:0:0 | GSSA Variable __package__ | examples.py:1:1:1:66 | GSSA Variable __package__ |
|
||||
| examples.py:0:0:0:0 | GSSA Variable a | examples.py:1:1:1:66 | GSSA Variable a |
|
||||
| examples.py:0:0:0:0 | GSSA Variable fields_with_local_flow | examples.py:1:1:1:66 | GSSA Variable fields_with_local_flow |
|
||||
| examples.py:0:0:0:0 | GSSA Variable myobj | examples.py:1:1:1:66 | GSSA Variable myobj |
|
||||
| examples.py:0:0:0:0 | GSSA Variable obj | examples.py:1:1:1:66 | GSSA Variable obj |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:1:1:1:66 | GSSA Variable object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:6:13:6:18 | ControlFlowNode for object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable x | examples.py:1:1:1:66 | GSSA Variable x |
|
||||
| examples.py:0:0:0:0 | SSA variable $ | examples.py:1:1:1:66 | SSA variable $ |
|
||||
| examples.py:0:0:0:0 | SSA variable * | examples.py:1:1:1:66 | SSA variable * |
|
||||
| examples.py:1:1:1:66 | GSSA Variable SOURCE | examples.py:49:7:49:19 | GSSA Variable SOURCE |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:6:7:6:11 | GSSA Variable MyObj |
|
||||
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:25:9:25:13 | ControlFlowNode for MyObj |
|
||||
| examples.py:6:13:6:18 | ControlFlowNode for object | examples.py:11:17:11:22 | ControlFlowNode for object |
|
||||
| examples.py:7:5:7:28 | ControlFlowNode for FunctionExpr | examples.py:7:9:7:16 | SSA variable __init__ |
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:12 | ControlFlowNode for self |
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:16 | SSA variable self |
|
||||
| examples.py:7:24:7:26 | SSA variable foo | examples.py:8:20:8:22 | ControlFlowNode for foo |
|
||||
| examples.py:11:1:11:24 | ControlFlowNode for ClassExpr | examples.py:11:7:11:15 | GSSA Variable NestedObj |
|
||||
| examples.py:11:7:11:15 | GSSA Variable NestedObj | examples.py:33:5:33:13 | ControlFlowNode for NestedObj |
|
||||
| examples.py:12:5:12:23 | ControlFlowNode for FunctionExpr | examples.py:12:9:12:16 | SSA variable __init__ |
|
||||
| examples.py:12:5:12:23 | GSSA Variable MyObj | examples.py:13:20:13:24 | ControlFlowNode for MyObj |
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:12 | ControlFlowNode for self |
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:16 | SSA variable self |
|
||||
| examples.py:15:5:15:21 | ControlFlowNode for FunctionExpr | examples.py:15:9:15:14 | SSA variable getObj |
|
||||
| examples.py:15:16:15:19 | SSA variable self | examples.py:16:16:16:19 | ControlFlowNode for self |
|
||||
| examples.py:20:1:20:19 | ControlFlowNode for FunctionExpr | examples.py:20:5:20:10 | GSSA Variable setFoo |
|
||||
| examples.py:20:1:20:19 | GSSA Variable SINK_F | examples.py:21:5:21:10 | ControlFlowNode for SINK_F |
|
||||
| examples.py:20:5:20:10 | GSSA Variable setFoo | examples.py:27:1:27:6 | ControlFlowNode for setFoo |
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:21:12:21:14 | ControlFlowNode for obj |
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:22:5:22:11 | SSA variable obj |
|
||||
| examples.py:20:17:20:17 | SSA variable x | examples.py:22:15:22:15 | ControlFlowNode for x |
|
||||
| examples.py:21:12:21:14 | ControlFlowNode for obj | examples.py:22:5:22:7 | ControlFlowNode for obj |
|
||||
| examples.py:21:12:21:14 | [post read] ControlFlowNode for obj | examples.py:22:5:22:7 | ControlFlowNode for obj |
|
||||
| examples.py:25:1:25:5 | GSSA Variable myobj | examples.py:27:1:27:21 | GSSA Variable myobj |
|
||||
| examples.py:25:1:25:5 | GSSA Variable myobj | examples.py:27:8:27:12 | ControlFlowNode for myobj |
|
||||
| examples.py:25:9:25:13 | ControlFlowNode for MyObj | examples.py:49:7:49:11 | ControlFlowNode for MyObj |
|
||||
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:25:1:25:5 | GSSA Variable myobj |
|
||||
@@ -60,21 +42,18 @@
|
||||
| examples.py:40:5:40:10 | ControlFlowNode for SOURCE | examples.py:40:1:40:1 | GSSA Variable x |
|
||||
| examples.py:40:5:40:10 | ControlFlowNode for SOURCE | examples.py:49:13:49:18 | ControlFlowNode for SOURCE |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:44:1:44:1 | ControlFlowNode for a |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:44:1:44:10 | GSSA Variable a |
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:42:1:42:1 | GSSA Variable a |
|
||||
| examples.py:44:1:44:1 | ControlFlowNode for a | examples.py:46:6:46:6 | ControlFlowNode for a |
|
||||
| examples.py:44:1:44:1 | [post read] ControlFlowNode for a | examples.py:46:6:46:6 | ControlFlowNode for a |
|
||||
| examples.py:46:1:46:4 | ControlFlowNode for SINK | examples.py:50:1:50:4 | ControlFlowNode for SINK |
|
||||
| examples.py:49:1:49:3 | GSSA Variable obj | examples.py:50:6:50:8 | ControlFlowNode for obj |
|
||||
| examples.py:49:7:49:19 | ControlFlowNode for MyObj() | examples.py:49:1:49:3 | GSSA Variable obj |
|
||||
| examples.py:49:7:49:19 | GSSA Variable SOURCE | examples.py:59:6:59:35 | GSSA Variable SOURCE |
|
||||
| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:59:29:59:34 | ControlFlowNode for SOURCE |
|
||||
| examples.py:49:13:49:18 | [post arg] ControlFlowNode for SOURCE | examples.py:59:29:59:34 | ControlFlowNode for SOURCE |
|
||||
| examples.py:50:1:50:4 | ControlFlowNode for SINK | examples.py:59:1:59:4 | ControlFlowNode for SINK |
|
||||
| examples.py:53:1:53:30 | ControlFlowNode for FunctionExpr | examples.py:53:5:53:26 | GSSA Variable fields_with_local_flow |
|
||||
| examples.py:53:1:53:30 | GSSA Variable MyObj | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:53:5:53:26 | GSSA Variable fields_with_local_flow | examples.py:59:6:59:27 | ControlFlowNode for fields_with_local_flow |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:11:54:18 | SSA variable x |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:17:54:17 | ControlFlowNode for x |
|
||||
| examples.py:54:5:54:7 | SSA variable obj | examples.py:55:9:55:11 | ControlFlowNode for obj |
|
||||
| examples.py:54:11:54:18 | ControlFlowNode for MyObj() | examples.py:54:5:54:7 | SSA variable obj |
|
||||
@@ -83,63 +62,38 @@
|
||||
| test.py:2:13:2:26 | ControlFlowNode for Str | test.py:2:1:2:9 | GSSA Variable NONSOURCE |
|
||||
| test.py:3:10:3:17 | ControlFlowNode for Str | test.py:3:1:3:6 | GSSA Variable SOURCE |
|
||||
| test.py:6:1:6:17 | ControlFlowNode for FunctionExpr | test.py:6:5:6:13 | GSSA Variable is_source |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:12:7:12 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:29:7:29 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:29:7:29 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:47:7:47 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:71:7:71 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:10:1:10:12 | ControlFlowNode for FunctionExpr | test.py:10:5:10:8 | GSSA Variable SINK |
|
||||
| test.py:10:1:10:12 | GSSA Variable is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:11:18:11:18 | ControlFlowNode for x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:12:9:12:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:14:9:14:13 | SSA variable x |
|
||||
| test.py:11:18:11:18 | ControlFlowNode for x | test.py:14:34:14:34 | ControlFlowNode for x |
|
||||
| test.py:11:18:11:18 | [post arg] ControlFlowNode for x | test.py:14:34:14:34 | ControlFlowNode for x |
|
||||
| test.py:12:9:12:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:14:9:14:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:17:1:17:14 | ControlFlowNode for FunctionExpr | test.py:17:5:17:10 | GSSA Variable SINK_F |
|
||||
| test.py:17:1:17:14 | GSSA Variable is_source | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:18:18:18:18 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:9:19:13 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:21:9:21:13 | SSA variable x |
|
||||
| test.py:18:18:18:18 | ControlFlowNode for x | test.py:19:34:19:34 | ControlFlowNode for x |
|
||||
| test.py:18:18:18:18 | [post arg] ControlFlowNode for x | test.py:19:34:19:34 | ControlFlowNode for x |
|
||||
| test.py:19:9:19:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:21:9:21:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:25:1:25:20 | ControlFlowNode for ClassExpr | test.py:25:7:25:11 | GSSA Variable MyObj |
|
||||
| test.py:25:13:25:18 | ControlFlowNode for object | test.py:33:17:33:22 | ControlFlowNode for object |
|
||||
| test.py:26:5:26:28 | ControlFlowNode for FunctionExpr | test.py:26:9:26:16 | SSA variable __init__ |
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:12 | ControlFlowNode for self |
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:16 | SSA variable self |
|
||||
| test.py:26:24:26:26 | SSA variable foo | test.py:27:20:27:22 | ControlFlowNode for foo |
|
||||
| test.py:29:5:29:26 | ControlFlowNode for FunctionExpr | test.py:29:9:29:14 | SSA variable setFoo |
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:12 | ControlFlowNode for self |
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:16 | SSA variable self |
|
||||
| test.py:29:22:29:24 | SSA variable foo | test.py:30:20:30:22 | ControlFlowNode for foo |
|
||||
| test.py:33:1:33:24 | ControlFlowNode for ClassExpr | test.py:33:7:33:15 | GSSA Variable NestedObj |
|
||||
| test.py:34:5:34:23 | ControlFlowNode for FunctionExpr | test.py:34:9:34:16 | SSA variable __init__ |
|
||||
| test.py:34:5:34:23 | GSSA Variable MyObj | test.py:35:20:35:24 | ControlFlowNode for MyObj |
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:12 | ControlFlowNode for self |
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:16 | SSA variable self |
|
||||
| test.py:37:5:37:21 | ControlFlowNode for FunctionExpr | test.py:37:9:37:14 | SSA variable getObj |
|
||||
| test.py:37:16:37:19 | SSA variable self | test.py:38:16:38:19 | ControlFlowNode for self |
|
||||
| test.py:41:1:41:19 | ControlFlowNode for FunctionExpr | test.py:41:5:41:10 | GSSA Variable setFoo |
|
||||
| test.py:41:1:41:19 | GSSA Variable SINK_F | test.py:42:5:42:10 | ControlFlowNode for SINK_F |
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:42:12:42:14 | ControlFlowNode for obj |
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:43:5:43:11 | SSA variable obj |
|
||||
| test.py:41:17:41:17 | SSA variable x | test.py:43:15:43:15 | ControlFlowNode for x |
|
||||
| test.py:42:12:42:14 | ControlFlowNode for obj | test.py:43:5:43:7 | ControlFlowNode for obj |
|
||||
| test.py:42:12:42:14 | [post read] ControlFlowNode for obj | test.py:43:5:43:7 | ControlFlowNode for obj |
|
||||
@@ -148,7 +102,6 @@
|
||||
| test.py:46:1:46:20 | GSSA Variable SINK | test.py:50:5:50:8 | ControlFlowNode for SINK |
|
||||
| test.py:46:1:46:20 | GSSA Variable SOURCE | test.py:49:19:49:24 | ControlFlowNode for SOURCE |
|
||||
| test.py:46:1:46:20 | GSSA Variable setFoo | test.py:49:5:49:10 | ControlFlowNode for setFoo |
|
||||
| test.py:47:5:47:9 | SSA variable myobj | test.py:49:5:49:25 | SSA variable myobj |
|
||||
| test.py:47:5:47:9 | SSA variable myobj | test.py:49:12:49:16 | ControlFlowNode for myobj |
|
||||
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:47:5:47:9 | SSA variable myobj |
|
||||
| test.py:49:12:49:16 | ControlFlowNode for myobj | test.py:50:10:50:14 | ControlFlowNode for myobj |
|
||||
@@ -158,7 +111,6 @@
|
||||
| test.py:53:1:53:27 | GSSA Variable SINK | test.py:57:5:57:8 | ControlFlowNode for SINK |
|
||||
| test.py:53:1:53:27 | GSSA Variable SOURCE | test.py:56:18:56:23 | ControlFlowNode for SOURCE |
|
||||
| test.py:54:5:54:9 | SSA variable myobj | test.py:56:5:56:9 | ControlFlowNode for myobj |
|
||||
| test.py:54:5:54:9 | SSA variable myobj | test.py:56:5:56:24 | SSA variable myobj |
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:54:5:54:9 | SSA variable myobj |
|
||||
| test.py:56:5:56:9 | ControlFlowNode for myobj | test.py:57:10:57:14 | ControlFlowNode for myobj |
|
||||
| test.py:56:5:56:9 | [post read] ControlFlowNode for myobj | test.py:57:10:57:14 | ControlFlowNode for myobj |
|
||||
@@ -179,7 +131,6 @@
|
||||
| test.py:71:5:71:5 | SSA variable x | test.py:75:22:75:22 | ControlFlowNode for x |
|
||||
| test.py:71:9:71:14 | ControlFlowNode for SOURCE | test.py:71:5:71:5 | SSA variable x |
|
||||
| test.py:73:5:73:5 | SSA variable a | test.py:75:5:75:5 | ControlFlowNode for a |
|
||||
| test.py:73:5:73:5 | SSA variable a | test.py:75:5:75:14 | SSA variable a |
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:73:5:73:5 | SSA variable a |
|
||||
| test.py:75:5:75:5 | ControlFlowNode for a | test.py:77:10:77:10 | ControlFlowNode for a |
|
||||
| test.py:75:5:75:5 | [post read] ControlFlowNode for a | test.py:77:10:77:10 | ControlFlowNode for a |
|
||||
@@ -197,7 +148,6 @@
|
||||
| test.py:86:11:86:27 | ControlFlowNode for MyObj() | test.py:86:5:86:7 | SSA variable obj |
|
||||
| test.py:90:1:90:30 | ControlFlowNode for FunctionExpr | test.py:90:5:90:26 | GSSA Variable fields_with_local_flow |
|
||||
| test.py:90:1:90:30 | GSSA Variable MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:11:91:18 | SSA variable x |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:17:91:17 | ControlFlowNode for x |
|
||||
| test.py:91:5:91:7 | SSA variable obj | test.py:92:9:92:11 | ControlFlowNode for obj |
|
||||
| test.py:91:11:91:18 | ControlFlowNode for MyObj() | test.py:91:5:91:7 | SSA variable obj |
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:1:1:1:66 | GSSA Variable SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:1:1:1:66 | GSSA Variable SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:28:1:28:4 | ControlFlowNode for SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:28:1:28:4 | ControlFlowNode for SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:37:1:37:4 | ControlFlowNode for SINK |
|
||||
@@ -10,10 +8,6 @@
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:50:1:50:4 | ControlFlowNode for SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:59:1:59:4 | ControlFlowNode for SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK | examples.py:59:1:59:4 | ControlFlowNode for SINK |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK_F | examples.py:1:1:1:66 | GSSA Variable SINK_F |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SINK_F | examples.py:1:1:1:66 | GSSA Variable SINK_F |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:1:1:1:66 | GSSA Variable SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:1:1:1:66 | GSSA Variable SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:27:15:27:20 | ControlFlowNode for SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:27:15:27:20 | ControlFlowNode for SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:31:1:31:1 | GSSA Variable x |
|
||||
@@ -28,48 +22,20 @@
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:40:5:40:10 | ControlFlowNode for SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:44:18:44:18 | ControlFlowNode for x |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:44:18:44:18 | ControlFlowNode for x |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:49:7:49:19 | GSSA Variable SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:49:7:49:19 | GSSA Variable SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:49:13:49:18 | ControlFlowNode for SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:49:13:49:18 | ControlFlowNode for SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:59:6:59:35 | GSSA Variable SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:59:6:59:35 | GSSA Variable SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:59:29:59:34 | ControlFlowNode for SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable SOURCE | examples.py:59:29:59:34 | ControlFlowNode for SOURCE |
|
||||
| examples.py:0:0:0:0 | GSSA Variable __name__ | examples.py:1:1:1:66 | GSSA Variable __name__ |
|
||||
| examples.py:0:0:0:0 | GSSA Variable __name__ | examples.py:1:1:1:66 | GSSA Variable __name__ |
|
||||
| examples.py:0:0:0:0 | GSSA Variable __package__ | examples.py:1:1:1:66 | GSSA Variable __package__ |
|
||||
| examples.py:0:0:0:0 | GSSA Variable __package__ | examples.py:1:1:1:66 | GSSA Variable __package__ |
|
||||
| examples.py:0:0:0:0 | GSSA Variable a | examples.py:1:1:1:66 | GSSA Variable a |
|
||||
| examples.py:0:0:0:0 | GSSA Variable a | examples.py:1:1:1:66 | GSSA Variable a |
|
||||
| examples.py:0:0:0:0 | GSSA Variable fields_with_local_flow | examples.py:1:1:1:66 | GSSA Variable fields_with_local_flow |
|
||||
| examples.py:0:0:0:0 | GSSA Variable fields_with_local_flow | examples.py:1:1:1:66 | GSSA Variable fields_with_local_flow |
|
||||
| examples.py:0:0:0:0 | GSSA Variable myobj | examples.py:1:1:1:66 | GSSA Variable myobj |
|
||||
| examples.py:0:0:0:0 | GSSA Variable myobj | examples.py:1:1:1:66 | GSSA Variable myobj |
|
||||
| examples.py:0:0:0:0 | GSSA Variable obj | examples.py:1:1:1:66 | GSSA Variable obj |
|
||||
| examples.py:0:0:0:0 | GSSA Variable obj | examples.py:1:1:1:66 | GSSA Variable obj |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:1:1:1:66 | GSSA Variable object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:1:1:1:66 | GSSA Variable object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:6:13:6:18 | ControlFlowNode for object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:6:13:6:18 | ControlFlowNode for object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:11:17:11:22 | ControlFlowNode for object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:11:17:11:22 | ControlFlowNode for object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable x | examples.py:1:1:1:66 | GSSA Variable x |
|
||||
| examples.py:0:0:0:0 | GSSA Variable x | examples.py:1:1:1:66 | GSSA Variable x |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples | examples.py:13:20:13:24 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples | examples.py:13:20:13:24 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module examples | examples.py:21:5:21:10 | ControlFlowNode for SINK_F |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module examples | examples.py:21:5:21:10 | ControlFlowNode for SINK_F |
|
||||
| examples.py:0:0:0:0 | SSA variable $ | examples.py:1:1:1:66 | SSA variable $ |
|
||||
| examples.py:0:0:0:0 | SSA variable $ | examples.py:1:1:1:66 | SSA variable $ |
|
||||
| examples.py:0:0:0:0 | SSA variable * | examples.py:1:1:1:66 | SSA variable * |
|
||||
| examples.py:0:0:0:0 | SSA variable * | examples.py:1:1:1:66 | SSA variable * |
|
||||
| examples.py:1:1:1:66 | GSSA Variable SOURCE | examples.py:49:7:49:19 | GSSA Variable SOURCE |
|
||||
| examples.py:1:1:1:66 | GSSA Variable SOURCE | examples.py:49:7:49:19 | GSSA Variable SOURCE |
|
||||
| examples.py:1:1:1:66 | GSSA Variable SOURCE | examples.py:59:6:59:35 | GSSA Variable SOURCE |
|
||||
| examples.py:1:1:1:66 | GSSA Variable SOURCE | examples.py:59:6:59:35 | GSSA Variable SOURCE |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:6:7:6:11 | GSSA Variable MyObj |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:6:7:6:11 | GSSA Variable MyObj |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:25:9:25:13 | ControlFlowNode for MyObj |
|
||||
@@ -90,10 +56,6 @@
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:12 | ControlFlowNode for self |
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:12 | ControlFlowNode for self |
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:12 | ControlFlowNode for self |
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:16 | SSA variable self |
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:16 | SSA variable self |
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:16 | SSA variable self |
|
||||
| examples.py:7:18:7:21 | SSA variable self | examples.py:8:9:8:16 | SSA variable self |
|
||||
| examples.py:7:24:7:26 | SSA variable foo | examples.py:8:20:8:22 | ControlFlowNode for foo |
|
||||
| examples.py:7:24:7:26 | SSA variable foo | examples.py:8:20:8:22 | ControlFlowNode for foo |
|
||||
| examples.py:7:24:7:26 | SSA variable foo | examples.py:8:20:8:22 | ControlFlowNode for foo |
|
||||
@@ -130,10 +92,6 @@
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:12 | ControlFlowNode for self |
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:12 | ControlFlowNode for self |
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:12 | ControlFlowNode for self |
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:16 | SSA variable self |
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:16 | SSA variable self |
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:16 | SSA variable self |
|
||||
| examples.py:12:18:12:21 | SSA variable self | examples.py:13:9:13:16 | SSA variable self |
|
||||
| examples.py:13:9:13:12 | [post store] ControlFlowNode for self | examples.py:33:5:33:15 | ControlFlowNode for NestedObj() |
|
||||
| examples.py:13:9:13:12 | [post store] ControlFlowNode for self | examples.py:33:5:33:15 | ControlFlowNode for NestedObj() |
|
||||
| examples.py:13:9:13:12 | [post store] ControlFlowNode for self | examples.py:42:5:42:15 | ControlFlowNode for NestedObj() |
|
||||
@@ -169,10 +127,6 @@
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:22:5:22:7 | ControlFlowNode for obj |
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:22:5:22:7 | ControlFlowNode for obj |
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:22:5:22:7 | ControlFlowNode for obj |
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:22:5:22:11 | SSA variable obj |
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:22:5:22:11 | SSA variable obj |
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:22:5:22:11 | SSA variable obj |
|
||||
| examples.py:20:12:20:14 | SSA variable obj | examples.py:22:5:22:11 | SSA variable obj |
|
||||
| examples.py:20:12:20:14 | SSA variable obj [Attribute foo] | examples.py:21:12:21:14 | ControlFlowNode for obj [Attribute foo] |
|
||||
| examples.py:20:17:20:17 | SSA variable x | examples.py:22:15:22:15 | ControlFlowNode for x |
|
||||
| examples.py:20:17:20:17 | SSA variable x | examples.py:22:15:22:15 | ControlFlowNode for x |
|
||||
@@ -193,8 +147,6 @@
|
||||
| examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] | examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] |
|
||||
| examples.py:22:15:22:15 | ControlFlowNode for x | examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] |
|
||||
| examples.py:22:15:22:15 | ControlFlowNode for x | examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] |
|
||||
| examples.py:25:1:25:5 | GSSA Variable myobj | examples.py:27:1:27:21 | GSSA Variable myobj |
|
||||
| examples.py:25:1:25:5 | GSSA Variable myobj | examples.py:27:1:27:21 | GSSA Variable myobj |
|
||||
| examples.py:25:1:25:5 | GSSA Variable myobj | examples.py:27:8:27:12 | ControlFlowNode for myobj |
|
||||
| examples.py:25:1:25:5 | GSSA Variable myobj | examples.py:27:8:27:12 | ControlFlowNode for myobj |
|
||||
| examples.py:25:1:25:5 | GSSA Variable myobj | examples.py:28:6:28:10 | ControlFlowNode for myobj |
|
||||
@@ -205,8 +157,6 @@
|
||||
| examples.py:25:9:25:13 | ControlFlowNode for MyObj | examples.py:49:7:49:11 | ControlFlowNode for MyObj |
|
||||
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:25:1:25:5 | GSSA Variable myobj |
|
||||
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:25:1:25:5 | GSSA Variable myobj |
|
||||
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:27:1:27:21 | GSSA Variable myobj |
|
||||
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:27:1:27:21 | GSSA Variable myobj |
|
||||
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:27:8:27:12 | ControlFlowNode for myobj |
|
||||
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:27:8:27:12 | ControlFlowNode for myobj |
|
||||
| examples.py:25:9:25:19 | ControlFlowNode for MyObj() | examples.py:28:6:28:10 | ControlFlowNode for myobj |
|
||||
@@ -349,8 +299,6 @@
|
||||
| examples.py:40:5:40:10 | ControlFlowNode for SOURCE | examples.py:59:29:59:34 | ControlFlowNode for SOURCE |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:44:1:44:1 | ControlFlowNode for a |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:44:1:44:1 | ControlFlowNode for a |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:44:1:44:10 | GSSA Variable a |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:44:1:44:10 | GSSA Variable a |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:46:6:46:6 | ControlFlowNode for a |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a | examples.py:46:6:46:6 | ControlFlowNode for a |
|
||||
| examples.py:42:1:42:1 | GSSA Variable a [Attribute obj, Attribute foo] | examples.py:44:1:44:1 | ControlFlowNode for a [Attribute obj, Attribute foo] |
|
||||
@@ -361,8 +309,6 @@
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:42:1:42:1 | GSSA Variable a |
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:44:1:44:1 | ControlFlowNode for a |
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:44:1:44:1 | ControlFlowNode for a |
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:44:1:44:10 | GSSA Variable a |
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:44:1:44:10 | GSSA Variable a |
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:46:6:46:6 | ControlFlowNode for a |
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() | examples.py:46:6:46:6 | ControlFlowNode for a |
|
||||
| examples.py:42:5:42:15 | ControlFlowNode for NestedObj() [Attribute obj, Attribute foo] | examples.py:42:1:42:1 | GSSA Variable a [Attribute obj, Attribute foo] |
|
||||
@@ -397,8 +343,6 @@
|
||||
| examples.py:49:7:49:19 | ControlFlowNode for MyObj() | examples.py:50:6:50:8 | ControlFlowNode for obj |
|
||||
| examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] | examples.py:49:1:49:3 | GSSA Variable obj [Attribute foo] |
|
||||
| examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] | examples.py:50:6:50:8 | ControlFlowNode for obj [Attribute foo] |
|
||||
| examples.py:49:7:49:19 | GSSA Variable SOURCE | examples.py:59:6:59:35 | GSSA Variable SOURCE |
|
||||
| examples.py:49:7:49:19 | GSSA Variable SOURCE | examples.py:59:6:59:35 | GSSA Variable SOURCE |
|
||||
| examples.py:49:7:49:19 | [pre objCreate] ControlFlowNode for MyObj() | examples.py:7:18:7:21 | SSA variable self |
|
||||
| examples.py:49:7:49:19 | [pre objCreate] ControlFlowNode for MyObj() | examples.py:7:18:7:21 | SSA variable self |
|
||||
| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:7:24:7:26 | SSA variable foo |
|
||||
@@ -420,10 +364,6 @@
|
||||
| examples.py:53:1:53:30 | GSSA Variable MyObj | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:53:5:53:26 | GSSA Variable fields_with_local_flow | examples.py:59:6:59:27 | ControlFlowNode for fields_with_local_flow |
|
||||
| examples.py:53:5:53:26 | GSSA Variable fields_with_local_flow | examples.py:59:6:59:27 | ControlFlowNode for fields_with_local_flow |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:11:54:18 | SSA variable x |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:11:54:18 | SSA variable x |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:11:54:18 | SSA variable x |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:11:54:18 | SSA variable x |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:17:54:17 | ControlFlowNode for x |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:17:54:17 | ControlFlowNode for x |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:17:54:17 | ControlFlowNode for x |
|
||||
@@ -544,26 +484,6 @@
|
||||
| test.py:6:1:6:17 | ControlFlowNode for FunctionExpr | test.py:6:5:6:13 | GSSA Variable is_source |
|
||||
| test.py:6:5:6:13 | GSSA Variable is_source | test.py:0:0:0:0 | ModuleVariableNode for Global Variable is_source in Module test |
|
||||
| test.py:6:5:6:13 | GSSA Variable is_source | test.py:0:0:0:0 | ModuleVariableNode for Global Variable is_source in Module test |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:12:7:12 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:12:7:12 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:12:7:12 | ControlFlowNode for x |
|
||||
@@ -572,50 +492,18 @@
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:29:7:29 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:29:7:29 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:29:7:29 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:29:7:29 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:29:7:29 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:29:7:29 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:29:7:29 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:47:7:47 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:47:7:47 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:47:7:47 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:47:7:47 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:5:7:78 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:29:7:29 | ControlFlowNode for x |
|
||||
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:29:7:29 | ControlFlowNode for x |
|
||||
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:29:7:29 | ControlFlowNode for x |
|
||||
@@ -648,34 +536,6 @@
|
||||
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:47:7:47 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:29:7:29 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
@@ -684,68 +544,20 @@
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:58:7:58 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:47:7:47 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:58:7:58 | SSA variable x | test.py:7:71:7:71 | SSA variable x |
|
||||
| test.py:7:71:7:71 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:71:7:71 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:71:7:71 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:7:71:7:71 | SSA variable x | test.py:7:5:7:78 | SSA variable x |
|
||||
| test.py:10:1:10:12 | ControlFlowNode for FunctionExpr | test.py:10:5:10:8 | GSSA Variable SINK |
|
||||
| test.py:10:1:10:12 | ControlFlowNode for FunctionExpr | test.py:10:5:10:8 | GSSA Variable SINK |
|
||||
| test.py:10:1:10:12 | GSSA Variable is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:10:1:10:12 | GSSA Variable is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:10:5:10:8 | GSSA Variable SINK | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test |
|
||||
| test.py:10:5:10:8 | GSSA Variable SINK | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:11:18:11:18 | ControlFlowNode for x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:11:18:11:18 | ControlFlowNode for x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:11:18:11:18 | ControlFlowNode for x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:11:18:11:18 | ControlFlowNode for x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:12:9:12:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:12:9:12:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:12:9:12:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:12:9:12:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:14:9:14:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:14:9:14:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:14:9:14:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:14:9:14:13 | SSA variable x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:14:34:14:34 | ControlFlowNode for x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:14:34:14:34 | ControlFlowNode for x |
|
||||
| test.py:10:10:10:10 | SSA variable x | test.py:14:34:14:34 | ControlFlowNode for x |
|
||||
@@ -774,40 +586,20 @@
|
||||
| test.py:11:18:11:18 | [post arg] ControlFlowNode for x | test.py:87:10:87:16 | [post arg] ControlFlowNode for Attribute |
|
||||
| test.py:11:18:11:18 | [post arg] ControlFlowNode for x | test.py:97:10:97:39 | [post arg] ControlFlowNode for fields_with_local_flow() |
|
||||
| test.py:11:18:11:18 | [post arg] ControlFlowNode for x | test.py:97:10:97:39 | [post arg] ControlFlowNode for fields_with_local_flow() |
|
||||
| test.py:12:9:12:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:12:9:12:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:12:9:12:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:12:9:12:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:14:9:14:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:14:9:14:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:14:9:14:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:14:9:14:13 | SSA variable x | test.py:10:1:10:12 | SSA variable x |
|
||||
| test.py:17:1:17:14 | ControlFlowNode for FunctionExpr | test.py:17:5:17:10 | GSSA Variable SINK_F |
|
||||
| test.py:17:1:17:14 | ControlFlowNode for FunctionExpr | test.py:17:5:17:10 | GSSA Variable SINK_F |
|
||||
| test.py:17:1:17:14 | GSSA Variable is_source | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:17:1:17:14 | GSSA Variable is_source | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:17:5:17:10 | GSSA Variable SINK_F | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module test |
|
||||
| test.py:17:5:17:10 | GSSA Variable SINK_F | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module test |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:18:18:18:18 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:18:18:18:18 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:18:18:18:18 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:18:18:18:18 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:9:19:13 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:9:19:13 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:9:19:13 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:9:19:13 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:34:19:34 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:34:19:34 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:34:19:34 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:19:34:19:34 | ControlFlowNode for x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:21:9:21:13 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:21:9:21:13 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:21:9:21:13 | SSA variable x |
|
||||
| test.py:17:12:17:12 | SSA variable x | test.py:21:9:21:13 | SSA variable x |
|
||||
| test.py:18:18:18:18 | ControlFlowNode for x | test.py:6:15:6:15 | SSA variable x |
|
||||
| test.py:18:18:18:18 | ControlFlowNode for x | test.py:6:15:6:15 | SSA variable x |
|
||||
| test.py:18:18:18:18 | ControlFlowNode for x | test.py:6:15:6:15 | SSA variable x |
|
||||
@@ -820,16 +612,8 @@
|
||||
| test.py:18:18:18:18 | [post arg] ControlFlowNode for x | test.py:19:34:19:34 | ControlFlowNode for x |
|
||||
| test.py:18:18:18:18 | [post arg] ControlFlowNode for x | test.py:42:12:42:18 | [post arg] ControlFlowNode for Attribute |
|
||||
| test.py:18:18:18:18 | [post arg] ControlFlowNode for x | test.py:42:12:42:18 | [post arg] ControlFlowNode for Attribute |
|
||||
| test.py:19:9:19:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:19:9:19:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:19:9:19:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:19:9:19:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:19:34:19:34 | [post arg] ControlFlowNode for x | test.py:42:12:42:18 | [post arg] ControlFlowNode for Attribute |
|
||||
| test.py:19:34:19:34 | [post arg] ControlFlowNode for x | test.py:42:12:42:18 | [post arg] ControlFlowNode for Attribute |
|
||||
| test.py:21:9:21:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:21:9:21:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:21:9:21:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:21:9:21:13 | SSA variable x | test.py:17:1:17:14 | SSA variable x |
|
||||
| test.py:25:1:25:20 | ControlFlowNode for ClassExpr | test.py:25:7:25:11 | GSSA Variable MyObj |
|
||||
| test.py:25:1:25:20 | ControlFlowNode for ClassExpr | test.py:25:7:25:11 | GSSA Variable MyObj |
|
||||
| test.py:25:7:25:11 | GSSA Variable MyObj | test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test |
|
||||
@@ -842,10 +626,6 @@
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:12 | ControlFlowNode for self |
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:12 | ControlFlowNode for self |
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:12 | ControlFlowNode for self |
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:16 | SSA variable self |
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:16 | SSA variable self |
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:16 | SSA variable self |
|
||||
| test.py:26:18:26:21 | SSA variable self | test.py:27:9:27:16 | SSA variable self |
|
||||
| test.py:26:24:26:26 | SSA variable foo | test.py:27:20:27:22 | ControlFlowNode for foo |
|
||||
| test.py:26:24:26:26 | SSA variable foo | test.py:27:20:27:22 | ControlFlowNode for foo |
|
||||
| test.py:26:24:26:26 | SSA variable foo | test.py:27:20:27:22 | ControlFlowNode for foo |
|
||||
@@ -876,10 +656,6 @@
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:12 | ControlFlowNode for self |
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:12 | ControlFlowNode for self |
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:12 | ControlFlowNode for self |
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:16 | SSA variable self |
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:16 | SSA variable self |
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:16 | SSA variable self |
|
||||
| test.py:29:16:29:19 | SSA variable self | test.py:30:9:30:16 | SSA variable self |
|
||||
| test.py:29:22:29:24 | SSA variable foo | test.py:30:20:30:22 | ControlFlowNode for foo |
|
||||
| test.py:29:22:29:24 | SSA variable foo | test.py:30:20:30:22 | ControlFlowNode for foo |
|
||||
| test.py:29:22:29:24 | SSA variable foo | test.py:30:20:30:22 | ControlFlowNode for foo |
|
||||
@@ -901,10 +677,6 @@
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:12 | ControlFlowNode for self |
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:12 | ControlFlowNode for self |
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:12 | ControlFlowNode for self |
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:16 | SSA variable self |
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:16 | SSA variable self |
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:16 | SSA variable self |
|
||||
| test.py:34:18:34:21 | SSA variable self | test.py:35:9:35:16 | SSA variable self |
|
||||
| test.py:35:9:35:12 | [post store] ControlFlowNode for self | test.py:63:9:63:19 | ControlFlowNode for NestedObj() |
|
||||
| test.py:35:9:35:12 | [post store] ControlFlowNode for self | test.py:63:9:63:19 | ControlFlowNode for NestedObj() |
|
||||
| test.py:35:9:35:12 | [post store] ControlFlowNode for self | test.py:73:9:73:19 | ControlFlowNode for NestedObj() |
|
||||
@@ -947,10 +719,6 @@
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:43:5:43:7 | ControlFlowNode for obj |
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:43:5:43:7 | ControlFlowNode for obj |
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:43:5:43:7 | ControlFlowNode for obj |
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:43:5:43:11 | SSA variable obj |
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:43:5:43:11 | SSA variable obj |
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:43:5:43:11 | SSA variable obj |
|
||||
| test.py:41:12:41:14 | SSA variable obj | test.py:43:5:43:11 | SSA variable obj |
|
||||
| test.py:41:12:41:14 | SSA variable obj [Attribute foo] | test.py:42:12:42:14 | ControlFlowNode for obj [Attribute foo] |
|
||||
| test.py:41:17:41:17 | SSA variable x | test.py:43:15:43:15 | ControlFlowNode for x |
|
||||
| test.py:41:17:41:17 | SSA variable x | test.py:43:15:43:15 | ControlFlowNode for x |
|
||||
@@ -987,8 +755,6 @@
|
||||
| test.py:46:1:46:20 | GSSA Variable SOURCE | test.py:49:19:49:24 | ControlFlowNode for SOURCE |
|
||||
| test.py:46:1:46:20 | GSSA Variable setFoo | test.py:49:5:49:10 | ControlFlowNode for setFoo |
|
||||
| test.py:46:1:46:20 | GSSA Variable setFoo | test.py:49:5:49:10 | ControlFlowNode for setFoo |
|
||||
| test.py:47:5:47:9 | SSA variable myobj | test.py:49:5:49:25 | SSA variable myobj |
|
||||
| test.py:47:5:47:9 | SSA variable myobj | test.py:49:5:49:25 | SSA variable myobj |
|
||||
| test.py:47:5:47:9 | SSA variable myobj | test.py:49:12:49:16 | ControlFlowNode for myobj |
|
||||
| test.py:47:5:47:9 | SSA variable myobj | test.py:49:12:49:16 | ControlFlowNode for myobj |
|
||||
| test.py:47:5:47:9 | SSA variable myobj | test.py:50:10:50:14 | ControlFlowNode for myobj |
|
||||
@@ -997,8 +763,6 @@
|
||||
| test.py:47:5:47:9 | SSA variable myobj [Attribute foo] | test.py:50:10:50:14 | ControlFlowNode for myobj [Attribute foo] |
|
||||
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:47:5:47:9 | SSA variable myobj |
|
||||
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:47:5:47:9 | SSA variable myobj |
|
||||
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:49:5:49:25 | SSA variable myobj |
|
||||
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:49:5:49:25 | SSA variable myobj |
|
||||
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:49:12:49:16 | ControlFlowNode for myobj |
|
||||
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:49:12:49:16 | ControlFlowNode for myobj |
|
||||
| test.py:47:13:47:23 | ControlFlowNode for MyObj() | test.py:50:10:50:14 | ControlFlowNode for myobj |
|
||||
@@ -1037,8 +801,6 @@
|
||||
| test.py:53:1:53:27 | GSSA Variable SOURCE | test.py:56:18:56:23 | ControlFlowNode for SOURCE |
|
||||
| test.py:54:5:54:9 | SSA variable myobj | test.py:56:5:56:9 | ControlFlowNode for myobj |
|
||||
| test.py:54:5:54:9 | SSA variable myobj | test.py:56:5:56:9 | ControlFlowNode for myobj |
|
||||
| test.py:54:5:54:9 | SSA variable myobj | test.py:56:5:56:24 | SSA variable myobj |
|
||||
| test.py:54:5:54:9 | SSA variable myobj | test.py:56:5:56:24 | SSA variable myobj |
|
||||
| test.py:54:5:54:9 | SSA variable myobj | test.py:57:10:57:14 | ControlFlowNode for myobj |
|
||||
| test.py:54:5:54:9 | SSA variable myobj | test.py:57:10:57:14 | ControlFlowNode for myobj |
|
||||
| test.py:54:5:54:9 | SSA variable myobj [Attribute foo] | test.py:56:5:56:9 | ControlFlowNode for myobj [Attribute foo] |
|
||||
@@ -1047,8 +809,6 @@
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:54:5:54:9 | SSA variable myobj |
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:56:5:56:9 | ControlFlowNode for myobj |
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:56:5:56:9 | ControlFlowNode for myobj |
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:56:5:56:24 | SSA variable myobj |
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:56:5:56:24 | SSA variable myobj |
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:57:10:57:14 | ControlFlowNode for myobj |
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() | test.py:57:10:57:14 | ControlFlowNode for myobj |
|
||||
| test.py:54:13:54:23 | ControlFlowNode for MyObj() [Attribute foo] | test.py:54:5:54:9 | SSA variable myobj [Attribute foo] |
|
||||
@@ -1154,8 +914,6 @@
|
||||
| test.py:71:9:71:14 | ControlFlowNode for SOURCE | test.py:75:22:75:22 | ControlFlowNode for x |
|
||||
| test.py:73:5:73:5 | SSA variable a | test.py:75:5:75:5 | ControlFlowNode for a |
|
||||
| test.py:73:5:73:5 | SSA variable a | test.py:75:5:75:5 | ControlFlowNode for a |
|
||||
| test.py:73:5:73:5 | SSA variable a | test.py:75:5:75:14 | SSA variable a |
|
||||
| test.py:73:5:73:5 | SSA variable a | test.py:75:5:75:14 | SSA variable a |
|
||||
| test.py:73:5:73:5 | SSA variable a | test.py:77:10:77:10 | ControlFlowNode for a |
|
||||
| test.py:73:5:73:5 | SSA variable a | test.py:77:10:77:10 | ControlFlowNode for a |
|
||||
| test.py:73:5:73:5 | SSA variable a [Attribute obj, Attribute foo] | test.py:75:5:75:5 | ControlFlowNode for a [Attribute obj, Attribute foo] |
|
||||
@@ -1166,8 +924,6 @@
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:73:5:73:5 | SSA variable a |
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:75:5:75:5 | ControlFlowNode for a |
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:75:5:75:5 | ControlFlowNode for a |
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:75:5:75:14 | SSA variable a |
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:75:5:75:14 | SSA variable a |
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:77:10:77:10 | ControlFlowNode for a |
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() | test.py:77:10:77:10 | ControlFlowNode for a |
|
||||
| test.py:73:9:73:19 | ControlFlowNode for NestedObj() [Attribute obj, Attribute foo] | test.py:73:5:73:5 | SSA variable a [Attribute obj, Attribute foo] |
|
||||
@@ -1259,10 +1015,6 @@
|
||||
| test.py:90:1:90:30 | GSSA Variable MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:90:5:90:26 | GSSA Variable fields_with_local_flow | test.py:0:0:0:0 | ModuleVariableNode for Global Variable fields_with_local_flow in Module test |
|
||||
| test.py:90:5:90:26 | GSSA Variable fields_with_local_flow | test.py:0:0:0:0 | ModuleVariableNode for Global Variable fields_with_local_flow in Module test |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:11:91:18 | SSA variable x |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:11:91:18 | SSA variable x |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:11:91:18 | SSA variable x |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:11:91:18 | SSA variable x |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:17:91:17 | ControlFlowNode for x |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:17:91:17 | ControlFlowNode for x |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:17:91:17 | ControlFlowNode for x |
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
| examples.py:53:1:53:30 | GSSA Variable MyObj | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:11:54:18 | SSA variable x |
|
||||
| examples.py:53:28:53:28 | SSA variable x | examples.py:54:17:54:17 | ControlFlowNode for x |
|
||||
| examples.py:54:5:54:7 | SSA variable obj | examples.py:55:9:55:11 | ControlFlowNode for obj |
|
||||
| examples.py:54:11:54:18 | ControlFlowNode for MyObj() | examples.py:54:5:54:7 | SSA variable obj |
|
||||
| examples.py:55:5:55:5 | SSA variable a | examples.py:56:12:56:12 | ControlFlowNode for a |
|
||||
| examples.py:55:9:55:15 | ControlFlowNode for Attribute | examples.py:55:5:55:5 | SSA variable a |
|
||||
| test.py:90:1:90:30 | GSSA Variable MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:11:91:18 | SSA variable x |
|
||||
| test.py:90:28:90:28 | SSA variable x | test.py:91:17:91:17 | ControlFlowNode for x |
|
||||
| test.py:91:5:91:7 | SSA variable obj | test.py:92:9:92:11 | ControlFlowNode for obj |
|
||||
| test.py:91:11:91:18 | ControlFlowNode for MyObj() | test.py:91:5:91:7 | SSA variable obj |
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
importModule
|
||||
| test1.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
|
||||
| test1.py:1:8:1:12 | GSSA Variable mypkg | mypkg |
|
||||
| test2.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
|
||||
| test2.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
|
||||
| test2.py:1:19:1:21 | GSSA Variable foo | mypkg.foo |
|
||||
| test2.py:1:24:1:26 | GSSA Variable bar | mypkg.bar |
|
||||
| test3.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg.foo |
|
||||
| test3.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg.bar |
|
||||
| test3.py:2:8:2:16 | GSSA Variable mypkg | mypkg |
|
||||
| test4.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg.foo |
|
||||
| test4.py:1:21:1:24 | GSSA Variable _foo | mypkg.foo |
|
||||
| test4.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg.bar |
|
||||
| test4.py:2:21:2:24 | GSSA Variable _bar | mypkg.bar |
|
||||
| test5.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
|
||||
| test5.py:1:8:1:12 | GSSA Variable mypkg | mypkg |
|
||||
| test5.py:9:6:9:10 | ControlFlowNode for ImportExpr | mypkg |
|
||||
| test5.py:9:26:9:29 | GSSA Variable _bar | mypkg.bar |
|
||||
| test6.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg |
|
||||
| test6.py:1:8:1:12 | GSSA Variable mypkg | mypkg |
|
||||
| test6.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg.foo |
|
||||
| test6.py:5:8:5:16 | GSSA Variable mypkg | mypkg |
|
||||
| test7.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg |
|
||||
| test7.py:1:19:1:21 | GSSA Variable foo | mypkg.foo |
|
||||
| test7.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg.foo |
|
||||
| test7.py:5:8:5:16 | GSSA Variable mypkg | mypkg |
|
||||
| test7.py:9:6:9:10 | ControlFlowNode for ImportExpr | mypkg |
|
||||
| test7.py:9:19:9:21 | GSSA Variable foo | mypkg.foo |
|
||||
importMember
|
||||
| test2.py:1:19:1:21 | GSSA Variable foo | mypkg | foo |
|
||||
| test2.py:1:24:1:26 | GSSA Variable bar | mypkg | bar |
|
||||
| test5.py:9:26:9:29 | GSSA Variable _bar | mypkg | bar |
|
||||
| test7.py:1:19:1:21 | GSSA Variable foo | mypkg | foo |
|
||||
| test7.py:9:19:9:21 | GSSA Variable foo | mypkg | foo |
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
|
||||
query predicate importModule(DataFlow::Node res, string name) { res = DataFlow::importModule(name) }
|
||||
|
||||
query predicate importMember(DataFlow::Node res, string moduleName, string memberName) {
|
||||
res = DataFlow::importMember(moduleName, memberName)
|
||||
}
|
||||
query predicate importNode(DataFlow::Node res, string name) { res = DataFlow::importNode(name) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
| test.py:3:1:3:7 | GSSA Variable tainted | test.py:4:1:4:13 | GSSA Variable tainted |
|
||||
| test.py:3:1:3:7 | GSSA Variable tainted | test.py:4:6:4:12 | ControlFlowNode for tainted |
|
||||
| test.py:3:11:3:16 | ControlFlowNode for SOURCE | test.py:3:1:3:7 | GSSA Variable tainted |
|
||||
| test.py:6:1:6:11 | ControlFlowNode for FunctionExpr | test.py:6:5:6:8 | GSSA Variable func |
|
||||
| test.py:7:5:7:16 | SSA variable also_tainted | test.py:8:5:8:22 | SSA variable also_tainted |
|
||||
| test.py:7:5:7:16 | SSA variable also_tainted | test.py:8:10:8:21 | ControlFlowNode for also_tainted |
|
||||
| test.py:7:20:7:25 | ControlFlowNode for SOURCE | test.py:7:5:7:16 | SSA variable also_tainted |
|
||||
|
||||
@@ -137,9 +137,10 @@
|
||||
| test_string.py:143 | fail | binary_decode_encode | base64.decodestring(..) |
|
||||
| test_string.py:148 | fail | binary_decode_encode | quopri.encodestring(..) |
|
||||
| test_string.py:149 | fail | binary_decode_encode | quopri.decodestring(..) |
|
||||
| test_string.py:158 | ok | test_os_path_join | os.path.join(..) |
|
||||
| test_string.py:159 | ok | test_os_path_join | os.path.join(..) |
|
||||
| test_string.py:160 | ok | test_os_path_join | os.path.join(..) |
|
||||
| test_string.py:161 | ok | test_os_path_join | os.path.join(..) |
|
||||
| test_string.py:162 | ok | test_os_path_join | ospath_alias.join(..) |
|
||||
| test_unpacking.py:16 | ok | unpacking | a |
|
||||
| test_unpacking.py:16 | ok | unpacking | b |
|
||||
| test_unpacking.py:16 | ok | unpacking | c |
|
||||
|
||||
@@ -152,12 +152,14 @@ def binary_decode_encode():
|
||||
|
||||
def test_os_path_join():
|
||||
import os
|
||||
import os.path as ospath_alias
|
||||
print("\n# test_os_path_join")
|
||||
ts = TAINTED_STRING
|
||||
ensure_tainted(
|
||||
os.path.join(ts, "foo", "bar"),
|
||||
os.path.join(ts),
|
||||
os.path.join("foo", "bar", ts),
|
||||
ospath_alias.join("foo", "bar", ts),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -29,3 +29,73 @@ def test_incompatible_types():
|
||||
expects_int(x) # $int=field $f+:str=field
|
||||
x.field = str("Hello") # $f+:int=field $str=field $f+:int $str
|
||||
expects_string(x) # $f+:int=field $str=field
|
||||
|
||||
|
||||
# Attributes assigned statically to a class
|
||||
|
||||
class MyClass: # $tracked=field
|
||||
field = tracked # $tracked
|
||||
|
||||
lookup = MyClass.field # $tracked $tracked=field
|
||||
instance = MyClass() # $tracked=field
|
||||
lookup2 = instance.field # $f-:tracked
|
||||
|
||||
## Dynamic attribute access
|
||||
|
||||
# Via `getattr`/`setattr`
|
||||
|
||||
def setattr_immediate_write():
|
||||
x = SomeClass() # $tracked=foo
|
||||
setattr(x,"foo", tracked) # $tracked $tracked=foo
|
||||
y = x.foo # $tracked $tracked=foo
|
||||
do_stuff(y) # $tracked
|
||||
|
||||
def getattr_immediate_read():
|
||||
x = SomeClass() # $tracked=foo
|
||||
x.foo = tracked # $tracked $tracked=foo
|
||||
y = getattr(x,"foo") # $tracked $tracked=foo
|
||||
do_stuff(y) # $tracked
|
||||
|
||||
def setattr_indirect_write():
|
||||
attr = "foo"
|
||||
x = SomeClass() # $tracked=foo
|
||||
setattr(x, attr, tracked) # $tracked $tracked=foo
|
||||
y = x.foo # $tracked $tracked=foo
|
||||
do_stuff(y) # $tracked
|
||||
|
||||
def getattr_indirect_read():
|
||||
attr = "foo"
|
||||
x = SomeClass() # $tracked=foo
|
||||
x.foo = tracked # $tracked $tracked=foo
|
||||
y = getattr(x, attr) #$tracked $tracked=foo
|
||||
do_stuff(y) # $tracked
|
||||
|
||||
# Via `__dict__` -- not currently implemented.
|
||||
|
||||
def dunder_dict_immediate_write():
|
||||
x = SomeClass() # $f-:tracked=foo
|
||||
x.__dict__["foo"] = tracked # $tracked $f-:tracked=foo
|
||||
y = x.foo # $f-:tracked $f-:tracked=foo
|
||||
do_stuff(y) # $f-:tracked
|
||||
|
||||
def dunder_dict_immediate_read():
|
||||
x = SomeClass() # $tracked=foo
|
||||
x.foo = tracked # $tracked $tracked=foo
|
||||
y = x.__dict__["foo"] # $f-:tracked $tracked=foo
|
||||
do_stuff(y) # $f-:tracked
|
||||
|
||||
def dunder_dict_indirect_write():
|
||||
attr = "foo"
|
||||
x = SomeClass() # $f-:tracked=foo
|
||||
x.__dict__[attr] = tracked # $tracked $f-:tracked=foo
|
||||
y = x.foo # $f-:tracked $f-:tracked=foo
|
||||
do_stuff(y) # $f-:tracked
|
||||
|
||||
def dunder_dict_indirect_read():
|
||||
attr = "foo"
|
||||
x = SomeClass() # $tracked=foo
|
||||
x.foo = tracked # $tracked $tracked=foo
|
||||
y = x.__dict__[attr] # $f-:tracked $tracked=foo
|
||||
do_stuff(y) # $f-:tracked
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
from module import attr as attr_ref
|
||||
|
||||
x = attr_ref
|
||||
|
||||
def fun():
|
||||
y = attr_ref
|
||||
|
||||
# The following should _not_ be a reference to the above module, since we don't actually import it.
|
||||
z = module
|
||||
@@ -0,0 +1,9 @@
|
||||
import module.attr as attr_ref
|
||||
|
||||
x = attr_ref
|
||||
|
||||
def fun():
|
||||
y = attr_ref
|
||||
|
||||
# The following should _not_ be a reference to the above module, since we don't actually import it.
|
||||
z = module
|
||||
@@ -0,0 +1,10 @@
|
||||
module_tracker
|
||||
| import_as_attr.py:1:6:1:11 | ControlFlowNode for ImportExpr |
|
||||
module_attr_tracker
|
||||
| import_as_attr.py:0:0:0:0 | ModuleVariableNode for Global Variable attr_ref in Module import_as_attr |
|
||||
| import_as_attr.py:1:20:1:35 | ControlFlowNode for ImportMember |
|
||||
| import_as_attr.py:1:28:1:35 | GSSA Variable attr_ref |
|
||||
| import_as_attr.py:3:1:3:1 | GSSA Variable x |
|
||||
| import_as_attr.py:3:5:3:12 | ControlFlowNode for attr_ref |
|
||||
| import_as_attr.py:6:5:6:5 | SSA variable y |
|
||||
| import_as_attr.py:6:9:6:16 | ControlFlowNode for attr_ref |
|
||||
@@ -0,0 +1,23 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import experimental.dataflow.TypeTracker
|
||||
|
||||
DataFlow::Node module_tracker(TypeTracker t) {
|
||||
t.start() and
|
||||
result = DataFlow::importNode("module")
|
||||
or
|
||||
exists(TypeTracker t2 | result = module_tracker(t2).track(t2, t))
|
||||
}
|
||||
|
||||
query DataFlow::Node module_tracker() { result = module_tracker(DataFlow::TypeTracker::end()) }
|
||||
|
||||
DataFlow::Node module_attr_tracker(TypeTracker t) {
|
||||
t.startInAttr("attr") and
|
||||
result = module_tracker()
|
||||
or
|
||||
exists(TypeTracker t2 | result = module_attr_tracker(t2).track(t2, t))
|
||||
}
|
||||
|
||||
query DataFlow::Node module_attr_tracker() {
|
||||
result = module_attr_tracker(DataFlow::TypeTracker::end())
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -1,98 +1,98 @@
|
||||
| test.py:6 | fail | test_taint | name |
|
||||
| test.py:6 | fail | test_taint | number |
|
||||
| test.py:7 | ok | test_taint | foo |
|
||||
| test.py:14 | ok | test_taint | request.environ |
|
||||
| test.py:15 | ok | test_taint | request.environ.get(..) |
|
||||
| test.py:17 | ok | test_taint | request.path |
|
||||
| test.py:18 | ok | test_taint | request.full_path |
|
||||
| test.py:19 | ok | test_taint | request.base_url |
|
||||
| test.py:20 | ok | test_taint | request.url |
|
||||
| test.py:23 | fail | test_taint | request.accept_charsets.best |
|
||||
| test.py:24 | fail | test_taint | request.accept_charsets.best_match(..) |
|
||||
| test.py:25 | ok | test_taint | request.accept_charsets[0] |
|
||||
| test.py:26 | ok | test_taint | request.accept_encodings |
|
||||
| test.py:27 | ok | test_taint | request.accept_languages |
|
||||
| test.py:28 | ok | test_taint | request.accept_mimetypes |
|
||||
| test.py:31 | ok | test_taint | request.access_control_request_headers |
|
||||
| test.py:33 | ok | test_taint | request.access_control_request_method |
|
||||
| test.py:35 | ok | test_taint | request.access_route |
|
||||
| test.py:36 | ok | test_taint | request.access_route[0] |
|
||||
| test.py:39 | ok | test_taint | request.args |
|
||||
| test.py:40 | ok | test_taint | request.args['key'] |
|
||||
| test.py:41 | ok | test_taint | request.args.getlist(..) |
|
||||
| test.py:44 | ok | test_taint | request.authorization |
|
||||
| test.py:45 | ok | test_taint | request.authorization['username'] |
|
||||
| test.py:46 | fail | test_taint | request.authorization.username |
|
||||
| test.py:49 | ok | test_taint | request.cache_control |
|
||||
| test.py:51 | fail | test_taint | request.cache_control.max_age |
|
||||
| test.py:52 | fail | test_taint | request.cache_control.max_stale |
|
||||
| test.py:53 | fail | test_taint | request.cache_control.min_fresh |
|
||||
| test.py:55 | ok | test_taint | request.content_encoding |
|
||||
| test.py:57 | ok | test_taint | request.content_md5 |
|
||||
| test.py:59 | ok | test_taint | request.content_type |
|
||||
| test.py:62 | ok | test_taint | request.cookies |
|
||||
| test.py:63 | ok | test_taint | request.cookies['key'] |
|
||||
| test.py:65 | ok | test_taint | request.data |
|
||||
| test.py:68 | ok | test_taint | request.files |
|
||||
| test.py:69 | ok | test_taint | request.files['key'] |
|
||||
| test.py:70 | fail | test_taint | request.files['key'].filename |
|
||||
| test.py:71 | fail | test_taint | request.files['key'].stream |
|
||||
| test.py:72 | ok | test_taint | request.files.getlist(..) |
|
||||
| test.py:73 | fail | test_taint | request.files.getlist(..)[0].filename |
|
||||
| test.py:74 | fail | test_taint | request.files.getlist(..)[0].stream |
|
||||
| test.py:77 | ok | test_taint | request.form |
|
||||
| test.py:78 | ok | test_taint | request.form['key'] |
|
||||
| test.py:79 | ok | test_taint | request.form.getlist(..) |
|
||||
| test.py:81 | ok | test_taint | request.get_data() |
|
||||
| test.py:83 | ok | test_taint | request.get_json() |
|
||||
| test.py:84 | ok | test_taint | request.get_json()['foo'] |
|
||||
| test.py:85 | ok | test_taint | request.get_json()['foo']['bar'] |
|
||||
| test.py:89 | ok | test_taint | request.headers |
|
||||
| test.py:90 | ok | test_taint | request.headers['key'] |
|
||||
| test.py:91 | fail | test_taint | request.headers.get_all(..) |
|
||||
| test.py:92 | fail | test_taint | request.headers.getlist(..) |
|
||||
| test.py:93 | ok | test_taint | list(..) |
|
||||
| test.py:94 | fail | test_taint | request.headers.to_wsgi_list() |
|
||||
| test.py:96 | ok | test_taint | request.json |
|
||||
| test.py:97 | ok | test_taint | request.json['foo'] |
|
||||
| test.py:98 | ok | test_taint | request.json['foo']['bar'] |
|
||||
| test.py:100 | ok | test_taint | request.method |
|
||||
| test.py:102 | ok | test_taint | request.mimetype |
|
||||
| test.py:104 | ok | test_taint | request.mimetype_params |
|
||||
| test.py:106 | ok | test_taint | request.origin |
|
||||
| test.py:109 | ok | test_taint | request.pragma |
|
||||
| test.py:111 | ok | test_taint | request.query_string |
|
||||
| test.py:113 | ok | test_taint | request.referrer |
|
||||
| test.py:115 | ok | test_taint | request.remote_addr |
|
||||
| test.py:117 | ok | test_taint | request.remote_user |
|
||||
| test.py:120 | ok | test_taint | request.stream |
|
||||
| test.py:121 | ok | test_taint | request.input_stream |
|
||||
| test.py:123 | ok | test_taint | request.url |
|
||||
| test.py:125 | ok | test_taint | request.user_agent |
|
||||
| test.py:128 | ok | test_taint | request.values |
|
||||
| test.py:129 | ok | test_taint | request.values['key'] |
|
||||
| test.py:130 | ok | test_taint | request.values.getlist(..) |
|
||||
| test.py:133 | ok | test_taint | request.view_args |
|
||||
| test.py:134 | ok | test_taint | request.view_args['key'] |
|
||||
| test.py:138 | ok | test_taint | request.script_root |
|
||||
| test.py:139 | ok | test_taint | request.url_root |
|
||||
| test.py:143 | ok | test_taint | request.charset |
|
||||
| test.py:144 | ok | test_taint | request.url_charset |
|
||||
| test.py:148 | ok | test_taint | request.date |
|
||||
| test.py:151 | ok | test_taint | request.endpoint |
|
||||
| test.py:156 | ok | test_taint | request.host |
|
||||
| test.py:157 | ok | test_taint | request.host_url |
|
||||
| test.py:159 | ok | test_taint | request.scheme |
|
||||
| test.py:161 | ok | test_taint | request.script_root |
|
||||
| test.py:169 | ok | test_taint | request.args |
|
||||
| test.py:170 | ok | test_taint | a |
|
||||
| test.py:171 | ok | test_taint | b |
|
||||
| test.py:173 | ok | test_taint | request.args['key'] |
|
||||
| test.py:174 | ok | test_taint | a['key'] |
|
||||
| test.py:175 | ok | test_taint | b['key'] |
|
||||
| test.py:177 | ok | test_taint | request.args.getlist(..) |
|
||||
| test.py:178 | ok | test_taint | a.getlist(..) |
|
||||
| test.py:179 | ok | test_taint | b.getlist(..) |
|
||||
| test.py:180 | ok | test_taint | gl(..) |
|
||||
| test.py:187 | ok | test_taint | req.path |
|
||||
| test.py:188 | ok | test_taint | gd() |
|
||||
| taint_test.py:6 | ok | test_taint | name |
|
||||
| taint_test.py:6 | ok | test_taint | number |
|
||||
| taint_test.py:7 | ok | test_taint | foo |
|
||||
| taint_test.py:14 | ok | test_taint | request.environ |
|
||||
| taint_test.py:15 | ok | test_taint | request.environ.get(..) |
|
||||
| taint_test.py:17 | ok | test_taint | request.path |
|
||||
| taint_test.py:18 | ok | test_taint | request.full_path |
|
||||
| taint_test.py:19 | ok | test_taint | request.base_url |
|
||||
| taint_test.py:20 | ok | test_taint | request.url |
|
||||
| taint_test.py:23 | fail | test_taint | request.accept_charsets.best |
|
||||
| taint_test.py:24 | fail | test_taint | request.accept_charsets.best_match(..) |
|
||||
| taint_test.py:25 | ok | test_taint | request.accept_charsets[0] |
|
||||
| taint_test.py:26 | ok | test_taint | request.accept_encodings |
|
||||
| taint_test.py:27 | ok | test_taint | request.accept_languages |
|
||||
| taint_test.py:28 | ok | test_taint | request.accept_mimetypes |
|
||||
| taint_test.py:31 | ok | test_taint | request.access_control_request_headers |
|
||||
| taint_test.py:33 | ok | test_taint | request.access_control_request_method |
|
||||
| taint_test.py:35 | ok | test_taint | request.access_route |
|
||||
| taint_test.py:36 | ok | test_taint | request.access_route[0] |
|
||||
| taint_test.py:39 | ok | test_taint | request.args |
|
||||
| taint_test.py:40 | ok | test_taint | request.args['key'] |
|
||||
| taint_test.py:41 | ok | test_taint | request.args.getlist(..) |
|
||||
| taint_test.py:44 | ok | test_taint | request.authorization |
|
||||
| taint_test.py:45 | ok | test_taint | request.authorization['username'] |
|
||||
| taint_test.py:46 | fail | test_taint | request.authorization.username |
|
||||
| taint_test.py:49 | ok | test_taint | request.cache_control |
|
||||
| taint_test.py:51 | fail | test_taint | request.cache_control.max_age |
|
||||
| taint_test.py:52 | fail | test_taint | request.cache_control.max_stale |
|
||||
| taint_test.py:53 | fail | test_taint | request.cache_control.min_fresh |
|
||||
| taint_test.py:55 | ok | test_taint | request.content_encoding |
|
||||
| taint_test.py:57 | ok | test_taint | request.content_md5 |
|
||||
| taint_test.py:59 | ok | test_taint | request.content_type |
|
||||
| taint_test.py:62 | ok | test_taint | request.cookies |
|
||||
| taint_test.py:63 | ok | test_taint | request.cookies['key'] |
|
||||
| taint_test.py:65 | ok | test_taint | request.data |
|
||||
| taint_test.py:68 | ok | test_taint | request.files |
|
||||
| taint_test.py:69 | ok | test_taint | request.files['key'] |
|
||||
| taint_test.py:70 | fail | test_taint | request.files['key'].filename |
|
||||
| taint_test.py:71 | fail | test_taint | request.files['key'].stream |
|
||||
| taint_test.py:72 | ok | test_taint | request.files.getlist(..) |
|
||||
| taint_test.py:73 | fail | test_taint | request.files.getlist(..)[0].filename |
|
||||
| taint_test.py:74 | fail | test_taint | request.files.getlist(..)[0].stream |
|
||||
| taint_test.py:77 | ok | test_taint | request.form |
|
||||
| taint_test.py:78 | ok | test_taint | request.form['key'] |
|
||||
| taint_test.py:79 | ok | test_taint | request.form.getlist(..) |
|
||||
| taint_test.py:81 | ok | test_taint | request.get_data() |
|
||||
| taint_test.py:83 | ok | test_taint | request.get_json() |
|
||||
| taint_test.py:84 | ok | test_taint | request.get_json()['foo'] |
|
||||
| taint_test.py:85 | ok | test_taint | request.get_json()['foo']['bar'] |
|
||||
| taint_test.py:89 | ok | test_taint | request.headers |
|
||||
| taint_test.py:90 | ok | test_taint | request.headers['key'] |
|
||||
| taint_test.py:91 | fail | test_taint | request.headers.get_all(..) |
|
||||
| taint_test.py:92 | fail | test_taint | request.headers.getlist(..) |
|
||||
| taint_test.py:93 | ok | test_taint | list(..) |
|
||||
| taint_test.py:94 | fail | test_taint | request.headers.to_wsgi_list() |
|
||||
| taint_test.py:96 | ok | test_taint | request.json |
|
||||
| taint_test.py:97 | ok | test_taint | request.json['foo'] |
|
||||
| taint_test.py:98 | ok | test_taint | request.json['foo']['bar'] |
|
||||
| taint_test.py:100 | ok | test_taint | request.method |
|
||||
| taint_test.py:102 | ok | test_taint | request.mimetype |
|
||||
| taint_test.py:104 | ok | test_taint | request.mimetype_params |
|
||||
| taint_test.py:106 | ok | test_taint | request.origin |
|
||||
| taint_test.py:109 | ok | test_taint | request.pragma |
|
||||
| taint_test.py:111 | ok | test_taint | request.query_string |
|
||||
| taint_test.py:113 | ok | test_taint | request.referrer |
|
||||
| taint_test.py:115 | ok | test_taint | request.remote_addr |
|
||||
| taint_test.py:117 | ok | test_taint | request.remote_user |
|
||||
| taint_test.py:120 | ok | test_taint | request.stream |
|
||||
| taint_test.py:121 | ok | test_taint | request.input_stream |
|
||||
| taint_test.py:123 | ok | test_taint | request.url |
|
||||
| taint_test.py:125 | ok | test_taint | request.user_agent |
|
||||
| taint_test.py:128 | ok | test_taint | request.values |
|
||||
| taint_test.py:129 | ok | test_taint | request.values['key'] |
|
||||
| taint_test.py:130 | ok | test_taint | request.values.getlist(..) |
|
||||
| taint_test.py:133 | ok | test_taint | request.view_args |
|
||||
| taint_test.py:134 | ok | test_taint | request.view_args['key'] |
|
||||
| taint_test.py:138 | ok | test_taint | request.script_root |
|
||||
| taint_test.py:139 | ok | test_taint | request.url_root |
|
||||
| taint_test.py:143 | ok | test_taint | request.charset |
|
||||
| taint_test.py:144 | ok | test_taint | request.url_charset |
|
||||
| taint_test.py:148 | ok | test_taint | request.date |
|
||||
| taint_test.py:151 | ok | test_taint | request.endpoint |
|
||||
| taint_test.py:156 | ok | test_taint | request.host |
|
||||
| taint_test.py:157 | ok | test_taint | request.host_url |
|
||||
| taint_test.py:159 | ok | test_taint | request.scheme |
|
||||
| taint_test.py:161 | ok | test_taint | request.script_root |
|
||||
| taint_test.py:169 | ok | test_taint | request.args |
|
||||
| taint_test.py:170 | ok | test_taint | a |
|
||||
| taint_test.py:171 | ok | test_taint | b |
|
||||
| taint_test.py:173 | ok | test_taint | request.args['key'] |
|
||||
| taint_test.py:174 | ok | test_taint | a['key'] |
|
||||
| taint_test.py:175 | ok | test_taint | b['key'] |
|
||||
| taint_test.py:177 | ok | test_taint | request.args.getlist(..) |
|
||||
| taint_test.py:178 | ok | test_taint | a.getlist(..) |
|
||||
| taint_test.py:179 | ok | test_taint | b.getlist(..) |
|
||||
| taint_test.py:180 | ok | test_taint | gl(..) |
|
||||
| taint_test.py:187 | ok | test_taint | req.path |
|
||||
| taint_test.py:188 | ok | test_taint | gd() |
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import flask
|
||||
|
||||
from flask import Flask, request, make_response
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/") # $routeSetup="/"
|
||||
def hello_world(): # $routeHandler
|
||||
return "Hello World!"
|
||||
|
||||
from flask.views import MethodView
|
||||
|
||||
class MyView(MethodView):
|
||||
|
||||
def get(self, user_id): # $f-:routeHandler
|
||||
if user_id is None:
|
||||
# return a list of users
|
||||
pass
|
||||
else:
|
||||
# expose a single user
|
||||
pass
|
||||
|
||||
the_view = MyView.as_view('my_view')
|
||||
|
||||
app.add_url_rule('/the/', defaults={'user_id': None}, # $routeSetup="/the/"
|
||||
view_func=the_view, methods=['GET',])
|
||||
|
||||
@app.route("/dangerous") # $routeSetup="/dangerous"
|
||||
def dangerous(): # $routeHandler
|
||||
return request.args.get('payload')
|
||||
|
||||
@app.route("/dangerous-with-cfg-split") # $routeSetup="/dangerous-with-cfg-split"
|
||||
def dangerous2(): # $routeHandler
|
||||
x = request.form['param0']
|
||||
if request.method == "POST":
|
||||
return request.form['param1']
|
||||
return None
|
||||
|
||||
@app.route("/unsafe") # $routeSetup="/unsafe"
|
||||
def unsafe(): # $routeHandler
|
||||
first_name = request.args.get('name', '')
|
||||
return make_response("Your name is " + first_name)
|
||||
|
||||
@app.route("/safe") # $routeSetup="/safe"
|
||||
def safe(): # $routeHandler
|
||||
first_name = request.args.get('name', '')
|
||||
return make_response("Your name is " + escape(first_name))
|
||||
|
||||
@app.route("/hello/<name>") # $routeSetup="/hello/<name>"
|
||||
def hello(name): # $routeHandler $routedParameter=name
|
||||
return make_response("Your name is " + name)
|
||||
|
||||
@app.route("/foo/<path:subpath>") # $routeSetup="/foo/<path:subpath>"
|
||||
def foo(subpath): # $routeHandler $routedParameter=subpath
|
||||
return make_response("The subpath is " + subpath)
|
||||
|
||||
@app.route("/multiple/") # $routeSetup="/multiple/"
|
||||
@app.route("/multiple/foo/<foo>") # $routeSetup="/multiple/foo/<foo>"
|
||||
@app.route("/multiple/bar/<bar>") # $routeSetup="/multiple/bar/<bar>"
|
||||
def multiple(foo=None, bar=None): # $routeHandler $routedParameter=foo $routedParameter=bar
|
||||
return make_response("foo={!r} bar={!r}".format(foo, bar))
|
||||
|
||||
@app.route("/complex/<string(length=2):lang_code>") # $routeSetup="/complex/<string(length=2):lang_code>"
|
||||
def complex(lang_code): # $routeHandler $routedParameter=lang_code
|
||||
return make_response("lang_code {}".format(lang_code))
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
||||
@@ -0,0 +1,31 @@
|
||||
import flask
|
||||
|
||||
from flask import Flask, make_response
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
SOME_ROUTE = "/some/route"
|
||||
@app.route(SOME_ROUTE) # $routeSetup="/some/route"
|
||||
def some_route(): # $routeHandler
|
||||
return make_response("some_route")
|
||||
|
||||
|
||||
def index(): # $routeHandler
|
||||
return make_response("index")
|
||||
app.add_url_rule('/index', 'index', index) # $routeSetup="/index"
|
||||
|
||||
|
||||
# We don't support this yet, and I think that's OK
|
||||
def later_set(): # $f-:routeHandler
|
||||
return make_response("later_set")
|
||||
app.add_url_rule('/later-set', 'later_set', view_func=None) # $routeSetup="/later-set"
|
||||
app.view_functions['later_set'] = later_set
|
||||
|
||||
|
||||
@app.route(UNKNOWN_ROUTE) # $routeSetup
|
||||
def unkown_route(foo, bar): # $routeHandler $routedParameter=foo $routedParameter=bar
|
||||
return make_response("unkown_route")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
||||
@@ -1,8 +1,8 @@
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/test_taint/<name>/<int:number>')
|
||||
def test_taint(name = "World!", number="0", foo="foo"):
|
||||
@app.route("/test_taint/<name>/<int:number>") # $routeSetup="/test_taint/<name>/<int:number>"
|
||||
def test_taint(name = "World!", number="0", foo="foo"): # $routeHandler $routedParameter=name $routedParameter=number
|
||||
ensure_tainted(name, number)
|
||||
ensure_not_tainted(foo)
|
||||
|
||||
@@ -191,8 +191,8 @@ def test_taint(name = "World!", number="0", foo="foo"):
|
||||
|
||||
|
||||
|
||||
@app.route('/debug/<foo>/<bar>', methods=['GET'])
|
||||
def debug(foo, bar):
|
||||
@app.route("/debug/<foo>/<bar>", methods=['GET']) # $routeSetup="/debug/<foo>/<bar>"
|
||||
def debug(foo, bar): # $routeHandler $routedParameter=foo $routedParameter=bar
|
||||
print("request.view_args", request.view_args)
|
||||
|
||||
print("request.headers {!r}".format(request.headers))
|
||||
@@ -202,8 +202,8 @@ def debug(foo, bar):
|
||||
|
||||
return 'ok'
|
||||
|
||||
@app.route('/stream', methods=['POST'])
|
||||
def stream():
|
||||
@app.route("/stream", methods=['POST']) # $routeSetup="/stream"
|
||||
def stream(): # $routeHandler
|
||||
print(request.path)
|
||||
s = request.stream
|
||||
print(s)
|
||||
@@ -212,8 +212,8 @@ def stream():
|
||||
|
||||
return 'ok'
|
||||
|
||||
@app.route('/input_stream', methods=['POST'])
|
||||
def input_stream():
|
||||
@app.route("/input_stream", methods=['POST']) # $routeSetup="/input_stream"
|
||||
def input_stream(): # $routeHandler
|
||||
print(request.path)
|
||||
s = request.input_stream
|
||||
print(s)
|
||||
@@ -223,15 +223,15 @@ def input_stream():
|
||||
|
||||
return 'ok'
|
||||
|
||||
@app.route('/form', methods=['POST'])
|
||||
def form():
|
||||
@app.route("/form", methods=['POST']) # $routeSetup="/form"
|
||||
def form(): # $routeHandler
|
||||
print(request.path)
|
||||
print("request.form", request.form)
|
||||
|
||||
return 'ok'
|
||||
|
||||
@app.route('/cache_control', methods=['POST'])
|
||||
def cache_control():
|
||||
@app.route("/cache_control", methods=['POST']) # $routeSetup="/cache_control"
|
||||
def cache_control(): # $routeHandler
|
||||
print(request.path)
|
||||
print("request.cache_control.max_age", request.cache_control.max_age, type(request.cache_control.max_age))
|
||||
print("request.cache_control.max_stale", request.cache_control.max_stale, type(request.cache_control.max_stale))
|
||||
@@ -239,16 +239,16 @@ def cache_control():
|
||||
|
||||
return 'ok'
|
||||
|
||||
@app.route('/file_upload', methods=['POST'])
|
||||
def file_upload():
|
||||
@app.route("/file_upload", methods=['POST']) # $routeSetup="/file_upload"
|
||||
def file_upload(): # $routeHandler
|
||||
print(request.path)
|
||||
for k,v in request.files.items():
|
||||
print(k, v, v.name, v.filename, v.stream)
|
||||
|
||||
return 'ok'
|
||||
|
||||
@app.route('/args', methods=['GET'])
|
||||
def args():
|
||||
@app.route("/args", methods=['GET']) # $routeSetup="/args"
|
||||
def args(): # $routeHandler
|
||||
print(request.path)
|
||||
print("request.args", request.args)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1,39 @@
|
||||
"""tests for the 'invoke' package
|
||||
|
||||
see https://www.pyinvoke.org/
|
||||
"""
|
||||
|
||||
import invoke
|
||||
|
||||
invoke.run("cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
invoke.run(command="cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
|
||||
|
||||
def with_sudo():
|
||||
invoke.sudo("cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
invoke.sudo(command="cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
|
||||
|
||||
def manual_context():
|
||||
c = invoke.Context()
|
||||
c.run("cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
c.sudo("cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
|
||||
# invoke.Context is just an alias for invoke.context.Context
|
||||
c2 = invoke.context.Context()
|
||||
c2.run("cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
|
||||
|
||||
manual_context()
|
||||
|
||||
|
||||
def foo_helper(c):
|
||||
c.run("cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
|
||||
|
||||
# for use with the 'invoke' command-line tool
|
||||
@invoke.task
|
||||
def foo(c):
|
||||
# 'c' is a invoke.context.Context
|
||||
c.run("cmd1; cmd2") # $getCommand="cmd1; cmd2"
|
||||
foo_helper(c)
|
||||
@@ -0,0 +1,2 @@
|
||||
# exec statement is Python 2 specific
|
||||
exec "print(42)" # $getCode="print(42)"
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --max-import-depth=1 --lang=2
|
||||
@@ -0,0 +1,4 @@
|
||||
import builtins
|
||||
|
||||
# exec being part of builtins is Python 3 only
|
||||
builtins.exec("print(42)") # $getCode="print(42)"
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --max-import-depth=1 --lang=3
|
||||
@@ -0,0 +1,39 @@
|
||||
# without this, `eval("print(42)")` becomes invalid syntax in Python 2, since print is a
|
||||
# statement
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
import builtins
|
||||
if sys.version_info[0] == 2:
|
||||
import __builtin__ as builtins
|
||||
|
||||
exec("print(42)") # $getCode="print(42)"
|
||||
eval("print(42)") # $getCode="print(42)"
|
||||
|
||||
builtins.eval("print(42)") # $getCode="print(42)"
|
||||
|
||||
cmd = compile("print(42)", "<filename>", "exec")
|
||||
exec(cmd) # $getCode=cmd
|
||||
|
||||
cmd = builtins.compile("print(42)", "<filename>", "exec")
|
||||
exec(cmd) # $getCode=cmd
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# taint related
|
||||
|
||||
|
||||
def test_additional_taint():
|
||||
src = TAINTED_STRING
|
||||
|
||||
cmd1 = compile(src, "<filename>", "exec")
|
||||
cmd2 = compile(source=src, filename="<filename>", mode="exec")
|
||||
cmd3 = builtins.compile(src, "<filename>", "exec")
|
||||
|
||||
ensure_tainted(
|
||||
src,
|
||||
cmd1,
|
||||
cmd2,
|
||||
cmd3,
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
# without this, `eval("print(42)")` becomes invalid syntax in Python 2, since print is a
|
||||
# statement
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
def eval(*args, **kwargs):
|
||||
raise Exception("no eval")
|
||||
|
||||
|
||||
# This function call might be marked as a code execution, but it actually isn't.
|
||||
eval("print(42)") # $f+:getCode="print(42)"
|
||||
@@ -0,0 +1,13 @@
|
||||
# without this, `eval("print(42)")` becomes invalid syntax in Python 2, since print is a
|
||||
# statement
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
def foo(*args, **kwargs):
|
||||
raise Exception("no eval")
|
||||
|
||||
|
||||
eval = foo
|
||||
|
||||
# This function call might be marked as a code execution, but it actually isn't.
|
||||
eval("print(42)") # $f+:getCode="print(42)"
|
||||
@@ -0,0 +1,19 @@
|
||||
# without this, `eval("print(42)")` becomes invalid syntax in Python 2, since print is a
|
||||
# statement
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
import builtins
|
||||
if sys.version_info[0] == 2:
|
||||
import __builtin__ as builtins
|
||||
|
||||
|
||||
def foo(*args, **kwargs):
|
||||
raise Exception("no eval")
|
||||
|
||||
|
||||
builtins.eval = foo
|
||||
|
||||
# This function call might be marked as a code execution, but it actually isn't.
|
||||
eval("print(42)") # $f+:getCode="print(42)"
|
||||
@@ -0,0 +1,4 @@
|
||||
| CodeExecution.py:35 | ok | test_additional_taint | src |
|
||||
| CodeExecution.py:36 | ok | test_additional_taint | cmd1 |
|
||||
| CodeExecution.py:37 | ok | test_additional_taint | cmd2 |
|
||||
| CodeExecution.py:38 | ok | test_additional_taint | cmd3 |
|
||||
@@ -0,0 +1,2 @@
|
||||
import experimental.dataflow.tainttracking.TestTaintLib
|
||||
import experimental.dataflow.RemoteFlowSources
|
||||
@@ -22,8 +22,8 @@ class SystemCommandExecutionTest extends InlineExpectationsTest {
|
||||
override string getARelevantTag() { result = "getCommand" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(SystemCommandExecution sce, DataFlow::Node command |
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
command = sce.getCommand() and
|
||||
location = command.getLocation() and
|
||||
element = command.toString() and
|
||||
@@ -32,3 +32,56 @@ class SystemCommandExecutionTest extends InlineExpectationsTest {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class CodeExecutionTest extends InlineExpectationsTest {
|
||||
CodeExecutionTest() { this = "CodeExecutionTest" }
|
||||
|
||||
override string getARelevantTag() { result = "getCode" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(CodeExecution ce, DataFlow::Node code |
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
code = ce.getCode() and
|
||||
location = code.getLocation() and
|
||||
element = code.toString() and
|
||||
value = value_from_expr(code.asExpr()) and
|
||||
tag = "getCode"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class HttpServerRouteSetupTest extends InlineExpectationsTest {
|
||||
HttpServerRouteSetupTest() { this = "HttpServerRouteSetupTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["routeSetup", "routeHandler", "routedParameter"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(HTTP::Server::RouteSetup setup |
|
||||
location = setup.getLocation() and
|
||||
element = setup.toString() and
|
||||
(
|
||||
value = "\"" + setup.getUrlPattern() + "\""
|
||||
or
|
||||
not exists(setup.getUrlPattern()) and
|
||||
value = ""
|
||||
) and
|
||||
tag = "routeSetup"
|
||||
)
|
||||
or
|
||||
exists(HTTP::Server::RouteSetup setup, Function func |
|
||||
func = setup.getARouteHandler() and
|
||||
location = func.getLocation() and
|
||||
element = func.toString() and
|
||||
value = "" and
|
||||
tag = "routeHandler"
|
||||
)
|
||||
or
|
||||
exists(HTTP::Server::RouteSetup setup, Parameter param |
|
||||
param = setup.getARoutedParameter() and
|
||||
location = param.getLocation() and
|
||||
element = param.toString() and
|
||||
value = param.asName().getId() and
|
||||
tag = "routedParameter"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
edges
|
||||
| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:7:10:7:13 | ControlFlowNode for code |
|
||||
| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:8:10:8:13 | ControlFlowNode for code |
|
||||
| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:10:10:10:12 | ControlFlowNode for cmd |
|
||||
nodes
|
||||
| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| code_injection.py:7:10:7:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code |
|
||||
| code_injection.py:8:10:8:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code |
|
||||
| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
|
||||
#select
|
||||
| code_injection.py:7:10:7:13 | ControlFlowNode for code | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:7:10:7:13 | ControlFlowNode for code | $@ flows to here and is interpreted as code. | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | A user-provided value |
|
||||
| code_injection.py:8:10:8:13 | ControlFlowNode for code | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:8:10:8:13 | ControlFlowNode for code | $@ flows to here and is interpreted as code. | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | A user-provided value |
|
||||
| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | $@ flows to here and is interpreted as code. | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | A user-provided value |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security-new-dataflow/CWE-094/CodeInjection.ql
|
||||
@@ -0,0 +1,10 @@
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/code-execution")
|
||||
def code_execution():
|
||||
code = request.args.get("code")
|
||||
exec(code)
|
||||
eval(code)
|
||||
cmd = compile(code, "<filename>", "exec")
|
||||
exec(cmd)
|
||||
Reference in New Issue
Block a user