Skip to content

Commit 66fd43f

Browse files
committed
add def edge for function returns
1 parent d8eea7b commit 66fd43f

File tree

2 files changed

+26
-25
lines changed

2 files changed

+26
-25
lines changed

python/ql/lib/semmle/python/ApiGraphs.qll

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ module API {
7979
/**
8080
* Gets a call to the function represented by this API component.
8181
*/
82-
DataFlow::CallCfgNode getACall() { result = this.getReturn().getAnImmediateUse() } // TODO: Make a API::CallNode.
82+
DataFlow::CallCfgNode getACall() { result = this.getReturn().getAnImmediateUse() } // TODO: Make a API::CallNode. After I figure out named parameters
8383

8484
/**
8585
* Gets a node representing member `m` of this API component.
@@ -441,7 +441,6 @@ module API {
441441
)
442442
}
443443

444-
// TODO: Compare with JS, check that I'm not missing stuff
445444
/**
446445
* Holds if `rhs` is the right-hand side of a definition of a node that should have an
447446
* incoming edge from `base` labeled `lbl` in the API graph.
@@ -470,30 +469,31 @@ module API {
470469
lbl = Label::member(item.getKey().(StrConst).getS()) and
471470
rhs.asExpr() = item.getValue()
472471
)
473-
// or
474-
// special case: from `require('m')` to an export of `prop` in `m`
475-
// TODO: Figure out if this is needed.
476-
/*
477-
* exists(Import imp, Module m, string prop |
478-
* pred = imp.getImportedModuleNode() and
479-
* m = imp.getImportedModule() and
480-
* lbl = Label::member(prop) and
481-
* rhs = m.getAnExportedValue(prop)
482-
* )
483-
* or
484-
* // TODO:
485-
* exists(DataFlow::FunctionNode fn | fn = pred |
486-
* not fn.getFunction().isAsync() and
487-
* lbl = Label::return() and
488-
* rhs = fn.getAReturn()
489-
* )
490-
* or
491-
* lbl = Label::promised() and
492-
* PromiseFlow::storeStep(rhs, pred, Promises::valueProp())
493-
*/
494-
472+
or
473+
exists(CallableExpr fn | fn = pred.asExpr() |
474+
not fn.getInnerScope().isAsync() and
475+
lbl = Label::return() and
476+
exists(Return ret |
477+
rhs.asExpr() = ret.getValue() and
478+
ret.getScope() = fn.getInnerScope()
479+
)
495480
)
481+
)
496482
or
483+
// or
484+
// special case: from `require('m')` to an export of `prop` in `m`
485+
// TODO: Figure out if this is needed.
486+
/*
487+
* exists(Import imp, Module m, string prop |
488+
* pred = imp.getImportedModuleNode() and
489+
* m = imp.getImportedModule() and
490+
* lbl = Label::member(prop) and
491+
* rhs = m.getAnExportedValue(prop)
492+
* )
493+
* or
494+
* // TODO:
495+
*/
496+
497497
/*
498498
* or // TODO:
499499
* exists(DataFlow::FunctionNode f |
@@ -727,6 +727,7 @@ module API {
727727
succ = MkDef(rhs)
728728
)
729729
// TODO: Compare with JS, check that I'm not missing stuff
730+
// TODO: Port MkAsyncFuncResult?
730731
}
731732

732733
/**

python/ql/test/library-tests/ApiGraphs/deftest2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
class MyView(View): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass()
66
myvar = 45 #$ def=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("myvar")
77
def my_method(self): #$ def=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("my_method") use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("my_method").getParameter(0)
8-
pass
8+
return 3 #$ def=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("my_method").getReturn()
99

1010
instance = MyView() #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getReturn()
1111

0 commit comments

Comments
 (0)