Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bbf925f

Browse files
committed
Python: Magic subscript and format
(this in preparation for addressing reviews)
1 parent ca7c045 commit bbf925f

2 files changed

Lines changed: 63 additions & 6 deletions

File tree

python/ql/src/semmle/python/Magic.qll

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ module MagicMethod {
2222
/** Gets the controlflow node that would be passed as the specified argument. */
2323
abstract ControlFlowNode getArg(int n);
2424

25-
/** Gets the control flow node corresponding to the instance
26-
* that would define the magic method. */
25+
/**
26+
* Gets the control flow node corresponding to the instance
27+
* that would define the magic method.
28+
*/
2729
ControlFlowNode getSelf() { result = this.getArg(0) }
2830
}
2931

@@ -47,15 +49,63 @@ module MagicMethod {
4749
class MagicBinOp extends MagicMethod::Potential, BinaryExprNode {
4850
Operator operator;
4951

50-
MagicBinOp() { this.getOp() = operator}
52+
MagicBinOp() { this.getOp() = operator }
5153

52-
override string getMagicMethodName() {
53-
result = operator.getSpecialMethodName()
54-
}
54+
override string getMagicMethodName() { result = operator.getSpecialMethodName() }
5555

5656
override ControlFlowNode getArg(int n) {
5757
n = 0 and result = this.getLeft()
5858
or
5959
n = 1 and result = this.getRight()
6060
}
6161
}
62+
63+
/** A subscript expression node that might correspond to a magic method call. */
64+
abstract class MagicSubscript extends MagicMethod::Potential, SubscriptNode {
65+
override ControlFlowNode getArg(int n) {
66+
n = 0 and result = this.getObject()
67+
or
68+
n = 1 and result = this.getIndex()
69+
}
70+
}
71+
72+
/** A subscript expression node that might correspond to a call to __getitem__. */
73+
class MagicGetItem extends MagicSubscript {
74+
MagicGetItem() { this.isLoad() }
75+
76+
override string getMagicMethodName() { result = "__getitem__" }
77+
}
78+
79+
/** A subscript expression node that might correspond to a call to __setitem__. */
80+
class MagicSetItem extends MagicSubscript {
81+
MagicSetItem() { this.isStore() }
82+
83+
override string getMagicMethodName() { result = "__setitem__" }
84+
85+
override ControlFlowNode getArg(int n) {
86+
n = 0 and result = this.getObject()
87+
or
88+
n = 1 and result = this.getIndex()
89+
or
90+
n = 2 and result = this.getValueNode()
91+
}
92+
93+
private ControlFlowNode getValueNode() {
94+
exists(AssignStmt a |
95+
a.getATarget() = this.getNode() and
96+
result.getNode() = a.getValue()
97+
)
98+
or
99+
exists(AugAssign a |
100+
a.getTarget() = this.getNode() and
101+
result.getNode() = a.getValue()
102+
)
103+
}
104+
}
105+
106+
/** A subscript expression node that might correspond to a call to __delitem__. */
107+
class MagicDelItem extends MagicSubscript {
108+
MagicDelItem() { this.isDelete() }
109+
110+
override string getMagicMethodName() { result = "__delitem__" }
111+
}

python/ql/test/experimental/dataflow/coverage/classesCallGraph.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
| classes.py:178:7:178:28 | ControlFlowNode for frozenset() | classes.py:178:7:178:28 | ControlFlowNode for frozenset() |
44
| classes.py:182:7:182:26 | ControlFlowNode for dict() | classes.py:182:7:182:26 | ControlFlowNode for dict() |
55
| classes.py:303:28:303:51 | ControlFlowNode for dict() | classes.py:303:28:303:51 | ControlFlowNode for dict() |
6+
| classes.py:428:3:428:14 | ControlFlowNode for with_getitem | classes.py:422:19:422:22 | SSA variable self |
7+
| classes.py:428:16:428:16 | ControlFlowNode for IntegerLiteral | classes.py:422:25:422:27 | SSA variable key |
8+
| classes.py:438:3:438:14 | ControlFlowNode for with_setitem | classes.py:433:19:433:22 | SSA variable self |
9+
| classes.py:438:16:438:16 | ControlFlowNode for IntegerLiteral | classes.py:433:25:433:27 | SSA variable key |
10+
| classes.py:438:21:438:22 | ControlFlowNode for Str | classes.py:433:30:433:34 | SSA variable value |
11+
| classes.py:448:7:448:18 | ControlFlowNode for with_delitem | classes.py:443:19:443:22 | SSA variable self |
12+
| classes.py:448:20:448:20 | ControlFlowNode for IntegerLiteral | classes.py:443:25:443:27 | SSA variable key |
613
| classes.py:466:12:466:24 | ControlFlowNode for Attribute() | classes.py:466:12:466:24 | ControlFlowNode for Attribute() |
714
| classes.py:505:3:505:10 | ControlFlowNode for with_add | classes.py:499:15:499:18 | SSA variable self |
815
| classes.py:505:14:505:21 | ControlFlowNode for with_add | classes.py:499:21:499:25 | SSA variable other |

0 commit comments

Comments
 (0)