From 5ddcb16cd6eb2c6f61797de86384cf3f50978f28 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 29 Aug 2024 14:43:14 +0200 Subject: [PATCH] Java: Add content based model generation test. --- .../modelgenerator/CaptureContentSummaryModels.ql | 6 +++--- .../dataflow/CaptureContentSummaryModels.expected | 2 ++ .../dataflow/CaptureContentSummaryModels.ql | 11 +++++++++++ .../test/utils/modelgenerator/dataflow/p/Factory.java | 5 ++++- .../utils/modelgenerator/dataflow/p/FinalClass.java | 1 + .../utils/modelgenerator/dataflow/p/FluentAPI.java | 1 + .../modelgenerator/dataflow/p/ImmutablePojo.java | 4 ++++ .../utils/modelgenerator/dataflow/p/Inheritance.java | 6 ++++++ .../utils/modelgenerator/dataflow/p/InnerClasses.java | 2 ++ .../utils/modelgenerator/dataflow/p/InnerHolder.java | 4 ++++ .../test/utils/modelgenerator/dataflow/p/Joiner.java | 11 +++++++++++ .../modelgenerator/dataflow/p/MultipleImpl2.java | 1 + .../modelgenerator/dataflow/p/MultipleImpls.java | 7 +++++++ .../utils/modelgenerator/dataflow/p/ParamFlow.java | 11 +++++++++++ .../ql/test/utils/modelgenerator/dataflow/p/Pojo.java | 9 ++++++++- .../dataflow/p/PrivateFlowViaPublicInterface.java | 6 ++++++ 16 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.expected create mode 100644 java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql diff --git a/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index 0a2f5185533..e0e793348f5 100644 --- a/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -1,8 +1,8 @@ /** - * @name Capture field based summary models. - * @description Finds applicable field based summary models to be used by other queries. + * @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/fieldbased-summary-models + * @id java/utils/modelgenerator/contentbased-summary-models * @tags modelgenerator */ diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.expected b/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.expected new file mode 100644 index 00000000000..cb6fc390349 --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.expected @@ -0,0 +1,2 @@ +unexpectedModel +expectedModel diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql new file mode 100644 index 00000000000..3d2a2e07ac6 --- /dev/null +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql @@ -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 diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java index 1887e0ca73e..23381486e5f 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Factory.java @@ -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; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java index 2638f818854..b436a4ed650 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java @@ -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; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java index b7793e30666..1799dc3ec4c 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FluentAPI.java @@ -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; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java index 0a2cf2d7dbd..9d83f6bf842 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java @@ -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; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Inheritance.java b/java/ql/test/utils/modelgenerator/dataflow/p/Inheritance.java index 8c083cd3972..d36cba1e099 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Inheritance.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Inheritance.java @@ -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; diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java index 5b6a8427a3f..8fef83143cb 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java @@ -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; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java index e09680dad52..5e8a050a428 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java @@ -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(); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java index 10fc72c907f..cf7626eba61 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java @@ -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) { diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java index 3e5d9abd768..09984a4742f 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java @@ -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; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java index 1bf73599588..164f55ae732 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java @@ -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; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java index d175ee9c71e..05614c392e4 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java @@ -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 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 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 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 target) { target.add(data); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java index 9d5de0517e1..e6fb581aac2 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java @@ -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 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 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 target) { target.add(value); } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java index eeebabeb68c..b5a1de27d4a 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java @@ -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); }