Add a ContentSet for any tuple or dictionary element

This commit is contained in:
Owen Mansel-Chan
2026-05-28 16:48:23 +01:00
parent 812e8e6b34
commit df15a719cb
5 changed files with 11 additions and 9 deletions

View File

@@ -1078,7 +1078,7 @@ module Conversions {
nodeFrom = decoding.getAnInput() and
nodeTo = decoding.getOutput()
) and
(c.isAnyTupleElement() or c.isAnyDictionaryElement())
c.isAnyTupleOrDictionaryElement()
}
predicate encoderReadStep(Node nodeFrom, ContentSet c, Node nodeTo) {
@@ -1086,7 +1086,7 @@ module Conversions {
nodeFrom = encoding.getAnInput() and
nodeTo = encoding.getOutput()
) and
(c.isAnyTupleElement() or c.isAnyDictionaryElement())
c.isAnyTupleOrDictionaryElement()
}
predicate formatReadStep(Node nodeFrom, ContentSet c, Node nodeTo) {

View File

@@ -914,7 +914,8 @@ class CapturedVariableContent extends Content, TCapturedVariableContent {
private newtype TContentSet =
TSingletonContent(Content c) or
TAnyTupleElement() or
TAnyDictionaryElement()
TAnyDictionaryElement() or
TAnyTupleOrDictionaryElement()
/**
* An entity that represents a set of `Content`s.
@@ -932,6 +933,9 @@ class ContentSet extends TContentSet {
/** Holds if this content set is the wildcard for all dictionary elements. */
predicate isAnyDictionaryElement() { this = TAnyDictionaryElement() }
/** Holds if this content set is the wildcard for all tuple elements or dictionary elements. */
predicate isAnyTupleOrDictionaryElement() { this = TAnyTupleOrDictionaryElement() }
/** Gets a content that may be stored into when storing into this set. */
Content getAStoreContent() { this = TSingletonContent(result) }

View File

@@ -87,6 +87,8 @@ module Input implements InputSig<Location, DataFlowImplSpecific::PythonDataFlow>
cs.isAnyTupleElement() and result = "AnyTupleElement" and arg = ""
or
cs.isAnyDictionaryElement() and result = "AnyDictionaryElement" and arg = ""
or
cs.isAnyTupleOrDictionaryElement() and result = "AnyTupleOrDictionaryElement" and arg = ""
}
bindingset[token]

View File

@@ -21,9 +21,7 @@ private predicate defaultTaintReadContent(DataFlow::ContentSet contentSet) {
// expand to one row per (node, distinct key or index) and the framework's
// read-set relation grows quadratically). `ContentSet.getAReadContent` expands
// these wildcards back to the specific contents when matching against stores.
contentSet.isAnyTupleElement()
or
contentSet.isAnyDictionaryElement()
contentSet.isAnyTupleOrDictionaryElement()
or
// List and set element content is already imprecise, so no wildcard expansion is
// needed.

View File

@@ -61,9 +61,7 @@ module EscapingCaptureFlowConfig implements DataFlow::ConfigSig {
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet cs) {
isSink(node) and
(
cs.isAnyTupleElement()
or
cs.isAnyDictionaryElement()
cs.isAnyTupleOrDictionaryElement()
or
cs.getAStoreContent() instanceof DataFlow::ListElementContent
or