C#/Java: Add a query that uses both content based and non-content based model generation.

This commit is contained in:
Michael Nebel
2024-09-23 11:02:21 +02:00
parent a128383760
commit 8310faa2e9
9 changed files with 93 additions and 7 deletions

View File

@@ -9,5 +9,5 @@
import internal.CaptureModels
from DataFlowSummaryTargetApi api, string flow
where flow = ContentSensitive::captureFlow(api)
where flow = ContentSensitive::captureFlow(api, _)
select flow order by flow

View File

@@ -0,0 +1,13 @@
/**
* @name Capture mixed neutral models.
* @description Finds neutral models to be used by other queries.
* @kind diagnostic
* @id cs/utils/modelgenerator/mixed-neutral-models
* @tags modelgenerator
*/
import internal.CaptureModels
from DataFlowSummaryTargetApi api, string noflow
where noflow = captureMixedNeutral(api)
select noflow order by noflow

View File

@@ -0,0 +1,13 @@
/**
* @name Capture mixed summary models.
* @description Finds applicable summary models to be used by other queries.
* @kind diagnostic
* @id cs/utils/modelgenerator/mixed-summary-models
* @tags modelgenerator
*/
import internal.CaptureModels
from DataFlowSummaryTargetApi api, string flow
where flow = captureMixedFlow(api, _)
select flow order by flow

View File

@@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels
import TestUtilities.InlineMadTest
module InlineMadTestConfig implements InlineMadTestConfigSig {
string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c) }
string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _) }
string getKind() { result = "contentbased-summary" }
}

View File

@@ -9,5 +9,5 @@
import internal.CaptureModels
from DataFlowSummaryTargetApi api, string flow
where flow = ContentSensitive::captureFlow(api)
where flow = ContentSensitive::captureFlow(api, _)
select flow order by flow

View File

@@ -0,0 +1,13 @@
/**
* @name Capture mixed neutral models.
* @description Finds neutral models to be used by other queries.
* @kind diagnostic
* @id java/utils/modelgenerator/mixed-neutral-models
* @tags modelgenerator
*/
import internal.CaptureModels
from DataFlowSummaryTargetApi api, string noflow
where noflow = captureMixedNeutral(api)
select noflow order by noflow

View File

@@ -0,0 +1,13 @@
/**
* @name Capture mixed summary models.
* @description Finds applicable summary models to be used by other queries.
* @kind diagnostic
* @id java/utils/modelgenerator/mixed-summary-models
* @tags modelgenerator
*/
import internal.CaptureModels
from DataFlowSummaryTargetApi api, string flow
where flow = captureMixedFlow(api, _)
select flow order by flow

View File

@@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels
import TestUtilities.InlineMadTest
module InlineMadTestConfig implements InlineMadTestConfigSig {
string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c) }
string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _) }
string getKind() { result = "contentbased-summary" }
}

View File

@@ -854,13 +854,13 @@ module MakeModelGenerator<
/**
* Gets the content based summary model(s) of the API `api` (if there is flow from a parameter to
* the return value or a parameter).
* the return value or a parameter). `lift` is true, if the model should be lifted, otherwise false.
*
* Models are lifted to the best type in case the read and store access paths do not
* contain a field or synthetic field access.
*/
string captureFlow(ContentDataFlowSummaryTargetApi api) {
exists(string input, string output, boolean lift, boolean preservesValue |
string captureFlow(ContentDataFlowSummaryTargetApi api, boolean lift) {
exists(string input, string output, boolean preservesValue |
captureFlow0(api, input, output, _, lift) and
preservesValue = max(boolean p | captureFlow0(api, input, output, p, lift)) and
result = ContentModelPrinting::asModel(api, input, output, preservesValue, lift)
@@ -868,6 +868,40 @@ module MakeModelGenerator<
}
}
/**
* Gets the summary model(s) for `api`, if any. `lift` is true if the model is lifted
* otherwise false.
* The following heuristic is applied:
* 1. If content based flow yields at lease one summary for an API, then we use that.
* 2. If content based flow does not yield any summary for an API, then we try and
* generate flow summaries using the non-content based summary generator.
*/
string captureMixedFlow(DataFlowSummaryTargetApi api, boolean lift) {
result = ContentSensitive::captureFlow(api, lift)
or
not exists(ContentSensitive::captureFlow(api, lift)) and
result = captureFlow(api) and
lift = true
}
/**
* Gets the neutral summary model for `api`, if any.
* A neutral summary model is generated, if we are not generating
* a mixed summary model that applies to `api`.
*/
string captureMixedNeutral(DataFlowSummaryTargetApi api) {
not exists(DataFlowSummaryTargetApi api0, boolean lift |
exists(captureMixedFlow(api0, lift)) and
(
lift = false and api0 = api
or
lift = true and api0.lift() = api.lift()
)
) and
api.isRelevant() and
result = ModelPrinting::asNeutralSummaryModel(api)
}
/**
* A dataflow configuration used for finding new sources.
* The sources are the already known existing sources and the sinks are the API return nodes.