Merge pull request #8628 from michaelnebel/csharp/generatedkind

C#: Introduce generated flag as a part of the kind column for flow summaries
This commit is contained in:
Michael Nebel
2022-04-07 08:43:30 +02:00
committed by GitHub
27 changed files with 467 additions and 299 deletions

View File

@@ -404,10 +404,17 @@ private 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
string output, string kind, boolean generated
) {
exists(string row |
sourceModel(row) and
@@ -419,14 +426,14 @@ predicate sourceModel(
row.splitAt(";", 4) = signature and
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = output and
row.splitAt(";", 7) = kind
exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated))
)
}
/** 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
string input, string kind, boolean generated
) {
exists(string row |
sinkModel(row) and
@@ -438,22 +445,22 @@ predicate sinkModel(
row.splitAt(";", 4) = signature and
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = input and
row.splitAt(";", 7) = kind
exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated))
)
}
/** 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
string input, string output, string kind, boolean generated
) {
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, _)
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, string row
string input, string output, string kind, boolean generated, string row
) {
summaryModel(row) and
row.splitAt(";", 0) = namespace and
@@ -465,13 +472,13 @@ predicate summaryModel(
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = input and
row.splitAt(";", 7) = output and
row.splitAt(";", 8) = kind
exists(string k | row.splitAt(";", 8) = k and getKind(k, kind, generated))
}
private predicate relevantPackage(string package) {
sourceModel(package, _, _, _, _, _, _, _) or
sinkModel(package, _, _, _, _, _, _, _) or
summaryModel(package, _, _, _, _, _, _, _, _)
sourceModel(package, _, _, _, _, _, _, _, _) or
sinkModel(package, _, _, _, _, _, _, _, _) or
summaryModel(package, _, _, _, _, _, _, _, _, _, _)
}
private predicate packageLink(string shortpkg, string longpkg) {
@@ -499,25 +506,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 |
string ext, string output, boolean generated |
canonicalPkgLink(package, subpkg) and
sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind)
sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind, generated)
)
or
part = "sink" and
n =
strictcount(string subpkg, string type, boolean subtypes, string name, string signature,
string ext, string input |
string ext, string input, boolean generated |
canonicalPkgLink(package, subpkg) and
sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind)
sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind, generated)
)
or
part = "summary" and
n =
strictcount(string subpkg, string type, boolean subtypes, string name, string signature,
string ext, string input, string output |
string ext, string input, string output, boolean generated |
canonicalPkgLink(package, subpkg) and
summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind)
summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, generated)
)
)
}
@@ -527,11 +534,11 @@ module CsvValidation {
/** Holds if some row in a CSV-based flow model appears to contain typos. */
query predicate invalidModelRow(string msg) {
exists(string pred, string namespace, string type, string name, string signature, string ext |
sourceModel(namespace, type, _, name, signature, ext, _, _) and pred = "source"
sourceModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "source"
or
sinkModel(namespace, type, _, name, signature, ext, _, _) and pred = "sink"
sinkModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "sink"
or
summaryModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "summary"
summaryModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "summary"
|
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
@@ -550,9 +557,9 @@ module CsvValidation {
)
or
exists(string pred, string input, string part |
sinkModel(_, _, _, _, _, _, input, _) and pred = "sink"
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
or
summaryModel(_, _, _, _, _, _, input, _, _) and pred = "summary"
summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary"
|
(
invalidSpecComponent(input, part) and
@@ -567,9 +574,9 @@ module CsvValidation {
)
or
exists(string pred, string output, string part |
sourceModel(_, _, _, _, _, _, output, _) and pred = "source"
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
or
summaryModel(_, _, _, _, _, _, _, output, _) and pred = "summary"
summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary"
|
invalidSpecComponent(output, part) and
not part = "" and
@@ -598,6 +605,13 @@ module CsvValidation {
msg = "Invalid boolean \"" + b + "\" in " + pred + " model."
)
)
or
exists(string row, string k, string kind | summaryModel(row) |
k = row.splitAt(";", 8) and
getKind(k, kind, _) and
not kind = ["taint", "value"] and
msg = "Invalid kind \"" + kind + "\" in summary model."
)
}
}
@@ -605,9 +619,9 @@ pragma[nomagic]
private predicate elementSpec(
string namespace, string type, boolean subtypes, string name, string signature, string ext
) {
sourceModel(namespace, type, subtypes, name, signature, ext, _, _) or
sinkModel(namespace, type, subtypes, name, signature, ext, _, _) or
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _)
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
}
private string paramsStringPart(Callable c, int i) {

View File

@@ -806,10 +806,10 @@ module Private {
module External {
/** Holds if `spec` is a relevant external specification. */
private predicate relevantSpec(string spec) {
summaryElement(_, spec, _, _) or
summaryElement(_, _, spec, _) or
sourceElement(_, spec, _) or
sinkElement(_, spec, _)
summaryElement(_, spec, _, _, _) or
summaryElement(_, _, spec, _, _) or
sourceElement(_, spec, _, _) or
sinkElement(_, spec, _, _)
}
private class AccessPathRange extends AccessPath::Range {
@@ -875,13 +875,20 @@ module Private {
}
private class SummarizedCallableExternal extends SummarizedCallable {
SummarizedCallableExternal() { summaryElement(this, _, _, _) }
SummarizedCallableExternal() { summaryElement(this, _, _, _, _) }
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
summaryElement(this, inSpec, outSpec, kind, false)
or
summaryElement(this, inSpec, outSpec, kind, true) and
not summaryElement(this, _, _, _, false)
}
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
exists(AccessPath inSpec, AccessPath outSpec, string kind |
summaryElement(this, inSpec, outSpec, kind) and
this.relevantSummaryElement(inSpec, outSpec, kind) and
interpretSpec(inSpec, input) and
interpretSpec(outSpec, output)
|
@@ -910,7 +917,7 @@ module Private {
private predicate sourceElementRef(InterpretNode ref, AccessPath output, string kind) {
exists(SourceOrSinkElement e |
sourceElement(e, output, kind) and
sourceElement(e, output, kind, _) and
if outputNeedsReference(output.getToken(0))
then e = ref.getCallTarget()
else e = ref.asElement()
@@ -919,7 +926,7 @@ module Private {
private predicate sinkElementRef(InterpretNode ref, AccessPath input, string kind) {
exists(SourceOrSinkElement e |
sinkElement(e, input, kind) and
sinkElement(e, input, kind, _) and
if inputNeedsReference(input.getToken(0))
then e = ref.getCallTarget()
else e = ref.asElement()

View File

@@ -53,13 +53,16 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) {
/**
* Holds if an external flow summary exists for `c` with input specification
* `input`, output specification `output`, and kind `kind`.
* `input`, output specification `output`, kind `kind`, and a flag `generated`
* stating whether the summary is autogenerated.
*/
predicate summaryElement(DataFlowCallable c, string input, string output, string kind) {
predicate summaryElement(
DataFlowCallable c, string input, string output, string kind, boolean generated
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind) and
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated) and
c.asCallable() = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
@@ -112,26 +115,28 @@ class SourceOrSinkElement = Top;
/**
* Holds if an external source specification exists for `e` with output specification
* `output` and kind `kind`.
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
* autogenerated.
*/
predicate sourceElement(SourceOrSinkElement e, string output, string kind) {
predicate sourceElement(SourceOrSinkElement e, string output, string kind, boolean generated) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind) and
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, generated) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
/**
* Holds if an external sink specification exists for `e` with input specification
* `input` and kind `kind`.
* `input`, kind `kind` and a flag `generated` stating whether the sink specification is
* autogenerated.
*/
predicate sinkElement(SourceOrSinkElement e, string input, string kind) {
predicate sinkElement(SourceOrSinkElement e, string input, string kind, boolean generated) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind) and
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, generated) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}

View File

@@ -41,7 +41,7 @@ private class CallableToTest extends Callable {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _) and
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) and
this = interpretElement(namespace, type, subtypes, name, signature, ext) and
this.isPublic() and
getRootType(this.getDeclaringType()).(RefType).isPublic()
@@ -64,7 +64,8 @@ private newtype TTestCase =
string inputSpec, string outputSpec
|
any(TargetSummaryModelCsv tsmc).row(row) and
summaryModel(namespace, type, subtypes, name, signature, ext, inputSpec, outputSpec, kind, row) and
summaryModel(namespace, type, subtypes, name, signature, ext, inputSpec, outputSpec, kind,
false, row) and
callable = interpretElement(namespace, type, subtypes, name, signature, ext) and
Private::External::interpretSpec(inputSpec, input) and
Private::External::interpretSpec(outputSpec, output)

View File

@@ -21,25 +21,25 @@ query string getAParseFailure(string reason) {
any(TargetSummaryModelCsv target).row(result) and
any(SummaryModelCsv model).row(result) and
(
not summaryModel(_, _, _, _, _, _, _, _, _, result) and
not summaryModel(_, _, _, _, _, _, _, _, _, _, result) and
reason = "row could not be parsed"
or
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, result) and
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, result) and
not interpretElement(namespace, type, subtypes, name, signature, ext) instanceof Callable and
reason = "callable could not be resolved"
)
or
exists(string inputSpec |
summaryModel(_, _, _, _, _, _, inputSpec, _, _, result) and
summaryModel(_, _, _, _, _, _, inputSpec, _, _, _, result) and
not Private::External::interpretSpec(inputSpec, _) and
reason = "input spec could not be parsed"
)
or
exists(string outputSpec |
summaryModel(_, _, _, _, _, _, _, outputSpec, _, result) and
summaryModel(_, _, _, _, _, _, _, outputSpec, _, _, result) and
not Private::External::interpretSpec(outputSpec, _) and
reason = "output spec could not be parsed"
)

View File

@@ -44,7 +44,7 @@ private string asSummaryModel(TargetApi api, string input, string output, string
result =
asPartialModel(api) + input + ";" //
+ output + ";" //
+ kind
+ "generated:" + kind
}
/**
@@ -68,7 +68,7 @@ private string asTaintModel(TargetApi api, string input, string output) {
*/
bindingset[input, kind]
private string asSinkModel(TargetApi api, string input, string kind) {
result = asPartialModel(api) + input + ";" + kind
result = asPartialModel(api) + input + ";" + "generated:" + kind
}
/**
@@ -76,7 +76,7 @@ private string asSinkModel(TargetApi api, string input, string kind) {
*/
bindingset[output, kind]
private string asSourceModel(TargetApi api, string output, string kind) {
result = asPartialModel(api) + output + ";" + kind
result = asPartialModel(api) + output + ";" + "generated:" + kind
}
/**

View File

@@ -24,6 +24,16 @@ public class C {
stepQualArg(argOut);
}
void fooGenerated() {
Object arg1 = new Object();
stepArgResGenerated(arg1);
Object arg2 = new Object();
// The summary for the first parameter is ignored, because it is generated and
// because there is hand written summary for the second parameter.
stepArgResGeneratedIgnored(arg1, arg2);
}
Object stepArgRes(Object x) { return null; }
void stepArgArg(Object in, Object out) { }
@@ -33,4 +43,8 @@ public class C {
Object stepQualRes() { return null; }
void stepQualArg(Object out) { }
Object stepArgResGenerated(Object x) { return null; }
Object stepArgResGeneratedIgnored(Object x, Object y) { return null; }
}

View File

@@ -8,3 +8,5 @@ invalidModelRow
| C.java:20:5:20:8 | this | C.java:20:5:20:22 | stepQualRes(...) |
| C.java:21:5:21:17 | this <.method> | C.java:21:5:21:17 | stepQualRes(...) |
| C.java:24:5:24:23 | this <.method> | C.java:24:17:24:22 | argOut [post update] |
| C.java:29:25:29:28 | arg1 | C.java:29:5:29:29 | stepArgResGenerated(...) |
| C.java:34:38:34:41 | arg2 | C.java:34:5:34:42 | stepArgResGeneratedIgnored(...) |

View File

@@ -13,7 +13,10 @@ class SummaryModelTest extends SummaryModelCsv {
"my.qltest;C;false;stepArgArg;(Object,Object);;Argument[0];Argument[1];taint",
"my.qltest;C;false;stepArgQual;(Object);;Argument[0];Argument[-1];taint",
"my.qltest;C;false;stepQualRes;();;Argument[-1];ReturnValue;taint",
"my.qltest;C;false;stepQualArg;(Object);;Argument[-1];Argument[0];taint"
"my.qltest;C;false;stepQualArg;(Object);;Argument[-1];Argument[0];taint",
"my.qltest;C;false;stepArgResGenerated;(Object);;Argument[0];ReturnValue;generated:taint",
"my.qltest;C;false;stepArgResGeneratedIgnored;(Object,Object);;Argument[0];ReturnValue;generated:taint",
"my.qltest;C;false;stepArgResGeneratedIgnored;(Object,Object);;Argument[1];ReturnValue;taint",
]
}
}

View File

@@ -1,4 +1,4 @@
| p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[-1];create-file |
| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];create-file |
| p;Sinks;true;readUrl;(URL,Charset);;Argument[0];open-url |
| p;Sources;true;readUrl;(URL);;Argument[0];open-url |
| p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[-1];generated:create-file |
| p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];generated:create-file |
| p;Sinks;true;readUrl;(URL,Charset);;Argument[0];generated:open-url |
| p;Sources;true;readUrl;(URL);;Argument[0];generated:open-url |

View File

@@ -1,5 +1,5 @@
| p;Sources;true;readUrl;(URL);;ReturnValue;remote |
| p;Sources;true;socketStream;();;ReturnValue;remote |
| p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0].ArrayElement;remote |
| p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1].Element;remote |
| p;Sources;true;wrappedSocketStream;();;ReturnValue;remote |
| p;Sources;true;readUrl;(URL);;ReturnValue;generated:remote |
| p;Sources;true;socketStream;();;ReturnValue;generated:remote |
| p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0].ArrayElement;generated:remote |
| p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1].Element;generated:remote |
| p;Sources;true;wrappedSocketStream;();;ReturnValue;generated:remote |

View File

@@ -1,46 +1,46 @@
| p;Factory;false;create;(String);;Argument[0];ReturnValue;taint |
| p;Factory;false;create;(String,int);;Argument[0];ReturnValue;taint |
| p;Factory;false;getValue;();;Argument[-1];ReturnValue;taint |
| p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint |
| p;FluentAPI;false;returnsThis;(String);;Argument[-1];ReturnValue;value |
| p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[-1];taint |
| p;ImmutablePojo;false;getValue;();;Argument[-1];ReturnValue;taint |
| p;ImmutablePojo;false;or;(String);;Argument[-1];ReturnValue;taint |
| p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint |
| p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint |
| p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint |
| p;InnerHolder;false;append;(String);;Argument[0];Argument[-1];taint |
| p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[-1];taint |
| p;InnerHolder;false;getValue;();;Argument[-1];ReturnValue;taint |
| p;InnerHolder;false;setContext;(String);;Argument[0];Argument[-1];taint |
| p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[-1];taint |
| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[-1];taint |
| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[-1];taint |
| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[-1];taint |
| p;Joiner;false;add;(CharSequence);;Argument[-1];ReturnValue;value |
| p;Joiner;false;merge;(Joiner);;Argument[-1];ReturnValue;value |
| p;Joiner;false;setEmptyValue;(CharSequence);;Argument[-1];ReturnValue;value |
| p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[-1];taint |
| p;Joiner;false;toString;();;Argument[-1];ReturnValue;taint |
| p;MultipleImpls$Strat2;true;getValue;();;Argument[-1];ReturnValue;taint |
| p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[-1];taint |
| p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint |
| p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;taint |
| p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint |
| p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;taint |
| p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;taint |
| p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;taint |
| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint |
| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint |
| p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint |
| p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint |
| p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint |
| p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint |
| p;Pojo;false;fillIn;(List);;Argument[-1];Argument[0].Element;taint |
| p;Pojo;false;getBoxedBytes;();;Argument[-1];ReturnValue;taint |
| p;Pojo;false;getBoxedChars;();;Argument[-1];ReturnValue;taint |
| p;Pojo;false;getByteArray;();;Argument[-1];ReturnValue;taint |
| p;Pojo;false;getCharArray;();;Argument[-1];ReturnValue;taint |
| p;Pojo;false;getValue;();;Argument[-1];ReturnValue;taint |
| p;Pojo;false;setValue;(String);;Argument[0];Argument[-1];taint |
| p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;taint |
| p;Factory;false;create;(String);;Argument[0];ReturnValue;generated:taint |
| p;Factory;false;create;(String,int);;Argument[0];ReturnValue;generated:taint |
| p;Factory;false;getValue;();;Argument[-1];ReturnValue;generated:taint |
| p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;generated:taint |
| p;FluentAPI;false;returnsThis;(String);;Argument[-1];ReturnValue;generated:value |
| p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[-1];generated:taint |
| p;ImmutablePojo;false;getValue;();;Argument[-1];ReturnValue;generated:taint |
| p;ImmutablePojo;false;or;(String);;Argument[-1];ReturnValue;generated:taint |
| p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;generated:taint |
| p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;generated:taint |
| p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;generated:taint |
| p;InnerHolder;false;append;(String);;Argument[0];Argument[-1];generated:taint |
| p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[-1];generated:taint |
| p;InnerHolder;false;getValue;();;Argument[-1];ReturnValue;generated:taint |
| p;InnerHolder;false;setContext;(String);;Argument[0];Argument[-1];generated:taint |
| p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[-1];generated:taint |
| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[-1];generated:taint |
| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[-1];generated:taint |
| p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[-1];generated:taint |
| p;Joiner;false;add;(CharSequence);;Argument[-1];ReturnValue;generated:value |
| p;Joiner;false;merge;(Joiner);;Argument[-1];ReturnValue;generated:value |
| p;Joiner;false;setEmptyValue;(CharSequence);;Argument[-1];ReturnValue;generated:value |
| p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[-1];generated:taint |
| p;Joiner;false;toString;();;Argument[-1];ReturnValue;generated:taint |
| p;MultipleImpls$Strat2;true;getValue;();;Argument[-1];ReturnValue;generated:taint |
| p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[-1];generated:taint |
| p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;generated:taint |
| p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;generated:taint |
| p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;generated:taint |
| p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;generated:taint |
| p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;generated:taint |
| p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;generated:taint |
| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;generated:taint |
| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;generated:taint |
| p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;generated:taint |
| p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;generated:taint |
| p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];generated:taint |
| p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];generated:taint |
| p;Pojo;false;fillIn;(List);;Argument[-1];Argument[0].Element;generated:taint |
| p;Pojo;false;getBoxedBytes;();;Argument[-1];ReturnValue;generated:taint |
| p;Pojo;false;getBoxedChars;();;Argument[-1];ReturnValue;generated:taint |
| p;Pojo;false;getByteArray;();;Argument[-1];ReturnValue;generated:taint |
| p;Pojo;false;getCharArray;();;Argument[-1];ReturnValue;generated:taint |
| p;Pojo;false;getValue;();;Argument[-1];ReturnValue;generated:taint |
| p;Pojo;false;setValue;(String);;Argument[0];Argument[-1];generated:taint |
| p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;generated:taint |