mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #16775 from michaelnebel/modelgen/refactorprinting
C#/Java: Parameterized module for model printing.
This commit is contained in:
@@ -61,10 +61,6 @@
|
||||
"java/ql/src/utils/modelgenerator/internal/CaptureModels.qll",
|
||||
"csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll"
|
||||
],
|
||||
"Model as Data Generation Java/C# - CaptureModelsPrinting": [
|
||||
"java/ql/src/utils/modelgenerator/internal/CaptureModelsPrinting.qll",
|
||||
"csharp/ql/src/utils/modelgenerator/internal/CaptureModelsPrinting.qll"
|
||||
],
|
||||
"Sign Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
|
||||
|
||||
@@ -376,7 +376,7 @@ private predicate callableInfo(Callable c, string name, UnboundValueOrRefType de
|
||||
private class InterpretedCallable extends Callable {
|
||||
InterpretedCallable() {
|
||||
exists(string namespace, string type, string name |
|
||||
partialModel(this, namespace, type, name, _) and
|
||||
partialModel(this, namespace, type, _, name, _) and
|
||||
elementSpec(namespace, type, _, name, _, _)
|
||||
)
|
||||
or
|
||||
@@ -520,32 +520,19 @@ string parameterQualifiedTypeNamesToString(Callable c) {
|
||||
}
|
||||
|
||||
predicate partialModel(
|
||||
UnboundCallable c, string namespace, string type, string name, string parameters
|
||||
Callable c, string namespace, string type, string extensible, string name, string parameters
|
||||
) {
|
||||
QN::hasQualifiedName(c, namespace, type, name) and
|
||||
extensible = getCallableOverride(c) and
|
||||
parameters = "(" + parameterQualifiedTypeNamesToString(c) + ")"
|
||||
}
|
||||
|
||||
/** Computes the first 6 columns for positive CSV rows of `c`. */
|
||||
string asPartialModel(UnboundCallable c) {
|
||||
exists(string namespace, string type, string name, string parameters |
|
||||
partialModel(c, namespace, type, name, parameters) and
|
||||
result =
|
||||
namespace + ";" //
|
||||
+ type + ";" //
|
||||
+ getCallableOverride(c) + ";" //
|
||||
+ name + ";" //
|
||||
+ parameters + ";" //
|
||||
+ /* ext + */ ";" //
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the signature of `c` in the format `namespace;type;name;parameters`.
|
||||
*/
|
||||
string getSignature(UnboundCallable c) {
|
||||
exists(string namespace, string type, string name, string parameters |
|
||||
partialModel(c, namespace, type, name, parameters)
|
||||
partialModel(c, namespace, type, _, name, parameters)
|
||||
|
|
||||
result =
|
||||
namespace + ";" //
|
||||
|
||||
@@ -8,7 +8,7 @@ predicate interpretCallable(
|
||||
) {
|
||||
exists(Callable c, string signature1 |
|
||||
c = interpretBaseDeclaration(namespace0, type0, name0, signature0) and
|
||||
partialModel(c, namespace, type, name, signature1) and
|
||||
partialModel(c, namespace, type, _, name, signature1) and
|
||||
if signature0 = "" then signature = "" else signature = signature1
|
||||
)
|
||||
or
|
||||
|
||||
@@ -33,13 +33,13 @@ class DataFlowTargetApi extends TargetApiSpecific {
|
||||
DataFlowTargetApi() { not isUninterestingForDataFlowModels(this) }
|
||||
}
|
||||
|
||||
private module Printing implements PrintingSig {
|
||||
private module ModelPrintingInput implements ModelPrintingSig {
|
||||
class Api = DataFlowTargetApi;
|
||||
|
||||
string getProvenance() { result = "df-generated" }
|
||||
}
|
||||
|
||||
module ModelPrinting = PrintingImpl<Printing>;
|
||||
module Printing = ModelPrinting<ModelPrintingInput>;
|
||||
|
||||
/**
|
||||
* Holds if `c` is a relevant content kind, where the underlying type is relevant.
|
||||
@@ -94,7 +94,7 @@ string captureQualifierFlow(TargetApiSpecific api) {
|
||||
api = returnNodeEnclosingCallable(ret) and
|
||||
isOwnInstanceAccessNode(ret)
|
||||
) and
|
||||
result = ModelPrinting::asValueModel(api, qualifierString(), "ReturnValue")
|
||||
result = Printing::asValueModel(api, qualifierString(), "ReturnValue")
|
||||
}
|
||||
|
||||
private int accessPathLimit0() { result = 2 }
|
||||
@@ -202,7 +202,7 @@ string captureThroughFlow(DataFlowTargetApi api) {
|
||||
input = parameterNodeAsInput(p) and
|
||||
output = returnNodeExt.getOutput() and
|
||||
input != output and
|
||||
result = ModelPrinting::asTaintModel(api, input, output)
|
||||
result = Printing::asTaintModel(api, input, output)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ string captureSource(DataFlowTargetApi api) {
|
||||
ExternalFlow::sourceNode(source, kind) and
|
||||
api = sink.getEnclosingCallable() and
|
||||
not irrelevantSourceSinkApi(source.getEnclosingCallable(), api) and
|
||||
result = ModelPrinting::asSourceModel(api, sink.getOutput(), kind)
|
||||
result = Printing::asSourceModel(api, sink.getOutput(), kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -291,6 +291,6 @@ string captureSink(DataFlowTargetApi api) {
|
||||
PropagateToSink::flow(src, sink) and
|
||||
ExternalFlow::sinkNode(sink, kind) and
|
||||
api = src.getEnclosingCallable() and
|
||||
result = ModelPrinting::asSinkModel(api, asInputArgument(src), kind)
|
||||
result = Printing::asSinkModel(api, asInputArgument(src), kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,72 +1,11 @@
|
||||
private import CaptureModelsSpecific
|
||||
private import csharp as CS
|
||||
private import codeql.mad.modelgenerator.ModelPrinting
|
||||
private import semmle.code.csharp.dataflow.internal.ExternalFlow as ExternalFlow
|
||||
|
||||
signature module PrintingSig {
|
||||
/**
|
||||
* The class of APIs relevant for model generation.
|
||||
*/
|
||||
class Api extends TargetApiSpecific;
|
||||
private module ModelPrintingLang implements ModelPrintingLangSig {
|
||||
class Callable = CS::Callable;
|
||||
|
||||
/**
|
||||
* Gets the string representation of the provenance of the models.
|
||||
*/
|
||||
string getProvenance();
|
||||
predicate partialModel = ExternalFlow::partialModel/6;
|
||||
}
|
||||
|
||||
module PrintingImpl<PrintingSig Printing> {
|
||||
/**
|
||||
* Gets the summary model for `api` with `input`, `output` and `kind`.
|
||||
*/
|
||||
bindingset[input, output, kind]
|
||||
private string asSummaryModel(Printing::Api api, string input, string output, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + input + ";" //
|
||||
+ output + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
string asNeutralSummaryModel(Printing::Api api) {
|
||||
result =
|
||||
asPartialNeutralModel(api) //
|
||||
+ "summary" + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value summary model for `api` with `input` and `output`.
|
||||
*/
|
||||
bindingset[input, output]
|
||||
string asValueModel(Printing::Api api, string input, string output) {
|
||||
result = asSummaryModel(api, input, output, "value")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the taint summary model for `api` with `input` and `output`.
|
||||
*/
|
||||
bindingset[input, output]
|
||||
string asTaintModel(Printing::Api api, string input, string output) {
|
||||
result = asSummaryModel(api, input, output, "taint")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sink model for `api` with `input` and `kind`.
|
||||
*/
|
||||
bindingset[input, kind]
|
||||
string asSinkModel(Printing::Api api, string input, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + input + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source model for `api` with `output` and `kind`.
|
||||
*/
|
||||
bindingset[output, kind]
|
||||
string asSourceModel(Printing::Api api, string output, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + output + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
}
|
||||
import ModelPrintingImpl<ModelPrintingLang>
|
||||
|
||||
@@ -130,10 +130,6 @@ class TargetApiSpecific extends Callable {
|
||||
predicate isRelevant() { relevant(this) }
|
||||
}
|
||||
|
||||
string asPartialModel(TargetApiSpecific api) { result = ExternalFlow::asPartialModel(api.lift()) }
|
||||
|
||||
string asPartialNeutralModel(TargetApiSpecific api) { result = ExternalFlow::getSignature(api) }
|
||||
|
||||
/**
|
||||
* Holds if `t` is a type that is generally used for bulk data in collection types.
|
||||
* Eg. char[] is roughly equivalent to string and thus a highly
|
||||
|
||||
@@ -89,5 +89,5 @@ string captureFlow(DataFlowTargetApi api) {
|
||||
string captureNoFlow(DataFlowTargetApi api) {
|
||||
not exists(DataFlowTargetApi api0 | exists(captureFlow(api0)) and api0.lift() = api.lift()) and
|
||||
api.isRelevant() and
|
||||
result = ModelPrinting::asNeutralSummaryModel(api)
|
||||
result = Printing::asNeutralSummaryModel(api)
|
||||
}
|
||||
|
||||
@@ -177,13 +177,13 @@ private predicate output(Callable callable, TypeParameter tp, string output) {
|
||||
delegateSink(callable, tp, output)
|
||||
}
|
||||
|
||||
private module Printing implements PrintingSig {
|
||||
private module ModelPrintingInput implements ModelPrintingSig {
|
||||
class Api = TypeBasedFlowTargetApi;
|
||||
|
||||
string getProvenance() { result = "tb-generated" }
|
||||
}
|
||||
|
||||
private module ModelPrinting = PrintingImpl<Printing>;
|
||||
private module Printing = ModelPrinting<ModelPrintingInput>;
|
||||
|
||||
/**
|
||||
* A class of callables that are relevant generating summaries for based
|
||||
@@ -221,7 +221,7 @@ class TypeBasedFlowTargetApi extends Specific::TargetApiSpecific {
|
||||
output(this, tp, output) and
|
||||
input != output
|
||||
|
|
||||
result = ModelPrinting::asValueModel(this, input, output)
|
||||
result = Printing::asValueModel(this, input, output)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ class DataFlowTargetApi extends TargetApiSpecific {
|
||||
DataFlowTargetApi() { not isUninterestingForDataFlowModels(this) }
|
||||
}
|
||||
|
||||
private module Printing implements PrintingSig {
|
||||
private module ModelPrintingInput implements ModelPrintingSig {
|
||||
class Api = DataFlowTargetApi;
|
||||
|
||||
string getProvenance() { result = "df-generated" }
|
||||
}
|
||||
|
||||
module ModelPrinting = PrintingImpl<Printing>;
|
||||
module Printing = ModelPrinting<ModelPrintingInput>;
|
||||
|
||||
/**
|
||||
* Holds if `c` is a relevant content kind, where the underlying type is relevant.
|
||||
@@ -94,7 +94,7 @@ string captureQualifierFlow(TargetApiSpecific api) {
|
||||
api = returnNodeEnclosingCallable(ret) and
|
||||
isOwnInstanceAccessNode(ret)
|
||||
) and
|
||||
result = ModelPrinting::asValueModel(api, qualifierString(), "ReturnValue")
|
||||
result = Printing::asValueModel(api, qualifierString(), "ReturnValue")
|
||||
}
|
||||
|
||||
private int accessPathLimit0() { result = 2 }
|
||||
@@ -202,7 +202,7 @@ string captureThroughFlow(DataFlowTargetApi api) {
|
||||
input = parameterNodeAsInput(p) and
|
||||
output = returnNodeExt.getOutput() and
|
||||
input != output and
|
||||
result = ModelPrinting::asTaintModel(api, input, output)
|
||||
result = Printing::asTaintModel(api, input, output)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ string captureSource(DataFlowTargetApi api) {
|
||||
ExternalFlow::sourceNode(source, kind) and
|
||||
api = sink.getEnclosingCallable() and
|
||||
not irrelevantSourceSinkApi(source.getEnclosingCallable(), api) and
|
||||
result = ModelPrinting::asSourceModel(api, sink.getOutput(), kind)
|
||||
result = Printing::asSourceModel(api, sink.getOutput(), kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -291,6 +291,6 @@ string captureSink(DataFlowTargetApi api) {
|
||||
PropagateToSink::flow(src, sink) and
|
||||
ExternalFlow::sinkNode(sink, kind) and
|
||||
api = src.getEnclosingCallable() and
|
||||
result = ModelPrinting::asSinkModel(api, asInputArgument(src), kind)
|
||||
result = Printing::asSinkModel(api, asInputArgument(src), kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,72 +1,11 @@
|
||||
private import CaptureModelsSpecific
|
||||
private import java as J
|
||||
private import codeql.mad.modelgenerator.ModelPrinting
|
||||
private import CaptureModelsSpecific as Specific
|
||||
|
||||
signature module PrintingSig {
|
||||
/**
|
||||
* The class of APIs relevant for model generation.
|
||||
*/
|
||||
class Api extends TargetApiSpecific;
|
||||
private module ModelPrintingLang implements ModelPrintingLangSig {
|
||||
class Callable = J::Callable;
|
||||
|
||||
/**
|
||||
* Gets the string representation of the provenance of the models.
|
||||
*/
|
||||
string getProvenance();
|
||||
predicate partialModel = Specific::partialModel/6;
|
||||
}
|
||||
|
||||
module PrintingImpl<PrintingSig Printing> {
|
||||
/**
|
||||
* Gets the summary model for `api` with `input`, `output` and `kind`.
|
||||
*/
|
||||
bindingset[input, output, kind]
|
||||
private string asSummaryModel(Printing::Api api, string input, string output, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + input + ";" //
|
||||
+ output + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
string asNeutralSummaryModel(Printing::Api api) {
|
||||
result =
|
||||
asPartialNeutralModel(api) //
|
||||
+ "summary" + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value summary model for `api` with `input` and `output`.
|
||||
*/
|
||||
bindingset[input, output]
|
||||
string asValueModel(Printing::Api api, string input, string output) {
|
||||
result = asSummaryModel(api, input, output, "value")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the taint summary model for `api` with `input` and `output`.
|
||||
*/
|
||||
bindingset[input, output]
|
||||
string asTaintModel(Printing::Api api, string input, string output) {
|
||||
result = asSummaryModel(api, input, output, "taint")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sink model for `api` with `input` and `kind`.
|
||||
*/
|
||||
bindingset[input, kind]
|
||||
string asSinkModel(Printing::Api api, string input, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + input + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source model for `api` with `output` and `kind`.
|
||||
*/
|
||||
bindingset[output, kind]
|
||||
string asSourceModel(Printing::Api api, string output, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + output + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
}
|
||||
import ModelPrintingImpl<ModelPrintingLang>
|
||||
|
||||
@@ -110,53 +110,25 @@ private string isExtensible(Callable c) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate type name for the model.
|
||||
* Holds if the callable `c` is in package `package`
|
||||
* and is a member of `type`.
|
||||
*/
|
||||
private string typeAsModel(Callable c) {
|
||||
exists(RefType type | type = c.getDeclaringType() |
|
||||
result =
|
||||
type.getCompilationUnit().getPackage().getName() + ";" +
|
||||
type.getErasure().(J::RefType).nestedName()
|
||||
private predicate qualifiedName(Callable c, string package, string type) {
|
||||
exists(RefType t | t = c.getDeclaringType() |
|
||||
package = t.getCompilationUnit().getPackage().getName() and
|
||||
type = t.getErasure().(J::RefType).nestedName()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate partialModel(
|
||||
Callable api, string type, string extensible, string name, string parameters
|
||||
predicate partialModel(
|
||||
Callable api, string package, string type, string extensible, string name, string parameters
|
||||
) {
|
||||
type = typeAsModel(api) and
|
||||
qualifiedName(api, package, type) and
|
||||
extensible = isExtensible(api) and
|
||||
name = api.getName() and
|
||||
parameters = ExternalFlow::paramsString(api)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the first 6 columns for MaD rows.
|
||||
*/
|
||||
string asPartialModel(TargetApiSpecific api) {
|
||||
exists(string type, string extensible, string name, string parameters |
|
||||
partialModel(api.lift(), type, extensible, name, parameters) and
|
||||
result =
|
||||
type + ";" //
|
||||
+ extensible + ";" //
|
||||
+ name + ";" //
|
||||
+ parameters + ";" //
|
||||
+ /* ext + */ ";" //
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the first 4 columns for neutral MaD rows.
|
||||
*/
|
||||
string asPartialNeutralModel(TargetApiSpecific api) {
|
||||
exists(string type, string name, string parameters |
|
||||
partialModel(api, type, _, name, parameters) and
|
||||
result =
|
||||
type + ";" //
|
||||
+ name + ";" //
|
||||
+ parameters + ";" //
|
||||
)
|
||||
}
|
||||
|
||||
predicate isPrimitiveTypeUsedForBulkData(J::Type t) {
|
||||
t.hasName(["byte", "char", "Byte", "Character"])
|
||||
}
|
||||
|
||||
@@ -80,5 +80,5 @@ string captureFlow(DataFlowTargetApi api) {
|
||||
string captureNoFlow(DataFlowTargetApi api) {
|
||||
not exists(DataFlowTargetApi api0 | exists(captureFlow(api0)) and api0.lift() = api.lift()) and
|
||||
api.isRelevant() and
|
||||
result = ModelPrinting::asNeutralSummaryModel(api)
|
||||
result = Printing::asNeutralSummaryModel(api)
|
||||
}
|
||||
|
||||
@@ -283,13 +283,13 @@ private predicate output(Callable callable, TypeVariable tv, string output) {
|
||||
functionalSink(callable, tv, output)
|
||||
}
|
||||
|
||||
module Printing implements PrintingSig {
|
||||
module ModelPrintingInput implements ModelPrintingSig {
|
||||
class Api = TypeBasedFlowTargetApi;
|
||||
|
||||
string getProvenance() { result = "tb-generated" }
|
||||
}
|
||||
|
||||
private module ModelPrinting = PrintingImpl<Printing>;
|
||||
private module Printing = ModelPrinting<ModelPrintingInput>;
|
||||
|
||||
/**
|
||||
* A class of callables that are relevant generating summaries for based
|
||||
@@ -327,7 +327,7 @@ class TypeBasedFlowTargetApi extends Specific::TargetApiSpecific {
|
||||
output(this, tv, output) and
|
||||
input != output
|
||||
|
|
||||
result = ModelPrinting::asValueModel(this, input, output)
|
||||
result = Printing::asValueModel(this, input, output)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
120
shared/mad/codeql/mad/modelgenerator/ModelPrinting.qll
Normal file
120
shared/mad/codeql/mad/modelgenerator/ModelPrinting.qll
Normal file
@@ -0,0 +1,120 @@
|
||||
signature module ModelPrintingLangSig {
|
||||
/**
|
||||
* A class of callables.
|
||||
*/
|
||||
class Callable;
|
||||
|
||||
/**
|
||||
* Holds if `container`, `type`, `name`, and `parameters` contain the type signature of `api`
|
||||
* and `extensible` is the string representation of a boolean that is true, if
|
||||
* `api` can be overridden (otherwise false).
|
||||
*/
|
||||
predicate partialModel(
|
||||
Callable api, string container, string type, string extensible, string name, string parameters
|
||||
);
|
||||
}
|
||||
|
||||
module ModelPrintingImpl<ModelPrintingLangSig Lang> {
|
||||
signature module ModelPrintingSig {
|
||||
/**
|
||||
* The class of APIs relevant for model generation.
|
||||
*/
|
||||
class Api extends Lang::Callable {
|
||||
Lang::Callable lift();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of the provenance of the models.
|
||||
*/
|
||||
string getProvenance();
|
||||
}
|
||||
|
||||
module ModelPrinting<ModelPrintingSig Printing> {
|
||||
/**
|
||||
* Computes the first 6 columns for MaD rows used for summaries, sources and sinks.
|
||||
*/
|
||||
private string asPartialModel(Printing::Api api) {
|
||||
exists(string container, string type, string extensible, string name, string parameters |
|
||||
Lang::partialModel(api.lift(), container, type, extensible, name, parameters) and
|
||||
result =
|
||||
container + ";" //
|
||||
+ type + ";" //
|
||||
+ extensible + ";" //
|
||||
+ name + ";" //
|
||||
+ parameters + ";" //
|
||||
+ /* ext + */ ";" //
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the first 4 columns for neutral MaD rows.
|
||||
*/
|
||||
private string asPartialNeutralModel(Printing::Api api) {
|
||||
exists(string container, string type, string name, string parameters |
|
||||
Lang::partialModel(api, container, type, _, name, parameters) and
|
||||
result =
|
||||
container + ";" //
|
||||
+ type + ";" //
|
||||
+ name + ";" //
|
||||
+ parameters + ";" //
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary model for `api` with `input`, `output` and `kind`.
|
||||
*/
|
||||
bindingset[input, output, kind]
|
||||
private string asSummaryModel(Printing::Api api, string input, string output, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + input + ";" //
|
||||
+ output + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
string asNeutralSummaryModel(Printing::Api api) {
|
||||
result =
|
||||
asPartialNeutralModel(api) //
|
||||
+ "summary" + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value summary model for `api` with `input` and `output`.
|
||||
*/
|
||||
bindingset[input, output]
|
||||
string asValueModel(Printing::Api api, string input, string output) {
|
||||
result = asSummaryModel(api, input, output, "value")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the taint summary model for `api` with `input` and `output`.
|
||||
*/
|
||||
bindingset[input, output]
|
||||
string asTaintModel(Printing::Api api, string input, string output) {
|
||||
result = asSummaryModel(api, input, output, "taint")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sink model for `api` with `input` and `kind`.
|
||||
*/
|
||||
bindingset[input, kind]
|
||||
string asSinkModel(Printing::Api api, string input, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + input + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source model for `api` with `output` and `kind`.
|
||||
*/
|
||||
bindingset[output, kind]
|
||||
string asSourceModel(Printing::Api api, string output, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + output + ";" //
|
||||
+ kind + ";" //
|
||||
+ Printing::getProvenance()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user