Skip to content

Commit

Permalink
Merge pull request #16775 from michaelnebel/modelgen/refactorprinting
Browse files Browse the repository at this point in the history
C#/Java: Parameterized module for model printing.
  • Loading branch information
michaelnebel committed Jun 24, 2024
2 parents f04a85e + 9cd16fd commit abc7cc3
Show file tree
Hide file tree
Showing 14 changed files with 168 additions and 219 deletions.
4 changes: 0 additions & 4 deletions config/identical-files.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 + ";" //
Expand Down
2 changes: 1 addition & 1 deletion csharp/ql/src/utils/modelconverter/InterpretModel.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 }
Expand Down Expand Up @@ -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)
)
}

Expand Down Expand Up @@ -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)
)
}

Expand Down Expand Up @@ -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)
)
}
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
)
}
}
Expand Down
12 changes: 6 additions & 6 deletions java/ql/src/utils/modelgenerator/internal/CaptureModels.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 }
Expand Down Expand Up @@ -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)
)
}

Expand Down Expand Up @@ -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)
)
}

Expand Down Expand Up @@ -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)
)
}
Original file line number Diff line number Diff line change
@@ -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>
Loading

0 comments on commit abc7cc3

Please sign in to comment.