Python: Add flow-step for arg[1] to dict.setdefault

This commit is contained in:
Rasmus Wriedt Larsen
2023-04-24 12:29:21 +02:00
parent 7453533ba4
commit 1a97e8f329
2 changed files with 25 additions and 1 deletions

View File

@@ -3795,6 +3795,30 @@ private module StdlibPrivate {
preservesValue = true
}
}
/**
* A flow summary for `dict.setdefault`.
*
* See https://docs.python.org/3.10/library/stdtypes.html#dict.setdefault
*/
class DictSetdefaultSummary extends SummarizedCallable {
DictSetdefaultSummary() { this = "dict.setdefault" }
override DataFlow::CallCfgNode getACall() {
result.(DataFlow::MethodCallNode).calls(_, "setdefault")
}
override DataFlow::ArgumentNode getACallback() {
result.(DataFlow::AttrRead).getAttributeName() = "setdefault"
}
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
// store/read steps with dictionary content of this is modeled in DataFlowPrivate
input = "Argument[1]" and
output = "ReturnValue" and
preservesValue = true
}
}
}
// ---------------------------------------------------------------------------

View File

@@ -49,7 +49,7 @@ def test_dict_update():
def test_setdefault():
d = {}
x = d.setdefault("key", SOURCE)
SINK(x) # $ MISSING: flow="SOURCE, l:-1 -> d.setdefault(..)"
SINK(x) # $ flow="SOURCE, l:-1 -> x"
SINK(d["key"]) # $ flow="SOURCE, l:-2 -> d['key']"
SINK(d.setdefault("key", NONSOURCE)) # $ flow="SOURCE, l:-3 -> d.setdefault(..)"