mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
Merge pull request #810 from markshannon/python-hide-magic-variables
Python hide magic variables
This commit is contained in:
@@ -4,6 +4,13 @@ import python
|
||||
/** A variable, either a global or local variable (including parameters) */
|
||||
class Variable extends @py_variable {
|
||||
|
||||
Variable() {
|
||||
exists(string name |
|
||||
variable(this, _, name) and
|
||||
not name = "*" and not name = "$"
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the identifier (name) of this variable */
|
||||
string getId() {
|
||||
variable(this, _, result)
|
||||
|
||||
@@ -26,7 +26,11 @@ abstract class PythonSsaSourceVariable extends SsaSourceVariable {
|
||||
}
|
||||
|
||||
override string getName() {
|
||||
result = this.(Variable).getId()
|
||||
variable(this, _, result)
|
||||
}
|
||||
|
||||
Scope getScope() {
|
||||
variable(this, result, _)
|
||||
}
|
||||
|
||||
abstract ControlFlowNode getAnImplicitUse();
|
||||
@@ -46,7 +50,7 @@ abstract class PythonSsaSourceVariable extends SsaSourceVariable {
|
||||
/* Add a use at the end of scope for all variables to keep them live
|
||||
* This is necessary for taint-tracking.
|
||||
*/
|
||||
result = this.(Variable).getScope().getANormalExit()
|
||||
result = this.getScope().getANormalExit()
|
||||
}
|
||||
|
||||
override predicate hasDefiningNode(ControlFlowNode def) {
|
||||
@@ -107,7 +111,6 @@ class FunctionLocalVariable extends PythonSsaSourceVariable {
|
||||
}
|
||||
|
||||
override ControlFlowNode getScopeEntryDefinition() {
|
||||
not this.(LocalVariable).getId() = "*" and
|
||||
exists(Scope s |
|
||||
s.getEntryNode() = result |
|
||||
s = this.(LocalVariable).getScope() and
|
||||
@@ -146,7 +149,6 @@ class NonLocalVariable extends PythonSsaSourceVariable {
|
||||
}
|
||||
|
||||
override CallNode redefinedAtCallSite() {
|
||||
not this.(LocalVariable).getId() = "*" and
|
||||
result.getScope().getScope*() = this.(LocalVariable).getScope()
|
||||
}
|
||||
|
||||
@@ -163,7 +165,6 @@ class ClassLocalVariable extends PythonSsaSourceVariable {
|
||||
}
|
||||
|
||||
override ControlFlowNode getScopeEntryDefinition() {
|
||||
not this.(LocalVariable).getId() = "*" and
|
||||
result = this.(LocalVariable).getScope().getEntryNode()
|
||||
}
|
||||
|
||||
@@ -235,7 +236,6 @@ class ModuleVariable extends PythonSsaSourceVariable {
|
||||
}
|
||||
|
||||
override ControlFlowNode getScopeEntryDefinition() {
|
||||
not this.(GlobalVariable).getId() = "*" and
|
||||
exists(Scope s |
|
||||
s.getEntryNode() = result |
|
||||
/* Module entry point */
|
||||
@@ -253,13 +253,6 @@ class ModuleVariable extends PythonSsaSourceVariable {
|
||||
this = scope.getOuterVariable(_) or
|
||||
this.(Variable).getAUse().getScope() = scope
|
||||
)
|
||||
or
|
||||
this.(GlobalVariable).getId() = "*" and
|
||||
exists(Scope s |
|
||||
s.getEntryNode() = result and
|
||||
this.(Variable).getScope() = s and
|
||||
exists(ImportStar is | is.getScope() = s)
|
||||
)
|
||||
}
|
||||
|
||||
override CallNode redefinedAtCallSite() { none() }
|
||||
@@ -307,6 +300,29 @@ class EscapingGlobalVariable extends ModuleVariable {
|
||||
|
||||
}
|
||||
|
||||
class SpecialSsaSourceVariable extends PythonSsaSourceVariable {
|
||||
|
||||
SpecialSsaSourceVariable() {
|
||||
variable(this, _, "*") or variable(this, _, "$")
|
||||
}
|
||||
|
||||
override ControlFlowNode getAnImplicitUse() {
|
||||
exists(ImportTimeScope s |
|
||||
result = s.getANormalExit() and this.getScope() = s
|
||||
)
|
||||
}
|
||||
|
||||
override ControlFlowNode getScopeEntryDefinition() {
|
||||
/* Module entry point */
|
||||
this.getScope().getEntryNode() = result
|
||||
}
|
||||
|
||||
override CallNode redefinedAtCallSite() {
|
||||
result.(CallNode).getScope().getScope*() = this.(GlobalVariable).getScope()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private predicate variable_or_attribute_defined_out_of_scope(Variable v) {
|
||||
exists(NameNode n | n.defines(v) and not n.getScope() = v.getScope())
|
||||
or
|
||||
@@ -330,7 +346,7 @@ cached module SsaSource {
|
||||
|
||||
/** Holds if `v` is used as the receiver in a method call. */
|
||||
cached predicate method_call_refinement(Variable v, ControlFlowNode use, CallNode call) {
|
||||
use = v.getAUse() and
|
||||
use = v.getAUse() and
|
||||
call.getFunction().(AttrNode).getObject() = use
|
||||
}
|
||||
|
||||
@@ -387,16 +403,17 @@ cached module SsaSource {
|
||||
/** Holds if the name of `var` refers to a submodule of a package and `f` is the entry point
|
||||
* to the __init__ module of that package.
|
||||
*/
|
||||
cached predicate init_module_submodule_defn(Variable var, ControlFlowNode f) {
|
||||
cached predicate init_module_submodule_defn(PythonSsaSourceVariable var, ControlFlowNode f) {
|
||||
var instanceof GlobalVariable and
|
||||
exists(Module init |
|
||||
init.isPackageInit() and exists(init.getPackage().getSubModule(var.getId())) and
|
||||
var instanceof GlobalVariable and init.getEntryNode() = f and
|
||||
init.isPackageInit() and exists(init.getPackage().getSubModule(var.getName())) and
|
||||
init.getEntryNode() = f and
|
||||
var.getScope() = init
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the `v` is in scope at a `from import ... *` and may thus be redefined by that statement */
|
||||
cached predicate import_star_refinement(Variable v, ControlFlowNode use, ControlFlowNode def) {
|
||||
cached predicate import_star_refinement(PythonSsaSourceVariable v, ControlFlowNode use, ControlFlowNode def) {
|
||||
use = def and def instanceof ImportStarNode
|
||||
and
|
||||
(
|
||||
@@ -443,7 +460,7 @@ cached module SsaSource {
|
||||
|
||||
}
|
||||
|
||||
private predicate refinement(Variable v, ControlFlowNode use, ControlFlowNode def) {
|
||||
private predicate refinement(PythonSsaSourceVariable v, ControlFlowNode use, ControlFlowNode def) {
|
||||
SsaSource::import_star_refinement(v, use, def)
|
||||
or
|
||||
SsaSource::attribute_assignment_refinement(v, use, def)
|
||||
@@ -456,5 +473,5 @@ private predicate refinement(Variable v, ControlFlowNode use, ControlFlowNode de
|
||||
or
|
||||
SsaSource::method_call_refinement(v, use, def)
|
||||
or
|
||||
def = v.(PythonSsaSourceVariable).redefinedAtCallSite() and def = use
|
||||
def = v.redefinedAtCallSite() and def = use
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ module PointsTo {
|
||||
or
|
||||
exists(Module init |
|
||||
init = package.getInitModule().getModule() |
|
||||
not exists(Variable v | v.getScope() = init | v.getId() = name or v.getId() = "*")
|
||||
not exists(PythonSsaSourceVariable v | v.getScope() = init | v.getName() = name or v.getName() = "*")
|
||||
or
|
||||
exists(EssaVariable v, PointsToContext imp |
|
||||
v.getScope() = init and v.getName() = "*" and v.getAUse() = init.getANormalExit() |
|
||||
@@ -145,7 +145,7 @@ module PointsTo {
|
||||
or
|
||||
not exists(EssaVariable var | var.getAUse() = m.getANormalExit() and var.getSourceVariable().getName() = name) and
|
||||
exists(EssaVariable var, PointsToContext imp |
|
||||
var.getAUse() = m.getANormalExit() and var.getSourceVariable().getName() = "*" |
|
||||
var.getAUse() = m.getANormalExit() and var.getName() = "*" |
|
||||
SSA::ssa_variable_named_attribute_points_to(var, imp, name, obj, cls, origin) and
|
||||
imp.isImport() and obj != undefinedVariable()
|
||||
)
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
| __init__.py:0 | *_0 = ScopeEntryDefinition |
|
||||
| __init__.py:0 | __name___0 = ScopeEntryDefinition |
|
||||
| __init__.py:0 | __package___0 = ScopeEntryDefinition |
|
||||
| __init__.py:0 | module2_0 = ImplicitSubModuleDefinition |
|
||||
| __init__.py:0 | moduleX_0 = ImplicitSubModuleDefinition |
|
||||
| __init__.py:0 | sys_0 = ScopeEntryDefinition |
|
||||
| __init__.py:1 | *_1 = ImportStarRefinement(*_0) |
|
||||
| __init__.py:1 | __name___1 = ImportStarRefinement(__name___0) |
|
||||
| __init__.py:1 | __package___1 = ImportStarRefinement(__package___0) |
|
||||
| __init__.py:1 | sys_1 = ImportStarRefinement(sys_0) |
|
||||
| __init__.py:2 | *_2 = ImportStarRefinement(*_1) |
|
||||
| __init__.py:2 | __name___2 = ImportStarRefinement(__name___1) |
|
||||
| __init__.py:2 | __package___2 = ImportStarRefinement(__package___1) |
|
||||
| __init__.py:2 | module_0 = ImportMember |
|
||||
@@ -498,7 +495,6 @@
|
||||
| h_classes.py:52 | arg1_0 = ParameterDefinition |
|
||||
| h_classes.py:52 | n_0 = FunctionExpr |
|
||||
| h_classes.py:52 | self_0 = ParameterDefinition |
|
||||
| i_imports.py:0 | *_0 = ScopeEntryDefinition |
|
||||
| i_imports.py:0 | BytesIO_0 = ScopeEntryDefinition |
|
||||
| i_imports.py:0 | StringIO_0 = ScopeEntryDefinition |
|
||||
| i_imports.py:0 | __name___0 = ScopeEntryDefinition |
|
||||
@@ -513,7 +509,6 @@
|
||||
| i_imports.py:3 | a_0 = IntegerLiteral |
|
||||
| i_imports.py:4 | b_0 = IntegerLiteral |
|
||||
| i_imports.py:5 | c_0 = IntegerLiteral |
|
||||
| i_imports.py:7 | *_1 = ImportStarRefinement(*_0) |
|
||||
| i_imports.py:7 | BytesIO_1 = ImportStarRefinement(BytesIO_0) |
|
||||
| i_imports.py:7 | StringIO_1 = ImportStarRefinement(StringIO_0) |
|
||||
| i_imports.py:7 | __name___1 = ImportStarRefinement(__name___0) |
|
||||
@@ -528,7 +523,6 @@
|
||||
| i_imports.py:13 | argv_1 = ImportMember |
|
||||
| i_imports.py:17 | sys_1 = ImportExpr |
|
||||
| i_imports.py:23 | code_1 = ImportExpr |
|
||||
| i_imports.py:27 | *_2 = ImportStarRefinement(*_1) |
|
||||
| i_imports.py:27 | __name___2 = ImportStarRefinement(__name___1) |
|
||||
| i_imports.py:27 | __package___2 = ImportStarRefinement(__package___1) |
|
||||
| i_imports.py:27 | a_2 = ImportStarRefinement(a_1) |
|
||||
|
||||
@@ -4,5 +4,5 @@ import python
|
||||
import Util
|
||||
|
||||
from EssaVariable v, EssaDefinition def
|
||||
where def = v.getDefinition()
|
||||
where def = v.getDefinition() and not v.getSourceVariable() instanceof SpecialSsaSourceVariable
|
||||
select locate(def.getLocation(), "abdefghijknrs_"), v.getRepresentation() + " = " + def.getRepresentation()
|
||||
|
||||
@@ -37,16 +37,6 @@
|
||||
| g_class_init.py:52 | self_3 | version | phi(self_1, self_2) | 'v2' | runtime |
|
||||
| g_class_init.py:52 | self_3 | version | phi(self_1, self_2) | 'v3' | runtime |
|
||||
| g_class_init.py:54 | self_1 | version | Pi(self_0) [true] | 'v2' | runtime |
|
||||
| i_imports.py:7 | *_1 | x | ImportStarRefinement(*_0) | float 1.0 | import |
|
||||
| i_imports.py:7 | *_1 | y | ImportStarRefinement(*_0) | float 2.0 | import |
|
||||
| i_imports.py:27 | *_2 | module1 | ImportStarRefinement(*_1) | Module code.test_package.module1 | import |
|
||||
| i_imports.py:27 | *_2 | module2 | ImportStarRefinement(*_1) | Module code.test_package.module2 | import |
|
||||
| i_imports.py:27 | *_2 | p | ImportStarRefinement(*_1) | int 1 | import |
|
||||
| i_imports.py:27 | *_2 | q | ImportStarRefinement(*_1) | int 2 | import |
|
||||
| i_imports.py:27 | *_2 | r | ImportStarRefinement(*_1) | Dict | import |
|
||||
| i_imports.py:27 | *_2 | s | ImportStarRefinement(*_1) | NoneType None | import |
|
||||
| i_imports.py:27 | *_2 | x | ImportStarRefinement(*_1) | float 1.0 | import |
|
||||
| i_imports.py:27 | *_2 | y | ImportStarRefinement(*_1) | float 2.0 | import |
|
||||
| k_getsetattr.py:6 | self_0 | a | ParameterDefinition | float 7.0 | code/k_getsetattr.py:15 from runtime |
|
||||
| k_getsetattr.py:6 | self_0 | c | ParameterDefinition | int 2 | code/k_getsetattr.py:15 from runtime |
|
||||
| k_getsetattr.py:7 | self_1 | a | ArgumentRefinement(self_0) | int 0 | code/k_getsetattr.py:15 from runtime |
|
||||
|
||||
@@ -5,7 +5,7 @@ private import semmle.python.pointsto.PointsToContext
|
||||
import Util
|
||||
|
||||
from EssaVariable var, string name, Object o, PointsToContext ctx
|
||||
where PointsTo::Test::ssa_variable_named_attribute_points_to(var, ctx, name, o, _, _)
|
||||
where PointsTo::Test::ssa_variable_named_attribute_points_to(var, ctx, name, o, _, _) and not var.getSourceVariable() instanceof SpecialSsaSourceVariable
|
||||
select
|
||||
locate(var.getDefinition().getLocation(), "abdfgikm"), var.getRepresentation(),
|
||||
name, var.getDefinition().getRepresentation(), repr(o), ctx
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
| __init__.py:0 | *_2 | Exit node for Module code.test_package.__init__ |
|
||||
| __init__.py:0 | __name___0 | Exit node for Module code.__init__ |
|
||||
| __init__.py:0 | __name___0 | Exit node for Module code.package.__init__ |
|
||||
| __init__.py:0 | __name___2 | Exit node for Module code.test_package.__init__ |
|
||||
@@ -12,11 +11,9 @@
|
||||
| __init__.py:0 | moduleX_1 | Exit node for Module code.package.__init__ |
|
||||
| __init__.py:0 | module_0 | Exit node for Module code.package.__init__ |
|
||||
| __init__.py:0 | sys_2 | Exit node for Module code.test_package.__init__ |
|
||||
| __init__.py:1 | *_0 | ControlFlowNode for from module1 import * |
|
||||
| __init__.py:1 | __name___0 | ControlFlowNode for from module1 import * |
|
||||
| __init__.py:1 | __package___0 | ControlFlowNode for from module1 import * |
|
||||
| __init__.py:1 | sys_0 | ControlFlowNode for from module1 import * |
|
||||
| __init__.py:2 | *_1 | ControlFlowNode for from module2 import * |
|
||||
| __init__.py:2 | __name___1 | ControlFlowNode for from module2 import * |
|
||||
| __init__.py:2 | __package___1 | ControlFlowNode for from module2 import * |
|
||||
| __init__.py:2 | sys_1 | ControlFlowNode for from module2 import * |
|
||||
|
||||
@@ -5,5 +5,5 @@ import semmle.python.pointsto.PointsTo
|
||||
import Util
|
||||
|
||||
from EssaVariable var, ControlFlowNode use
|
||||
where use = var.getAUse()
|
||||
where use = var.getAUse() and not var.getSourceVariable() instanceof SpecialSsaSourceVariable
|
||||
select locate(use.getLocation(), "abdeghjks_"), var.getRepresentation(), use.toString()
|
||||
|
||||
Reference in New Issue
Block a user