|
12 | 12 | */ |
13 | 13 |
|
14 | 14 | import python |
15 | | -private import LegacyPointsTo |
| 15 | +private import semmle.python.ApiGraphs |
16 | 16 | import Definition |
17 | 17 |
|
18 | 18 | predicate is_increment(Stmt s) { |
@@ -41,23 +41,16 @@ predicate one_item_only(For f) { |
41 | 41 | ) |
42 | 42 | } |
43 | 43 |
|
44 | | -predicate points_to_call_to_range(ControlFlowNode f) { |
45 | | - /* (x)range is a function in Py2 and a class in Py3, so we must treat it as a plain object */ |
46 | | - exists(Value range | |
47 | | - range = Value::named("range") or |
48 | | - range = Value::named("xrange") |
49 | | - | |
50 | | - f = range.getACall() |
51 | | - ) |
| 44 | +/** Holds if `node` is a call to `range`, `xrange`, or `list(range(...))`. */ |
| 45 | +predicate call_to_range(DataFlow::Node node) { |
| 46 | + node = API::builtin(["range", "xrange"]).getACall() |
52 | 47 | or |
53 | | - /* In case points-to fails due to 'from six.moves import range' or similar. */ |
54 | | - exists(string range | f.getNode().(Call).getFunc().(Name).getId() = range | |
55 | | - range = "range" or range = "xrange" |
56 | | - ) |
| 48 | + /* Handle 'from six.moves import range' or similar. */ |
| 49 | + node = API::moduleImport("six").getMember("moves").getMember(["range", "xrange"]).getACall() |
57 | 50 | or |
58 | 51 | /* Handle list(range(...)) and list(list(range(...))) */ |
59 | | - f.(CallNode).(ControlFlowNodeWithPointsTo).pointsTo().getClass() = ClassValue::list() and |
60 | | - points_to_call_to_range(f.(CallNode).getArg(0)) |
| 52 | + node = API::builtin("list").getACall() and |
| 53 | + call_to_range(node.(DataFlow::CallCfgNode).getArg(0)) |
61 | 54 | } |
62 | 55 |
|
63 | 56 | /** Whether n is a use of a variable that is a not effectively a constant. */ |
@@ -102,8 +95,8 @@ from For f, Variable v, string msg |
102 | 95 | where |
103 | 96 | f.getTarget() = v.getAnAccess() and |
104 | 97 | not f.getAStmt().contains(v.getAnAccess()) and |
105 | | - not points_to_call_to_range(f.getIter().getAFlowNode()) and |
106 | | - not points_to_call_to_range(get_comp_iterable(f)) and |
| 98 | + not call_to_range(DataFlow::exprNode(f.getIter())) and |
| 99 | + not call_to_range(DataFlow::exprNode(get_comp_iterable(f).getNode())) and |
107 | 100 | not name_acceptable_for_unused_variable(v) and |
108 | 101 | not f.getScope().getName() = "genexpr" and |
109 | 102 | not empty_loop(f) and |
|
0 commit comments