Go: Move Go package-grouping support into shared lib.

This commit is contained in:
Anders Schack-Mulligen
2025-12-11 10:35:39 +01:00
parent e262438557
commit 5bddc8d289
8 changed files with 104 additions and 138 deletions

View File

@@ -53,4 +53,6 @@ extensible predicate neutralModel(
module Extensions implements SharedMaD::ExtensionsSig { module Extensions implements SharedMaD::ExtensionsSig {
import ExternalFlowExtensions import ExternalFlowExtensions
predicate packageGrouping(string group, string package) { none() }
} }

View File

@@ -53,4 +53,6 @@ extensible predicate neutralModel(
module Extensions implements SharedMaD::ExtensionsSig { module Extensions implements SharedMaD::ExtensionsSig {
import ExternalFlowExtensions import ExternalFlowExtensions
predicate packageGrouping(string group, string package) { none() }
} }

View File

@@ -107,86 +107,6 @@ module FlowExtensions = Extensions;
/** Gets the prefix for a group of packages. */ /** Gets the prefix for a group of packages. */
private string groupPrefix() { result = "group:" } private string groupPrefix() { result = "group:" }
/**
* Gets a package represented by `packageOrGroup`.
*
* If `packageOrGroup` is of the form `group:<groupname>` then `result` is a
* package in the group `<groupname>`, as determined by `packageGrouping`.
* Otherwise, `result` is `packageOrGroup`.
*/
bindingset[packageOrGroup]
private string getPackage(string packageOrGroup) {
not exists(string group | packageOrGroup = groupPrefix() + group) and result = packageOrGroup
or
exists(string group |
FlowExtensions::packageGrouping(group, result) and
packageOrGroup = groupPrefix() + group
)
}
/**
* Holds if a source model exists for the given parameters.
*
* Note that `group:` references are expanded into one or more actual packages
* by this predicate.
*/
predicate sourceModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
exists(string packageOrGroup |
package = getPackage(packageOrGroup) and
FlowExtensions::sourceModel(packageOrGroup, type, subtypes, name, signature, ext, output, kind,
provenance, madId)
)
}
/**
* Holds if a sink model exists for the given parameters.
*
* Note that `group:` references are expanded into one or more actual packages
* by this predicate.
*/
predicate sinkModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
exists(string packageOrGroup | package = getPackage(packageOrGroup) |
FlowExtensions::sinkModel(packageOrGroup, type, subtypes, name, signature, ext, input, kind,
provenance, madId)
)
}
/**
* Holds if a summary model exists for the given parameters.
*
* Note that `group:` references are expanded into one or more actual packages
* by this predicate.
*/
predicate summaryModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
exists(string packageOrGroup | package = getPackage(packageOrGroup) |
FlowExtensions::summaryModel(packageOrGroup, type, subtypes, name, signature, ext, input,
output, kind, provenance, madId)
)
}
/**
* Holds if a neutral model exists for the given parameters.
*
* Note that `group:` references are expanded into one or more actual packages
* by this predicate.
*/
predicate neutralModel(
string package, string type, string name, string signature, string kind, string provenance
) {
exists(string packageOrGroup | package = getPackage(packageOrGroup) |
FlowExtensions::neutralModel(packageOrGroup, type, name, signature, kind, provenance)
)
}
bindingset[p] bindingset[p]
private string cleanPackage(string p) { private string cleanPackage(string p) {
exists(string noPrefix | exists(string noPrefix |

View File

@@ -137,11 +137,9 @@ module SourceSinkInterpretationInput implements
SourceOrSinkElement e, string output, string kind, Public::Provenance provenance, string model SourceOrSinkElement e, string output, string kind, Public::Provenance provenance, string model
) { ) {
exists( exists(
string package, string type, boolean subtypes, string name, string signature, string ext, string package, string type, boolean subtypes, string name, string signature, string ext
QlBuiltins::ExtensionId madId
| |
sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance, madId) and sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance, model) and
model = "MaD:" + madId.toString() and
e = interpretElement(package, type, subtypes, name, signature, ext) e = interpretElement(package, type, subtypes, name, signature, ext)
) )
} }
@@ -154,11 +152,9 @@ module SourceSinkInterpretationInput implements
SourceOrSinkElement e, string input, string kind, Public::Provenance provenance, string model SourceOrSinkElement e, string input, string kind, Public::Provenance provenance, string model
) { ) {
exists( exists(
string package, string type, boolean subtypes, string name, string signature, string ext, string package, string type, boolean subtypes, string name, string signature, string ext
QlBuiltins::ExtensionId madId
| |
sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, madId) and sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, model) and
model = "MaD:" + madId.toString() and
e = interpretElement(package, type, subtypes, name, signature, ext) e = interpretElement(package, type, subtypes, name, signature, ext)
) )
} }
@@ -504,12 +500,10 @@ module Private {
string model string model
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext
QlBuiltins::ExtensionId madId
| |
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind,
provenance, madId) and provenance, model) and
model = "MaD:" + madId.toString() and
c.asFunction() = c.asFunction() =
interpretElement(namespace, type, subtypes, name, signature, ext).asEntity() interpretElement(namespace, type, subtypes, name, signature, ext).asEntity()
) )

View File

@@ -192,24 +192,6 @@ abstract private class ActiveExperimentalModelsInternal extends string {
deprecated class ActiveExperimentalModels = ActiveExperimentalModelsInternal; deprecated class ActiveExperimentalModels = ActiveExperimentalModelsInternal;
/** Holds if a barrier model exists for the given parameters. */
predicate barrierModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
Extensions::barrierModel(package, type, subtypes, name, signature, ext, output, kind, provenance,
madId)
}
/** Holds if a barrier guard model exists for the given parameters. */
predicate barrierGuardModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string input, string acceptingvalue, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
Extensions::barrierGuardModel(package, type, subtypes, name, signature, ext, input,
acceptingvalue, kind, provenance, madId)
}
/** /**
* Holds if the given extension tuple `madId` should pretty-print as `model`. * Holds if the given extension tuple `madId` should pretty-print as `model`.
* *
@@ -255,9 +237,6 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
) )
} }
/** Holds if a neutral model exists for the given parameters. */
predicate neutralModel = Extensions::neutralModel/6;
/** Provides a query predicate to check the MaD models for validation errors. */ /** Provides a query predicate to check the MaD models for validation errors. */
module ModelValidation { module ModelValidation {
private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax

View File

@@ -98,4 +98,6 @@ extensible predicate experimentalSummaryModel(
module Extensions implements SharedMaD::ExtensionsSig { module Extensions implements SharedMaD::ExtensionsSig {
import ExternalFlowExtensions import ExternalFlowExtensions
predicate packageGrouping(string group, string package) { none() }
} }

View File

@@ -264,11 +264,10 @@ module SourceSinkInterpretationInput implements
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext,
SourceOrSinkElement baseBarrier, string originalOutput, QlBuiltins::ExtensionId madId SourceOrSinkElement baseBarrier, string originalOutput
| |
barrierModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, barrierModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind,
provenance, madId) and provenance, model) and
model = "MaD:" + madId.toString() and
baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
( (
e = baseBarrier and output = originalOutput e = baseBarrier and output = originalOutput
@@ -284,11 +283,10 @@ module SourceSinkInterpretationInput implements
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext,
SourceOrSinkElement baseBarrier, string originalInput, QlBuiltins::ExtensionId madId SourceOrSinkElement baseBarrier, string originalInput
| |
barrierGuardModel(namespace, type, subtypes, name, signature, ext, originalInput, barrierGuardModel(namespace, type, subtypes, name, signature, ext, originalInput,
acceptingvalue, kind, provenance, madId) and acceptingvalue, kind, provenance, model) and
model = "MaD:" + madId.toString() and
baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
( (
e = baseBarrier and input = originalInput e = baseBarrier and input = originalInput

View File

@@ -49,6 +49,11 @@ signature module ExtensionsSig {
predicate neutralModel( predicate neutralModel(
string namespace, string type, string name, string signature, string kind, string provenance string namespace, string type, string name, string signature, string kind, string provenance
); );
/**
* Holds if the package `package` is part of the group `group`.
*/
predicate packageGrouping(string group, string package);
} }
signature module InputSig { signature module InputSig {
@@ -157,6 +162,27 @@ module ModelsAsData<ExtensionsSig Extensions, InputSig Input> {
) )
} }
/** Gets the prefix for a group of packages/namespaces. */
private string groupPrefix() { result = "group:" }
/**
* Gets a package/namespace represented by `namespaceOrGroup`.
*
* If `namespaceOrGroup` is of the form `group:<groupname>` then `result` is a
* package/namespace in the group `<groupname>`, as determined by `packageGrouping`.
* Otherwise, `result` is `namespaceOrGroup`.
*/
bindingset[namespaceOrGroup]
private string getNamespace(string namespaceOrGroup) {
not exists(string group | namespaceOrGroup = groupPrefix() + group) and
result = namespaceOrGroup
or
exists(string group |
Extensions::packageGrouping(group, result) and
namespaceOrGroup = groupPrefix() + group
)
}
/** /**
* Holds if a source model exists for the given parameters. * Holds if a source model exists for the given parameters.
*/ */
@@ -164,14 +190,16 @@ module ModelsAsData<ExtensionsSig Extensions, InputSig Input> {
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, string model string output, string kind, string provenance, string model
) { ) {
exists(QlBuiltins::ExtensionId madId | exists(string namespaceOrGroup | namespace = getNamespace(namespaceOrGroup) |
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, exists(QlBuiltins::ExtensionId madId |
provenance, madId) and Extensions::sourceModel(namespaceOrGroup, type, subtypes, name, signature, ext, output,
model = "MaD:" + madId.toString() kind, provenance, madId) and
model = "MaD:" + madId.toString()
)
or
Input::additionalSourceModel(namespaceOrGroup, type, subtypes, name, signature, ext, output,
kind, provenance, model)
) )
or
Input::additionalSourceModel(namespace, type, subtypes, name, signature, ext, output, kind,
provenance, model)
} }
/** /**
@@ -181,14 +209,42 @@ module ModelsAsData<ExtensionsSig Extensions, InputSig Input> {
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance, string model string input, string kind, string provenance, string model
) { ) {
exists(QlBuiltins::ExtensionId madId | exists(string namespaceOrGroup | namespace = getNamespace(namespaceOrGroup) |
Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, exists(QlBuiltins::ExtensionId madId |
Extensions::sinkModel(namespaceOrGroup, type, subtypes, name, signature, ext, input, kind,
provenance, madId) and
model = "MaD:" + madId.toString()
)
or
Input::additionalSinkModel(namespaceOrGroup, type, subtypes, name, signature, ext, input,
kind, provenance, model)
)
}
/** Holds if a barrier model exists for the given parameters. */
predicate barrierModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, string model
) {
exists(string namespaceOrGroup, QlBuiltins::ExtensionId madId |
namespace = getNamespace(namespaceOrGroup) and
Extensions::barrierModel(namespaceOrGroup, type, subtypes, name, signature, ext, output, kind,
provenance, madId) and provenance, madId) and
model = "MaD:" + madId.toString() model = "MaD:" + madId.toString()
) )
or }
Input::additionalSinkModel(namespace, type, subtypes, name, signature, ext, input, kind,
provenance, model) /** Holds if a barrier guard model exists for the given parameters. */
predicate barrierGuardModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string acceptingvalue, string kind, string provenance, string model
) {
exists(string namespaceOrGroup, QlBuiltins::ExtensionId madId |
namespace = getNamespace(namespaceOrGroup) and
Extensions::barrierGuardModel(namespaceOrGroup, type, subtypes, name, signature, ext, input,
acceptingvalue, kind, provenance, madId) and
model = "MaD:" + madId.toString()
)
} }
/** /**
@@ -198,14 +254,27 @@ module ModelsAsData<ExtensionsSig Extensions, InputSig Input> {
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance, string model string input, string output, string kind, string provenance, string model
) { ) {
exists(QlBuiltins::ExtensionId madId | exists(string namespaceOrGroup | namespace = getNamespace(namespaceOrGroup) |
Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, exists(QlBuiltins::ExtensionId madId |
provenance, madId) and Extensions::summaryModel(namespaceOrGroup, type, subtypes, name, signature, ext, input,
model = "MaD:" + madId.toString() output, kind, provenance, madId) and
model = "MaD:" + madId.toString()
)
or
Input::additionalSummaryModel(namespaceOrGroup, type, subtypes, name, signature, ext, input,
output, kind, provenance, model)
)
}
/**
* Holds if a neutral model exists for the given parameters.
*/
predicate neutralModel(
string namespace, string type, string name, string signature, string kind, string provenance
) {
exists(string namespaceOrGroup | namespace = getNamespace(namespaceOrGroup) |
Extensions::neutralModel(namespaceOrGroup, type, name, signature, kind, provenance)
) )
or
Input::additionalSummaryModel(namespace, type, subtypes, name, signature, ext, input, output,
kind, provenance, model)
} }
private predicate relevantNamespace(string namespace) { private predicate relevantNamespace(string namespace) {