diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java index 5e8a050a428cb..b44c397bb1a5d 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerHolder.java @@ -37,8 +37,14 @@ public void append(String 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 + // contentbased-summary=p;InnerHolder;false;getValue;();;Argument[this].SyntheticField[p.InnerHolder.sb];ReturnValue;taint;df-generated public String getValue() { + return sb.toString(); + } + + // summary=p;InnerHolder;false;getContextValue;();;Argument[this];ReturnValue;taint;df-generated + // contentbased-summary=p;InnerHolder;false;getContextValue;();;Argument[this].SyntheticField[p.InnerHolder.context].SyntheticField[p.InnerHolder$Context.value];ReturnValue;value;df-generated + public String getContextValue() { 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 cf7626eba6199..5998af55f61e3 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Joiner.java @@ -22,8 +22,7 @@ public Joiner(CharSequence delimiter) { // 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 + // No content based summaries for prefix and suffix as they are "dead" synthetic fields. 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"); @@ -36,8 +35,7 @@ public Joiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) // 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 + // No content based summary as emptyValue is "dead" (synthetic)field. // contentbased-summary=p;Joiner;false;setEmptyValue;(CharSequence);;Argument[this];ReturnValue;value;df-generated public Joiner setEmptyValue(CharSequence emptyValue) { this.emptyValue = @@ -45,6 +43,12 @@ public Joiner setEmptyValue(CharSequence emptyValue) { return this; } + // summary=p;Joiner;false;getDelimiter;();;Argument[this];ReturnValue;taint;df-generated + // contentbased-summary=p;Joiner;false;getDelimiter;();;Argument[this].SyntheticField[p.Joiner.delimiter];ReturnValue;value;df-generated + public String getDelimiter() { + return delimiter; + } + private static int getChars(String s, char[] chars, int start) { int len = s.length(); s.getChars(0, len, chars, start); @@ -78,8 +82,8 @@ public String toString() { } // 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 + // MISSING content based summaries for "elts". This could be a synthetic field. public Joiner add(CharSequence newElement) { final String elt = String.valueOf(newElement); if (elts == null) { @@ -103,8 +107,8 @@ private int checkAddLength(int oldLen, int inc) { } // 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 + // MISSING content based summaries for "elts". This could be a synthetic field. public Joiner merge(Joiner other) { Objects.requireNonNull(other); if (other.elts == null) { diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java index 164f55ae73272..e854327d0325d 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java @@ -30,18 +30,16 @@ public static class Strat2 implements Strategy { 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 + // The content based summary is not lifted as it pertains to a (synthetic)field. + // contentbased-summary=p;MultipleImpls$Strat2;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 + // The content based summary is not lifted as it pertains to a (synthetic)field. + // 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/Pojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java index e6fb581aac2bc..345e23b0c2188 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Pojo.java @@ -26,9 +26,18 @@ int length() { 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}; + private char[] charArray; + private Byte[] byteObjectArray; + + // summary=p;Pojo;false;Pojo;(Byte[],char[]);;Argument[0];Argument[this];taint;df-generated + // summary=p;Pojo;false;Pojo;(Byte[],char[]);;Argument[1];Argument[this];taint;df-generated + // contentbased-summary=p;Pojo;false;Pojo;(Byte[],char[]);;Argument[0];Argument[this].SyntheticField[p.Pojo.byteObjectArray];value;df-generated + // contentbased-summary=p;Pojo;false;Pojo;(Byte[],char[]);;Argument[1];Argument[this].SyntheticField[p.Pojo.charArray];value;df-generated + public Pojo(Byte[] byteObjectArray, char[] charArray) { + this.byteObjectArray = byteObjectArray; + this.charArray = charArray; + } // 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 @@ -75,6 +84,12 @@ public byte[] getByteArray() { return byteArray; } + // summary=p;Pojo;false;setByteArray;(byte[]);;Argument[0];Argument[this];taint;df-generated + // contentbased-summary=p;Pojo;false;setByteArray;(byte[]);;Argument[0];Argument[this].Field[p.Pojo.byteArray];value;df-generated + public void setByteArray(byte[] value) { + byteArray = value; + } + // neutral=p;Pojo;getFloatArray;();summary;df-generated public float[] getFloatArray() { return floatArray; @@ -91,7 +106,7 @@ public Collection getBoxedCollection() { } // 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 + // No content based summary as charList is a "dead" (synthetic)field. public List getBoxedChars() { return charList; } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java index b5a1de27d4a9a..2e27e22753829 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/PrivateFlowViaPublicInterface.java @@ -29,9 +29,8 @@ public PrivateImplWithSink(File file) { } // 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 + // No content based summary as the summary for openStream can't be lifted as it pertains to a + // field. @Override public OutputStream openStream() throws IOException { return new FileOutputStream(file); @@ -54,9 +53,6 @@ public OutputStream openStreamNone() throws IOException { } // 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); }