mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
Python: support callbacks to library calls
TODO: The member predicate `LibraryLambdaMethod::getACall` is currently too permissive. Ideally, we would have `libraryCallHasLambdaArg` as in Ruby. But even a more precise `libraryCall` predicate might be fine.
This commit is contained in:
@@ -91,6 +91,29 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari
|
||||
|
||||
class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack;
|
||||
|
||||
private module LibraryCallbackSummaries {
|
||||
private class LibraryLambdaMethod extends SummarizedCallable {
|
||||
LibraryLambdaMethod() { this = "<library method accepting a callback>" }
|
||||
|
||||
final override CallCfgNode getACall() {
|
||||
exists(ExtractedDataFlowCall call | result.getNode() = call.getNode() |
|
||||
not exists(call.getCallable())
|
||||
)
|
||||
}
|
||||
|
||||
final override ArgumentNode getACallback() { none() }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
exists(int i |
|
||||
i in [0 .. 10] and
|
||||
input = "Argument[" + i + "]" and
|
||||
output = "Argument[" + i + "].Parameter[lambda-self]"
|
||||
) and
|
||||
preservesValue = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SummarizedCallableFromModel extends SummarizedCallable {
|
||||
string type;
|
||||
string path;
|
||||
|
||||
@@ -166,6 +166,9 @@ string getMadRepresentationSpecific(SummaryComponent sc) {
|
||||
string getParameterPosition(ParameterPosition pos) {
|
||||
pos.isSelf() and result = "self"
|
||||
or
|
||||
pos.isLambdaSelf() and
|
||||
result = "lambda-self"
|
||||
or
|
||||
exists(int i |
|
||||
pos.isPositional(i) and
|
||||
result = i.toString()
|
||||
@@ -181,6 +184,9 @@ string getParameterPosition(ParameterPosition pos) {
|
||||
string getArgumentPosition(ArgumentPosition pos) {
|
||||
pos.isSelf() and result = "self"
|
||||
or
|
||||
pos.isLambdaSelf() and
|
||||
result = "lambda-self"
|
||||
or
|
||||
exists(int i |
|
||||
pos.isPositional(i) and
|
||||
result = i.toString()
|
||||
@@ -305,6 +311,9 @@ ArgumentPosition parseParamBody(string s) {
|
||||
or
|
||||
s = "self" and
|
||||
result.isSelf()
|
||||
or
|
||||
s = "lambda-self" and
|
||||
result.isLambdaSelf()
|
||||
}
|
||||
|
||||
/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */
|
||||
@@ -321,4 +330,7 @@ ParameterPosition parseArgBody(string s) {
|
||||
or
|
||||
s = "self" and
|
||||
result.isSelf()
|
||||
or
|
||||
s = "lambda-self" and
|
||||
result.isLambdaSelf()
|
||||
}
|
||||
|
||||
@@ -45,4 +45,4 @@ def test_library_call():
|
||||
for x in map(set, [1]):
|
||||
pass
|
||||
|
||||
SINK(captured["x"]) #$ MISSING:captured
|
||||
SINK(captured["x"]) #$ captured
|
||||
|
||||
Reference in New Issue
Block a user