Merge branch 'main' into python-flask-routed-parameter

This commit is contained in:
Rasmus Wriedt Larsen
2020-10-14 10:16:00 +02:00
370 changed files with 33139 additions and 5610 deletions

View File

@@ -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). */
@@ -115,11 +115,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 +126,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
)
}
/**

View 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)) }
}

View File

@@ -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."
}
}

View File

@@ -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. */
@@ -170,6 +165,9 @@ module EssaFlow {
nodeTo.(EssaNode).getVar() = p.getVariable() and
nodeFrom.(EssaNode).getVar() = p.getAnInput()
)
or
// If expressions
nodeFrom.asCfgNode() = nodeTo.asCfgNode().(IfExprNode).getAnOperand()
}
predicate useToNextUse(NameNode nodeFrom, NameNode nodeTo) {

View File

@@ -5,6 +5,7 @@
private import python
private import DataFlowPrivate
import experimental.dataflow.TypeTracker
import Attributes
private import semmle.python.essa.SsaCompute
/**
@@ -22,7 +23,7 @@ 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
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 */
@@ -103,7 +104,7 @@ class EssaNode extends Node, TEssaNode {
}
class CfgNode extends Node, TCfgNode {
DataFlowCfgNode node;
ControlFlowNode node;
CfgNode() { this = TCfgNode(node) }

View File

@@ -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.getAnImportedModuleName() = name)
}

View File

@@ -20,7 +20,7 @@ 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))
}
@@ -33,7 +33,7 @@ private 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()

View File

@@ -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)`

View File

@@ -15,3 +15,4 @@ uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -29,128 +29,132 @@ edges
| datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] |
| datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] | datamodel.py:159:6:159:17 | ControlFlowNode for Attribute |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:36:21:36:26 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:50:9:50:14 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:84:10:84:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:91:10:91:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:101:10:101:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:106:22:106:27 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:111:10:111:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:49:9:49:14 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:81:10:81:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:87:10:87:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:97:10:97:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:102:22:102:27 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:107:10:107:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:119:10:119:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:124:10:124:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:129:10:129:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:134:22:134:27 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:139:10:139:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:152:15:152:20 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:157:15:157:20 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:184:23:184:28 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:189:25:189:30 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:200:34:200:39 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:344:11:344:16 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:348:11:348:16 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:352:16:352:21 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:375:28:375:33 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:457:12:457:17 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:462:28:462:33 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:504:9:504:14 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:129:22:129:27 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:134:10:134:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:146:15:146:20 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:151:15:151:20 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:177:23:177:28 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:182:25:182:30 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:193:34:193:39 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:330:11:330:16 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:334:11:334:16 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:338:16:338:21 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:361:28:361:33 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:414:10:414:15 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:422:34:422:39 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:446:12:446:17 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:453:28:453:33 | ControlFlowNode for SOURCE |
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:502:9:502:14 | ControlFlowNode for SOURCE |
| test.py:14:1:14:6 | GSSA Variable SOURCE | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test |
| test.py:14:10:14:17 | ControlFlowNode for Str | test.py:14:1:14:6 | GSSA Variable SOURCE |
| test.py:36:10:36:26 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:37:9:37:9 | ControlFlowNode for x [Tuple element at index 1] |
| test.py:36:21:36:26 | ControlFlowNode for SOURCE | test.py:36:10:36:26 | ControlFlowNode for Tuple [Tuple element at index 1] |
| test.py:37:9:37:9 | ControlFlowNode for x [Tuple element at index 1] | test.py:37:9:37:12 | ControlFlowNode for Subscript |
| test.py:37:9:37:12 | ControlFlowNode for Subscript | test.py:38:10:38:10 | ControlFlowNode for y |
| test.py:50:9:50:14 | ControlFlowNode for SOURCE | test.py:51:10:51:10 | ControlFlowNode for x |
| test.py:57:9:57:16 | ControlFlowNode for Str | test.py:58:10:58:10 | ControlFlowNode for x |
| test.py:62:9:62:17 | ControlFlowNode for Str | test.py:63:10:63:10 | ControlFlowNode for x |
| test.py:67:9:67:10 | ControlFlowNode for IntegerLiteral | test.py:68:10:68:10 | ControlFlowNode for x |
| test.py:72:9:72:12 | ControlFlowNode for FloatLiteral | test.py:73:10:73:10 | ControlFlowNode for x |
| test.py:84:10:84:15 | ControlFlowNode for SOURCE | test.py:85:10:85:10 | ControlFlowNode for x |
| test.py:91:9:91:16 | ControlFlowNode for List [List element] | test.py:92:10:92:10 | ControlFlowNode for x [List element] |
| test.py:91:10:91:15 | ControlFlowNode for SOURCE | test.py:91:9:91:16 | ControlFlowNode for List [List element] |
| test.py:92:10:92:10 | ControlFlowNode for x [List element] | test.py:92:10:92:13 | ControlFlowNode for Subscript |
| test.py:101:9:101:37 | ControlFlowNode for ListComp [List element] | test.py:102:10:102:10 | ControlFlowNode for x [List element] |
| test.py:101:10:101:15 | ControlFlowNode for SOURCE | test.py:101:9:101:37 | ControlFlowNode for ListComp [List element] |
| test.py:102:10:102:10 | ControlFlowNode for x [List element] | test.py:102:10:102:13 | ControlFlowNode for Subscript |
| test.py:106:9:106:29 | ControlFlowNode for ListComp [List element] | test.py:107:10:107:10 | ControlFlowNode for x [List element] |
| test.py:106:10:106:10 | ControlFlowNode for y | test.py:106:9:106:29 | ControlFlowNode for ListComp [List element] |
| test.py:106:16:106:16 | SSA variable y | test.py:106:10:106:10 | ControlFlowNode for y |
| test.py:106:21:106:28 | ControlFlowNode for List [List element] | test.py:106:16:106:16 | SSA variable y |
| test.py:106:22:106:27 | ControlFlowNode for SOURCE | test.py:106:21:106:28 | ControlFlowNode for List [List element] |
| test.py:107:10:107:10 | ControlFlowNode for x [List element] | test.py:107:10:107:13 | ControlFlowNode for Subscript |
| test.py:111:9:111:16 | ControlFlowNode for List [List element] | test.py:112:21:112:21 | ControlFlowNode for l [List element] |
| test.py:111:10:111:15 | ControlFlowNode for SOURCE | test.py:111:9:111:16 | ControlFlowNode for List [List element] |
| test.py:112:9:112:22 | ControlFlowNode for ListComp [List element] | test.py:113:10:113:10 | ControlFlowNode for x [List element] |
| test.py:112:10:112:10 | ControlFlowNode for y | test.py:112:9:112:22 | ControlFlowNode for ListComp [List element] |
| test.py:112:16:112:16 | SSA variable y | test.py:112:10:112:10 | ControlFlowNode for y |
| test.py:112:21:112:21 | ControlFlowNode for l [List element] | test.py:112:16:112:16 | SSA variable y |
| test.py:113:10:113:10 | ControlFlowNode for x [List element] | test.py:113:10:113:13 | ControlFlowNode for Subscript |
| test.py:124:9:124:16 | ControlFlowNode for Set [List element] | test.py:125:10:125:10 | ControlFlowNode for x [List element] |
| test.py:124:10:124:15 | ControlFlowNode for SOURCE | test.py:124:9:124:16 | ControlFlowNode for Set [List element] |
| test.py:125:10:125:10 | ControlFlowNode for x [List element] | test.py:125:10:125:16 | ControlFlowNode for Attribute() |
| test.py:129:9:129:37 | ControlFlowNode for SetComp [Set element] | test.py:130:10:130:10 | ControlFlowNode for x [Set element] |
| test.py:129:10:129:15 | ControlFlowNode for SOURCE | test.py:129:9:129:37 | ControlFlowNode for SetComp [Set element] |
| test.py:49:9:49:14 | ControlFlowNode for SOURCE | test.py:50:10:50:10 | ControlFlowNode for x |
| test.py:55:9:55:16 | ControlFlowNode for Str | test.py:56:10:56:10 | ControlFlowNode for x |
| test.py:60:9:60:17 | ControlFlowNode for Str | test.py:61:10:61:10 | ControlFlowNode for x |
| test.py:65:9:65:10 | ControlFlowNode for IntegerLiteral | test.py:66:10:66:10 | ControlFlowNode for x |
| test.py:70:9:70:12 | ControlFlowNode for FloatLiteral | test.py:71:10:71:10 | ControlFlowNode for x |
| test.py:81:10:81:15 | ControlFlowNode for SOURCE | test.py:82:10:82:10 | ControlFlowNode for x |
| test.py:87:9:87:16 | ControlFlowNode for List [List element] | test.py:88:10:88:10 | ControlFlowNode for x [List element] |
| test.py:87:10:87:15 | ControlFlowNode for SOURCE | test.py:87:9:87:16 | ControlFlowNode for List [List element] |
| test.py:88:10:88:10 | ControlFlowNode for x [List element] | test.py:88:10:88:13 | ControlFlowNode for Subscript |
| test.py:97:9:97:37 | ControlFlowNode for ListComp [List element] | test.py:98:10:98:10 | ControlFlowNode for x [List element] |
| test.py:97:10:97:15 | ControlFlowNode for SOURCE | test.py:97:9:97:37 | ControlFlowNode for ListComp [List element] |
| test.py:98:10:98:10 | ControlFlowNode for x [List element] | test.py:98:10:98:13 | ControlFlowNode for Subscript |
| test.py:102:9:102:29 | ControlFlowNode for ListComp [List element] | test.py:103:10:103:10 | ControlFlowNode for x [List element] |
| test.py:102:10:102:10 | ControlFlowNode for y | test.py:102:9:102:29 | ControlFlowNode for ListComp [List element] |
| test.py:102:16:102:16 | SSA variable y | test.py:102:10:102:10 | ControlFlowNode for y |
| test.py:102:21:102:28 | ControlFlowNode for List [List element] | test.py:102:16:102:16 | SSA variable y |
| test.py:102:22:102:27 | ControlFlowNode for SOURCE | test.py:102:21:102:28 | ControlFlowNode for List [List element] |
| test.py:103:10:103:10 | ControlFlowNode for x [List element] | test.py:103:10:103:13 | ControlFlowNode for Subscript |
| test.py:107:9:107:16 | ControlFlowNode for List [List element] | test.py:108:21:108:21 | ControlFlowNode for l [List element] |
| test.py:107:10:107:15 | ControlFlowNode for SOURCE | test.py:107:9:107:16 | ControlFlowNode for List [List element] |
| test.py:108:9:108:22 | ControlFlowNode for ListComp [List element] | test.py:109:10:109:10 | ControlFlowNode for x [List element] |
| test.py:108:10:108:10 | ControlFlowNode for y | test.py:108:9:108:22 | ControlFlowNode for ListComp [List element] |
| test.py:108:16:108:16 | SSA variable y | test.py:108:10:108:10 | ControlFlowNode for y |
| test.py:108:21:108:21 | ControlFlowNode for l [List element] | test.py:108:16:108:16 | SSA variable y |
| test.py:109:10:109:10 | ControlFlowNode for x [List element] | test.py:109:10:109:13 | ControlFlowNode for Subscript |
| test.py:119:9:119:16 | ControlFlowNode for Set [List element] | test.py:120:10:120:10 | ControlFlowNode for x [List element] |
| test.py:119:10:119:15 | ControlFlowNode for SOURCE | test.py:119:9:119:16 | ControlFlowNode for Set [List element] |
| test.py:120:10:120:10 | ControlFlowNode for x [List element] | test.py:120:10:120:16 | ControlFlowNode for Attribute() |
| test.py:124:9:124:37 | ControlFlowNode for SetComp [Set element] | test.py:125:10:125:10 | ControlFlowNode for x [Set element] |
| test.py:124:10:124:15 | ControlFlowNode for SOURCE | test.py:124:9:124:37 | ControlFlowNode for SetComp [Set element] |
| test.py:125:10:125:10 | ControlFlowNode for x [Set element] | test.py:125:10:125:16 | ControlFlowNode for Attribute() |
| test.py:129:9:129:29 | ControlFlowNode for SetComp [Set element] | test.py:130:10:130:10 | ControlFlowNode for x [Set element] |
| test.py:129:10:129:10 | ControlFlowNode for y | test.py:129:9:129:29 | ControlFlowNode for SetComp [Set element] |
| test.py:129:16:129:16 | SSA variable y | test.py:129:10:129:10 | ControlFlowNode for y |
| test.py:129:21:129:28 | ControlFlowNode for List [List element] | test.py:129:16:129:16 | SSA variable y |
| test.py:129:22:129:27 | ControlFlowNode for SOURCE | test.py:129:21:129:28 | ControlFlowNode for List [List element] |
| test.py:130:10:130:10 | ControlFlowNode for x [Set element] | test.py:130:10:130:16 | ControlFlowNode for Attribute() |
| test.py:134:9:134:29 | ControlFlowNode for SetComp [Set element] | test.py:135:10:135:10 | ControlFlowNode for x [Set element] |
| test.py:134:10:134:10 | ControlFlowNode for y | test.py:134:9:134:29 | ControlFlowNode for SetComp [Set element] |
| test.py:134:16:134:16 | SSA variable y | test.py:134:10:134:10 | ControlFlowNode for y |
| test.py:134:21:134:28 | ControlFlowNode for List [List element] | test.py:134:16:134:16 | SSA variable y |
| test.py:134:22:134:27 | ControlFlowNode for SOURCE | test.py:134:21:134:28 | ControlFlowNode for List [List element] |
| test.py:135:10:135:10 | ControlFlowNode for x [Set element] | test.py:135:10:135:16 | ControlFlowNode for Attribute() |
| test.py:139:9:139:16 | ControlFlowNode for Set [List element] | test.py:140:21:140:21 | ControlFlowNode for l [List element] |
| test.py:139:10:139:15 | ControlFlowNode for SOURCE | test.py:139:9:139:16 | ControlFlowNode for Set [List element] |
| test.py:140:9:140:22 | ControlFlowNode for SetComp [Set element] | test.py:141:10:141:10 | ControlFlowNode for x [Set element] |
| test.py:140:10:140:10 | ControlFlowNode for y | test.py:140:9:140:22 | ControlFlowNode for SetComp [Set element] |
| test.py:140:16:140:16 | SSA variable y | test.py:140:10:140:10 | ControlFlowNode for y |
| test.py:140:21:140:21 | ControlFlowNode for l [List element] | test.py:140:16:140:16 | SSA variable y |
| test.py:141:10:141:10 | ControlFlowNode for x [Set element] | test.py:141:10:141:16 | ControlFlowNode for Attribute() |
| test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] |
| test.py:152:15:152:20 | ControlFlowNode for SOURCE | test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:153:10:153:15 | ControlFlowNode for Subscript |
| test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] |
| test.py:157:15:157:20 | ControlFlowNode for SOURCE | test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:158:10:158:19 | ControlFlowNode for Attribute() |
| test.py:184:9:184:42 | ControlFlowNode for ListComp [List element] | test.py:185:10:185:10 | ControlFlowNode for x [List element] |
| test.py:184:10:184:10 | ControlFlowNode for y | test.py:184:9:184:42 | ControlFlowNode for ListComp [List element] |
| test.py:184:16:184:16 | SSA variable z [List element] | test.py:184:41:184:41 | ControlFlowNode for z [List element] |
| test.py:184:21:184:30 | ControlFlowNode for List [List element, List element] | test.py:184:16:184:16 | SSA variable z [List element] |
| test.py:184:22:184:29 | ControlFlowNode for List [List element] | test.py:184:21:184:30 | ControlFlowNode for List [List element, List element] |
| test.py:184:23:184:28 | ControlFlowNode for SOURCE | test.py:184:22:184:29 | ControlFlowNode for List [List element] |
| test.py:184:36:184:36 | SSA variable y | test.py:184:10:184:10 | ControlFlowNode for y |
| test.py:184:41:184:41 | ControlFlowNode for z [List element] | test.py:184:36:184:36 | SSA variable y |
| test.py:185:10:185:10 | ControlFlowNode for x [List element] | test.py:185:10:185:13 | ControlFlowNode for Subscript |
| test.py:189:9:189:68 | ControlFlowNode for ListComp [List element] | test.py:190:10:190:10 | ControlFlowNode for x [List element] |
| test.py:189:10:189:10 | ControlFlowNode for y | test.py:189:9:189:68 | ControlFlowNode for ListComp [List element] |
| test.py:189:16:189:16 | SSA variable v [List element, List element, ... (3)] | test.py:189:45:189:45 | ControlFlowNode for v [List element, List element, ... (3)] |
| test.py:189:21:189:34 | ControlFlowNode for List [List element, List element, ... (4)] | test.py:189:16:189:16 | SSA variable v [List element, List element, ... (3)] |
| test.py:189:22:189:33 | ControlFlowNode for List [List element, List element, ... (3)] | test.py:189:21:189:34 | ControlFlowNode for List [List element, List element, ... (4)] |
| test.py:189:23:189:32 | ControlFlowNode for List [List element, List element] | test.py:189:22:189:33 | ControlFlowNode for List [List element, List element, ... (3)] |
| test.py:189:24:189:31 | ControlFlowNode for List [List element] | test.py:189:23:189:32 | ControlFlowNode for List [List element, List element] |
| test.py:189:25:189:30 | ControlFlowNode for SOURCE | test.py:189:24:189:31 | ControlFlowNode for List [List element] |
| test.py:189:40:189:40 | SSA variable u [List element, List element] | test.py:189:56:189:56 | ControlFlowNode for u [List element, List element] |
| test.py:189:45:189:45 | ControlFlowNode for v [List element, List element, ... (3)] | test.py:189:40:189:40 | SSA variable u [List element, List element] |
| test.py:189:51:189:51 | SSA variable z [List element] | test.py:189:67:189:67 | ControlFlowNode for z [List element] |
| test.py:189:56:189:56 | ControlFlowNode for u [List element, List element] | test.py:189:51:189:51 | SSA variable z [List element] |
| test.py:189:62:189:62 | SSA variable y | test.py:189:10:189:10 | ControlFlowNode for y |
| test.py:189:67:189:67 | ControlFlowNode for z [List element] | test.py:189:62:189:62 | SSA variable y |
| test.py:190:10:190:10 | ControlFlowNode for x [List element] | test.py:190:10:190:13 | ControlFlowNode for Subscript |
| test.py:200:9:200:42 | ControlFlowNode for ListComp [List element] | test.py:201:10:201:10 | ControlFlowNode for x [List element] |
| test.py:200:10:200:10 | ControlFlowNode for y | test.py:200:9:200:42 | ControlFlowNode for ListComp [List element] |
| test.py:200:16:200:16 | SSA variable y | test.py:200:10:200:10 | ControlFlowNode for y |
| test.py:200:22:200:22 | ControlFlowNode for z | test.py:200:22:200:40 | ControlFlowNode for GeneratorExp [List element] |
| test.py:200:22:200:40 | ControlFlowNode for GeneratorExp [List element] | test.py:200:16:200:16 | SSA variable y |
| test.py:200:28:200:28 | SSA variable z | test.py:200:22:200:22 | ControlFlowNode for z |
| test.py:200:33:200:40 | ControlFlowNode for List [List element] | test.py:200:28:200:28 | SSA variable z |
| test.py:200:34:200:39 | ControlFlowNode for SOURCE | test.py:200:33:200:40 | ControlFlowNode for List [List element] |
| test.py:201:10:201:10 | ControlFlowNode for x [List element] | test.py:201:10:201:13 | ControlFlowNode for Subscript |
| test.py:344:11:344:16 | ControlFlowNode for SOURCE | test.py:344:11:344:17 | ControlFlowNode for Tuple [Tuple element at index 0] |
| test.py:344:11:344:17 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:344:10:344:21 | ControlFlowNode for Subscript |
| test.py:348:10:348:17 | ControlFlowNode for List [List element] | test.py:348:10:348:20 | ControlFlowNode for Subscript |
| test.py:348:11:348:16 | ControlFlowNode for SOURCE | test.py:348:10:348:17 | ControlFlowNode for List [List element] |
| test.py:352:10:352:22 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:352:10:352:27 | ControlFlowNode for Subscript |
| test.py:352:16:352:21 | ControlFlowNode for SOURCE | test.py:352:10:352:22 | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:375:28:375:33 | ControlFlowNode for SOURCE | test.py:375:10:375:34 | ControlFlowNode for second() |
| test.py:457:12:457:17 | ControlFlowNode for SOURCE | test.py:457:10:457:18 | ControlFlowNode for f() |
| test.py:462:28:462:33 | ControlFlowNode for SOURCE | test.py:462:10:462:34 | ControlFlowNode for second() |
| test.py:504:9:504:14 | ControlFlowNode for SOURCE | test.py:506:10:506:10 | ControlFlowNode for a |
| test.py:504:9:504:14 | ControlFlowNode for SOURCE | test.py:511:10:511:10 | ControlFlowNode for b |
| test.py:134:9:134:16 | ControlFlowNode for Set [List element] | test.py:135:21:135:21 | ControlFlowNode for l [List element] |
| test.py:134:10:134:15 | ControlFlowNode for SOURCE | test.py:134:9:134:16 | ControlFlowNode for Set [List element] |
| test.py:135:9:135:22 | ControlFlowNode for SetComp [Set element] | test.py:136:10:136:10 | ControlFlowNode for x [Set element] |
| test.py:135:10:135:10 | ControlFlowNode for y | test.py:135:9:135:22 | ControlFlowNode for SetComp [Set element] |
| test.py:135:16:135:16 | SSA variable y | test.py:135:10:135:10 | ControlFlowNode for y |
| test.py:135:21:135:21 | ControlFlowNode for l [List element] | test.py:135:16:135:16 | SSA variable y |
| test.py:136:10:136:10 | ControlFlowNode for x [Set element] | test.py:136:10:136:16 | ControlFlowNode for Attribute() |
| test.py:146:9:146:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:147:10:147:10 | ControlFlowNode for x [Dictionary element at key s] |
| test.py:146:15:146:20 | ControlFlowNode for SOURCE | test.py:146:9:146:21 | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:147:10:147:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:147:10:147:15 | ControlFlowNode for Subscript |
| test.py:151:9:151:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:152:10:152:10 | ControlFlowNode for x [Dictionary element at key s] |
| test.py:151:15:151:20 | ControlFlowNode for SOURCE | test.py:151:9:151:21 | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:152:10:152:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:152:10:152:19 | ControlFlowNode for Attribute() |
| test.py:177:9:177:42 | ControlFlowNode for ListComp [List element] | test.py:178:10:178:10 | ControlFlowNode for x [List element] |
| test.py:177:10:177:10 | ControlFlowNode for y | test.py:177:9:177:42 | ControlFlowNode for ListComp [List element] |
| test.py:177:16:177:16 | SSA variable z [List element] | test.py:177:41:177:41 | ControlFlowNode for z [List element] |
| test.py:177:21:177:30 | ControlFlowNode for List [List element, List element] | test.py:177:16:177:16 | SSA variable z [List element] |
| test.py:177:22:177:29 | ControlFlowNode for List [List element] | test.py:177:21:177:30 | ControlFlowNode for List [List element, List element] |
| test.py:177:23:177:28 | ControlFlowNode for SOURCE | test.py:177:22:177:29 | ControlFlowNode for List [List element] |
| test.py:177:36:177:36 | SSA variable y | test.py:177:10:177:10 | ControlFlowNode for y |
| test.py:177:41:177:41 | ControlFlowNode for z [List element] | test.py:177:36:177:36 | SSA variable y |
| test.py:178:10:178:10 | ControlFlowNode for x [List element] | test.py:178:10:178:13 | ControlFlowNode for Subscript |
| test.py:182:9:182:68 | ControlFlowNode for ListComp [List element] | test.py:183:10:183:10 | ControlFlowNode for x [List element] |
| test.py:182:10:182:10 | ControlFlowNode for y | test.py:182:9:182:68 | ControlFlowNode for ListComp [List element] |
| test.py:182:16:182:16 | SSA variable v [List element, List element, ... (3)] | test.py:182:45:182:45 | ControlFlowNode for v [List element, List element, ... (3)] |
| test.py:182:21:182:34 | ControlFlowNode for List [List element, List element, ... (4)] | test.py:182:16:182:16 | SSA variable v [List element, List element, ... (3)] |
| test.py:182:22:182:33 | ControlFlowNode for List [List element, List element, ... (3)] | test.py:182:21:182:34 | ControlFlowNode for List [List element, List element, ... (4)] |
| test.py:182:23:182:32 | ControlFlowNode for List [List element, List element] | test.py:182:22:182:33 | ControlFlowNode for List [List element, List element, ... (3)] |
| test.py:182:24:182:31 | ControlFlowNode for List [List element] | test.py:182:23:182:32 | ControlFlowNode for List [List element, List element] |
| test.py:182:25:182:30 | ControlFlowNode for SOURCE | test.py:182:24:182:31 | ControlFlowNode for List [List element] |
| test.py:182:40:182:40 | SSA variable u [List element, List element] | test.py:182:56:182:56 | ControlFlowNode for u [List element, List element] |
| test.py:182:45:182:45 | ControlFlowNode for v [List element, List element, ... (3)] | test.py:182:40:182:40 | SSA variable u [List element, List element] |
| test.py:182:51:182:51 | SSA variable z [List element] | test.py:182:67:182:67 | ControlFlowNode for z [List element] |
| test.py:182:56:182:56 | ControlFlowNode for u [List element, List element] | test.py:182:51:182:51 | SSA variable z [List element] |
| test.py:182:62:182:62 | SSA variable y | test.py:182:10:182:10 | ControlFlowNode for y |
| test.py:182:67:182:67 | ControlFlowNode for z [List element] | test.py:182:62:182:62 | SSA variable y |
| test.py:183:10:183:10 | ControlFlowNode for x [List element] | test.py:183:10:183:13 | ControlFlowNode for Subscript |
| test.py:193:9:193:42 | ControlFlowNode for ListComp [List element] | test.py:194:10:194:10 | ControlFlowNode for x [List element] |
| test.py:193:10:193:10 | ControlFlowNode for y | test.py:193:9:193:42 | ControlFlowNode for ListComp [List element] |
| test.py:193:16:193:16 | SSA variable y | test.py:193:10:193:10 | ControlFlowNode for y |
| test.py:193:22:193:22 | ControlFlowNode for z | test.py:193:22:193:40 | ControlFlowNode for GeneratorExp [List element] |
| test.py:193:22:193:40 | ControlFlowNode for GeneratorExp [List element] | test.py:193:16:193:16 | SSA variable y |
| test.py:193:28:193:28 | SSA variable z | test.py:193:22:193:22 | ControlFlowNode for z |
| test.py:193:33:193:40 | ControlFlowNode for List [List element] | test.py:193:28:193:28 | SSA variable z |
| test.py:193:34:193:39 | ControlFlowNode for SOURCE | test.py:193:33:193:40 | ControlFlowNode for List [List element] |
| test.py:194:10:194:10 | ControlFlowNode for x [List element] | test.py:194:10:194:13 | ControlFlowNode for Subscript |
| test.py:330:11:330:16 | ControlFlowNode for SOURCE | test.py:330:11:330:17 | ControlFlowNode for Tuple [Tuple element at index 0] |
| test.py:330:11:330:17 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:330:10:330:21 | ControlFlowNode for Subscript |
| test.py:334:10:334:17 | ControlFlowNode for List [List element] | test.py:334:10:334:20 | ControlFlowNode for Subscript |
| test.py:334:11:334:16 | ControlFlowNode for SOURCE | test.py:334:10:334:17 | ControlFlowNode for List [List element] |
| test.py:338:10:338:22 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:338:10:338:27 | ControlFlowNode for Subscript |
| test.py:338:16:338:21 | ControlFlowNode for SOURCE | test.py:338:10:338:22 | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:361:28:361:33 | ControlFlowNode for SOURCE | test.py:361:10:361:34 | ControlFlowNode for second() |
| test.py:414:10:414:15 | ControlFlowNode for SOURCE | test.py:414:10:414:38 | ControlFlowNode for IfExp |
| test.py:422:34:422:39 | ControlFlowNode for SOURCE | test.py:422:10:422:39 | ControlFlowNode for IfExp |
| test.py:446:12:446:17 | ControlFlowNode for SOURCE | test.py:446:10:446:18 | ControlFlowNode for f() |
| test.py:453:28:453:33 | ControlFlowNode for SOURCE | test.py:453:10:453:34 | ControlFlowNode for second() |
| test.py:502:9:502:14 | ControlFlowNode for SOURCE | test.py:504:10:504:10 | ControlFlowNode for a |
| test.py:502:9:502:14 | ControlFlowNode for SOURCE | test.py:509:10:509:10 | ControlFlowNode for b |
nodes
| datamodel.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module datamodel | semmle.label | ModuleVariableNode for Global Variable SOURCE in Module datamodel |
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
@@ -179,126 +183,130 @@ nodes
| test.py:37:9:37:9 | ControlFlowNode for x [Tuple element at index 1] | semmle.label | ControlFlowNode for x [Tuple element at index 1] |
| test.py:37:9:37:12 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:38:10:38:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:50:9:50:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:51:10:51:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:57:9:57:16 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:58:10:58:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:62:9:62:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:63:10:63:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:67:9:67:10 | ControlFlowNode for IntegerLiteral | semmle.label | ControlFlowNode for IntegerLiteral |
| test.py:68:10:68:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:72:9:72:12 | ControlFlowNode for FloatLiteral | semmle.label | ControlFlowNode for FloatLiteral |
| test.py:73:10:73:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:84:10:84:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:85:10:85:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:91:9:91:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:91:10:91:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:92:10:92:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:92:10:92:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:101:9:101:37 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:101:10:101:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:102:10:102:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:102:10:102:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:106:9:106:29 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:106:10:106:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:106:16:106:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:106:21:106:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:106:22:106:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:107:10:107:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:107:10:107:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:111:9:111:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:111:10:111:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:112:9:112:22 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:112:10:112:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:112:16:112:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:112:21:112:21 | ControlFlowNode for l [List element] | semmle.label | ControlFlowNode for l [List element] |
| test.py:113:10:113:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:113:10:113:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:124:9:124:16 | ControlFlowNode for Set [List element] | semmle.label | ControlFlowNode for Set [List element] |
| test.py:49:9:49:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:50:10:50:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:55:9:55:16 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:56:10:56:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:60:9:60:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:61:10:61:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:65:9:65:10 | ControlFlowNode for IntegerLiteral | semmle.label | ControlFlowNode for IntegerLiteral |
| test.py:66:10:66:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:70:9:70:12 | ControlFlowNode for FloatLiteral | semmle.label | ControlFlowNode for FloatLiteral |
| test.py:71:10:71:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:81:10:81:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:82:10:82:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:87:9:87:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:87:10:87:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:88:10:88:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:88:10:88:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:97:9:97:37 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:97:10:97:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:98:10:98:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:98:10:98:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:102:9:102:29 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:102:10:102:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:102:16:102:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:102:21:102:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:102:22:102:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:103:10:103:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:103:10:103:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:107:9:107:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:107:10:107:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:108:9:108:22 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:108:10:108:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:108:16:108:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:108:21:108:21 | ControlFlowNode for l [List element] | semmle.label | ControlFlowNode for l [List element] |
| test.py:109:10:109:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:109:10:109:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:119:9:119:16 | ControlFlowNode for Set [List element] | semmle.label | ControlFlowNode for Set [List element] |
| test.py:119:10:119:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:120:10:120:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:120:10:120:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:124:9:124:37 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
| test.py:124:10:124:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:125:10:125:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:125:10:125:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
| test.py:125:10:125:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:129:9:129:37 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
| test.py:129:10:129:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:129:9:129:29 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
| test.py:129:10:129:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:129:16:129:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:129:21:129:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:129:22:129:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:130:10:130:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
| test.py:130:10:130:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:134:9:134:29 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
| test.py:134:10:134:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:134:16:134:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:134:21:134:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:134:22:134:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:135:10:135:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
| test.py:135:10:135:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:139:9:139:16 | ControlFlowNode for Set [List element] | semmle.label | ControlFlowNode for Set [List element] |
| test.py:139:10:139:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:140:9:140:22 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
| test.py:140:10:140:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:140:16:140:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:140:21:140:21 | ControlFlowNode for l [List element] | semmle.label | ControlFlowNode for l [List element] |
| test.py:141:10:141:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
| test.py:141:10:141:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:152:15:152:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
| test.py:153:10:153:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:157:15:157:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
| test.py:158:10:158:19 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:184:9:184:42 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:184:10:184:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:184:16:184:16 | SSA variable z [List element] | semmle.label | SSA variable z [List element] |
| test.py:184:21:184:30 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
| test.py:184:22:184:29 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:184:23:184:28 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:184:36:184:36 | SSA variable y | semmle.label | SSA variable y |
| test.py:184:41:184:41 | ControlFlowNode for z [List element] | semmle.label | ControlFlowNode for z [List element] |
| test.py:185:10:185:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:185:10:185:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:189:9:189:68 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:189:10:189:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:189:16:189:16 | SSA variable v [List element, List element, ... (3)] | semmle.label | SSA variable v [List element, List element, ... (3)] |
| test.py:189:21:189:34 | ControlFlowNode for List [List element, List element, ... (4)] | semmle.label | ControlFlowNode for List [List element, List element, ... (4)] |
| test.py:189:22:189:33 | ControlFlowNode for List [List element, List element, ... (3)] | semmle.label | ControlFlowNode for List [List element, List element, ... (3)] |
| test.py:189:23:189:32 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
| test.py:189:24:189:31 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:189:25:189:30 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:189:40:189:40 | SSA variable u [List element, List element] | semmle.label | SSA variable u [List element, List element] |
| test.py:189:45:189:45 | ControlFlowNode for v [List element, List element, ... (3)] | semmle.label | ControlFlowNode for v [List element, List element, ... (3)] |
| test.py:189:51:189:51 | SSA variable z [List element] | semmle.label | SSA variable z [List element] |
| test.py:189:56:189:56 | ControlFlowNode for u [List element, List element] | semmle.label | ControlFlowNode for u [List element, List element] |
| test.py:189:62:189:62 | SSA variable y | semmle.label | SSA variable y |
| test.py:189:67:189:67 | ControlFlowNode for z [List element] | semmle.label | ControlFlowNode for z [List element] |
| test.py:190:10:190:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:190:10:190:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:200:9:200:42 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:200:10:200:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:200:16:200:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:200:22:200:22 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
| test.py:200:22:200:40 | ControlFlowNode for GeneratorExp [List element] | semmle.label | ControlFlowNode for GeneratorExp [List element] |
| test.py:200:28:200:28 | SSA variable z | semmle.label | SSA variable z |
| test.py:200:33:200:40 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:200:34:200:39 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:201:10:201:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:201:10:201:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:344:10:344:21 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:344:11:344:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:344:11:344:17 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
| test.py:348:10:348:17 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:348:10:348:20 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:348:11:348:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:352:10:352:22 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:352:10:352:27 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:352:16:352:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:375:10:375:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
| test.py:375:28:375:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:457:10:457:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
| test.py:457:12:457:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:462:10:462:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
| test.py:462:28:462:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:504:9:504:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:506:10:506:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| test.py:511:10:511:10 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
| test.py:134:9:134:16 | ControlFlowNode for Set [List element] | semmle.label | ControlFlowNode for Set [List element] |
| test.py:134:10:134:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:135:9:135:22 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
| test.py:135:10:135:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:135:16:135:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:135:21:135:21 | ControlFlowNode for l [List element] | semmle.label | ControlFlowNode for l [List element] |
| test.py:136:10:136:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
| test.py:136:10:136:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:146:9:146:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:146:15:146:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:147:10:147:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
| test.py:147:10:147:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:151:9:151:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:151:15:151:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:152:10:152:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
| test.py:152:10:152:19 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:177:9:177:42 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:177:10:177:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:177:16:177:16 | SSA variable z [List element] | semmle.label | SSA variable z [List element] |
| test.py:177:21:177:30 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
| test.py:177:22:177:29 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:177:23:177:28 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:177:36:177:36 | SSA variable y | semmle.label | SSA variable y |
| test.py:177:41:177:41 | ControlFlowNode for z [List element] | semmle.label | ControlFlowNode for z [List element] |
| test.py:178:10:178:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:178:10:178:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:182:9:182:68 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:182:10:182:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:182:16:182:16 | SSA variable v [List element, List element, ... (3)] | semmle.label | SSA variable v [List element, List element, ... (3)] |
| test.py:182:21:182:34 | ControlFlowNode for List [List element, List element, ... (4)] | semmle.label | ControlFlowNode for List [List element, List element, ... (4)] |
| test.py:182:22:182:33 | ControlFlowNode for List [List element, List element, ... (3)] | semmle.label | ControlFlowNode for List [List element, List element, ... (3)] |
| test.py:182:23:182:32 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
| test.py:182:24:182:31 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:182:25:182:30 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:182:40:182:40 | SSA variable u [List element, List element] | semmle.label | SSA variable u [List element, List element] |
| test.py:182:45:182:45 | ControlFlowNode for v [List element, List element, ... (3)] | semmle.label | ControlFlowNode for v [List element, List element, ... (3)] |
| test.py:182:51:182:51 | SSA variable z [List element] | semmle.label | SSA variable z [List element] |
| test.py:182:56:182:56 | ControlFlowNode for u [List element, List element] | semmle.label | ControlFlowNode for u [List element, List element] |
| test.py:182:62:182:62 | SSA variable y | semmle.label | SSA variable y |
| test.py:182:67:182:67 | ControlFlowNode for z [List element] | semmle.label | ControlFlowNode for z [List element] |
| test.py:183:10:183:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:183:10:183:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:193:9:193:42 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
| test.py:193:10:193:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:193:16:193:16 | SSA variable y | semmle.label | SSA variable y |
| test.py:193:22:193:22 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
| test.py:193:22:193:40 | ControlFlowNode for GeneratorExp [List element] | semmle.label | ControlFlowNode for GeneratorExp [List element] |
| test.py:193:28:193:28 | SSA variable z | semmle.label | SSA variable z |
| test.py:193:33:193:40 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:193:34:193:39 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:194:10:194:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
| test.py:194:10:194:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:330:10:330:21 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:330:11:330:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:330:11:330:17 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
| test.py:334:10:334:17 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
| test.py:334:10:334:20 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:334:11:334:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:338:10:338:22 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
| test.py:338:10:338:27 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| test.py:338:16:338:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:361:10:361:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
| test.py:361:28:361:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:414:10:414:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:414:10:414:38 | ControlFlowNode for IfExp | semmle.label | ControlFlowNode for IfExp |
| test.py:422:10:422:39 | ControlFlowNode for IfExp | semmle.label | ControlFlowNode for IfExp |
| test.py:422:34:422:39 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:446:10:446:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
| test.py:446:12:446:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:453:10:453:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
| test.py:453:28:453:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:502:9:502:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:504:10:504:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
| test.py:509:10:509:10 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
#select
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:38:6:38:17 | ControlFlowNode for f() | Flow found |
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | Flow found |
@@ -326,53 +334,57 @@ nodes
| datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | Flow found |
| test.py:38:10:38:10 | ControlFlowNode for y | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:38:10:38:10 | ControlFlowNode for y | Flow found |
| test.py:38:10:38:10 | ControlFlowNode for y | test.py:36:21:36:26 | ControlFlowNode for SOURCE | test.py:38:10:38:10 | ControlFlowNode for y | Flow found |
| test.py:51:10:51:10 | ControlFlowNode for x | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:51:10:51:10 | ControlFlowNode for x | Flow found |
| test.py:51:10:51:10 | ControlFlowNode for x | test.py:50:9:50:14 | ControlFlowNode for SOURCE | test.py:51:10:51:10 | ControlFlowNode for x | Flow found |
| test.py:58:10:58:10 | ControlFlowNode for x | test.py:57:9:57:16 | ControlFlowNode for Str | test.py:58:10:58:10 | ControlFlowNode for x | Flow found |
| test.py:63:10:63:10 | ControlFlowNode for x | test.py:62:9:62:17 | ControlFlowNode for Str | test.py:63:10:63:10 | ControlFlowNode for x | Flow found |
| test.py:68:10:68:10 | ControlFlowNode for x | test.py:67:9:67:10 | ControlFlowNode for IntegerLiteral | test.py:68:10:68:10 | ControlFlowNode for x | Flow found |
| test.py:73:10:73:10 | ControlFlowNode for x | test.py:72:9:72:12 | ControlFlowNode for FloatLiteral | test.py:73:10:73:10 | ControlFlowNode for x | Flow found |
| test.py:85:10:85:10 | ControlFlowNode for x | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:85:10:85:10 | ControlFlowNode for x | Flow found |
| test.py:85:10:85:10 | ControlFlowNode for x | test.py:84:10:84:15 | ControlFlowNode for SOURCE | test.py:85:10:85:10 | ControlFlowNode for x | Flow found |
| test.py:92:10:92:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:92:10:92:13 | ControlFlowNode for Subscript | Flow found |
| test.py:92:10:92:13 | ControlFlowNode for Subscript | test.py:91:10:91:15 | ControlFlowNode for SOURCE | test.py:92:10:92:13 | ControlFlowNode for Subscript | Flow found |
| test.py:102:10:102:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:102:10:102:13 | ControlFlowNode for Subscript | Flow found |
| test.py:102:10:102:13 | ControlFlowNode for Subscript | test.py:101:10:101:15 | ControlFlowNode for SOURCE | test.py:102:10:102:13 | ControlFlowNode for Subscript | Flow found |
| test.py:107:10:107:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:107:10:107:13 | ControlFlowNode for Subscript | Flow found |
| test.py:107:10:107:13 | ControlFlowNode for Subscript | test.py:106:22:106:27 | ControlFlowNode for SOURCE | test.py:107:10:107:13 | ControlFlowNode for Subscript | Flow found |
| test.py:113:10:113:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:113:10:113:13 | ControlFlowNode for Subscript | Flow found |
| test.py:113:10:113:13 | ControlFlowNode for Subscript | test.py:111:10:111:15 | ControlFlowNode for SOURCE | test.py:113:10:113:13 | ControlFlowNode for Subscript | Flow found |
| test.py:50:10:50:10 | ControlFlowNode for x | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:50:10:50:10 | ControlFlowNode for x | Flow found |
| test.py:50:10:50:10 | ControlFlowNode for x | test.py:49:9:49:14 | ControlFlowNode for SOURCE | test.py:50:10:50:10 | ControlFlowNode for x | Flow found |
| test.py:56:10:56:10 | ControlFlowNode for x | test.py:55:9:55:16 | ControlFlowNode for Str | test.py:56:10:56:10 | ControlFlowNode for x | Flow found |
| test.py:61:10:61:10 | ControlFlowNode for x | test.py:60:9:60:17 | ControlFlowNode for Str | test.py:61:10:61:10 | ControlFlowNode for x | Flow found |
| test.py:66:10:66:10 | ControlFlowNode for x | test.py:65:9:65:10 | ControlFlowNode for IntegerLiteral | test.py:66:10:66:10 | ControlFlowNode for x | Flow found |
| test.py:71:10:71:10 | ControlFlowNode for x | test.py:70:9:70:12 | ControlFlowNode for FloatLiteral | test.py:71:10:71:10 | ControlFlowNode for x | Flow found |
| test.py:82:10:82:10 | ControlFlowNode for x | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:82:10:82:10 | ControlFlowNode for x | Flow found |
| test.py:82:10:82:10 | ControlFlowNode for x | test.py:81:10:81:15 | ControlFlowNode for SOURCE | test.py:82:10:82:10 | ControlFlowNode for x | Flow found |
| test.py:88:10:88:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:88:10:88:13 | ControlFlowNode for Subscript | Flow found |
| test.py:88:10:88:13 | ControlFlowNode for Subscript | test.py:87:10:87:15 | ControlFlowNode for SOURCE | test.py:88:10:88:13 | ControlFlowNode for Subscript | Flow found |
| test.py:98:10:98:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:98:10:98:13 | ControlFlowNode for Subscript | Flow found |
| test.py:98:10:98:13 | ControlFlowNode for Subscript | test.py:97:10:97:15 | ControlFlowNode for SOURCE | test.py:98:10:98:13 | ControlFlowNode for Subscript | Flow found |
| test.py:103:10:103:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:103:10:103:13 | ControlFlowNode for Subscript | Flow found |
| test.py:103:10:103:13 | ControlFlowNode for Subscript | test.py:102:22:102:27 | ControlFlowNode for SOURCE | test.py:103:10:103:13 | ControlFlowNode for Subscript | Flow found |
| test.py:109:10:109:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:109:10:109:13 | ControlFlowNode for Subscript | Flow found |
| test.py:109:10:109:13 | ControlFlowNode for Subscript | test.py:107:10:107:15 | ControlFlowNode for SOURCE | test.py:109:10:109:13 | ControlFlowNode for Subscript | Flow found |
| test.py:120:10:120:16 | ControlFlowNode for Attribute() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:120:10:120:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:120:10:120:16 | ControlFlowNode for Attribute() | test.py:119:10:119:15 | ControlFlowNode for SOURCE | test.py:120:10:120:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:125:10:125:16 | ControlFlowNode for Attribute() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:125:10:125:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:125:10:125:16 | ControlFlowNode for Attribute() | test.py:124:10:124:15 | ControlFlowNode for SOURCE | test.py:125:10:125:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:130:10:130:16 | ControlFlowNode for Attribute() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:130:10:130:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:130:10:130:16 | ControlFlowNode for Attribute() | test.py:129:10:129:15 | ControlFlowNode for SOURCE | test.py:130:10:130:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:135:10:135:16 | ControlFlowNode for Attribute() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:135:10:135:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:135:10:135:16 | ControlFlowNode for Attribute() | test.py:134:22:134:27 | ControlFlowNode for SOURCE | test.py:135:10:135:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:141:10:141:16 | ControlFlowNode for Attribute() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:141:10:141:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:141:10:141:16 | ControlFlowNode for Attribute() | test.py:139:10:139:15 | ControlFlowNode for SOURCE | test.py:141:10:141:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:153:10:153:15 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:153:10:153:15 | ControlFlowNode for Subscript | Flow found |
| test.py:153:10:153:15 | ControlFlowNode for Subscript | test.py:152:15:152:20 | ControlFlowNode for SOURCE | test.py:153:10:153:15 | ControlFlowNode for Subscript | Flow found |
| test.py:158:10:158:19 | ControlFlowNode for Attribute() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:158:10:158:19 | ControlFlowNode for Attribute() | Flow found |
| test.py:158:10:158:19 | ControlFlowNode for Attribute() | test.py:157:15:157:20 | ControlFlowNode for SOURCE | test.py:158:10:158:19 | ControlFlowNode for Attribute() | Flow found |
| test.py:185:10:185:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:185:10:185:13 | ControlFlowNode for Subscript | Flow found |
| test.py:185:10:185:13 | ControlFlowNode for Subscript | test.py:184:23:184:28 | ControlFlowNode for SOURCE | test.py:185:10:185:13 | ControlFlowNode for Subscript | Flow found |
| test.py:190:10:190:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:190:10:190:13 | ControlFlowNode for Subscript | Flow found |
| test.py:190:10:190:13 | ControlFlowNode for Subscript | test.py:189:25:189:30 | ControlFlowNode for SOURCE | test.py:190:10:190:13 | ControlFlowNode for Subscript | Flow found |
| test.py:201:10:201:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:201:10:201:13 | ControlFlowNode for Subscript | Flow found |
| test.py:201:10:201:13 | ControlFlowNode for Subscript | test.py:200:34:200:39 | ControlFlowNode for SOURCE | test.py:201:10:201:13 | ControlFlowNode for Subscript | Flow found |
| test.py:344:10:344:21 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:344:10:344:21 | ControlFlowNode for Subscript | Flow found |
| test.py:344:10:344:21 | ControlFlowNode for Subscript | test.py:344:11:344:16 | ControlFlowNode for SOURCE | test.py:344:10:344:21 | ControlFlowNode for Subscript | Flow found |
| test.py:348:10:348:20 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:348:10:348:20 | ControlFlowNode for Subscript | Flow found |
| test.py:348:10:348:20 | ControlFlowNode for Subscript | test.py:348:11:348:16 | ControlFlowNode for SOURCE | test.py:348:10:348:20 | ControlFlowNode for Subscript | Flow found |
| test.py:352:10:352:27 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:352:10:352:27 | ControlFlowNode for Subscript | Flow found |
| test.py:352:10:352:27 | ControlFlowNode for Subscript | test.py:352:16:352:21 | ControlFlowNode for SOURCE | test.py:352:10:352:27 | ControlFlowNode for Subscript | Flow found |
| test.py:375:10:375:34 | ControlFlowNode for second() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:375:10:375:34 | ControlFlowNode for second() | Flow found |
| test.py:375:10:375:34 | ControlFlowNode for second() | test.py:375:28:375:33 | ControlFlowNode for SOURCE | test.py:375:10:375:34 | ControlFlowNode for second() | Flow found |
| test.py:457:10:457:18 | ControlFlowNode for f() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:457:10:457:18 | ControlFlowNode for f() | Flow found |
| test.py:457:10:457:18 | ControlFlowNode for f() | test.py:457:12:457:17 | ControlFlowNode for SOURCE | test.py:457:10:457:18 | ControlFlowNode for f() | Flow found |
| test.py:462:10:462:34 | ControlFlowNode for second() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:462:10:462:34 | ControlFlowNode for second() | Flow found |
| test.py:462:10:462:34 | ControlFlowNode for second() | test.py:462:28:462:33 | ControlFlowNode for SOURCE | test.py:462:10:462:34 | ControlFlowNode for second() | Flow found |
| test.py:506:10:506:10 | ControlFlowNode for a | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:506:10:506:10 | ControlFlowNode for a | Flow found |
| test.py:506:10:506:10 | ControlFlowNode for a | test.py:504:9:504:14 | ControlFlowNode for SOURCE | test.py:506:10:506:10 | ControlFlowNode for a | Flow found |
| test.py:511:10:511:10 | ControlFlowNode for b | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:511:10:511:10 | ControlFlowNode for b | Flow found |
| test.py:511:10:511:10 | ControlFlowNode for b | test.py:504:9:504:14 | ControlFlowNode for SOURCE | test.py:511:10:511:10 | ControlFlowNode for b | Flow found |
| test.py:130:10:130:16 | ControlFlowNode for Attribute() | test.py:129:22:129:27 | ControlFlowNode for SOURCE | test.py:130:10:130:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:136:10:136:16 | ControlFlowNode for Attribute() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:136:10:136:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:136:10:136:16 | ControlFlowNode for Attribute() | test.py:134:10:134:15 | ControlFlowNode for SOURCE | test.py:136:10:136:16 | ControlFlowNode for Attribute() | Flow found |
| test.py:147:10:147:15 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:147:10:147:15 | ControlFlowNode for Subscript | Flow found |
| test.py:147:10:147:15 | ControlFlowNode for Subscript | test.py:146:15:146:20 | ControlFlowNode for SOURCE | test.py:147:10:147:15 | ControlFlowNode for Subscript | Flow found |
| test.py:152:10:152:19 | ControlFlowNode for Attribute() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:152:10:152:19 | ControlFlowNode for Attribute() | Flow found |
| test.py:152:10:152:19 | ControlFlowNode for Attribute() | test.py:151:15:151:20 | ControlFlowNode for SOURCE | test.py:152:10:152:19 | ControlFlowNode for Attribute() | Flow found |
| test.py:178:10:178:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:178:10:178:13 | ControlFlowNode for Subscript | Flow found |
| test.py:178:10:178:13 | ControlFlowNode for Subscript | test.py:177:23:177:28 | ControlFlowNode for SOURCE | test.py:178:10:178:13 | ControlFlowNode for Subscript | Flow found |
| test.py:183:10:183:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:183:10:183:13 | ControlFlowNode for Subscript | Flow found |
| test.py:183:10:183:13 | ControlFlowNode for Subscript | test.py:182:25:182:30 | ControlFlowNode for SOURCE | test.py:183:10:183:13 | ControlFlowNode for Subscript | Flow found |
| test.py:194:10:194:13 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:194:10:194:13 | ControlFlowNode for Subscript | Flow found |
| test.py:194:10:194:13 | ControlFlowNode for Subscript | test.py:193:34:193:39 | ControlFlowNode for SOURCE | test.py:194:10:194:13 | ControlFlowNode for Subscript | Flow found |
| test.py:330:10:330:21 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:330:10:330:21 | ControlFlowNode for Subscript | Flow found |
| test.py:330:10:330:21 | ControlFlowNode for Subscript | test.py:330:11:330:16 | ControlFlowNode for SOURCE | test.py:330:10:330:21 | ControlFlowNode for Subscript | Flow found |
| test.py:334:10:334:20 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:334:10:334:20 | ControlFlowNode for Subscript | Flow found |
| test.py:334:10:334:20 | ControlFlowNode for Subscript | test.py:334:11:334:16 | ControlFlowNode for SOURCE | test.py:334:10:334:20 | ControlFlowNode for Subscript | Flow found |
| test.py:338:10:338:27 | ControlFlowNode for Subscript | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:338:10:338:27 | ControlFlowNode for Subscript | Flow found |
| test.py:338:10:338:27 | ControlFlowNode for Subscript | test.py:338:16:338:21 | ControlFlowNode for SOURCE | test.py:338:10:338:27 | ControlFlowNode for Subscript | Flow found |
| test.py:361:10:361:34 | ControlFlowNode for second() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:361:10:361:34 | ControlFlowNode for second() | Flow found |
| test.py:361:10:361:34 | ControlFlowNode for second() | test.py:361:28:361:33 | ControlFlowNode for SOURCE | test.py:361:10:361:34 | ControlFlowNode for second() | Flow found |
| test.py:414:10:414:38 | ControlFlowNode for IfExp | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:414:10:414:38 | ControlFlowNode for IfExp | Flow found |
| test.py:414:10:414:38 | ControlFlowNode for IfExp | test.py:414:10:414:15 | ControlFlowNode for SOURCE | test.py:414:10:414:38 | ControlFlowNode for IfExp | Flow found |
| test.py:422:10:422:39 | ControlFlowNode for IfExp | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:422:10:422:39 | ControlFlowNode for IfExp | Flow found |
| test.py:422:10:422:39 | ControlFlowNode for IfExp | test.py:422:34:422:39 | ControlFlowNode for SOURCE | test.py:422:10:422:39 | ControlFlowNode for IfExp | Flow found |
| test.py:446:10:446:18 | ControlFlowNode for f() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:446:10:446:18 | ControlFlowNode for f() | Flow found |
| test.py:446:10:446:18 | ControlFlowNode for f() | test.py:446:12:446:17 | ControlFlowNode for SOURCE | test.py:446:10:446:18 | ControlFlowNode for f() | Flow found |
| test.py:453:10:453:34 | ControlFlowNode for second() | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:453:10:453:34 | ControlFlowNode for second() | Flow found |
| test.py:453:10:453:34 | ControlFlowNode for second() | test.py:453:28:453:33 | ControlFlowNode for SOURCE | test.py:453:10:453:34 | ControlFlowNode for second() | Flow found |
| test.py:504:10:504:10 | ControlFlowNode for a | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:504:10:504:10 | ControlFlowNode for a | Flow found |
| test.py:504:10:504:10 | ControlFlowNode for a | test.py:502:9:502:14 | ControlFlowNode for SOURCE | test.py:504:10:504:10 | ControlFlowNode for a | Flow found |
| test.py:509:10:509:10 | ControlFlowNode for b | test.py:14:10:14:17 | ControlFlowNode for Str | test.py:509:10:509:10 | ControlFlowNode for b | Flow found |
| test.py:509:10:509:10 | ControlFlowNode for b | test.py:502:9:502:14 | ControlFlowNode for SOURCE | test.py:509:10:509:10 | ControlFlowNode for b | Flow found |

View File

@@ -6,31 +6,31 @@
| test.py:37:5:37:5 | SSA variable y | test.py:38:5:38:11 | SSA variable y |
| test.py:37:5:37:5 | SSA variable y | test.py:38:10:38:10 | ControlFlowNode for y |
| test.py:37:9:37:12 | ControlFlowNode for Subscript | test.py:37:5:37:5 | SSA variable y |
| test.py:188:1:188:53 | GSSA Variable SINK | test.py:190:5:190:8 | ControlFlowNode for SINK |
| test.py:188:1:188:53 | GSSA Variable SOURCE | test.py:189:25:189:30 | ControlFlowNode for SOURCE |
| test.py:189:5:189:5 | SSA variable x | test.py:190:10:190:10 | ControlFlowNode for x |
| test.py:189:9:189:68 | ControlFlowNode for ListComp | test.py:189:5:189:5 | SSA variable x |
| test.py:189:9:189:68 | SSA variable u | test.py:189:9:189:68 | SSA variable u |
| test.py:189:9:189:68 | SSA variable u | test.py:189:9:189:68 | SSA variable u |
| test.py:189:9:189:68 | SSA variable u | test.py:189:9:189:68 | SSA variable u |
| test.py:189:9:189:68 | SSA variable v | test.py:189:9:189:68 | SSA variable v |
| test.py:189:9:189:68 | SSA variable y | test.py:189:9:189:68 | SSA variable y |
| test.py:189:9:189:68 | SSA variable y | test.py:189:9:189:68 | SSA variable y |
| test.py:189:9:189:68 | SSA variable y | test.py:189:9:189:68 | SSA variable y |
| test.py:189:9:189:68 | SSA variable y | test.py:189:9:189:68 | SSA variable y |
| test.py:189:9:189:68 | SSA variable y | test.py:189:9:189:68 | SSA variable y |
| test.py:189:9:189:68 | SSA variable y | test.py:189:9:189:68 | SSA variable y |
| test.py:189:9:189:68 | SSA variable y | test.py:189:9:189:68 | SSA variable y |
| test.py:189:9:189:68 | SSA variable z | test.py:189:9:189:68 | SSA variable z |
| test.py:189:9:189:68 | SSA variable z | test.py:189:9:189:68 | SSA variable z |
| test.py:189:9:189:68 | SSA variable z | test.py:189:9:189:68 | SSA variable z |
| test.py:189:9:189:68 | SSA variable z | test.py:189:9:189:68 | SSA variable z |
| test.py:189:9:189:68 | SSA variable z | test.py:189:9:189:68 | SSA variable z |
| test.py:189:16:189:16 | SSA variable v | test.py:189:9:189:68 | SSA variable v |
| test.py:189:16:189:16 | SSA variable v | test.py:189:45:189:45 | ControlFlowNode for v |
| test.py:189:40:189:40 | SSA variable u | test.py:189:9:189:68 | SSA variable u |
| test.py:189:40:189:40 | SSA variable u | test.py:189:56:189:56 | ControlFlowNode for u |
| test.py:189:51:189:51 | SSA variable z | test.py:189:9:189:68 | SSA variable z |
| test.py:189:51:189:51 | SSA variable z | test.py:189:67:189:67 | ControlFlowNode for z |
| test.py:189:62:189:62 | SSA variable y | test.py:189:9:189:68 | SSA variable y |
| test.py:189:62:189:62 | SSA variable y | test.py:189:10:189:10 | ControlFlowNode for y |
| test.py:181:1:181:53 | GSSA Variable SINK | test.py:183:5:183:8 | ControlFlowNode for SINK |
| test.py:181:1:181:53 | GSSA Variable SOURCE | test.py:182:25:182:30 | ControlFlowNode for SOURCE |
| test.py:182:5:182:5 | SSA variable x | test.py:183:10:183:10 | ControlFlowNode for x |
| test.py:182:9:182:68 | ControlFlowNode for ListComp | test.py:182:5:182:5 | SSA variable x |
| test.py:182:9:182:68 | SSA variable u | test.py:182:9:182:68 | SSA variable u |
| test.py:182:9:182:68 | SSA variable u | test.py:182:9:182:68 | SSA variable u |
| test.py:182:9:182:68 | SSA variable u | test.py:182:9:182:68 | SSA variable u |
| test.py:182:9:182:68 | SSA variable v | test.py:182:9:182:68 | SSA variable v |
| test.py:182:9:182:68 | SSA variable y | test.py:182:9:182:68 | SSA variable y |
| test.py:182:9:182:68 | SSA variable y | test.py:182:9:182:68 | SSA variable y |
| test.py:182:9:182:68 | SSA variable y | test.py:182:9:182:68 | SSA variable y |
| test.py:182:9:182:68 | SSA variable y | test.py:182:9:182:68 | SSA variable y |
| test.py:182:9:182:68 | SSA variable y | test.py:182:9:182:68 | SSA variable y |
| test.py:182:9:182:68 | SSA variable y | test.py:182:9:182:68 | SSA variable y |
| test.py:182:9:182:68 | SSA variable y | test.py:182:9:182:68 | SSA variable y |
| test.py:182:9:182:68 | SSA variable z | test.py:182:9:182:68 | SSA variable z |
| test.py:182:9:182:68 | SSA variable z | test.py:182:9:182:68 | SSA variable z |
| test.py:182:9:182:68 | SSA variable z | test.py:182:9:182:68 | SSA variable z |
| test.py:182:9:182:68 | SSA variable z | test.py:182:9:182:68 | SSA variable z |
| test.py:182:9:182:68 | SSA variable z | test.py:182:9:182:68 | SSA variable z |
| test.py:182:16:182:16 | SSA variable v | test.py:182:9:182:68 | SSA variable v |
| test.py:182:16:182:16 | SSA variable v | test.py:182:45:182:45 | ControlFlowNode for v |
| test.py:182:40:182:40 | SSA variable u | test.py:182:9:182:68 | SSA variable u |
| test.py:182:40:182:40 | SSA variable u | test.py:182:56:182:56 | ControlFlowNode for u |
| test.py:182:51:182:51 | SSA variable z | test.py:182:9:182:68 | SSA variable z |
| test.py:182:51:182:51 | SSA variable z | test.py:182:67:182:67 | ControlFlowNode for z |
| test.py:182:62:182:62 | SSA variable y | test.py:182:9:182:68 | SSA variable y |
| test.py:182:62:182:62 | SSA variable y | test.py:182:10:182:10 | ControlFlowNode for y |

View File

@@ -43,16 +43,14 @@ def test_tuple_negative():
y = x[0]
SINK_F(y)
# 6.2.1. Identifiers (Names)
def test_names():
x = SOURCE
SINK(x)
# 6.2.2. Literals
def test_string_literal():
x = "source"
SINK(x)
@@ -77,16 +75,14 @@ def test_imagnumber_literal():
x = 42j
SINK(x) # Flow missing
# 6.2.3. Parenthesized forms
def test_parenthesized_form():
x = (SOURCE)
SINK(x)
# 6.2.5. List displays
def test_list_display():
x = [SOURCE]
SINK(x[0])
@@ -114,12 +110,11 @@ def test_list_comprehension_inflow():
def test_nested_list_display():
x = [* [SOURCE]]
x = [*[SOURCE]]
SINK(x[0]) # Flow missing
# 6.2.6. Set displays
def test_set_display():
x = {SOURCE}
SINK(x.pop())
@@ -142,12 +137,11 @@ def test_set_comprehension_inflow():
def test_nested_set_display():
x = {* {SOURCE}}
x = {*{SOURCE}}
SINK(x.pop()) # Flow missing
# 6.2.7. Dictionary displays
def test_dict_display():
x = {"s": SOURCE}
SINK(x["s"])
@@ -169,17 +163,16 @@ def test_dict_comprehension_pop():
def test_nested_dict_display():
x = {** {"s": SOURCE}}
x = {**{"s": SOURCE}}
SINK(x["s"]) # Flow missing
def test_nested_dict_display_pop():
x = {** {"s": SOURCE}}
x = {**{"s": SOURCE}}
SINK(x.pop("s")) # Flow missing
# Nested comprehensions
def test_nested_comprehension():
x = [y for z in [[SOURCE]] for y in z]
SINK(x[0])
@@ -200,16 +193,14 @@ def test_nested_comprehension_paren():
x = [y for y in (z for z in [SOURCE])]
SINK(x[0])
# 6.2.8. Generator expressions
def test_generator():
x = (SOURCE for y in [NONSOURCE])
SINK([*x][0]) # Flow missing
# 6.2.9. Yield expressions
def gen(x):
yield x
@@ -227,16 +218,14 @@ def test_yield_from():
g = gen_from(SOURCE)
SINK(next(g)) # Flow missing
# a statement rather than an expression, but related to generators
def test_for():
for x in gen(SOURCE):
SINK(x) # Flow missing
# 6.2.9.1. Generator-iterator methods
def test___next__():
g = gen(SOURCE)
SINK(g.__next__()) # Flow missing
@@ -266,21 +255,20 @@ def test_throw():
n = next(g)
SINK(g.throw(TypeError)) # Flow missing
# no `test_close` as `close` involves no data flow
# 6.2.9.3. Asynchronous generator functions
async def agen(x):
yield x
# 6.2.9.4. Asynchronous generator-iterator methods
# helper to run async test functions
def runa(a):
import asyncio
asyncio.run(a)
@@ -325,9 +313,8 @@ async def atest_athrow():
def test_athrow():
runa(atest_athrow())
# 6.3.1. Attribute references
class C:
a = SOURCE
@@ -335,11 +322,10 @@ class C:
def test_attribute_reference():
SINK(C.a) # Flow missing
# overriding __getattr__ should be tested by the class coverage tests
# 6.3.2. Subscriptions
def test_subscription_tuple():
SINK((SOURCE,)[0])
@@ -351,6 +337,7 @@ def test_subscription_list():
def test_subscription_mapping():
SINK({"s": SOURCE}["s"])
# overriding __getitem__ should be tested by the class coverage tests
@@ -362,11 +349,10 @@ def test_slicing():
s = l[0:1:1]
SINK(s[0]) # Flow missing
# The grammar seems to allow `l[0:1:1, 0:1]`, but the interpreter does not like it
# 6.3.4. Calls
def second(a, b):
return b
@@ -406,79 +392,92 @@ def f_extra_keyword(a, **b):
def test_call_extra_keyword():
SINK(f_extra_keyword(NONSOURCE, b=SOURCE)) # Flow missing
# return the name of the first extra keyword argument
def f_extra_keyword_flow(**a):
return [*a][0]
# call the function with our source as the name of the keyword arguemnt
def test_call_extra_keyword_flow():
SINK(f_extra_keyword_flow(**{SOURCE: None})) # Flow missing
# 6.12. Assignment expressions
def test_assignment_expression():
x = NONSOURCE
SINK(x := SOURCE) # Flow missing
# 6.13. Conditional expressions
def test_conditional_true():
SINK(SOURCE if True else NONSOURCE) # Flow missing
SINK(SOURCE if True else NONSOURCE)
def test_conditional_true_guards():
SINK_F(NONSOURCE if True else SOURCE)
def test_conditional_false():
SINK(NONSOURCE if False else SOURCE) # Flow missing
SINK(NONSOURCE if False else SOURCE)
def test_conditional_false_guards():
SINK_F(SOURCE if False else NONSOURCE)
# Condition is evaluated first, so x is SOURCE once chosen
def test_conditional_evaluation_true():
x = NONSOURCE
SINK(x if (SOURCE == (x := SOURCE)) else NONSOURCE) # Flow missing
# Condition is evaluated first, so x is SOURCE once chosen
def test_conditional_evaluation_false():
x = NONSOURCE
SINK(NONSOURCE if (NONSOURCE == (x := SOURCE)) else x) # Flow missing
# 6.14. Lambdas
def test_lambda():
def f(x): return x
def f(x):
return x
SINK(f(SOURCE))
def test_lambda_positional():
def second(a, b): return b
def second(a, b):
return b
SINK(second(NONSOURCE, SOURCE))
def test_lambda_positional_negative():
def second(a, b): return b
def second(a, b):
return b
SINK_F(second(SOURCE, NONSOURCE))
def test_lambda_keyword():
def second(a, b): return b
def second(a, b):
return b
SINK(second(NONSOURCE, b=SOURCE)) # Flow missing
def test_lambda_unpack_iterable():
def second(a, b): return b
def second(a, b):
return b
SINK(second(NONSOURCE, *[SOURCE])) # Flow missing
def test_lambda_unpack_mapping():
def second(a, b): return b
def second(a, b):
return b
SINK(second(NONSOURCE, **{"b": SOURCE})) # Flow missing
@@ -491,9 +490,8 @@ def test_lambda_extra_keyword():
f_extra_keyword = lambda a, **b: b["b"]
SINK(f_extra_keyword(NONSOURCE, b=SOURCE)) # Flow missing
# call the function with our source as the name of the keyword arguemnt
def test_lambda_extra_keyword_flow():
# return the name of the first extra keyword argument
f_extra_keyword_flow = lambda **a: [*a][0]

View File

@@ -1,20 +1,33 @@
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 |
| test3.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg.foo |
| test3.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |

View File

@@ -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) }

View File

@@ -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 |

View File

@@ -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),
)

View File

@@ -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

View File

@@ -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

View File

@@ -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 |

View File

@@ -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())
}

View File

@@ -0,0 +1,4 @@
x = tracked # $tracked
def func():
return tracked # $tracked

View File

@@ -49,6 +49,14 @@ def global_var_write_test():
write_g(x) # $tracked
use_g()
def test_import():
import mymodule
mymodule.x # $f-:tracked
y = mymodule.func() # $tracked
y # $tracked
# ------------------------------------------------------------------------------
def expects_int(x): # $int
do_int_stuff(x) # $int