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

Skip to content

Commit db23dad

Browse files
committed
Python: Allow callables to connect to calls freely
1 parent b092df4 commit db23dad

2 files changed

Lines changed: 23 additions & 22 deletions

File tree

python/ql/src/experimental/dataflow/internal/DataFlowPrivate.qll

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,18 @@ module ArgumentPassing {
270270
)
271271
}
272272

273+
predicate connects(CallNode call, CallableValue callable) {
274+
exists(DataFlowCall c |
275+
call = c.getNode() and
276+
callable = c.getCallable().getCallableValue()
277+
)
278+
}
279+
273280
/**
274281
* Gets the argument to `call` that is passed to the `n`th parameter of `callable`.
275282
*/
276283
Node getArg(CallNode call, CallableValue callable, int n) {
277-
call = callable.getACall() and
284+
connects(call, callable) and
278285
(
279286
// positional argument
280287
result = TCfgNode(call.getArg(n))
@@ -287,20 +294,14 @@ module ArgumentPassing {
287294
)
288295
or
289296
// a synthezised argument passed to the starred parameter (at position -1)
290-
exists(Function f |
291-
f = callable.getScope() and
292-
f.hasVarArg() and
293-
n = -1 and
294-
result = TPosOverflowNode(call, callable)
295-
)
297+
callable.getScope().hasVarArg() and
298+
n = -1 and
299+
result = TPosOverflowNode(call, callable)
296300
or
297301
// a synthezised argument passed to the doubly starred parameter (at position -2)
298-
exists(Function f |
299-
f = callable.getScope() and
300-
f.hasKwArg() and
301-
n = -2 and
302-
result = TKwOverflowNode(call, callable)
303-
)
302+
callable.getScope().hasKwArg() and
303+
n = -2 and
304+
result = TKwOverflowNode(call, callable)
304305
or
305306
// argument unpacked from dict
306307
exists(string name |
@@ -312,7 +313,7 @@ module ArgumentPassing {
312313

313314
/** Gets the control flow node that is passed as the `n`th overflow positional argument. */
314315
ControlFlowNode getPositionalOverflowArg(CallNode call, CallableValue callable, int n) {
315-
call = callable.getACall() and
316+
connects(call, callable) and
316317
exists(Function f, int posCount, int argNr |
317318
f = callable.getScope() and
318319
f.hasVarArg() and
@@ -325,7 +326,7 @@ module ArgumentPassing {
325326

326327
/** Gets the control flow node that is passed as the overflow keyword argument with key `key`. */
327328
ControlFlowNode getKeywordOverflowArg(CallNode call, CallableValue callable, string key) {
328-
call = callable.getACall() and
329+
connects(call, callable) and
329330
exists(Function f |
330331
f = callable.getScope() and
331332
f.hasKwArg() and
@@ -339,7 +340,7 @@ module ArgumentPassing {
339340
* It will then be passed to the `n`th parameter of `callable`.
340341
*/
341342
predicate call_unpacks(CallNode call, CallableValue callable, string name, int n) {
342-
call = callable.getACall() and
343+
connects(call, callable) and
343344
exists(Function f |
344345
f = callable.getScope() and
345346
not exists(call.getArg(n)) and // no positional arguement available

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ edges
2828
| datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] |
2929
| datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] |
3030
| datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] | datamodel.py:159:6:159:17 | ControlFlowNode for Attribute |
31-
| file://:0:0:0:0 | Data flow node | test.py:381:10:381:43 | ControlFlowNode for second() |
32-
| file://:0:0:0:0 | Data flow node | test.py:477:10:477:43 | ControlFlowNode for second() |
3331
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:42:21:42:26 | ControlFlowNode for SOURCE |
3432
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:55:9:55:14 | ControlFlowNode for SOURCE |
3533
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:87:9:87:14 | ControlFlowNode for SOURCE |
@@ -158,7 +156,8 @@ edges
158156
| test.py:344:16:344:21 | ControlFlowNode for SOURCE | test.py:344:10:344:22 | ControlFlowNode for Dict [Dictionary element at key s] |
159157
| test.py:365:28:365:33 | ControlFlowNode for SOURCE | test.py:365:10:365:34 | ControlFlowNode for second() |
160158
| test.py:373:30:373:35 | ControlFlowNode for SOURCE | test.py:373:10:373:36 | ControlFlowNode for second() |
161-
| test.py:381:30:381:42 | ControlFlowNode for Dict [Dictionary element at key b] | file://:0:0:0:0 | Data flow node |
159+
| test.py:381:10:381:43 | KwUnpacked b | test.py:381:10:381:43 | ControlFlowNode for second() |
160+
| test.py:381:30:381:42 | ControlFlowNode for Dict [Dictionary element at key b] | test.py:381:10:381:43 | KwUnpacked b |
162161
| test.py:381:36:381:41 | ControlFlowNode for SOURCE | test.py:381:30:381:42 | ControlFlowNode for Dict [Dictionary element at key b] |
163162
| test.py:389:10:389:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:389:10:389:39 | ControlFlowNode for f_extra_pos() |
164163
| test.py:389:33:389:38 | ControlFlowNode for SOURCE | test.py:389:10:389:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] |
@@ -167,7 +166,8 @@ edges
167166
| test.py:442:12:442:17 | ControlFlowNode for SOURCE | test.py:442:10:442:18 | ControlFlowNode for f() |
168167
| test.py:449:28:449:33 | ControlFlowNode for SOURCE | test.py:449:10:449:34 | ControlFlowNode for second() |
169168
| test.py:463:30:463:35 | ControlFlowNode for SOURCE | test.py:463:10:463:36 | ControlFlowNode for second() |
170-
| test.py:477:30:477:42 | ControlFlowNode for Dict [Dictionary element at key b] | file://:0:0:0:0 | Data flow node |
169+
| test.py:477:10:477:43 | KwUnpacked b | test.py:477:10:477:43 | ControlFlowNode for second() |
170+
| test.py:477:30:477:42 | ControlFlowNode for Dict [Dictionary element at key b] | test.py:477:10:477:43 | KwUnpacked b |
171171
| test.py:477:36:477:41 | ControlFlowNode for SOURCE | test.py:477:30:477:42 | ControlFlowNode for Dict [Dictionary element at key b] |
172172
| test.py:482:10:482:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:482:10:482:39 | ControlFlowNode for f_extra_pos() |
173173
| test.py:482:33:482:38 | ControlFlowNode for SOURCE | test.py:482:10:482:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] |
@@ -195,8 +195,6 @@ nodes
195195
| datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | semmle.label | ControlFlowNode for Customized() [Attribute b] |
196196
| datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] | semmle.label | ControlFlowNode for customized [Attribute b] |
197197
| datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
198-
| file://:0:0:0:0 | Data flow node | semmle.label | Data flow node |
199-
| file://:0:0:0:0 | Data flow node | semmle.label | Data flow node |
200198
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | semmle.label | ModuleVariableNode for Global Variable SOURCE in Module test |
201199
| test.py:20:1:20:6 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
202200
| test.py:20:10:20:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
@@ -321,6 +319,7 @@ nodes
321319
| test.py:373:10:373:36 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
322320
| test.py:373:30:373:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
323321
| test.py:381:10:381:43 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
322+
| test.py:381:10:381:43 | KwUnpacked b | semmle.label | KwUnpacked b |
324323
| test.py:381:30:381:42 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] |
325324
| test.py:381:36:381:41 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
326325
| test.py:389:10:389:39 | ControlFlowNode for f_extra_pos() | semmle.label | ControlFlowNode for f_extra_pos() |
@@ -336,6 +335,7 @@ nodes
336335
| test.py:463:10:463:36 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
337336
| test.py:463:30:463:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
338337
| test.py:477:10:477:43 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
338+
| test.py:477:10:477:43 | KwUnpacked b | semmle.label | KwUnpacked b |
339339
| test.py:477:30:477:42 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] |
340340
| test.py:477:36:477:41 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
341341
| test.py:482:10:482:39 | ControlFlowNode for f_extra_pos() | semmle.label | ControlFlowNode for f_extra_pos() |

0 commit comments

Comments
 (0)