diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index 895ef74b41e..3084983a605 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1316,7 +1316,9 @@ newtype TDataFlowCall = TNormalCall(CallNode call, Function target, CallType type) { resolveCall(call, target, type) } or TPotentialLibraryCall(CallNode call) or /** A synthesized call inside a summarized callable */ - TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, Node receiver) { + TSummaryCall( + FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver + ) { FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) } @@ -1448,12 +1450,12 @@ class PotentialLibraryCall extends ExtractedDataFlowCall, TPotentialLibraryCall */ class SummaryCall extends DataFlowCall, TSummaryCall { private FlowSummaryImpl::Public::SummarizedCallable c; - private Node receiver; + private FlowSummaryImpl::Private::SummaryNode receiver; SummaryCall() { this = TSummaryCall(c, receiver) } /** Gets the data flow node that this call targets. */ - Node getReceiver() { result = receiver } + FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver } override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c } @@ -1486,44 +1488,35 @@ abstract class ParameterNodeImpl extends Node { } /** A parameter for a library callable with a flow summary. */ -class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode { - private FlowSummaryImpl::Public::SummarizedCallable sc; - private ParameterPosition pos; +class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode { + SummaryParameterNode() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _) + } - SummaryParameterNode() { this = TSummaryParameterNode(sc, pos) } + private ParameterPosition getPosition() { + FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result) + } override Parameter getParameter() { none() } override predicate isParameterOf(DataFlowCallable c, ParameterPosition ppos) { - sc = c.asLibraryCallable() and ppos = pos - } - - override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = sc } - - override string toString() { result = "parameter " + pos + " of " + sc } - - // Hack to return "empty location" - override predicate hasLocationInfo( - string file, int startline, int startcolumn, int endline, int endcolumn - ) { - file = "" and - startline = 0 and - startcolumn = 0 and - endline = 0 and - endcolumn = 0 + this.getSummarizedCallable() = c.asLibraryCallable() and ppos = this.getPosition() } } /** A data-flow node used to model flow summaries. */ -class SummaryNode extends Node, TSummaryNode { - private FlowSummaryImpl::Public::SummarizedCallable c; - private FlowSummaryImpl::Private::SummaryNodeState state; +class FlowSummaryNode extends Node, TFlowSummaryNode { + FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) } - SummaryNode() { this = TSummaryNode(c, state) } + FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { + result = this.getSummaryNode().getSummarizedCallable() + } - override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c } + override DataFlowCallable getEnclosingCallable() { + result.asLibraryCallable() = this.getSummarizedCallable() + } - override string toString() { result = "[summary] " + state + " in " + c } + override string toString() { result = this.getSummaryNode().toString() } // Hack to return "empty location" override predicate hasLocationInfo( @@ -1537,26 +1530,30 @@ class SummaryNode extends Node, TSummaryNode { } } -private class SummaryReturnNode extends SummaryNode, ReturnNode { +private class SummaryReturnNode extends FlowSummaryNode, ReturnNode { private ReturnKind rk; - SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this, rk) } + SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) } override ReturnKind getKind() { result = rk } } -private class SummaryArgumentNode extends SummaryNode, ArgumentNode { - SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) } +private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode { + SummaryArgumentNode() { + FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _) + } override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos) + FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos) } } -private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNodeImpl { - private Node pre; +private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl { + private FlowSummaryNode pre; - SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) } + SummaryPostUpdateNode() { + FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode()) + } override Node getPreUpdateNode() { result = pre } } @@ -1625,11 +1622,11 @@ private module OutNodes { } } - private class SummaryOutNode extends SummaryNode, OutNode { - SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) } + private class SummaryOutNode extends FlowSummaryNode, OutNode { + SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) } override DataFlowCall getCall(ReturnKind kind) { - FlowSummaryImpl::Private::summaryOutNode(result, this, kind) + FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind) } } } 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 de493e5bb53..a6dfefb5a77 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -441,14 +441,16 @@ predicate importTimeSummaryFlowStep(Node nodeFrom, Node nodeTo) { // This will miss statements inside functions called from the top level. isTopLevel(nodeFrom) and isTopLevel(nodeTo) and - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), true) } predicate runtimeSummaryFlowStep(Node nodeFrom, Node nodeTo) { // Anything not at the top level can be executed at runtime. not isTopLevel(nodeFrom) and not isTopLevel(nodeTo) and - FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode(), true) } /** `ModuleVariable`s are accessed via jump steps at runtime. */ @@ -529,7 +531,8 @@ predicate jumpStep(Node nodeFrom, Node nodeTo) { or jumpStepNotSharedWithTypeTracker(nodeFrom, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryJumpStep(nodeFrom, nodeTo) + FlowSummaryImpl::Private::Steps::summaryJumpStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), + nodeTo.(FlowSummaryNode).getSummaryNode()) } /** @@ -602,7 +605,8 @@ predicate storeStep(Node nodeFrom, Content c, Node nodeTo) { or any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom, c, nodeTo) + FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c, + nodeTo.(FlowSummaryNode).getSummaryNode()) or synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo) or @@ -806,7 +810,8 @@ predicate readStep(Node nodeFrom, Content c, Node nodeTo) { or attributeReadStep(nodeFrom, c, nodeTo) or - FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom, c, nodeTo) + FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c, + nodeTo.(FlowSummaryNode).getSummaryNode()) or synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo) } @@ -921,7 +926,7 @@ predicate clearsContent(Node n, Content c) { or dictClearStep(n, c) or - FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c) + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) or dictSplatParameterNodeClearStep(n, c) } @@ -978,9 +983,7 @@ predicate forceHighPrecision(Content c) { none() } predicate nodeIsHidden(Node n) { n instanceof ModuleVariableNode or - n instanceof SummaryNode - or - n instanceof SummaryParameterNode + n instanceof FlowSummaryNode or n instanceof SynthStarArgsElementParameterNode or @@ -1007,7 +1010,7 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) /** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { - receiver = call.(SummaryCall).getReceiver() and + receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() and exists(kind) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 683b17d6db7..49cf972ab04 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -105,14 +105,7 @@ newtype TNode = // So for now we live with having these synthetic ORM nodes for _all_ classes, which // is a bit wasteful, but we don't think it will hurt too much. TSyntheticOrmModelNode(Class cls) or - TSummaryNode( - FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state - ) { - FlowSummaryImpl::Private::summaryNodeRange(c, state) - } or - TSummaryParameterNode(FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition pos) { - FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos) - } or + TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or /** A synthetic node to capture positional arguments that are passed to a `*args` parameter. */ TSynthStarArgsElementParameterNode(DataFlowCallable callable) { exists(ParameterPosition ppos | ppos.isStarArgs(_) | exists(callable.getParameter(ppos))) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll index 67a047d8843..d938de5200a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImplSpecific.qll @@ -47,11 +47,8 @@ DataFlowCallable inject(SummarizedCallable c) { result.asLibraryCallable() = c } /** Gets the parameter position of the instance parameter. */ ArgumentPosition callbackSelfParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks -/** Gets the synthesized summary data-flow node for the given values. */ -Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) } - /** Gets the synthesized data-flow call for `receiver`. */ -SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() } +SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() } /** Gets the type of content `c`. */ DataFlowType getContentType(Content c) { any() }