mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #928 from markshannon/python-points-to-through-callsites
Python: Points-to should flow through call-sites if not assigned out of scope.
This commit is contained in:
@@ -300,6 +300,15 @@ class EscapingGlobalVariable extends ModuleVariable {
|
||||
|
||||
}
|
||||
|
||||
class EscapingAssignmentGlobalVariable extends EscapingGlobalVariable {
|
||||
|
||||
EscapingAssignmentGlobalVariable() {
|
||||
exists(NameNode n | n.defines(this) and not n.getScope() = this.getScope())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class SpecialSsaSourceVariable extends PythonSsaSourceVariable {
|
||||
|
||||
SpecialSsaSourceVariable() {
|
||||
|
||||
@@ -1713,14 +1713,23 @@ module PointsTo {
|
||||
*/
|
||||
pragma [noinline]
|
||||
private predicate callsite_points_to(CallsiteRefinement def, PointsToContext context, Object value, ClassObject cls, ObjectOrCfg origin) {
|
||||
exists(EssaVariable var, PointsToContext callee |
|
||||
Flow::callsite_exit_value_transfer(var, callee, def, context) and
|
||||
ssa_variable_points_to(var, callee, value, cls, origin)
|
||||
exists(SsaSourceVariable srcvar |
|
||||
srcvar = def.getSourceVariable() |
|
||||
if srcvar instanceof EscapingAssignmentGlobalVariable then (
|
||||
/* If global variable can be reassigned, we need to track it through calls */
|
||||
exists(EssaVariable var, PointsToContext callee |
|
||||
Flow::callsite_exit_value_transfer(var, callee, def, context) and
|
||||
ssa_variable_points_to(var, callee, value, cls, origin)
|
||||
)
|
||||
or
|
||||
callsite_points_to_python(def, context, value, cls, origin)
|
||||
or
|
||||
callsite_points_to_builtin(def, context, value, cls, origin)
|
||||
) else (
|
||||
/* Otherwise we can assume its value (but not those of its attributes or members) has not changed. */
|
||||
ssa_variable_points_to(def.getInput(), context, value, cls, origin)
|
||||
)
|
||||
)
|
||||
or
|
||||
callsite_points_to_python(def, context, value, cls, origin)
|
||||
or
|
||||
callsite_points_to_builtin(def, context, value, cls, origin)
|
||||
}
|
||||
|
||||
pragma [noinline]
|
||||
|
||||
@@ -625,31 +625,40 @@
|
||||
| r_regressions.py:0 | __name___0 = ScopeEntryDefinition |
|
||||
| r_regressions.py:0 | __package___0 = ScopeEntryDefinition |
|
||||
| r_regressions.py:0 | _names_0 = ScopeEntryDefinition |
|
||||
| r_regressions.py:0 | _names_3 = Pi(_names_1) [false] |
|
||||
| r_regressions.py:0 | _names_4 = phi(_names_2, _names_3) |
|
||||
| r_regressions.py:0 | gv_0 = ScopeEntryDefinition |
|
||||
| r_regressions.py:0 | mod_gv_0 = ScopeEntryDefinition |
|
||||
| r_regressions.py:0 | sys_0 = ScopeEntryDefinition |
|
||||
| r_regressions.py:0 | t_0 = ScopeEntryDefinition |
|
||||
| r_regressions.py:0 | t_2 = phi(t_0, t_1) |
|
||||
| r_regressions.py:5 | Queue_0 = ClassExpr |
|
||||
| r_regressions.py:7 | __init___0 = FunctionExpr |
|
||||
| r_regressions.py:7 | gv_5 = ScopeEntryDefinition |
|
||||
| r_regressions.py:7 | self_0 = ParameterDefinition |
|
||||
| r_regressions.py:9 | gv_6 = CallsiteRefinement(gv_5) |
|
||||
| r_regressions.py:9 | self_1 = SelfCallsiteRefinement(self_0) |
|
||||
| r_regressions.py:11 | _after_fork_0 = FunctionExpr |
|
||||
| r_regressions.py:11 | gv_7 = ScopeEntryDefinition |
|
||||
| r_regressions.py:11 | self_0 = ParameterDefinition |
|
||||
| r_regressions.py:12 | self_1 = AttributeAssignment '_closed'(self_0) |
|
||||
| r_regressions.py:13 | self_2 = AttributeAssignment '_close'(self_1) |
|
||||
| r_regressions.py:15 | close_0 = FunctionExpr |
|
||||
| r_regressions.py:15 | close_4 = Pi(close_0) [false] |
|
||||
| r_regressions.py:15 | close_5 = phi(close_3, close_4) |
|
||||
| r_regressions.py:15 | gv_8 = ScopeEntryDefinition |
|
||||
| r_regressions.py:15 | gv_33 = phi(gv_9, gv_11) |
|
||||
| r_regressions.py:15 | self_0 = ParameterDefinition |
|
||||
| r_regressions.py:15 | self_3 = phi(self_1, self_2) |
|
||||
| r_regressions.py:16 | self_1 = AttributeAssignment '_closed'(self_0) |
|
||||
| r_regressions.py:18 | gv_9 = CallsiteRefinement(gv_8) |
|
||||
| r_regressions.py:20 | close_0 = Attribute |
|
||||
| r_regressions.py:20 | close_1 = Attribute |
|
||||
| r_regressions.py:20 | gv_10 = phi(gv_8, gv_9) |
|
||||
| r_regressions.py:21 | close_2 = SingleSuccessorGuard(close_1) [true] |
|
||||
| r_regressions.py:22 | close_3 = Pi(close_0) [true] |
|
||||
| r_regressions.py:22 | self_2 = AttributeAssignment '_close'(self_1) |
|
||||
| r_regressions.py:23 | gv_11 = CallsiteRefinement(gv_9) |
|
||||
| r_regressions.py:27 | f_0 = FunctionExpr |
|
||||
| r_regressions.py:27 | gv_12 = ScopeEntryDefinition |
|
||||
| r_regressions.py:27 | gv_33 = phi(gv_12, gv_13) |
|
||||
| r_regressions.py:27 | x_0 = ParameterDefinition |
|
||||
| r_regressions.py:27 | x_5 = phi(x_3, x_4) |
|
||||
| r_regressions.py:27 | y_0 = ParameterDefinition |
|
||||
@@ -664,6 +673,7 @@
|
||||
| r_regressions.py:33 | y_1 = Pi(y_0) [false] |
|
||||
| r_regressions.py:33 | y_2 = phi(y_0, y_1) |
|
||||
| r_regressions.py:36 | y_3 = Pi(y_2) [true] |
|
||||
| r_regressions.py:39 | gv_13 = CallsiteRefinement(gv_12) |
|
||||
| r_regressions.py:39 | x_4 = phi(x_1, x_3) |
|
||||
| r_regressions.py:39 | y_4 = Pi(y_0) [true] |
|
||||
| r_regressions.py:39 | y_5 = phi(y_3, y_4) |
|
||||
@@ -671,53 +681,82 @@
|
||||
| r_regressions.py:39 | z_1 = Pi(z_0) [true] |
|
||||
| r_regressions.py:39 | z_2 = phi(z_0, z_1) |
|
||||
| r_regressions.py:42 | find_library_0 = FunctionExpr |
|
||||
| r_regressions.py:42 | gv_14 = ScopeEntryDefinition |
|
||||
| r_regressions.py:42 | name_0 = ParameterDefinition |
|
||||
| r_regressions.py:43 | __0 = ... |
|
||||
| r_regressions.py:43 | data_0 = ... |
|
||||
| r_regressions.py:43 | gv_15 = CallsiteRefinement(gv_14) |
|
||||
| r_regressions.py:46 | fail_0 = FunctionExpr |
|
||||
| r_regressions.py:46 | gv_16 = ScopeEntryDefinition |
|
||||
| r_regressions.py:46 | msg_0 = ParameterDefinition |
|
||||
| r_regressions.py:49 | C_0 = ClassExpr |
|
||||
| r_regressions.py:51 | fail_0 = FunctionExpr |
|
||||
| r_regressions.py:51 | fail_1 = ScopeEntryDefinition |
|
||||
| r_regressions.py:51 | gv_17 = ScopeEntryDefinition |
|
||||
| r_regressions.py:51 | msg_0 = ParameterDefinition |
|
||||
| r_regressions.py:51 | self_0 = ParameterDefinition |
|
||||
| r_regressions.py:52 | gv_18 = CallsiteRefinement(gv_17) |
|
||||
| r_regressions.py:52 | msg_1 = ArgumentRefinement(msg_0) |
|
||||
| r_regressions.py:58 | decorator_0 = ParameterDefinition |
|
||||
| r_regressions.py:58 | gv_19 = ScopeEntryDefinition |
|
||||
| r_regressions.py:58 | method_decorator_0 = FunctionExpr |
|
||||
| r_regressions.py:58 | name_0 = ParameterDefinition |
|
||||
| r_regressions.py:61 | _dec_0 = FunctionExpr |
|
||||
| r_regressions.py:61 | func_0 = ScopeEntryDefinition |
|
||||
| r_regressions.py:61 | gv_20 = ScopeEntryDefinition |
|
||||
| r_regressions.py:61 | gv_33 = phi(gv_23, gv_25) |
|
||||
| r_regressions.py:61 | is_class_6 = phi(is_class_4, is_class_5) |
|
||||
| r_regressions.py:61 | name_1 = ScopeEntryDefinition |
|
||||
| r_regressions.py:61 | obj_0 = ParameterDefinition |
|
||||
| r_regressions.py:61 | obj_3 = phi(obj_1, obj_2) |
|
||||
| r_regressions.py:62 | gv_21 = CallsiteRefinement(gv_20) |
|
||||
| r_regressions.py:62 | is_class_0 = isinstance() |
|
||||
| r_regressions.py:62 | obj_1 = ArgumentRefinement(obj_0) |
|
||||
| r_regressions.py:64 | gv_22 = CallsiteRefinement(gv_21) |
|
||||
| r_regressions.py:64 | is_class_1 = Pi(is_class_0) [true] |
|
||||
| r_regressions.py:66 | func_1 = obj |
|
||||
| r_regressions.py:66 | is_class_2 = Pi(is_class_0) [false] |
|
||||
| r_regressions.py:68 | _wrapper_0 = FunctionExpr |
|
||||
| r_regressions.py:68 | args_0 = ParameterDefinition |
|
||||
| r_regressions.py:68 | func_2 = phi(func_0, func_1) |
|
||||
| r_regressions.py:68 | gv_23 = phi(gv_21, gv_22) |
|
||||
| r_regressions.py:68 | gv_24 = ScopeEntryDefinition |
|
||||
| r_regressions.py:68 | is_class_3 = phi(is_class_1, is_class_2) |
|
||||
| r_regressions.py:68 | kwargs_0 = ParameterDefinition |
|
||||
| r_regressions.py:68 | self_0 = ParameterDefinition |
|
||||
| r_regressions.py:73 | gv_25 = CallsiteRefinement(gv_23) |
|
||||
| r_regressions.py:73 | is_class_4 = Pi(is_class_3) [true] |
|
||||
| r_regressions.py:73 | obj_2 = ArgumentRefinement(obj_1) |
|
||||
| r_regressions.py:76 | is_class_5 = Pi(is_class_3) [false] |
|
||||
| r_regressions.py:80 | deco_0 = FunctionExpr |
|
||||
| r_regressions.py:80 | func_0 = ParameterDefinition |
|
||||
| r_regressions.py:80 | gv_26 = ScopeEntryDefinition |
|
||||
| r_regressions.py:81 | _wrapper_0 = FunctionExpr |
|
||||
| r_regressions.py:81 | args_0 = ParameterDefinition |
|
||||
| r_regressions.py:81 | gv_27 = ScopeEntryDefinition |
|
||||
| r_regressions.py:81 | kwargs_0 = ParameterDefinition |
|
||||
| r_regressions.py:85 | deco_1 = ArgumentRefinement(deco_0) |
|
||||
| r_regressions.py:85 | gv_1 = CallsiteRefinement(gv_0) |
|
||||
| r_regressions.py:85 | gv_2 = CallsiteRefinement(gv_1) |
|
||||
| r_regressions.py:86 | TestFirst_1 = method_decorator()() |
|
||||
| r_regressions.py:87 | gv_28 = ScopeEntryDefinition |
|
||||
| r_regressions.py:87 | method_0 = FunctionExpr |
|
||||
| r_regressions.py:87 | self_0 = ParameterDefinition |
|
||||
| r_regressions.py:90 | gv_3 = CallsiteRefinement(gv_2) |
|
||||
| r_regressions.py:90 | gv_4 = CallsiteRefinement(gv_3) |
|
||||
| r_regressions.py:93 | sys_1 = ImportExpr |
|
||||
| r_regressions.py:95 | _names_1 = Attribute |
|
||||
| r_regressions.py:98 | _names_2 = Pi(_names_1) [true] |
|
||||
| r_regressions.py:98 | t_1 = ImportExpr |
|
||||
| r_regressions.py:100 | _names_3 = Pi(_names_1) [false] |
|
||||
| r_regressions.py:100 | _names_4 = phi(_names_2, _names_3) |
|
||||
| r_regressions.py:100 | gv_29 = C() |
|
||||
| r_regressions.py:100 | t_2 = phi(t_0, t_1) |
|
||||
| r_regressions.py:102 | gv_30 = CallsiteRefinement(gv_29) |
|
||||
| r_regressions.py:106 | gv_31 = ScopeEntryDefinition |
|
||||
| r_regressions.py:106 | mod_gv_1 = FunctionExpr |
|
||||
| r_regressions.py:106 | x_0 = ParameterDefinition |
|
||||
| r_regressions.py:107 | gv_32 = AttributeAssignment 'attr'(gv_31) |
|
||||
| s_scopes.py:0 | __name___0 = ScopeEntryDefinition |
|
||||
| s_scopes.py:0 | __package___0 = ScopeEntryDefinition |
|
||||
| s_scopes.py:0 | float_0 = ScopeEntryDefinition |
|
||||
|
||||
@@ -164,7 +164,9 @@
|
||||
| r_regressions.py:0 | Module code.r_regressions | f | Function f |
|
||||
| r_regressions.py:0 | Module code.r_regressions | fail | Function fail |
|
||||
| r_regressions.py:0 | Module code.r_regressions | find_library | Function find_library |
|
||||
| r_regressions.py:0 | Module code.r_regressions | gv | C() |
|
||||
| r_regressions.py:0 | Module code.r_regressions | method_decorator | Function method_decorator |
|
||||
| r_regressions.py:0 | Module code.r_regressions | mod_gv | Function mod_gv |
|
||||
| r_regressions.py:0 | Module code.r_regressions | sys | Module sys |
|
||||
| r_regressions.py:0 | Module code.r_regressions | t | Module time |
|
||||
| r_regressions.py:5 | Class Queue | __init__ | Function __init__ |
|
||||
|
||||
@@ -229,3 +229,7 @@
|
||||
| r_regressions.py:64 | ControlFlowNode for do_validation() | 64 |
|
||||
| r_regressions.py:90 | ControlFlowNode for Attribute | 90 |
|
||||
| r_regressions.py:90 | ControlFlowNode for Attribute() | 90 |
|
||||
| r_regressions.py:102 | ControlFlowNode for unrelated_call | 102 |
|
||||
| r_regressions.py:102 | ControlFlowNode for unrelated_call() | 102 |
|
||||
| r_regressions.py:107 | ControlFlowNode for Attribute | 106 |
|
||||
| r_regressions.py:107 | ControlFlowNode for x | 106 |
|
||||
|
||||
@@ -998,6 +998,13 @@
|
||||
| r_regressions.py:97 | ControlFlowNode for _names | tuple object | builtin-class tuple | 95 | import |
|
||||
| r_regressions.py:98 | ControlFlowNode for ImportExpr | Module time | builtin-class module | 98 | import |
|
||||
| r_regressions.py:98 | ControlFlowNode for t | Module time | builtin-class module | 98 | import |
|
||||
| r_regressions.py:100 | ControlFlowNode for C | class C | builtin-class type | 49 | import |
|
||||
| r_regressions.py:100 | ControlFlowNode for C() | C() | class C | 100 | import |
|
||||
| r_regressions.py:100 | ControlFlowNode for gv | C() | class C | 100 | import |
|
||||
| r_regressions.py:104 | ControlFlowNode for gv | C() | class C | 100 | import |
|
||||
| r_regressions.py:106 | ControlFlowNode for FunctionExpr | Function mod_gv | builtin-class function | 106 | import |
|
||||
| r_regressions.py:106 | ControlFlowNode for mod_gv | Function mod_gv | builtin-class function | 106 | import |
|
||||
| r_regressions.py:107 | ControlFlowNode for gv | C() | class C | 100 | runtime |
|
||||
| s_scopes.py:4 | ControlFlowNode for True | bool True | builtin-class bool | 4 | import |
|
||||
| s_scopes.py:4 | ControlFlowNode for float | bool True | builtin-class bool | 4 | import |
|
||||
| s_scopes.py:7 | ControlFlowNode for C2 | class C2 | builtin-class type | 7 | import |
|
||||
|
||||
@@ -486,10 +486,12 @@
|
||||
| n_nesting.py:10 | C_5 = ScopeEntryDefinition | int 1 | builtin-class int |
|
||||
| n_nesting.py:10 | compile_ops_3 = ScopeEntryDefinition | *UNDEFINED* | *UNKNOWN TYPE* |
|
||||
| n_nesting.py:10 | inner_0 = FunctionExpr | Function inner | builtin-class function |
|
||||
| n_nesting.py:11 | C_6 = CallsiteRefinement(C_5) | int 1 | builtin-class int |
|
||||
| n_nesting.py:13 | C_7 = ScopeEntryDefinition | int 1 | builtin-class int |
|
||||
| n_nesting.py:13 | compile_ops_4 = Pi(compile_ops_1) [false] | bool True | builtin-class bool |
|
||||
| n_nesting.py:13 | compile_ops_5 = ScopeEntryDefinition | *UNDEFINED* | *UNKNOWN TYPE* |
|
||||
| n_nesting.py:13 | inner_1 = FunctionExpr | Function inner | builtin-class function |
|
||||
| n_nesting.py:14 | C_8 = CallsiteRefinement(C_7) | int 1 | builtin-class int |
|
||||
| n_nesting.py:15 | attrs_0 = Dict | Dict | builtin-class dict |
|
||||
| n_nesting.py:16 | compile_ops_6 = phi(compile_ops_2, compile_ops_4) | bool True | builtin-class bool |
|
||||
| n_nesting.py:16 | inner_2 = phi(inner_0, inner_1) | Function inner | builtin-class function |
|
||||
|
||||
@@ -96,3 +96,14 @@ _names = sys.builtin_module_names
|
||||
|
||||
if 'time' in _names:
|
||||
import time as t
|
||||
|
||||
gv = C()
|
||||
|
||||
unrelated_call()
|
||||
|
||||
gv
|
||||
|
||||
def mod_gv(x):
|
||||
gv.attr = x
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user