From 38b1eb7c71a0dd77b59e493d3222a56f13c5ca31 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 1 Oct 2024 16:24:15 +0200 Subject: [PATCH] Python: just use `ListElementContent` for iterables --- .../dataflow/new/internal/DataFlowPrivate.qll | 27 ++----------------- .../lib/semmle/python/frameworks/Stdlib.qll | 4 +++ .../dataflow/coverage/test_builtins.py | 4 +-- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index 4d97f04d28d8..3d2329f0ad98 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -179,33 +179,10 @@ private predicate synthDictSplatArgumentNodeStoreStep( * data from `x.name` is stored into the `yield` (and can subsequently be read out of the iterable). */ predicate yieldStoreStep(Node nodeFrom, Content c, Node nodeTo) { - exists(Yield yield, Function func | + exists(Yield yield | nodeTo.asCfgNode() = yield.getAFlowNode() and nodeFrom.asCfgNode() = yield.getValue().getAFlowNode() and - func.containsInScope(yield) - | - exists(Comp comp | func = comp.getFunction() | - ( - comp instanceof ListComp or - comp instanceof GeneratorExp - ) and - c instanceof ListElementContent - or - comp instanceof SetComp and - c instanceof SetElementContent - or - comp instanceof DictComp and - c instanceof DictionaryElementAnyContent - ) - or - not exists(Comp comp | func = comp.getFunction()) and - ( - c instanceof ListElementContent - or - c instanceof SetElementContent - or - c instanceof DictionaryElementAnyContent - ) + c instanceof ListElementContent ) } diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 3c23b3929911..6d73258d65b8 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -4224,6 +4224,10 @@ module StdlibPrivate { preservesValue = true ) or + input = "Argument[0].ListElement.TupleElement[1]" and + output = "ReturnValue.DictionaryElementAny" and + preservesValue = true + or exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() | input = "Argument[" + key + ":]" and output = "ReturnValue.DictionaryElement[" + key + "]" and diff --git a/python/ql/test/library-tests/dataflow/coverage/test_builtins.py b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py index 245923370765..d0791ffae47b 100644 --- a/python/ql/test/library-tests/dataflow/coverage/test_builtins.py +++ b/python/ql/test/library-tests/dataflow/coverage/test_builtins.py @@ -132,8 +132,8 @@ def test_dict_from_keyword(): @expects(2) def test_dict_from_list(): d = dict([("k", SOURCE), ("k1", NONSOURCE)]) - SINK(d["k"]) #$ MISSING: flow="SOURCE, l:-1 -> d[k]" - SINK_F(d["k1"]) + SINK(d["k"]) #$ flow="SOURCE, l:-1 -> d['k']" + SINK_F(d["k1"]) #$ SPURIOUS: flow="SOURCE, l:-2 -> d['k1']" // due to imprecise list content @expects(2) def test_dict_from_dict():