mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Merge pull request #17566 from yoff/python/dict-can-take-multiple-args
Python: All dict constructor args are relevant
This commit is contained in:
@@ -368,14 +368,13 @@ abstract class DataFlowFunction extends DataFlowCallable, TFunction {
|
||||
int positionalOffset() { result = 0 }
|
||||
|
||||
override ParameterNode getParameter(ParameterPosition ppos) {
|
||||
// Do not handle lower bound positions (such as `[1..]`) here
|
||||
// they are handled by parameter matching and would create
|
||||
// inconsistencies here as multiple parameters could match such a position.
|
||||
exists(int index | ppos.isPositional(index) |
|
||||
result.getParameter() = func.getArg(index + this.positionalOffset())
|
||||
)
|
||||
or
|
||||
exists(int index1, int index2 | ppos.isPositionalLowerBound(index1) and index2 >= index1 |
|
||||
result.getParameter() = func.getArg(index2 + this.positionalOffset())
|
||||
)
|
||||
or
|
||||
exists(string name | ppos.isKeyword(name) | result.getParameter() = func.getArgByName(name))
|
||||
or
|
||||
// `*args`
|
||||
|
||||
@@ -4235,7 +4235,11 @@ module StdlibPrivate {
|
||||
// ---------------------------------------------------------------------------
|
||||
// Flow summaries for functions contructing containers
|
||||
// ---------------------------------------------------------------------------
|
||||
/** A flow summary for `dict`. */
|
||||
/**
|
||||
* A flow summary for `dict`.
|
||||
*
|
||||
* see https://docs.python.org/3/library/stdtypes.html#dict
|
||||
*/
|
||||
class DictSummary extends SummarizedCallable {
|
||||
DictSummary() { this = "builtins.dict" }
|
||||
|
||||
@@ -4246,18 +4250,23 @@ module StdlibPrivate {
|
||||
}
|
||||
|
||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||
// The positional argument contains a mapping.
|
||||
// TODO: Add the list-of-pairs version
|
||||
// TODO: these values can be overwritten by keyword arguments
|
||||
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
|
||||
input = "Argument[0].DictionaryElement[" + key + "]" and
|
||||
output = "ReturnValue.DictionaryElement[" + key + "]" and
|
||||
preservesValue = true
|
||||
)
|
||||
or
|
||||
// The keyword arguments are added to the dictionary.
|
||||
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
|
||||
input = "Argument[" + key + ":]" and
|
||||
output = "ReturnValue.DictionaryElement[" + key + "]" and
|
||||
preservesValue = true
|
||||
)
|
||||
or
|
||||
// Imprecise content in any argument ends up on the container itself.
|
||||
input = "Argument[0]" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = false
|
||||
|
||||
@@ -142,6 +142,14 @@ def test_dict_from_dict():
|
||||
SINK(d2["k"]) #$ flow="SOURCE, l:-2 -> d2['k']"
|
||||
SINK_F(d2["k1"])
|
||||
|
||||
@expects(4)
|
||||
def test_dict_from_multiple_args():
|
||||
d = dict([("k", SOURCE), ("k1", NONSOURCE)], k2 = SOURCE, k3 = NONSOURCE)
|
||||
SINK(d["k"]) #$ MISSING: flow="SOURCE, l:-1 -> d['k']"
|
||||
SINK_F(d["k1"])
|
||||
SINK(d["k2"]) #$ flow="SOURCE, l:-3 -> d['k2']"
|
||||
SINK_F(d["k3"])
|
||||
|
||||
## Container methods
|
||||
|
||||
### List
|
||||
|
||||
Reference in New Issue
Block a user