|
6 | 6 | private import python
|
7 | 7 | import semmle.python.dataflow.new.DataFlow::DataFlow
|
8 | 8 | private import semmle.python.dataflow.new.internal.DataFlowImplSpecific
|
| 9 | +private import semmle.python.dataflow.new.internal.DataFlowDispatch |
9 | 10 | private import semmle.python.dataflow.new.internal.TaintTrackingImplSpecific
|
10 | 11 | private import codeql.dataflow.internal.DataFlowImplConsistency
|
11 | 12 |
|
@@ -60,6 +61,45 @@ private module Input implements InputSig<PythonDataFlow> {
|
60 | 61 | isArgumentNode(arg, call, _) and
|
61 | 62 | isArgumentNode(arg, other, _)
|
62 | 63 | )
|
| 64 | + or |
| 65 | + // bound methods that refer to the same self argument. |
| 66 | + // Example: In `bm = self.foo; bm(); bm()` both bm() calls use the same `self` as |
| 67 | + // the (pos self) argument |
| 68 | + exists(AttrRead attr, DataFlowCall other | other != call | |
| 69 | + any(CfgNode n | n.asCfgNode() = call.getNode().(CallNode).getFunction()).getALocalSource() = |
| 70 | + attr and |
| 71 | + any(CfgNode n | n.asCfgNode() = other.getNode().(CallNode).getFunction()).getALocalSource() = |
| 72 | + attr and |
| 73 | + arg = call.getArgument(any(ArgumentPosition p | p.isSelf())) and |
| 74 | + arg = other.getArgument(any(ArgumentPosition p | p.isSelf())) |
| 75 | + ) |
| 76 | + or |
| 77 | + // `f = getattr(obj, "foo"); f()` where `obj` is used as (pos self) argument for |
| 78 | + // `f()` call |
| 79 | + exists(DataFlowCall getAttrCall, DataFlowCall methodCall, AttrRead attr | |
| 80 | + call in [getAttrCall, methodCall] |
| 81 | + | |
| 82 | + arg = getAttrCall.getArgument(any(ArgumentPosition p | p.isPositional(0))) and |
| 83 | + arg = methodCall.getArgument(any(ArgumentPosition p | p.isSelf())) and |
| 84 | + attr.getObject() = arg and |
| 85 | + attr.(CfgNode).getNode() = getAttrCall.getNode() |
| 86 | + ) |
| 87 | + or |
| 88 | + // In the code `super(Base, self).foo()` we use `self` as an argument in both the |
| 89 | + // super() call (pos 1) and in the .foo() call (pos self). |
| 90 | + exists(DataFlowCall superCall, DataFlowCall methodCall | call in [superCall, methodCall] | |
| 91 | + exists(superCallTwoArgumentTracker(_, arg)) and |
| 92 | + arg = superCall.getArgument(any(ArgumentPosition p | p.isPositional(1))) and |
| 93 | + arg = methodCall.getArgument(any(ArgumentPosition p | p.isSelf())) |
| 94 | + ) |
| 95 | + or |
| 96 | + // in the code `def func(self): super().foo(); super.bar()` we use `self` as the |
| 97 | + // (pos self) argument in both .foo() and .bar() calls. |
| 98 | + exists(Function f | |
| 99 | + exprNode(f.getArg(0)) = arg and |
| 100 | + call.getNode().getScope() = f and |
| 101 | + arg = call.getArgument(any(ArgumentPosition p | p.isSelf())) |
| 102 | + ) |
63 | 103 | }
|
64 | 104 | }
|
65 | 105 |
|
|
0 commit comments