mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Merge pull request #17330 from michaelnebel/java/modelgenfieldbased
Java/C#: Field based model generator (Experimental).
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
private import java
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.internal.ContentDataFlowImpl
|
||||
|
||||
module ContentDataFlow {
|
||||
import MakeImplContentDataFlow<Location, JavaDataFlow>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @name Capture content based summary models.
|
||||
* @description Finds applicable content based summary models to be used by other queries.
|
||||
* @kind diagnostic
|
||||
* @id java/utils/modelgenerator/contentbased-summary-models
|
||||
* @tags modelgenerator
|
||||
*/
|
||||
|
||||
import internal.CaptureModels
|
||||
|
||||
from DataFlowSummaryTargetApi api, string flow
|
||||
where flow = captureContentFlow(api)
|
||||
select flow order by flow
|
||||
@@ -18,17 +18,35 @@ private class ReturnNodeExt extends DataFlow::Node {
|
||||
kind = DataFlowImplCommon::getParamReturnPosition(this, _).getKind()
|
||||
}
|
||||
|
||||
string getOutput() {
|
||||
kind instanceof DataFlowImplCommon::ValueReturnKind and
|
||||
/**
|
||||
* Gets the kind of the return node.
|
||||
*/
|
||||
DataFlowImplCommon::ReturnKindExt getKind() { result = kind }
|
||||
}
|
||||
|
||||
bindingset[c]
|
||||
private signature string printCallableParamSig(Callable c, ParameterPosition p);
|
||||
|
||||
private module PrintReturnNodeExt<printCallableParamSig/2 printCallableParam> {
|
||||
string getOutput(ReturnNodeExt node) {
|
||||
node.getKind() instanceof DataFlowImplCommon::ValueReturnKind and
|
||||
result = "ReturnValue"
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
pos = kind.(DataFlowImplCommon::ParamUpdateReturnKind).getPosition() and
|
||||
result = paramReturnNodeAsOutput(returnNodeEnclosingCallable(this), pos)
|
||||
pos = node.getKind().(DataFlowImplCommon::ParamUpdateReturnKind).getPosition() and
|
||||
result = printCallableParam(returnNodeEnclosingCallable(node), pos)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
string getOutput(ReturnNodeExt node) {
|
||||
result = PrintReturnNodeExt<paramReturnNodeAsOutput/2>::getOutput(node)
|
||||
}
|
||||
|
||||
string getContentOutput(ReturnNodeExt node) {
|
||||
result = PrintReturnNodeExt<paramReturnNodeAsContentOutput/2>::getOutput(node)
|
||||
}
|
||||
|
||||
class DataFlowSummaryTargetApi extends SummaryTargetApi {
|
||||
DataFlowSummaryTargetApi() { not isUninterestingForDataFlowModels(this) }
|
||||
}
|
||||
@@ -71,7 +89,8 @@ private predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2
|
||||
* Holds if content `c` is either a field, a synthetic field or language specific
|
||||
* content of a relevant type or a container like content.
|
||||
*/
|
||||
private predicate isRelevantContent(DataFlow::ContentSet c) {
|
||||
pragma[nomagic]
|
||||
private predicate isRelevantContent0(DataFlow::ContentSet c) {
|
||||
isRelevantTypeInContent(c) or
|
||||
containerContent(c)
|
||||
}
|
||||
@@ -85,6 +104,16 @@ string parameterNodeAsInput(DataFlow::ParameterNode p) {
|
||||
result = qualifierString() and p instanceof InstanceParameterNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MaD string representation of the parameter `p`
|
||||
* when used in content flow.
|
||||
*/
|
||||
string parameterNodeAsContentInput(DataFlow::ParameterNode p) {
|
||||
result = parameterContentAccess(p.asParameter())
|
||||
or
|
||||
result = qualifierString() and p instanceof InstanceParameterNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MaD input string representation of `source`.
|
||||
*/
|
||||
@@ -170,7 +199,7 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig {
|
||||
) {
|
||||
exists(DataFlow::ContentSet c |
|
||||
DataFlowImplCommon::store(node1, c.getAStoreContent(), node2, _, _) and
|
||||
isRelevantContent(c) and
|
||||
isRelevantContent0(c) and
|
||||
(
|
||||
state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1
|
||||
or
|
||||
@@ -180,7 +209,7 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig {
|
||||
or
|
||||
exists(DataFlow::ContentSet c |
|
||||
DataFlowPrivate::readStep(node1, c, node2) and
|
||||
isRelevantContent(c) and
|
||||
isRelevantContent0(c) and
|
||||
state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep()
|
||||
)
|
||||
}
|
||||
@@ -196,6 +225,9 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig {
|
||||
|
||||
module PropagateFlow = TaintTracking::GlobalWithState<PropagateFlowConfig>;
|
||||
|
||||
/**
|
||||
* Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter.
|
||||
*/
|
||||
string captureThroughFlow0(
|
||||
DataFlowSummaryTargetApi api, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt
|
||||
) {
|
||||
@@ -203,7 +235,7 @@ string captureThroughFlow0(
|
||||
p.getEnclosingCallable() = api and
|
||||
returnNodeExt.(DataFlow::Node).getEnclosingCallable() = api and
|
||||
input = parameterNodeAsInput(p) and
|
||||
output = returnNodeExt.getOutput() and
|
||||
output = getOutput(returnNodeExt) and
|
||||
input != output and
|
||||
result = Printing::asTaintModel(api, input, output)
|
||||
)
|
||||
@@ -219,6 +251,69 @@ string captureThroughFlow(DataFlowSummaryTargetApi api) {
|
||||
)
|
||||
}
|
||||
|
||||
private module PropagateContentFlowConfig implements ContentDataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source instanceof DataFlow::ParameterNode and
|
||||
source.getEnclosingCallable() instanceof DataFlowSummaryTargetApi
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink instanceof ReturnNodeExt and
|
||||
sink.getEnclosingCallable() instanceof DataFlowSummaryTargetApi
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep = isAdditionalContentFlowStep/2;
|
||||
|
||||
predicate isBarrier(DataFlow::Node n) {
|
||||
exists(Type t | t = n.getType() and not isRelevantType(t))
|
||||
}
|
||||
|
||||
int accessPathLimit() { result = 2 }
|
||||
|
||||
predicate isRelevantContent(DataFlow::ContentSet s) { isRelevantContent0(s) }
|
||||
|
||||
DataFlow::FlowFeature getAFeature() {
|
||||
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
|
||||
}
|
||||
}
|
||||
|
||||
private module PropagateContentFlow = ContentDataFlow::Global<PropagateContentFlowConfig>;
|
||||
|
||||
private string getContent(PropagateContentFlow::AccessPath ap, int i) {
|
||||
exists(ContentSet head, PropagateContentFlow::AccessPath tail |
|
||||
head = ap.getHead() and
|
||||
tail = ap.getTail()
|
||||
|
|
||||
i = 0 and
|
||||
result = "." + printContent(head)
|
||||
or
|
||||
i > 0 and result = getContent(tail, i - 1)
|
||||
)
|
||||
}
|
||||
|
||||
private string printStoreAccessPath(PropagateContentFlow::AccessPath ap) {
|
||||
result = concat(int i | | getContent(ap, i), "" order by i)
|
||||
}
|
||||
|
||||
private string printReadAccessPath(PropagateContentFlow::AccessPath ap) {
|
||||
result = concat(int i | | getContent(ap, i), "" order by i desc)
|
||||
}
|
||||
|
||||
string captureContentFlow(DataFlowSummaryTargetApi api) {
|
||||
exists(
|
||||
DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt, string input, string output,
|
||||
PropagateContentFlow::AccessPath reads, PropagateContentFlow::AccessPath stores,
|
||||
boolean preservesValue
|
||||
|
|
||||
PropagateContentFlow::flow(p, reads, returnNodeExt, stores, preservesValue) and
|
||||
returnNodeExt.getEnclosingCallable() = api and
|
||||
input = parameterNodeAsContentInput(p) + printReadAccessPath(reads) and
|
||||
output = getContentOutput(returnNodeExt) + printStoreAccessPath(stores) and
|
||||
input != output and
|
||||
result = Printing::asModel(api, input, output, preservesValue)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A dataflow configuration used for finding new sources.
|
||||
* The sources are the already known existing sources and the sinks are the API return nodes.
|
||||
@@ -261,7 +356,7 @@ string captureSource(DataFlowSourceTargetApi api) {
|
||||
ExternalFlow::sourceNode(source, kind) and
|
||||
api = sink.getEnclosingCallable() and
|
||||
not irrelevantSourceSinkApi(source.getEnclosingCallable(), api) and
|
||||
result = Printing::asSourceModel(api, sink.getOutput(), kind)
|
||||
result = Printing::asSourceModel(api, getOutput(sink), kind)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
|
||||
private import java as J
|
||||
private import semmle.code.java.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.java.dataflow.internal.DataFlowUtil as DataFlowUtil
|
||||
private import semmle.code.java.dataflow.internal.ContainerFlow as ContainerFlow
|
||||
private import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import semmle.code.java.dataflow.internal.ModelExclusions
|
||||
private import semmle.code.java.dataflow.DataFlow as Df
|
||||
private import semmle.code.java.dataflow.internal.ContentDataFlow as Cdf
|
||||
private import semmle.code.java.dataflow.SSA as Ssa
|
||||
private import semmle.code.java.dataflow.TaintTracking as Tt
|
||||
import semmle.code.java.dataflow.ExternalFlow as ExternalFlow
|
||||
@@ -17,6 +19,8 @@ import semmle.code.java.dataflow.internal.DataFlowDispatch as DataFlowDispatch
|
||||
|
||||
module DataFlow = Df::DataFlow;
|
||||
|
||||
module ContentDataFlow = Cdf::ContentDataFlow;
|
||||
|
||||
module TaintTracking = Tt::TaintTracking;
|
||||
|
||||
class Type = J::Type;
|
||||
@@ -25,6 +29,8 @@ class Unit = J::Unit;
|
||||
|
||||
class Callable = J::Callable;
|
||||
|
||||
class ContentSet = DataFlowUtil::ContentSet;
|
||||
|
||||
private predicate isInfrequentlyUsed(J::CompilationUnit cu) {
|
||||
cu.getPackage().getName().matches("javax.swing%") or
|
||||
cu.getPackage().getName().matches("java.awt%")
|
||||
@@ -217,6 +223,12 @@ string parameterAccess(J::Parameter p) {
|
||||
else result = "Argument[" + p.getPosition() + "]"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MaD string representation of the parameter `p`
|
||||
* when used in content flow.
|
||||
*/
|
||||
string parameterContentAccess(J::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
|
||||
|
||||
class InstanceParameterNode = DataFlow::InstanceParameterNode;
|
||||
|
||||
class ParameterPosition = DataFlowDispatch::ParameterPosition;
|
||||
@@ -232,6 +244,17 @@ string paramReturnNodeAsOutput(Callable c, ParameterPosition pos) {
|
||||
result = qualifierString() and pos = -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MaD string representation of return through parameter at position
|
||||
* `pos` of callable `c` for content flow.
|
||||
*/
|
||||
bindingset[c]
|
||||
string paramReturnNodeAsContentOutput(Callable c, ParameterPosition pos) {
|
||||
result = parameterContentAccess(c.getParameter(pos))
|
||||
or
|
||||
result = qualifierString() and pos = -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enclosing callable of `ret`.
|
||||
*/
|
||||
@@ -305,3 +328,34 @@ bindingset[kind]
|
||||
predicate isRelevantSourceKind(string kind) { any() }
|
||||
|
||||
predicate containerContent = DataFlowPrivate::containerContent/1;
|
||||
|
||||
/**
|
||||
* Holds if there is a taint step from `node1` to `node2` in content flow.
|
||||
*/
|
||||
predicate isAdditionalContentFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
TaintTracking::defaultAdditionalTaintStep(node1, node2, _) and
|
||||
not exists(DataFlow::Content f |
|
||||
DataFlowPrivate::readStep(node1, f, node2) and containerContent(f)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MaD string representation of the contentset `c`.
|
||||
*/
|
||||
string printContent(ContentSet c) {
|
||||
exists(Field f, string name |
|
||||
f = c.(DataFlowUtil::FieldContent).getField() and name = f.getQualifiedName()
|
||||
|
|
||||
if f.isPublic() then result = "Field[" + name + "]" else result = "SyntheticField[" + name + "]"
|
||||
)
|
||||
or
|
||||
result = "SyntheticField[" + c.(DataFlowUtil::SyntheticFieldContent).getField() + "]"
|
||||
or
|
||||
c instanceof DataFlowUtil::CollectionContent and result = "Element"
|
||||
or
|
||||
c instanceof DataFlowUtil::ArrayContent and result = "ArrayElement"
|
||||
or
|
||||
c instanceof DataFlowUtil::MapValueContent and result = "MapValue"
|
||||
or
|
||||
c instanceof DataFlowUtil::MapKeyContent and result = "MapKey"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
unexpectedModel
|
||||
expectedModel
|
||||
@@ -0,0 +1,11 @@
|
||||
import java
|
||||
import utils.modelgenerator.internal.CaptureModels
|
||||
import TestUtilities.InlineMadTest
|
||||
|
||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||
string getCapturedModel(Callable c) { result = captureContentFlow(c) }
|
||||
|
||||
string getKind() { result = "contentbased-summary" }
|
||||
}
|
||||
|
||||
import InlineMadTest<InlineMadTestConfig>
|
||||
@@ -2,16 +2,18 @@ package p;
|
||||
|
||||
public final class Factory {
|
||||
|
||||
private String value;
|
||||
public String value;
|
||||
|
||||
private int intValue;
|
||||
|
||||
// summary=p;Factory;false;create;(String,int);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Factory;false;create;(String,int);;Argument[0];ReturnValue.Field[p.Factory.value];value;df-generated
|
||||
public static Factory create(String value, int foo) {
|
||||
return new Factory(value, foo);
|
||||
}
|
||||
|
||||
// summary=p;Factory;false;create;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Factory;false;create;(String);;Argument[0];ReturnValue.Field[p.Factory.value];value;df-generated
|
||||
public static Factory create(String value) {
|
||||
return new Factory(value, 0);
|
||||
}
|
||||
@@ -22,6 +24,7 @@ public final class Factory {
|
||||
}
|
||||
|
||||
// summary=p;Factory;false;getValue;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Factory;false;getValue;();;Argument[this].Field[p.Factory.value];ReturnValue;value;df-generated
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ public final class FinalClass {
|
||||
private static final String C = "constant";
|
||||
|
||||
// summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
public String returnsInput(String input) {
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package p;
|
||||
public final class FluentAPI {
|
||||
|
||||
// summary=p;FluentAPI;false;returnsThis;(String);;Argument[this];ReturnValue;value;df-generated
|
||||
// contentbased-summary=p;FluentAPI;false;returnsThis;(String);;Argument[this];ReturnValue;value;df-generated
|
||||
public FluentAPI returnsThis(String input) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,14 @@ public final class ImmutablePojo {
|
||||
private final long x;
|
||||
|
||||
// summary=p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;ImmutablePojo;false;ImmutablePojo;(String,int);;Argument[0];Argument[this].SyntheticField[p.ImmutablePojo.value];value;df-generated
|
||||
public ImmutablePojo(String value, int x) {
|
||||
this.value = value;
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
// summary=p;ImmutablePojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ImmutablePojo;false;getValue;();;Argument[this].SyntheticField[p.ImmutablePojo.value];ReturnValue;value;df-generated
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
@@ -24,6 +26,8 @@ public final class ImmutablePojo {
|
||||
|
||||
// summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// summary=p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
// contentbased-summary=p;ImmutablePojo;false;or;(String);;Argument[this].SyntheticField[p.ImmutablePojo.value];ReturnValue;value;df-generated
|
||||
public String or(String defaultValue) {
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public class Inheritance {
|
||||
|
||||
public class AImplBasePrivateImpl extends BasePrivate {
|
||||
// summary=p;Inheritance$AImplBasePrivateImpl;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Inheritance$AImplBasePrivateImpl;true;id;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
@Override
|
||||
public String id(String s) {
|
||||
return s;
|
||||
@@ -19,6 +20,7 @@ public class Inheritance {
|
||||
|
||||
public class AImplBasePublic extends BasePublic {
|
||||
// summary=p;Inheritance$BasePublic;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Inheritance$BasePublic;true;id;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
@Override
|
||||
public String id(String s) {
|
||||
return s;
|
||||
@@ -59,6 +61,7 @@ public class Inheritance {
|
||||
|
||||
public class BImpl extends B {
|
||||
// summary=p;Inheritance$IPublic1;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Inheritance$IPublic1;true;id;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
@Override
|
||||
public String id(String s) {
|
||||
return s;
|
||||
@@ -67,6 +70,7 @@ public class Inheritance {
|
||||
|
||||
public class CImpl extends C {
|
||||
// summary=p;Inheritance$C;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Inheritance$C;true;id;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
@Override
|
||||
public String id(String s) {
|
||||
return s;
|
||||
@@ -75,6 +79,7 @@ public class Inheritance {
|
||||
|
||||
public class DImpl extends D {
|
||||
// summary=p;Inheritance$IPublic2;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Inheritance$IPublic2;true;id;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
@Override
|
||||
public String id(String s) {
|
||||
return s;
|
||||
@@ -83,6 +88,7 @@ public class Inheritance {
|
||||
|
||||
public class EImpl extends E {
|
||||
// summary=p;Inheritance$EImpl;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Inheritance$EImpl;true;id;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
@Override
|
||||
public String id(String s) {
|
||||
return s;
|
||||
|
||||
@@ -10,12 +10,14 @@ public class InnerClasses {
|
||||
|
||||
public class CaptureMe {
|
||||
// summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
public String yesCm(String input) {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
// summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
public String yes(String input) {
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -19,21 +19,25 @@ public final class InnerHolder {
|
||||
private StringBuilder sb = new StringBuilder();
|
||||
|
||||
// summary=p;InnerHolder;false;setContext;(String);;Argument[0];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;InnerHolder;false;setContext;(String);;Argument[0];Argument[this].SyntheticField[p.InnerHolder.context].SyntheticField[p.InnerHolder$Context.value];value;df-generated
|
||||
public void setContext(String value) {
|
||||
context = new Context(value);
|
||||
}
|
||||
|
||||
// summary=p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;InnerHolder;false;explicitSetContext;(String);;Argument[0];Argument[this].SyntheticField[p.InnerHolder.context].SyntheticField[p.InnerHolder$Context.value];value;df-generated
|
||||
public void explicitSetContext(String value) {
|
||||
this.context = new Context(value);
|
||||
}
|
||||
|
||||
// summary=p;InnerHolder;false;append;(String);;Argument[0];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;InnerHolder;false;append;(String);;Argument[0];Argument[this].SyntheticField[p.InnerHolder.sb];taint;df-generated
|
||||
public void append(String value) {
|
||||
sb.append(value);
|
||||
}
|
||||
|
||||
// summary=p;InnerHolder;false;getValue;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;InnerHolder;false;getValue;();;Argument[this].SyntheticField[p.InnerHolder.context].SyntheticField[p.InnerHolder$Context.value];ReturnValue;value;df-generated
|
||||
public String getValue() {
|
||||
return context.getValue();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public final class Joiner {
|
||||
private String emptyValue;
|
||||
|
||||
// summary=p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;Joiner;false;Joiner;(CharSequence);;Argument[0];Argument[this].SyntheticField[p.Joiner.delimiter];taint;df-generated
|
||||
public Joiner(CharSequence delimiter) {
|
||||
this(delimiter, "", "");
|
||||
}
|
||||
@@ -20,6 +21,9 @@ public final class Joiner {
|
||||
// summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[this];taint;df-generated
|
||||
// summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[this];taint;df-generated
|
||||
// summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[0];Argument[this].SyntheticField[p.Joiner.delimiter];taint;df-generated
|
||||
// contentbased-summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[1];Argument[this].SyntheticField[p.Joiner.prefix];taint;df-generated
|
||||
// contentbased-summary=p;Joiner;false;Joiner;(CharSequence,CharSequence,CharSequence);;Argument[2];Argument[this].SyntheticField[p.Joiner.suffix];taint;df-generated
|
||||
public Joiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
|
||||
Objects.requireNonNull(prefix, "The prefix must not be null");
|
||||
Objects.requireNonNull(delimiter, "The delimiter must not be null");
|
||||
@@ -32,6 +36,9 @@ public final class Joiner {
|
||||
|
||||
// summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[this];taint;df-generated
|
||||
// summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated
|
||||
// contentbased-summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];Argument[this].SyntheticField[p.Joiner.emptyValue];taint;df-generated
|
||||
// contentbased-summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[0];ReturnValue.SyntheticField[p.Joiner.emptyValue];taint;df-generated
|
||||
// contentbased-summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated
|
||||
public Joiner setEmptyValue(CharSequence emptyValue) {
|
||||
this.emptyValue =
|
||||
Objects.requireNonNull(emptyValue, "The empty value must not be null").toString();
|
||||
@@ -71,6 +78,8 @@ public final class Joiner {
|
||||
}
|
||||
|
||||
// summary=p;Joiner;false;add;(CharSequence);;Argument[this];ReturnValue;value;df-generated
|
||||
// contentbased-summary=p;Joiner;false;add;(CharSequence);;Argument[this].SyntheticField[p.Joiner.elts].ArrayElement;ReturnValue.SyntheticField[p.Joiner.elts].ArrayElement;value;df-generated
|
||||
// contentbased-summary=p;Joiner;false;add;(CharSequence);;Argument[this];ReturnValue;value;df-generated
|
||||
public Joiner add(CharSequence newElement) {
|
||||
final String elt = String.valueOf(newElement);
|
||||
if (elts == null) {
|
||||
@@ -94,6 +103,8 @@ public final class Joiner {
|
||||
}
|
||||
|
||||
// summary=p;Joiner;false;merge;(Joiner);;Argument[this];ReturnValue;value;df-generated
|
||||
// contentbased-summary=p;Joiner;false;merge;(Joiner);;Argument[this].SyntheticField[p.Joiner.elts].ArrayElement;ReturnValue.SyntheticField[p.Joiner.elts].ArrayElement;value;df-generated
|
||||
// contentbased-summary=p;Joiner;false;merge;(Joiner);;Argument[this];ReturnValue;value;df-generated
|
||||
public Joiner merge(Joiner other) {
|
||||
Objects.requireNonNull(other);
|
||||
if (other.elts == null) {
|
||||
|
||||
@@ -17,6 +17,7 @@ class MultipleImpl2 {
|
||||
|
||||
public class Impl2 implements IInterface {
|
||||
// summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;value;df-generated
|
||||
public Object m(Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ public class MultipleImpls {
|
||||
|
||||
public static class Strat1 implements Strategy {
|
||||
// summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
public String doSomething(String value) {
|
||||
return value;
|
||||
}
|
||||
@@ -29,12 +30,18 @@ public class MultipleImpls {
|
||||
private String foo;
|
||||
|
||||
// summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this];taint;df-generated
|
||||
// A field based model should not be lifted if the field pertains to the concrete
|
||||
// implementation.
|
||||
// SPURIOUS-contentbased-summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];Argument[this].SyntheticField[p.MultipleImpls$Strat2.foo];value;df-generated
|
||||
public String doSomething(String value) {
|
||||
this.foo = value;
|
||||
return "none";
|
||||
}
|
||||
|
||||
// summary=p;MultipleImpls$Strat2;true;getValue;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// A field based model should not be lifted if the field pertains to the concrete
|
||||
// implementation.
|
||||
// SPURIOUS-contentbased-summary=p;MultipleImpls$Strat2;true;getValue;();;Argument[this].SyntheticField[p.MultipleImpls$Strat2.foo];ReturnValue;value;df-generated
|
||||
public String getValue() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.List;
|
||||
public class ParamFlow {
|
||||
|
||||
// summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;value;df-generated
|
||||
public String returnsInput(String input) {
|
||||
return input;
|
||||
}
|
||||
@@ -19,6 +20,8 @@ public class ParamFlow {
|
||||
|
||||
// summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;value;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;value;df-generated
|
||||
public String returnMultipleParameters(String one, String two) {
|
||||
if (System.currentTimeMillis() > 100) {
|
||||
return two;
|
||||
@@ -27,26 +30,31 @@ public class ParamFlow {
|
||||
}
|
||||
|
||||
// summary=p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;returnArrayElement;(String[]);;Argument[0].ArrayElement;ReturnValue;value;df-generated
|
||||
public String returnArrayElement(String[] input) {
|
||||
return input[0];
|
||||
}
|
||||
|
||||
// summary=p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;returnVarArgElement;(String[]);;Argument[0].ArrayElement;ReturnValue;value;df-generated
|
||||
public String returnVarArgElement(String... input) {
|
||||
return input[0];
|
||||
}
|
||||
|
||||
// summary=p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;returnCollectionElement;(List);;Argument[0].Element;ReturnValue;value;df-generated
|
||||
public String returnCollectionElement(List<String> input) {
|
||||
return input.get(0);
|
||||
}
|
||||
|
||||
// summary=p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;returnIteratorElement;(Iterator);;Argument[0].Element;ReturnValue;value;df-generated
|
||||
public String returnIteratorElement(Iterator<String> input) {
|
||||
return input.next();
|
||||
}
|
||||
|
||||
// summary=p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;returnIterableElement;(Iterable);;Argument[0].Element;ReturnValue;value;df-generated
|
||||
public String returnIterableElement(Iterable<String> input) {
|
||||
return input.iterator().next();
|
||||
}
|
||||
@@ -57,16 +65,19 @@ public class ParamFlow {
|
||||
}
|
||||
|
||||
// summary=p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;writeChunked;(byte[],OutputStream);;Argument[0];Argument[1];taint;df-generated
|
||||
public void writeChunked(byte[] data, OutputStream output) throws IOException {
|
||||
output.write(data, 0, data.length);
|
||||
}
|
||||
|
||||
// summary=p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;writeChunked;(char[],OutputStream);;Argument[0];Argument[1];taint;df-generated
|
||||
public void writeChunked(char[] data, OutputStream output) throws IOException {
|
||||
output.write(String.valueOf(data).getBytes(), 0, data.length);
|
||||
}
|
||||
|
||||
// summary=p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;taint;df-generated
|
||||
// contentbased-summary=p;ParamFlow;true;addTo;(String,List);;Argument[0];Argument[1].Element;value;df-generated
|
||||
public void addTo(String data, List<String> target) {
|
||||
target.add(data);
|
||||
}
|
||||
|
||||
@@ -24,18 +24,20 @@ public final class Pojo {
|
||||
|
||||
private int intValue = 2;
|
||||
|
||||
private byte[] byteArray = new byte[] {1, 2, 3};
|
||||
public byte[] byteArray = new byte[] {1, 2, 3};
|
||||
private float[] floatArray = new float[] {1, 2, 3};
|
||||
private char[] charArray = new char[] {'a', 'b', 'c'};
|
||||
private List<Character> charList = Arrays.asList('a', 'b', 'c');
|
||||
private Byte[] byteObjectArray = new Byte[] {1, 2, 3};
|
||||
|
||||
// summary=p;Pojo;false;getValue;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;getValue;();;Argument[this].SyntheticField[p.Pojo.value];ReturnValue;value;df-generated
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;setValue;(String);;Argument[0];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;setValue;(String);;Argument[0];Argument[this].SyntheticField[p.Pojo.value];value;df-generated
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
@@ -62,11 +64,13 @@ public final class Pojo {
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;getCharArray;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;getCharArray;();;Argument[this].SyntheticField[p.Pojo.charArray];ReturnValue;value;df-generated
|
||||
public char[] getCharArray() {
|
||||
return charArray;
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;getByteArray;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;getByteArray;();;Argument[this].Field[p.Pojo.byteArray];ReturnValue;value;df-generated
|
||||
public byte[] getByteArray() {
|
||||
return byteArray;
|
||||
}
|
||||
@@ -87,11 +91,13 @@ public final class Pojo {
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;getBoxedChars;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;getBoxedChars;();;Argument[this].SyntheticField[p.Pojo.charList];ReturnValue;value;df-generated
|
||||
public List<Character> getBoxedChars() {
|
||||
return charList;
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;getBoxedBytes;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;getBoxedBytes;();;Argument[this].SyntheticField[p.Pojo.byteObjectArray];ReturnValue;value;df-generated
|
||||
public Byte[] getBoxedBytes() {
|
||||
return byteObjectArray;
|
||||
}
|
||||
@@ -107,6 +113,7 @@ public final class Pojo {
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;fillIn;(List);;Argument[this];Argument[0].Element;taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;fillIn;(List);;Argument[this].SyntheticField[p.Pojo.value];Argument[0].Element;value;df-generated
|
||||
public void fillIn(List<String> target) {
|
||||
target.add(value);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ public class PrivateFlowViaPublicInterface {
|
||||
}
|
||||
|
||||
// summary=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// A field based model should not be lifted if the field pertains to the concrete
|
||||
// implementation.
|
||||
// SPURIOUS-contentbased-summary=p;PrivateFlowViaPublicInterface$SPI;true;openStream;();;Argument[this].SyntheticField[p.PrivateFlowViaPublicInterface$PrivateImplWithSink.file];ReturnValue;taint;df-generated
|
||||
@Override
|
||||
public OutputStream openStream() throws IOException {
|
||||
return new FileOutputStream(file);
|
||||
@@ -51,6 +54,9 @@ public class PrivateFlowViaPublicInterface {
|
||||
}
|
||||
|
||||
// summary=p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue;taint;df-generated
|
||||
// A field based model should not be lifted if the field pertains to the concrete
|
||||
// implementation.
|
||||
// SPURIOUS-contentbased-summary=p;PrivateFlowViaPublicInterface;true;createAnSPI;(File);;Argument[0];ReturnValue.SyntheticField[p.PrivateFlowViaPublicInterface$PrivateImplWithSink.file];value;df-generated
|
||||
public static SPI createAnSPI(File file) {
|
||||
return new PrivateImplWithSink(file);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user