mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
Merge pull request #11721 from michaelnebel/csharpjava/refactorprovenance
C#/Java: Re-factor provenance related predicates.
This commit is contained in:
@@ -410,11 +410,6 @@ Element interpretElement(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `c` has a `generated` summary.
|
||||
*/
|
||||
predicate hasSummary(Callable c, boolean generated) { summaryElement(c, _, _, _, generated) }
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
|
||||
@@ -241,15 +241,19 @@ module Public {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the summary is auto generated and not manually generated.
|
||||
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
|
||||
*/
|
||||
predicate isAutoGenerated() { none() }
|
||||
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
|
||||
|
||||
/**
|
||||
* Holds if the summary has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual summary that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { none() }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if there exists a summary that applies to `this` that has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { none() }
|
||||
}
|
||||
|
||||
/** A callable where there is no flow via the callable. */
|
||||
@@ -257,15 +261,19 @@ module Public {
|
||||
NeutralCallable() { neutralElement(this, _) }
|
||||
|
||||
/**
|
||||
* Holds if the neutral is auto generated.
|
||||
* Holds if the neutral is auto generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { neutralElement(this, true) }
|
||||
predicate isAutoGenerated() { neutralElement(this, "generated") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual neutral that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { neutralElement(this, generated) }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { neutralElement(this, provenance) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -997,12 +1005,12 @@ module Private {
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
AccessPath inSpec, AccessPath outSpec, string kind
|
||||
) {
|
||||
summaryElement(this, inSpec, outSpec, kind, true) and
|
||||
not summaryElement(this, _, _, _, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "generated") and
|
||||
not summaryElement(this, _, _, _, "manual")
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
|
||||
summaryElement(this, inSpec, outSpec, kind, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "manual")
|
||||
or
|
||||
this.relevantSummaryElementGenerated(inSpec, outSpec, kind)
|
||||
}
|
||||
@@ -1021,10 +1029,8 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) }
|
||||
|
||||
override predicate hasProvenance(boolean generated) {
|
||||
summaryElement(this, _, _, _, generated)
|
||||
override predicate hasProvenance(string provenance) {
|
||||
summaryElement(this, _, _, _, provenance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,69 +97,52 @@ DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) {
|
||||
result = Gvn::getGlobalValueNumber(any(ObjectType t))
|
||||
}
|
||||
|
||||
bindingset[provenance]
|
||||
private boolean isGenerated(string provenance) {
|
||||
provenance = "generated" and result = true
|
||||
or
|
||||
provenance != "generated" and result = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an external flow summary exists for `c` with input specification
|
||||
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
||||
* stating whether the summary is autogenerated.
|
||||
* `input`, output specification `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate summaryElement(Callable c, string input, string output, string kind, boolean generated) {
|
||||
predicate summaryElement(Callable c, string input, string output, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string provenance
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
c = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a neutral model exists for `c`, which means that there is no
|
||||
* flow through `c`. The flag `generated` states whether the neutral model is autogenerated.
|
||||
* Holds if a neutral model exists for `c` with provenance `provenace`,
|
||||
* which means that there is no flow through `c`.
|
||||
*/
|
||||
predicate neutralElement(Callable c, boolean generated) {
|
||||
exists(string namespace, string type, string name, string signature, string provenance |
|
||||
predicate neutralElement(Callable c, string provenance) {
|
||||
exists(string namespace, string type, string name, string signature |
|
||||
neutralModel(namespace, type, name, signature, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
c = interpretElement(namespace, type, false, name, signature, "")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an external source specification exists for `e` with output specification
|
||||
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
|
||||
* autogenerated.
|
||||
* `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate sourceElement(Element e, string output, string kind, boolean generated) {
|
||||
predicate sourceElement(Element e, string output, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string provenance
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an external sink specification exists for `e` with input specification
|
||||
* `input`, kind `kind` and a flag `generated` stating whether the sink specification is
|
||||
* autogenerated.
|
||||
* `input`, kind `kind` and provenance `provenance`.
|
||||
*/
|
||||
predicate sinkElement(Element e, string input, string kind, boolean generated) {
|
||||
predicate sinkElement(Element e, string input, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string provenance
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
* @id cs/utils/modelgenerator/discarded-summary-models
|
||||
*/
|
||||
|
||||
import semmle.code.csharp.dataflow.ExternalFlow
|
||||
import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import internal.CaptureModels
|
||||
import internal.CaptureSummaryFlow
|
||||
|
||||
from DataFlowTargetApi api, string flow
|
||||
where flow = captureFlow(api) and hasSummary(api, false)
|
||||
where
|
||||
flow = captureFlow(api) and
|
||||
api.(FlowSummaryImpl::Public::SummarizedCallable).isManual()
|
||||
select flow order by flow
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* @tags modelgenerator
|
||||
*/
|
||||
|
||||
import semmle.code.csharp.dataflow.ExternalFlow
|
||||
import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import internal.CaptureModels
|
||||
import internal.CaptureSummaryFlow
|
||||
|
||||
from DataFlowTargetApi api, string noflow
|
||||
where
|
||||
noflow = captureNoFlow(api) and
|
||||
not hasSummary(api, false)
|
||||
not api.(FlowSummaryImpl::Public::SummarizedCallable).isManual()
|
||||
select noflow order by noflow
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* @tags modelgenerator
|
||||
*/
|
||||
|
||||
import semmle.code.csharp.dataflow.ExternalFlow
|
||||
import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import internal.CaptureModels
|
||||
import internal.CaptureSummaryFlow
|
||||
|
||||
from DataFlowTargetApi api, string flow
|
||||
where flow = captureFlow(api) and not hasSummary(api, false)
|
||||
where flow = captureFlow(api) and not api.(FlowSummaryImpl::Public::SummarizedCallable).isManual()
|
||||
select flow order by flow
|
||||
|
||||
@@ -124,17 +124,10 @@ predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
|
||||
/** Holds if `row` is a summary model. */
|
||||
predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
|
||||
|
||||
bindingset[input]
|
||||
private predicate getKind(string input, string kind, boolean generated) {
|
||||
input.splitAt(":", 0) = "generated" and kind = input.splitAt(":", 1) and generated = true
|
||||
or
|
||||
not input.matches("%:%") and kind = input and generated = false
|
||||
}
|
||||
|
||||
/** Holds if a source model exists for the given parameters. */
|
||||
predicate sourceModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string output, string kind, boolean generated
|
||||
string output, string kind, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
sourceModel(row) and
|
||||
@@ -146,14 +139,15 @@ predicate sourceModel(
|
||||
row.splitAt(";", 4) = signature and
|
||||
row.splitAt(";", 5) = ext and
|
||||
row.splitAt(";", 6) = output and
|
||||
exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated))
|
||||
row.splitAt(";", 7) = kind and
|
||||
provenance = "manual"
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if a sink model exists for the given parameters. */
|
||||
predicate sinkModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string kind, boolean generated
|
||||
string input, string kind, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
sinkModel(row) and
|
||||
@@ -165,34 +159,30 @@ predicate sinkModel(
|
||||
row.splitAt(";", 4) = signature and
|
||||
row.splitAt(";", 5) = ext and
|
||||
row.splitAt(";", 6) = input and
|
||||
exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated))
|
||||
row.splitAt(";", 7) = kind and
|
||||
provenance = "manual"
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if a summary model exists for the given parameters. */
|
||||
predicate summaryModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string output, string kind, boolean generated
|
||||
string input, string output, string kind, string provenance
|
||||
) {
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated, _)
|
||||
}
|
||||
|
||||
/** Holds if a summary model `row` exists for the given parameters. */
|
||||
predicate summaryModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string output, string kind, boolean generated, string row
|
||||
) {
|
||||
summaryModel(row) and
|
||||
row.splitAt(";", 0) = namespace and
|
||||
row.splitAt(";", 1) = type and
|
||||
row.splitAt(";", 2) = subtypes.toString() and
|
||||
subtypes = [true, false] and
|
||||
row.splitAt(";", 3) = name and
|
||||
row.splitAt(";", 4) = signature and
|
||||
row.splitAt(";", 5) = ext and
|
||||
row.splitAt(";", 6) = input and
|
||||
row.splitAt(";", 7) = output and
|
||||
exists(string k | row.splitAt(";", 8) = k and getKind(k, kind, generated))
|
||||
exists(string row |
|
||||
summaryModel(row) and
|
||||
row.splitAt(";", 0) = namespace and
|
||||
row.splitAt(";", 1) = type and
|
||||
row.splitAt(";", 2) = subtypes.toString() and
|
||||
subtypes = [true, false] and
|
||||
row.splitAt(";", 3) = name and
|
||||
row.splitAt(";", 4) = signature and
|
||||
row.splitAt(";", 5) = ext and
|
||||
row.splitAt(";", 6) = input and
|
||||
row.splitAt(";", 7) = output and
|
||||
row.splitAt(";", 8) = kind
|
||||
) and
|
||||
provenance = "manual"
|
||||
}
|
||||
|
||||
/** Holds if `package` have CSV framework coverage. */
|
||||
@@ -241,25 +231,25 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int
|
||||
part = "source" and
|
||||
n =
|
||||
strictcount(string subpkg, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string output, boolean generated |
|
||||
string ext, string output, string provenance |
|
||||
canonicalPackageHasASubpackage(package, subpkg) and
|
||||
sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind, generated)
|
||||
sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind, provenance)
|
||||
)
|
||||
or
|
||||
part = "sink" and
|
||||
n =
|
||||
strictcount(string subpkg, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string input, boolean generated |
|
||||
string ext, string input, string provenance |
|
||||
canonicalPackageHasASubpackage(package, subpkg) and
|
||||
sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind, generated)
|
||||
sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind, provenance)
|
||||
)
|
||||
or
|
||||
part = "summary" and
|
||||
n =
|
||||
strictcount(string subpkg, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string input, string output, boolean generated |
|
||||
string ext, string input, string output, string provenance |
|
||||
canonicalPackageHasASubpackage(package, subpkg) and
|
||||
summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, generated)
|
||||
summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, provenance)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -298,9 +288,8 @@ module CsvValidation {
|
||||
}
|
||||
|
||||
private string getInvalidModelKind() {
|
||||
exists(string row, string k, string kind | summaryModel(row) |
|
||||
k = row.splitAt(";", 8) and
|
||||
getKind(k, kind, _) and
|
||||
exists(string row, string kind | summaryModel(row) |
|
||||
kind = row.splitAt(";", 8) and
|
||||
not kind = ["taint", "value"] and
|
||||
result = "Invalid kind \"" + kind + "\" in summary model."
|
||||
)
|
||||
|
||||
@@ -241,15 +241,19 @@ module Public {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the summary is auto generated and not manually generated.
|
||||
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
|
||||
*/
|
||||
predicate isAutoGenerated() { none() }
|
||||
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
|
||||
|
||||
/**
|
||||
* Holds if the summary has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual summary that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { none() }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if there exists a summary that applies to `this` that has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { none() }
|
||||
}
|
||||
|
||||
/** A callable where there is no flow via the callable. */
|
||||
@@ -257,15 +261,19 @@ module Public {
|
||||
NeutralCallable() { neutralElement(this, _) }
|
||||
|
||||
/**
|
||||
* Holds if the neutral is auto generated.
|
||||
* Holds if the neutral is auto generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { neutralElement(this, true) }
|
||||
predicate isAutoGenerated() { neutralElement(this, "generated") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual neutral that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { neutralElement(this, generated) }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { neutralElement(this, provenance) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -997,12 +1005,12 @@ module Private {
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
AccessPath inSpec, AccessPath outSpec, string kind
|
||||
) {
|
||||
summaryElement(this, inSpec, outSpec, kind, true) and
|
||||
not summaryElement(this, _, _, _, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "generated") and
|
||||
not summaryElement(this, _, _, _, "manual")
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
|
||||
summaryElement(this, inSpec, outSpec, kind, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "manual")
|
||||
or
|
||||
this.relevantSummaryElementGenerated(inSpec, outSpec, kind)
|
||||
}
|
||||
@@ -1021,10 +1029,8 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) }
|
||||
|
||||
override predicate hasProvenance(boolean generated) {
|
||||
summaryElement(this, _, _, _, generated)
|
||||
override predicate hasProvenance(string provenance) {
|
||||
summaryElement(this, _, _, _, provenance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,26 +60,25 @@ DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { any(
|
||||
|
||||
/**
|
||||
* Holds if an external flow summary exists for `c` with input specification
|
||||
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
||||
* stating whether the summary is autogenerated.
|
||||
* `input`, output specification `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate summaryElement(
|
||||
SummarizedCallableBase c, string input, string output, string kind, boolean generated
|
||||
SummarizedCallableBase c, string input, string output, string kind, string provenance
|
||||
) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated) and
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) and
|
||||
c.asFunction() = interpretElement(namespace, type, subtypes, name, signature, ext).asEntity()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a neutral model exists for `c`, which means that there is no
|
||||
* flow through `c`. The flag `generated` states whether the model is autogenerated.
|
||||
* Holds if a neutral model exists for `c` with provenance `provenance`,
|
||||
* which means that there is no flow through `c`.
|
||||
* Note. Neutral models have not been implemented for Go.
|
||||
*/
|
||||
predicate neutralElement(SummarizedCallable c, boolean generated) { none() }
|
||||
predicate neutralElement(SummarizedCallable c, string provenance) { none() }
|
||||
|
||||
/** Gets the summary component for specification component `c`, if any. */
|
||||
bindingset[c]
|
||||
@@ -152,28 +151,26 @@ class SourceOrSinkElement extends TSourceOrSinkElement {
|
||||
|
||||
/**
|
||||
* Holds if an external source specification exists for `e` with output specification
|
||||
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
|
||||
* autogenerated.
|
||||
* `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate sourceElement(SourceOrSinkElement e, string output, string kind, boolean generated) {
|
||||
predicate sourceElement(SourceOrSinkElement e, string output, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, generated) and
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an external sink specification exists for `e` with input specification
|
||||
* `input`, kind `kind` and a flag `generated` stating whether the sink specification is
|
||||
* autogenerated.
|
||||
* `input`, kind `kind` and provenance `provenance`.
|
||||
*/
|
||||
predicate sinkElement(SourceOrSinkElement e, string input, string kind, boolean generated) {
|
||||
predicate sinkElement(SourceOrSinkElement e, string input, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, generated) and
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -241,15 +241,19 @@ module Public {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the summary is auto generated and not manually generated.
|
||||
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
|
||||
*/
|
||||
predicate isAutoGenerated() { none() }
|
||||
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
|
||||
|
||||
/**
|
||||
* Holds if the summary has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual summary that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { none() }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if there exists a summary that applies to `this` that has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { none() }
|
||||
}
|
||||
|
||||
/** A callable where there is no flow via the callable. */
|
||||
@@ -257,15 +261,19 @@ module Public {
|
||||
NeutralCallable() { neutralElement(this, _) }
|
||||
|
||||
/**
|
||||
* Holds if the neutral is auto generated.
|
||||
* Holds if the neutral is auto generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { neutralElement(this, true) }
|
||||
predicate isAutoGenerated() { neutralElement(this, "generated") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual neutral that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { neutralElement(this, generated) }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { neutralElement(this, provenance) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -997,12 +1005,12 @@ module Private {
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
AccessPath inSpec, AccessPath outSpec, string kind
|
||||
) {
|
||||
summaryElement(this, inSpec, outSpec, kind, true) and
|
||||
not summaryElement(this, _, _, _, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "generated") and
|
||||
not summaryElement(this, _, _, _, "manual")
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
|
||||
summaryElement(this, inSpec, outSpec, kind, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "manual")
|
||||
or
|
||||
this.relevantSummaryElementGenerated(inSpec, outSpec, kind)
|
||||
}
|
||||
@@ -1021,10 +1029,8 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) }
|
||||
|
||||
override predicate hasProvenance(boolean generated) {
|
||||
summaryElement(this, _, _, _, generated)
|
||||
override predicate hasProvenance(string provenance) {
|
||||
summaryElement(this, _, _, _, provenance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,13 +66,6 @@ DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) {
|
||||
result instanceof TypeObject
|
||||
}
|
||||
|
||||
bindingset[provenance]
|
||||
private boolean isGenerated(string provenance) {
|
||||
provenance = "generated" and result = true
|
||||
or
|
||||
provenance != "generated" and result = false
|
||||
}
|
||||
|
||||
private predicate relatedArgSpec(Callable c, string spec) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
@@ -138,19 +131,17 @@ private predicate correspondingKotlinParameterDefaultsArgSpec(
|
||||
|
||||
/**
|
||||
* Holds if an external flow summary exists for `c` with input specification
|
||||
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
||||
* stating whether the summary is autogenerated.
|
||||
* `input`, output specification `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate summaryElement(
|
||||
SummarizedCallableBase c, string input, string output, string kind, boolean generated
|
||||
SummarizedCallableBase c, string input, string output, string kind, string provenance
|
||||
) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string provenance, string originalInput, string originalOutput, Callable baseCallable
|
||||
string originalInput, string originalOutput, Callable baseCallable
|
||||
|
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, originalInput, originalOutput,
|
||||
kind, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
baseCallable = interpretElement(namespace, type, subtypes, name, signature, ext) and
|
||||
(
|
||||
c.asCallable() = baseCallable and input = originalInput and output = originalOutput
|
||||
@@ -163,13 +154,12 @@ predicate summaryElement(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a neutral model exists for `c`, which means that there is no
|
||||
* flow through `c`. The flag `generated` states whether the model is autogenerated.
|
||||
* Holds if a neutral model exists for `c` with provenance `provenance`,
|
||||
* which means that there is no flow through `c`.
|
||||
*/
|
||||
predicate neutralElement(SummarizedCallableBase c, boolean generated) {
|
||||
exists(string namespace, string type, string name, string signature, string provenance |
|
||||
predicate neutralElement(SummarizedCallableBase c, string provenance) {
|
||||
exists(string namespace, string type, string name, string signature |
|
||||
neutralModel(namespace, type, name, signature, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
c.asCallable() = interpretElement(namespace, type, false, name, signature, "")
|
||||
)
|
||||
}
|
||||
@@ -222,16 +212,14 @@ class SourceOrSinkElement = Top;
|
||||
|
||||
/**
|
||||
* Holds if an external source specification exists for `e` with output specification
|
||||
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
|
||||
* autogenerated.
|
||||
* `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate sourceElement(SourceOrSinkElement e, string output, string kind, boolean generated) {
|
||||
predicate sourceElement(SourceOrSinkElement e, string output, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string provenance, SourceOrSinkElement baseSource, string originalOutput
|
||||
SourceOrSinkElement baseSource, string originalOutput
|
||||
|
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
baseSource = interpretElement(namespace, type, subtypes, name, signature, ext) and
|
||||
(
|
||||
e = baseSource and output = originalOutput
|
||||
@@ -243,16 +231,14 @@ predicate sourceElement(SourceOrSinkElement e, string output, string kind, boole
|
||||
|
||||
/**
|
||||
* Holds if an external sink specification exists for `e` with input specification
|
||||
* `input`, kind `kind` and a flag `generated` stating whether the sink specification is
|
||||
* autogenerated.
|
||||
* `input`, kind `kind` and provenance `provenance`.
|
||||
*/
|
||||
predicate sinkElement(SourceOrSinkElement e, string input, string kind, boolean generated) {
|
||||
predicate sinkElement(SourceOrSinkElement e, string input, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string provenance, SourceOrSinkElement baseSink, string originalInput
|
||||
SourceOrSinkElement baseSink, string originalInput
|
||||
|
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, originalInput, kind, provenance) and
|
||||
generated = isGenerated(provenance) and
|
||||
baseSink = interpretElement(namespace, type, subtypes, name, signature, ext) and
|
||||
(
|
||||
e = baseSink and originalInput = input
|
||||
|
||||
@@ -26,15 +26,16 @@ private int getNumMadModeledApis(string package, string provenance) {
|
||||
sc.isAutoGenerated() and
|
||||
provenance = "generated"
|
||||
or
|
||||
// "manual-only"
|
||||
sc.hasProvenance(false) and
|
||||
not sc.hasProvenance(true) and
|
||||
provenance = "manual"
|
||||
or
|
||||
// "both"
|
||||
sc.hasProvenance(false) and
|
||||
sc.hasProvenance(true) and
|
||||
provenance = "both"
|
||||
sc.isManual() and
|
||||
(
|
||||
if sc.hasProvenance("generated")
|
||||
then
|
||||
// "both"
|
||||
provenance = "both"
|
||||
else
|
||||
// "manual-only"
|
||||
provenance = "manual"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -78,11 +78,11 @@ class TopJdkApi extends SummarizedCallableBase {
|
||||
}
|
||||
|
||||
/** Holds if this API has a manual summary model. */
|
||||
private predicate hasManualSummary() { this.(SummarizedCallable).hasProvenance(false) }
|
||||
private predicate hasManualSummary() { this.(SummarizedCallable).isManual() }
|
||||
|
||||
/** Holds if this API has a manual neutral model. */
|
||||
private predicate hasManualNeutral() {
|
||||
this.(FlowSummaryImpl::Public::NeutralCallable).hasProvenance(false)
|
||||
this.(FlowSummaryImpl::Public::NeutralCallable).isManual()
|
||||
}
|
||||
|
||||
/** Holds if this API has a manual MaD model. */
|
||||
|
||||
@@ -241,15 +241,19 @@ module Public {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the summary is auto generated and not manually generated.
|
||||
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
|
||||
*/
|
||||
predicate isAutoGenerated() { none() }
|
||||
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
|
||||
|
||||
/**
|
||||
* Holds if the summary has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual summary that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { none() }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if there exists a summary that applies to `this` that has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { none() }
|
||||
}
|
||||
|
||||
/** A callable where there is no flow via the callable. */
|
||||
@@ -257,15 +261,19 @@ module Public {
|
||||
NeutralCallable() { neutralElement(this, _) }
|
||||
|
||||
/**
|
||||
* Holds if the neutral is auto generated.
|
||||
* Holds if the neutral is auto generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { neutralElement(this, true) }
|
||||
predicate isAutoGenerated() { neutralElement(this, "generated") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual neutral that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { neutralElement(this, generated) }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { neutralElement(this, provenance) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -997,12 +1005,12 @@ module Private {
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
AccessPath inSpec, AccessPath outSpec, string kind
|
||||
) {
|
||||
summaryElement(this, inSpec, outSpec, kind, true) and
|
||||
not summaryElement(this, _, _, _, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "generated") and
|
||||
not summaryElement(this, _, _, _, "manual")
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
|
||||
summaryElement(this, inSpec, outSpec, kind, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "manual")
|
||||
or
|
||||
this.relevantSummaryElementGenerated(inSpec, outSpec, kind)
|
||||
}
|
||||
@@ -1021,10 +1029,8 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) }
|
||||
|
||||
override predicate hasProvenance(boolean generated) {
|
||||
summaryElement(this, _, _, _, generated)
|
||||
override predicate hasProvenance(string provenance) {
|
||||
summaryElement(this, _, _, _, provenance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,25 +78,24 @@ DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { any(
|
||||
|
||||
/**
|
||||
* Holds if an external flow summary exists for `c` with input specification
|
||||
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
||||
* stating whether the summary is autogenerated.
|
||||
* `input`, output specification `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate summaryElement(
|
||||
FlowSummary::SummarizedCallable c, string input, string output, string kind, boolean generated
|
||||
FlowSummary::SummarizedCallable c, string input, string output, string kind, string provenance
|
||||
) {
|
||||
exists(boolean preservesValue |
|
||||
c.propagatesFlowExt(input, output, preservesValue) and
|
||||
(if preservesValue = true then kind = "value" else kind = "taint") and
|
||||
generated = false
|
||||
provenance = "manual"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a neutral model exists for `c`, which means that there is no
|
||||
* flow through `c`. The flag `generated` states whether the neutral model is autogenerated.
|
||||
* Holds if a neutral model exists for `c` with provenance `provenance`,
|
||||
* which means that there is no flow through `c`.
|
||||
* Note. Neutral models have not been implemented for Python.
|
||||
*/
|
||||
predicate neutralElement(FlowSummary::SummarizedCallable c, boolean generated) { none() }
|
||||
predicate neutralElement(FlowSummary::SummarizedCallable c, string provenance) { none() }
|
||||
|
||||
/**
|
||||
* Gets the summary component for specification component `c`, if any.
|
||||
@@ -137,17 +136,15 @@ ReturnKind getReturnValueKind() { any() }
|
||||
private module UnusedSourceSinkInterpretation {
|
||||
/**
|
||||
* Holds if an external source specification exists for `n` with output specification
|
||||
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
|
||||
* autogenerated.
|
||||
* `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate sourceElement(AstNode n, string output, string kind, boolean generated) { none() }
|
||||
predicate sourceElement(AstNode n, string output, string kind, string provenance) { none() }
|
||||
|
||||
/**
|
||||
* Holds if an external sink specification exists for `n` with input specification
|
||||
* `input`, kind `kind` and a flag `generated` stating whether the sink specification is
|
||||
* autogenerated.
|
||||
* `input`, kind `kind` and provenance `provenance`.
|
||||
*/
|
||||
predicate sinkElement(AstNode n, string input, string kind, boolean generated) { none() }
|
||||
predicate sinkElement(AstNode n, string input, string kind, string provenance) { none() }
|
||||
|
||||
class SourceOrSinkElement = AstNode;
|
||||
|
||||
|
||||
@@ -241,15 +241,19 @@ module Public {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the summary is auto generated and not manually generated.
|
||||
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
|
||||
*/
|
||||
predicate isAutoGenerated() { none() }
|
||||
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
|
||||
|
||||
/**
|
||||
* Holds if the summary has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual summary that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { none() }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if there exists a summary that applies to `this` that has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { none() }
|
||||
}
|
||||
|
||||
/** A callable where there is no flow via the callable. */
|
||||
@@ -257,15 +261,19 @@ module Public {
|
||||
NeutralCallable() { neutralElement(this, _) }
|
||||
|
||||
/**
|
||||
* Holds if the neutral is auto generated.
|
||||
* Holds if the neutral is auto generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { neutralElement(this, true) }
|
||||
predicate isAutoGenerated() { neutralElement(this, "generated") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual neutral that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { neutralElement(this, generated) }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { neutralElement(this, provenance) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -997,12 +1005,12 @@ module Private {
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
AccessPath inSpec, AccessPath outSpec, string kind
|
||||
) {
|
||||
summaryElement(this, inSpec, outSpec, kind, true) and
|
||||
not summaryElement(this, _, _, _, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "generated") and
|
||||
not summaryElement(this, _, _, _, "manual")
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
|
||||
summaryElement(this, inSpec, outSpec, kind, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "manual")
|
||||
or
|
||||
this.relevantSummaryElementGenerated(inSpec, outSpec, kind)
|
||||
}
|
||||
@@ -1021,10 +1029,8 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) }
|
||||
|
||||
override predicate hasProvenance(boolean generated) {
|
||||
summaryElement(this, _, _, _, generated)
|
||||
override predicate hasProvenance(string provenance) {
|
||||
summaryElement(this, _, _, _, provenance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,25 +49,23 @@ DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { any(
|
||||
|
||||
/**
|
||||
* Holds if an external flow summary exists for `c` with input specification
|
||||
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
||||
* stating whether the summary is autogenerated.
|
||||
* `input`, output specification `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate summaryElement(
|
||||
FlowSummary::SummarizedCallable c, string input, string output, string kind, boolean generated
|
||||
FlowSummary::SummarizedCallable c, string input, string output, string kind, string provenance
|
||||
) {
|
||||
exists(boolean preservesValue |
|
||||
c.propagatesFlowExt(input, output, preservesValue) and
|
||||
(if preservesValue = true then kind = "value" else kind = "taint") and
|
||||
generated = false
|
||||
provenance = "manual"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a neutral model exists for `c`, which means that there is no
|
||||
* flow through `c`. The flag `generated` states whether the neutral model is autogenerated.
|
||||
* Note. Neutral models have not been implemented for ruby.
|
||||
* Holds if a neutral model exists for `c` with provenance `provenance`,
|
||||
* which means that there is no flow through `c`.
|
||||
*/
|
||||
predicate neutralElement(FlowSummary::SummarizedCallable c, boolean generated) { none() }
|
||||
predicate neutralElement(FlowSummary::SummarizedCallable c, string provenance) { none() }
|
||||
|
||||
bindingset[arg]
|
||||
private SummaryComponent interpretElementArg(string arg) {
|
||||
@@ -207,17 +205,15 @@ NormalReturnKind getReturnValueKind() { any() }
|
||||
private module UnusedSourceSinkInterpretation {
|
||||
/**
|
||||
* Holds if an external source specification exists for `n` with output specification
|
||||
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
|
||||
* autogenerated.
|
||||
* `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate sourceElement(AstNode n, string output, string kind, boolean generated) { none() }
|
||||
predicate sourceElement(AstNode n, string output, string kind, string provenance) { none() }
|
||||
|
||||
/**
|
||||
* Holds if an external sink specification exists for `n` with input specification
|
||||
* `input`, kind `kind` and a flag `generated` stating whether the sink specification is
|
||||
* autogenerated.
|
||||
* `input`, kind `kind` and provenance `provenance`.
|
||||
*/
|
||||
predicate sinkElement(AstNode n, string input, string kind, boolean generated) { none() }
|
||||
predicate sinkElement(AstNode n, string input, string kind, string provenance) { none() }
|
||||
|
||||
class SourceOrSinkElement = AstNode;
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
|
||||
/** Holds if a source model exists for the given parameters. */
|
||||
predicate sourceModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string output, string kind, boolean generated
|
||||
string output, string kind, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
sourceModel(row) and
|
||||
@@ -149,13 +149,13 @@ predicate sourceModel(
|
||||
row.splitAt(";", 6) = output and
|
||||
row.splitAt(";", 7) = kind
|
||||
) and
|
||||
generated = false
|
||||
provenance = "manual"
|
||||
}
|
||||
|
||||
/** Holds if a sink model exists for the given parameters. */
|
||||
predicate sinkModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string kind, boolean generated
|
||||
string input, string kind, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
sinkModel(row) and
|
||||
@@ -169,13 +169,13 @@ predicate sinkModel(
|
||||
row.splitAt(";", 6) = input and
|
||||
row.splitAt(";", 7) = kind
|
||||
) and
|
||||
generated = false
|
||||
provenance = "manual"
|
||||
}
|
||||
|
||||
/** Holds if a summary model exists for the given parameters. */
|
||||
predicate summaryModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string output, string kind, boolean generated
|
||||
string input, string output, string kind, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
summaryModel(row) and
|
||||
@@ -190,7 +190,7 @@ predicate summaryModel(
|
||||
row.splitAt(";", 7) = output and
|
||||
row.splitAt(";", 8) = kind
|
||||
) and
|
||||
generated = false
|
||||
provenance = "manual"
|
||||
}
|
||||
|
||||
private predicate relevantNamespace(string namespace) {
|
||||
@@ -224,25 +224,25 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
|
||||
part = "source" and
|
||||
n =
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string output, boolean generated |
|
||||
string ext, string output, string provenance |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, generated)
|
||||
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance)
|
||||
)
|
||||
or
|
||||
part = "sink" and
|
||||
n =
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string input, boolean generated |
|
||||
string ext, string input, string provenance |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, generated)
|
||||
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance)
|
||||
)
|
||||
or
|
||||
part = "summary" and
|
||||
n =
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string input, string output, boolean generated |
|
||||
string ext, string input, string output, string provenance |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, generated)
|
||||
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -241,15 +241,19 @@ module Public {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the summary is auto generated and not manually generated.
|
||||
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
|
||||
*/
|
||||
predicate isAutoGenerated() { none() }
|
||||
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
|
||||
|
||||
/**
|
||||
* Holds if the summary has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual summary that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { none() }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if there exists a summary that applies to `this` that has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { none() }
|
||||
}
|
||||
|
||||
/** A callable where there is no flow via the callable. */
|
||||
@@ -257,15 +261,19 @@ module Public {
|
||||
NeutralCallable() { neutralElement(this, _) }
|
||||
|
||||
/**
|
||||
* Holds if the neutral is auto generated.
|
||||
* Holds if the neutral is auto generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { neutralElement(this, true) }
|
||||
predicate isAutoGenerated() { neutralElement(this, "generated") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
* Holds if there exists a manual neutral that applies to `this`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { neutralElement(this, generated) }
|
||||
final predicate isManual() { this.hasProvenance("manual") }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has provenance `provenance`.
|
||||
*/
|
||||
predicate hasProvenance(string provenance) { neutralElement(this, provenance) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -997,12 +1005,12 @@ module Private {
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
AccessPath inSpec, AccessPath outSpec, string kind
|
||||
) {
|
||||
summaryElement(this, inSpec, outSpec, kind, true) and
|
||||
not summaryElement(this, _, _, _, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "generated") and
|
||||
not summaryElement(this, _, _, _, "manual")
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
|
||||
summaryElement(this, inSpec, outSpec, kind, false)
|
||||
summaryElement(this, inSpec, outSpec, kind, "manual")
|
||||
or
|
||||
this.relevantSummaryElementGenerated(inSpec, outSpec, kind)
|
||||
}
|
||||
@@ -1021,10 +1029,8 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) }
|
||||
|
||||
override predicate hasProvenance(boolean generated) {
|
||||
summaryElement(this, _, _, _, generated)
|
||||
override predicate hasProvenance(string provenance) {
|
||||
summaryElement(this, _, _, _, provenance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,51 +56,47 @@ DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { any(
|
||||
|
||||
/**
|
||||
* Holds if an external flow summary exists for `c` with input specification
|
||||
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
||||
* stating whether the summary is autogenerated.
|
||||
* `input`, output specification `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate summaryElement(
|
||||
AbstractFunctionDecl c, string input, string output, string kind, boolean generated
|
||||
AbstractFunctionDecl c, string input, string output, string kind, string provenance
|
||||
) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated) and
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) and
|
||||
c = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a neutral model exists for `c`, which means that there is no
|
||||
* flow through `c`. The flag `generated` states whether the neutral model is autogenerated.
|
||||
* Note. Neutral models have not been implemented for swift.
|
||||
* Holds if a neutral model exists for `c` with provenance `provenance`,
|
||||
* which means that there is no flow through `c`.
|
||||
*/
|
||||
predicate neutralElement(AbstractFunctionDecl c, boolean generated) { none() }
|
||||
predicate neutralElement(AbstractFunctionDecl c, string provenance) { none() }
|
||||
|
||||
/**
|
||||
* Holds if an external source specification exists for `e` with output specification
|
||||
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
|
||||
* autogenerated.
|
||||
* `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate sourceElement(Element e, string output, string kind, boolean generated) {
|
||||
predicate sourceElement(Element e, string output, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, generated) and
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an external sink specification exists for `e` with input specification
|
||||
* `input`, kind `kind` and a flag `generated` stating whether the sink specification is
|
||||
* autogenerated.
|
||||
* `input`, kind `kind` and provenance `provenance`.
|
||||
*/
|
||||
predicate sinkElement(Element e, string input, string kind, boolean generated) {
|
||||
predicate sinkElement(Element e, string input, string kind, string provenance) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, generated) and
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user