mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Merge pull request #17363 from michaelnebel/modelgen/fieldbasedimprovements
C#/Java: Content based model generation improvements.
This commit is contained in:
@@ -37,8 +37,14 @@ public final class InnerHolder {
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ public final class Joiner {
|
||||
// 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 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
|
||||
// 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 final class Joiner {
|
||||
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 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
|
||||
// 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 @@ 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
|
||||
// MISSING content based summaries for "elts". This could be a synthetic field.
|
||||
public Joiner merge(Joiner other) {
|
||||
Objects.requireNonNull(other);
|
||||
if (other.elts == null) {
|
||||
|
||||
13
java/ql/test/utils/modelgenerator/dataflow/p/MultiPaths.java
Normal file
13
java/ql/test/utils/modelgenerator/dataflow/p/MultiPaths.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package p;
|
||||
|
||||
public class MultiPaths {
|
||||
|
||||
// summary=p;MultiPaths;true;cond;(String,String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;MultiPaths;true;cond;(String,String);;Argument[0];ReturnValue;value;df-generated
|
||||
public String cond(String x, String other) {
|
||||
if (x == other) {
|
||||
return x.substring(0, 100);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -30,18 +30,16 @@ 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
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,20 @@ public final class Pojo {
|
||||
|
||||
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};
|
||||
private char[] charArray;
|
||||
private Byte[] byteObjectArray;
|
||||
private String stringValue1;
|
||||
private String stringValue2;
|
||||
|
||||
// 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 +86,12 @@ public final class Pojo {
|
||||
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 +108,7 @@ 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
|
||||
// No content based summary as charList is a "dead" (synthetic)field.
|
||||
public List<Character> getBoxedChars() {
|
||||
return charList;
|
||||
}
|
||||
@@ -117,4 +134,44 @@ public final class Pojo {
|
||||
public void fillIn(List<String> target) {
|
||||
target.add(value);
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;setStringValue1;(String);;Argument[0];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;setStringValue1;(String);;Argument[0];Argument[this].SyntheticField[p.Pojo.stringValue1];value;df-generated
|
||||
public void setStringValue1(String value) {
|
||||
this.stringValue1 = value;
|
||||
}
|
||||
|
||||
// neutral=p;Pojo;copyStringValue;();summary;df-generated
|
||||
// contentbased-summary=p;Pojo;false;copyStringValue;();;Argument[this].SyntheticField[p.Pojo.stringValue1];Argument[this].SyntheticField[p.Pojo.stringValue2];value;df-generated
|
||||
public void copyStringValue() {
|
||||
this.stringValue2 = this.stringValue1;
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;getStringValue2;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;getStringValue2;();;Argument[this].SyntheticField[p.Pojo.stringValue2];ReturnValue;value;df-generated
|
||||
public String getStringValue2() {
|
||||
return this.stringValue2;
|
||||
}
|
||||
|
||||
public class InnerPojo {
|
||||
private String value;
|
||||
|
||||
// summary=p;Pojo$InnerPojo;true;InnerPojo;(String);;Argument[0];Argument[this];taint;df-generated
|
||||
// contentbased-summary=p;Pojo$InnerPojo;true;InnerPojo;(String);;Argument[0];Argument[this].SyntheticField[p.Pojo$InnerPojo.value];value;df-generated
|
||||
public InnerPojo(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// summary=p;Pojo$InnerPojo;true;getValue;();;Argument[this];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Pojo$InnerPojo;true;getValue;();;Argument[this].SyntheticField[p.Pojo$InnerPojo.value];ReturnValue;value;df-generated
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// summary=p;Pojo;false;makeInnerPojo;(String);;Argument[0];ReturnValue;taint;df-generated
|
||||
// contentbased-summary=p;Pojo;false;makeInnerPojo;(String);;Argument[0];ReturnValue.SyntheticField[p.Pojo$InnerPojo.value];value;df-generated
|
||||
public InnerPojo makeInnerPojo(String value) {
|
||||
return new InnerPojo(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +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
|
||||
// This summary shouldn't be created because the method is private.
|
||||
// This is most likely because the lifting logic hasn't been properly adapted.
|
||||
// SPURIOUS-contentbased-summary=p;PrivateFlowViaPublicInterface$PrivateImplWithSink;false;openStream;();;Argument[this].SyntheticField[p.PrivateFlowViaPublicInterface$PrivateImplWithSink.file];ReturnValue;taint;df-generated
|
||||
@Override
|
||||
public OutputStream openStream() throws IOException {
|
||||
return new FileOutputStream(file);
|
||||
@@ -54,9 +54,7 @@ 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
|
||||
// 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