mirror of
https://github.com/github/codeql.git
synced 2026-02-28 12:53:49 +01:00
Java: Adapt to changes in FlowSummaryImpl
Missing manual models were added using the following code added to `FlowSummaryImpl.qll`:
```ql
private predicate testsummaryElement(
Input::SummarizedCallableBase c, string namespace, string type, boolean subtypes, string name,
string signature, string ext, string originalInput, string originalOutput, string kind,
string provenance, string model, boolean isExact
) {
exists(string input, string output, Callable baseCallable |
summaryModel(namespace, type, subtypes, name, signature, ext, originalInput, originalOutput,
kind, provenance, model) and
baseCallable = interpretElement(namespace, type, subtypes, name, signature, ext, isExact) and
(
c.asCallable() = baseCallable and input = originalInput and output = originalOutput
or
correspondingKotlinParameterDefaultsArgSpec(baseCallable, c.asCallable(), originalInput,
input) and
correspondingKotlinParameterDefaultsArgSpec(baseCallable, c.asCallable(), originalOutput,
output)
)
)
}
private predicate testsummaryElement2(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string originalInput, string originalOutput, string kind, string provenance, string model,
string namespace2, string type2
) {
exists(Input::SummarizedCallableBase c |
testsummaryElement(c, namespace2, type2, _, _, _, ext, originalInput, originalOutput, kind,
provenance, model, false) and
testsummaryElement(c, namespace, type, subtypes, name, _, _, _, _, _, provenance, _, true) and
signature = paramsString(c.asCallable()) and
not testsummaryElement(c, _, _, _, _, _, _, originalInput, originalOutput, kind, provenance,
_, true)
)
}
private string getAMissingManualModel(string namespace2, string type2) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string originalInput, string originalOutput, string kind, string provenance, string model
|
testsummaryElement2(namespace, type, subtypes, name, signature, ext, originalInput,
originalOutput, kind, provenance, model, namespace2, type2) and
result =
"- [\"" + namespace + "\", \"" + type + "\", True, \"" + name + "\", \"" + signature +
"\", \"\", \"" + originalInput + "\", \"" + originalOutput + "\", \"" + kind + "\", \"" +
provenance + "\"]"
)
}
```
This commit is contained in:
@@ -23,7 +23,7 @@ module Modification {
|
||||
/** Holds if the call `c` modifies a shared resource. */
|
||||
predicate isModifyingCall(Call c) {
|
||||
exists(SummarizedCallable sc, string output | sc.getACall() = c |
|
||||
sc.propagatesFlow(_, output, _, _) and
|
||||
sc.propagatesFlow(_, output, _, _, _, _) and
|
||||
output.matches("Argument[this]%")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -620,48 +620,25 @@ predicate barrierNode(Node node, string kind) { barrierNode(node, kind, _) }
|
||||
|
||||
// adapter class for converting Mad summaries to `SummarizedCallable`s
|
||||
private class SummarizedCallableAdapter extends SummarizedCallable {
|
||||
SummarizedCallableAdapter() { summaryElement(this, _, _, _, _, _, _) }
|
||||
string input_;
|
||||
string output_;
|
||||
string kind;
|
||||
Provenance p_;
|
||||
boolean isExact_;
|
||||
string model_;
|
||||
|
||||
private predicate relevantSummaryElementManual(
|
||||
string input, string output, string kind, string model
|
||||
) {
|
||||
exists(Provenance provenance |
|
||||
summaryElement(this, input, output, kind, provenance, model, _) and
|
||||
provenance.isManual()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
string input, string output, string kind, string model
|
||||
) {
|
||||
exists(Provenance provenance |
|
||||
summaryElement(this, input, output, kind, provenance, model, _) and
|
||||
provenance.isGenerated()
|
||||
) and
|
||||
not exists(Provenance provenance |
|
||||
neutralElement(this, "summary", provenance, _) and
|
||||
provenance.isManual()
|
||||
)
|
||||
}
|
||||
SummarizedCallableAdapter() { summaryElement(this, input_, output_, kind, p_, model_, isExact_) }
|
||||
|
||||
override predicate propagatesFlow(
|
||||
string input, string output, boolean preservesValue, string model
|
||||
string input, string output, boolean preservesValue, Provenance p, boolean isExact, string model
|
||||
) {
|
||||
exists(string kind |
|
||||
this.relevantSummaryElementManual(input, output, kind, model)
|
||||
or
|
||||
not this.relevantSummaryElementManual(_, _, _, _) and
|
||||
this.relevantSummaryElementGenerated(input, output, kind, model)
|
||||
|
|
||||
if kind = "value" then preservesValue = true else preservesValue = false
|
||||
)
|
||||
input = input_ and
|
||||
output = output_ and
|
||||
(if kind = "value" then preservesValue = true else preservesValue = false) and
|
||||
p = p_ and
|
||||
isExact = isExact_ and
|
||||
model = model_
|
||||
}
|
||||
|
||||
override predicate hasProvenance(Provenance provenance) {
|
||||
summaryElement(this, _, _, _, provenance, _, _)
|
||||
}
|
||||
|
||||
override predicate hasExactModel() { summaryElement(this, _, _, _, _, _, true) }
|
||||
}
|
||||
|
||||
final class SinkCallable = SinkModelCallable;
|
||||
|
||||
@@ -121,24 +121,31 @@ class SummarizedCallableBase extends TSummarizedCallableBase {
|
||||
|
||||
class Provenance = Impl::Public::Provenance;
|
||||
|
||||
class SummarizedCallable = Impl::Public::SummarizedCallable;
|
||||
/** Provides the `Range` class used to define the extent of `SummarizedCallable`. */
|
||||
module SummarizedCallable {
|
||||
class Range = Impl::Public::SummarizedCallable;
|
||||
}
|
||||
|
||||
class SummarizedCallable = Impl::Public::RelevantSummarizedCallable;
|
||||
|
||||
/**
|
||||
* An adapter class to add the flow summaries specified on `SyntheticCallable`
|
||||
* to `SummarizedCallable`.
|
||||
*/
|
||||
private class SummarizedSyntheticCallableAdapter extends SummarizedCallable, TSyntheticCallable {
|
||||
private class SummarizedSyntheticCallableAdapter extends SummarizedCallable::Range,
|
||||
TSyntheticCallable
|
||||
{
|
||||
override predicate propagatesFlow(
|
||||
string input, string output, boolean preservesValue, string model
|
||||
string input, string output, boolean preservesValue, Provenance p, boolean isExact, string model
|
||||
) {
|
||||
exists(SyntheticCallable sc |
|
||||
sc = this.asSyntheticCallable() and
|
||||
sc.propagatesFlow(input, output, preservesValue) and
|
||||
p = "manual" and
|
||||
isExact = true and
|
||||
model = sc
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasExactModel() { any() }
|
||||
}
|
||||
|
||||
deprecated class RequiredSummaryComponentStack = Impl::Private::RequiredSummaryComponentStack;
|
||||
|
||||
@@ -12,7 +12,11 @@ private import semmle.code.java.dispatch.internal.Unification
|
||||
|
||||
private module DispatchImpl {
|
||||
private predicate hasHighConfidenceTarget(Call c) {
|
||||
exists(Impl::Public::SummarizedCallable sc | sc.getACall() = c and not sc.applyGeneratedModel())
|
||||
exists(Impl::Public::SummarizedCallable sc, Impl::Public::Provenance p |
|
||||
sc.getACall() = c and
|
||||
sc.propagatesFlow(_, _, _, p, _, _) and
|
||||
not p.isGenerated()
|
||||
)
|
||||
or
|
||||
exists(Impl::Public::NeutralSummaryCallable nc | nc.getACall() = c and nc.hasManualModel())
|
||||
or
|
||||
@@ -25,8 +29,10 @@ private module DispatchImpl {
|
||||
private predicate hasExactManualModel(Call c, Callable tgt) {
|
||||
tgt = c.getCallee().getSourceDeclaration() and
|
||||
(
|
||||
exists(Impl::Public::SummarizedCallable sc |
|
||||
sc.getACall() = c and sc.hasExactModel() and sc.hasManualModel()
|
||||
exists(Impl::Public::SummarizedCallable sc, Impl::Public::Provenance p |
|
||||
sc.getACall() = c and
|
||||
sc.propagatesFlow(_, _, _, p, true, _) and
|
||||
p.isManual()
|
||||
)
|
||||
or
|
||||
exists(Impl::Public::NeutralSummaryCallable nc |
|
||||
@@ -57,16 +63,6 @@ private module DispatchImpl {
|
||||
exists(Call call | call = c.asCall() |
|
||||
result.asCallable() = sourceDispatch(call)
|
||||
or
|
||||
not (
|
||||
// Only use summarized callables with generated summaries in case
|
||||
// the static call target is not in the source code.
|
||||
// Note that if `applyGeneratedModel` holds it implies that there doesn't
|
||||
// exist a manual model.
|
||||
exists(Callable staticTarget | staticTarget = call.getCallee().getSourceDeclaration() |
|
||||
staticTarget.fromSource() and not staticTarget.isStub()
|
||||
) and
|
||||
result.asSummarizedCallable().applyGeneratedModel()
|
||||
) and
|
||||
result.asSummarizedCallable().getACall() = call
|
||||
)
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ module Input implements InputSig<Location, DataFlowImplSpecific::JavaDataFlow> {
|
||||
|
||||
class SummarizedCallableBase = FlowSummary::SummarizedCallableBase;
|
||||
|
||||
predicate callableFromSource(SummarizedCallableBase sc) {
|
||||
sc.asCallable() = any(Callable c | c.fromSource() and not c.isStub())
|
||||
}
|
||||
|
||||
class SourceBase = Void;
|
||||
|
||||
class SinkBase = Void;
|
||||
|
||||
@@ -68,19 +68,19 @@ private predicate mayInvokeCallback(SrcMethod m, int n) {
|
||||
(not m.fromSource() or m.isNative() or m.getFile().getAbsolutePath().matches("%/test/stubs/%"))
|
||||
}
|
||||
|
||||
private class SummarizedCallableWithCallback extends SummarizedCallable {
|
||||
private class SummarizedCallableWithCallback extends SummarizedCallable::Range {
|
||||
private int pos;
|
||||
|
||||
SummarizedCallableWithCallback() { mayInvokeCallback(this.asCallable(), pos) }
|
||||
|
||||
override predicate propagatesFlow(
|
||||
string input, string output, boolean preservesValue, string model
|
||||
string input, string output, boolean preservesValue, Provenance p, boolean isExact, string model
|
||||
) {
|
||||
input = "Argument[" + pos + "]" and
|
||||
output = "Argument[" + pos + "].Parameter[-1]" and
|
||||
preservesValue = true and
|
||||
p = "hq-generated" and
|
||||
isExact = true and
|
||||
model = "heuristic-callback"
|
||||
}
|
||||
|
||||
override predicate hasProvenance(Provenance provenance) { provenance = "hq-generated" }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user