Python: Points-to should flow through call-sites if not assigned outside of scope.

This commit is contained in:
Mark Shannon
2019-02-11 20:04:30 +00:00
parent be3191aa6b
commit 220b881096
8 changed files with 93 additions and 10 deletions

View File

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

View File

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