Merge pull request #1954 from asger-semmle/type-tracking-through-captured-vars

Approved by xiemaisi
This commit is contained in:
semmle-qlci
2019-09-23 12:10:30 +01:00
committed by GitHub
13 changed files with 125 additions and 5 deletions

View File

@@ -173,12 +173,20 @@ SourceNode nodeLeadingToInvocation() {
)
}
/**
* Holds if there is a call edge `invoke -> f` between a relevant invocation
* and a relevant function.
*/
predicate relevantCall(RelevantInvoke invoke, RelevantFunction f) {
FlowSteps::calls(invoke, f)
}
/**
* A call site that can be resolved to a function in the same project.
*/
class ResolvableCall extends RelevantInvoke {
ResolvableCall() {
FlowSteps::calls(this, _)
relevantCall(this, _)
or
this = resolvableCallback().getAnInvocation()
}

View File

@@ -0,0 +1,14 @@
/**
* @name DOM value references
* @description The number of references to a DOM value.
* @kind metric
* @metricType project
* @metricAggregate sum
* @tags meta
* @id js/meta/dom-value-refs
*/
import javascript
import CallGraphQuality
select projectRoot(), count(DOM::domValueRef())

View File

@@ -11,4 +11,4 @@
import javascript
import CallGraphQuality
select projectRoot(), count(NonExternalCall call)
select projectRoot(), count(RelevantInvoke call)

View File

@@ -11,4 +11,4 @@
import javascript
import CallGraphQuality
select projectRoot(), 100.0 * count(ResolvableCall call) / count(NonExternalCall call).(float)
select projectRoot(), 100.0 * count(ResolvableCall call) / count(RelevantInvoke call).(float)

View File

@@ -709,7 +709,8 @@ class ClassNode extends DataFlow::SourceNode {
result = getAClassReference(t.continue()).getAnInstantiation()
or
t.start() and
result.(AnalyzedNode).getAValue() = getAbstractInstanceValue()
result.(AnalyzedNode).getAValue() = getAbstractInstanceValue() and
not result = any(DataFlow::ClassNode cls).getAReceiverNode()
or
t.start() and
result = getAReceiverNode()

View File

@@ -107,6 +107,27 @@ module StepSummary {
pred = DataFlow::globalAccessPathRootPseudoNode() and
summary = LoadStep(name)
)
or
// Summarize calls with flow directly from a parameter to a return.
exists(DataFlow::ParameterNode param, DataFlow::FunctionNode fun |
(
param.flowsTo(fun.getAReturn()) and
summary = LevelStep()
or
exists(string prop |
param.getAPropertyRead(prop).flowsTo(fun.getAReturn()) and
summary = LoadStep(prop)
)
) and
if param = fun.getAParameter() then (
// Step from argument to call site.
argumentPassing(succ, pred, fun.getFunction(), param)
) else (
// Step from captured parameter to local call sites
pred = param and
succ = fun.getAnInvocation()
)
)
}
}