diff --git a/python/ql/lib/semmle/python/dataflow/new/FlowSummary.qll b/python/ql/lib/semmle/python/dataflow/new/FlowSummary.qll index 5e82700bd0e..0fac6bfaedd 100644 --- a/python/ql/lib/semmle/python/dataflow/new/FlowSummary.qll +++ b/python/ql/lib/semmle/python/dataflow/new/FlowSummary.qll @@ -90,39 +90,37 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari } class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack; -// // This gives access to getNodeFromPath, which is not constrained to `CallNode`s -// // as `resolvedSummaryBase` is. -// private import semmle.python.frameworks.data.internal.ApiGraphModels as AGM -// -// private class SummarizedCallableFromModel extends SummarizedCallable { -// string package; -// string type; -// string path; -// SummarizedCallableFromModel() { -// ModelOutput::relevantSummaryModel(package, type, path, _, _, _) and -// this = package + ";" + type + ";" + path -// } -// override CallCfgNode getACall() { -// exists(API::CallNode base | -// ModelOutput::resolvedSummaryBase(package, type, path, base) and -// result = base.getACall() -// ) -// } -// override ArgumentNode getACallback() { -// exists(API::Node base | -// base = AGM::getNodeFromPath(package, type, path) and -// result = base.getAValueReachableFromSource() -// ) -// } -// override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { -// exists(string kind | -// ModelOutput::relevantSummaryModel(package, type, path, input, output, kind) -// | -// kind = "value" and -// preservesValue = true -// or -// kind = "taint" and -// preservesValue = false -// ) -// } -// } + +private class SummarizedCallableFromModel extends SummarizedCallable { + string type; + string path; + + SummarizedCallableFromModel() { + ModelOutput::relevantSummaryModel(type, path, _, _, _) and + this = type + ";" + path + } + + override CallCfgNode getACall() { + exists(API::CallNode base | + ModelOutput::resolvedSummaryBase(type, path, base) and + result = base.getACall() + ) + } + + override ArgumentNode getACallback() { + exists(API::Node base | + ModelOutput::resolvedSummaryRefBase(type, path, base) and + result = base.getAValueReachableFromSource() + ) + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + exists(string kind | ModelOutput::relevantSummaryModel(type, path, input, output, kind) | + kind = "value" and + preservesValue = true + or + kind = "taint" and + preservesValue = false + ) + } +} diff --git a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll index 227f4ea22fb..6688ba36cd0 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -643,6 +643,15 @@ module ModelOutput { baseNode = getInvocationFromPath(type, path) } + /** + * Holds if a `baseNode` is an invocation identified by the `type,path` part of a summary row. + */ + cached + predicate resolvedSummaryRefBase(string type, string path, API::Node baseNode) { + summaryModel(type, path, _, _, _) and + baseNode = getNodeFromPath(type, path) + } + /** * Holds if `node` is seen as an instance of `type` due to a type definition * contributed by a CSV model.