mirror of
https://github.com/github/codeql.git
synced 2026-04-21 06:55:31 +02:00
Make tags for positive and negative examples more precise.
This commit is contained in:
@@ -17,8 +17,8 @@ class Test {
|
||||
public static void main(String[] args) throws Exception {
|
||||
AtomicReference<String> reference = new AtomicReference<>(); // uninteresting (parameterless constructor)
|
||||
reference.set( // $ sinkModel=set(Object):Argument[this]
|
||||
args[0] // $ negativeExample=set(Object):Argument[0] // modeled as a flow step
|
||||
); // $ negativeExample=set(Object):ReturnValue // return type is void
|
||||
args[0] // $ negativeSinkExample=set(Object):Argument[0] // modeled as a flow step
|
||||
); // $ negativeSourceExample=set(Object):ReturnValue // return type is void
|
||||
}
|
||||
|
||||
public static void callSupplier(Supplier<String> supplier) {
|
||||
@@ -27,35 +27,35 @@ class Test {
|
||||
|
||||
public static void copyFiles(Path source, Path target, CopyOption option) throws Exception {
|
||||
Files.copy(
|
||||
source, // $ positiveExample=copy(Path,Path,CopyOption[]):Argument[0](path-injection)
|
||||
target, // $ positiveExample=copy(Path,Path,CopyOption[]):Argument[1](path-injection)
|
||||
source, // $ positiveSinkExample=copy(Path,Path,CopyOption[]):Argument[0](path-injection)
|
||||
target, // $ positiveSinkExample=copy(Path,Path,CopyOption[]):Argument[1](path-injection)
|
||||
option // no candidate (not modeled, but source and target are modeled)
|
||||
); // $ sourceModel=copy(Path,Path,CopyOption[]):ReturnValue
|
||||
}
|
||||
|
||||
public static InputStream getInputStream(Path openPath) throws Exception {
|
||||
return Files.newInputStream(
|
||||
openPath // $ sinkModel=newInputStream(Path,OpenOption[]):Argument[0] positiveExample=newInputStream(Path,OpenOption[]):Argument[0](path-injection) // sink candidate because "only" ai-modeled, and useful as a candidate in regression testing
|
||||
openPath // $ sinkModel=newInputStream(Path,OpenOption[]):Argument[0] positiveSinkExample=newInputStream(Path,OpenOption[]):Argument[0](path-injection) // sink candidate because "only" ai-modeled, and useful as a candidate in regression testing
|
||||
); // $ sourceModel=newInputStream(Path,OpenOption[]):ReturnValue
|
||||
}
|
||||
|
||||
public static InputStream getInputStream(String openPath) throws Exception {
|
||||
return Test.getInputStream( // the call is not a source candidate (argument to local call)
|
||||
Paths.get(
|
||||
openPath // $ negativeExample=get(String,String[]):Argument[0] // modeled as a flow step
|
||||
openPath // $ negativeSinkExample=get(String,String[]):Argument[0] // modeled as a flow step
|
||||
) // $ sourceModel=get(String,String[]):ReturnValue
|
||||
);
|
||||
}
|
||||
|
||||
public static int compareFiles(File f1, File f2) {
|
||||
return f1.compareTo( // $ negativeExample=compareTo(File):Argument[this]
|
||||
f2 // $ negativeExample=compareTo(File):Argument[0] // modeled as not a sink
|
||||
); // $ negativeExample=compareTo(File):ReturnValue // return type is int
|
||||
return f1.compareTo( // $ negativeSinkExample=compareTo(File):Argument[this]
|
||||
f2 // $ negativeSinkExample=compareTo(File):Argument[0] // modeled as not a sink
|
||||
); // $ negativeSourceExample=compareTo(File):ReturnValue // return type is int
|
||||
}
|
||||
|
||||
public static void FilesWalkExample(Path p, FileVisitOption o) throws Exception {
|
||||
Files.walk(
|
||||
p, // $ negativeExample=walk(Path,FileVisitOption[]):Argument[0] // modeled as a flow step
|
||||
p, // $ negativeSinkExample=walk(Path,FileVisitOption[]):Argument[0] // modeled as a flow step
|
||||
o, // the implicit varargs array is a candidate, annotated on the last line of the call
|
||||
o // not a candidate (only the first arg corresponding to a varargs array
|
||||
// is extracted)
|
||||
@@ -63,7 +63,7 @@ class Test {
|
||||
}
|
||||
|
||||
public static void WebSocketExample(URLConnection c) throws Exception {
|
||||
c.getInputStream(); // $ sinkModel=getInputStream():Argument[this] positiveExample=getInputStream():ReturnValue(remote) // not a source candidate (manual modeling)
|
||||
c.getInputStream(); // $ sinkModel=getInputStream():Argument[this] positiveSourceExample=getInputStream():ReturnValue(remote) // not a source candidate (manual modeling)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,16 +88,16 @@ class MoreTests {
|
||||
public static void FilesListExample(Path p) throws Exception {
|
||||
Files.list(
|
||||
Files.createDirectories(
|
||||
p // $ positiveExample=createDirectories(Path,FileAttribute[]):Argument[0](path-injection)
|
||||
) // $ sourceModel=createDirectories(Path,FileAttribute[]):ReturnValue negativeExample=list(Path):Argument[0] // modeled as a flow step
|
||||
p // $ positiveSinkExample=createDirectories(Path,FileAttribute[]):Argument[0](path-injection)
|
||||
) // $ sourceModel=createDirectories(Path,FileAttribute[]):ReturnValue negativeSinkExample=list(Path):Argument[0] // modeled as a flow step
|
||||
); // $ sourceModel=list(Path):ReturnValue
|
||||
|
||||
Files.delete(
|
||||
p // $ sinkModel=delete(Path):Argument[0] positiveExample=delete(Path):Argument[0](path-injection)
|
||||
); // $ negativeExample=delete(Path):ReturnValue // return type is void
|
||||
p // $ sinkModel=delete(Path):Argument[0] positiveSinkExample=delete(Path):Argument[0](path-injection)
|
||||
); // $ negativeSourceExample=delete(Path):ReturnValue // return type is void
|
||||
|
||||
Files.deleteIfExists(
|
||||
p // $ sinkModel=deleteIfExists(Path):Argument[0] positiveExample=deleteIfExists(Path):Argument[0](path-injection)
|
||||
); // $ negativeExample=deleteIfExists(Path):ReturnValue // return type is boolean
|
||||
p // $ sinkModel=deleteIfExists(Path):Argument[0] positiveSinkExample=deleteIfExists(Path):Argument[0](path-injection)
|
||||
); // $ negativeSourceExample=deleteIfExists(Path):ReturnValue // return type is boolean
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,22 @@ signature module TestHelperSig<CandidateSig Candidate> {
|
||||
|
||||
module Extraction<CandidateSig Candidate, TestHelperSig<Candidate> TestHelper> implements TestSig {
|
||||
string getARelevantTag() {
|
||||
result in ["sourceModel", "sinkModel", "positiveExample", "negativeExample"]
|
||||
result in [
|
||||
"sourceModel", "sinkModel", // a candidate source/sink
|
||||
"positiveSourceExample", "positiveSinkExample", // a known source/sink
|
||||
"negativeSourceExample", "negativeSinkExample" // a known non-source/non-sink
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* If `extensibleType` is `sourceModel` then the result is `ifSource`, if it
|
||||
* is `sinkModel` then the result is `ifSink`.
|
||||
*/
|
||||
bindingset[extensibleType, ifSource, ifSink]
|
||||
private string ifSource(string extensibleType, string ifSource, string ifSink) {
|
||||
extensibleType = "sourceModel" and result = ifSource
|
||||
or
|
||||
extensibleType = "sinkModel" and result = ifSink
|
||||
}
|
||||
|
||||
additional predicate selectEndpoint(
|
||||
@@ -35,13 +50,13 @@ module Extraction<CandidateSig Candidate, TestHelperSig<Candidate> TestHelper> i
|
||||
suffix = ""
|
||||
or
|
||||
TestHelper::isNegativeExample(endpoint, name, signature, input, output, extensibleType) and
|
||||
tag = "negativeExample" and
|
||||
tag = "negative" + ifSource(extensibleType, "Source", "Sink") + "Example" and
|
||||
suffix = ""
|
||||
or
|
||||
exists(string endpointType |
|
||||
TestHelper::isPositiveExample(endpoint, endpointType, name, signature, input, output,
|
||||
extensibleType) and
|
||||
tag = "positiveExample" and
|
||||
tag = "positive" + ifSource(extensibleType, "Source", "Sink") + "Example" and
|
||||
suffix = "(" + endpointType + ")"
|
||||
)
|
||||
}
|
||||
@@ -56,9 +71,7 @@ module Extraction<CandidateSig Candidate, TestHelperSig<Candidate> TestHelper> i
|
||||
TestHelper::getEndpointLocation(endpoint) = location and
|
||||
endpoint.toString() = element and
|
||||
// for source models only the output is relevant, and vice versa for sink models
|
||||
if extensibleType = "sourceModel"
|
||||
then value = name + signature + ":" + output + suffix
|
||||
else value = name + signature + ":" + input + suffix
|
||||
value = name + signature + ":" + ifSource(extensibleType, output, input) + suffix
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public class PublicClass {
|
||||
}
|
||||
|
||||
// `input` and `input` are source candidates, but not sink candidates (is-style method)
|
||||
public Boolean isIgnored(Object input) { // $ negativeExample=isIgnored(Object):Argument[this] sourceModel=isIgnored(Object):Parameter[this] negativeExample=isIgnored(Object):Argument[0] sourceModel=isIgnored(Object):Parameter[0]
|
||||
public Boolean isIgnored(Object input) { // $ negativeSinkExample=isIgnored(Object):Argument[this] sourceModel=isIgnored(Object):Parameter[this] negativeSinkExample=isIgnored(Object):Argument[0] sourceModel=isIgnored(Object):Parameter[0]
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package java.io;
|
||||
|
||||
public class File {
|
||||
public int compareTo( // $ negativeExample=compareTo(File):Argument[this] negativeExample=compareTo(File):Parameter[this] // modeled as neutral
|
||||
File pathname // $ negativeExample=compareTo(File):Argument[0] negativeExample=compareTo(File):Parameter[0] // modeled as neutral
|
||||
public int compareTo( // $ negativeSinkExample=compareTo(File):Argument[this] negativeSourceExample=compareTo(File):Parameter[this] // modeled as neutral
|
||||
File pathname // $ negativeSinkExample=compareTo(File):Argument[0] negativeSourceExample=compareTo(File):Parameter[0] // modeled as neutral
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.nio.file.OpenOption;
|
||||
|
||||
public class Files {
|
||||
public static void copy( // method result is not a candidate source (void)
|
||||
Path source, // $ positiveExample=copy(Path,OutputStream):Argument[0](path-injection) // manual model exists
|
||||
Path source, // $ positiveSinkExample=copy(Path,OutputStream):Argument[0](path-injection) // manual model exists
|
||||
OutputStream out // $ sinkModel=copy(Path,OutputStream):Argument[1]
|
||||
/* NB: may be worthwhile to implement the
|
||||
same behavior as in application mode where out would not be a
|
||||
@@ -23,7 +23,7 @@ public class Files {
|
||||
}
|
||||
|
||||
public static InputStream newInputStream( // $ sourceModel=newInputStream(Path,OpenOption[]):ReturnValue
|
||||
Path openPath, // $ positiveExample=newInputStream(Path,OpenOption[]):Argument[0](path-injection) sinkModel=newInputStream(Path,OpenOption[]):Argument[0] // known sink, but still a candidate (ai-modeled, and useful as a candidate in regression testing)
|
||||
Path openPath, // $ positiveSinkExample=newInputStream(Path,OpenOption[]):Argument[0](path-injection) sinkModel=newInputStream(Path,OpenOption[]):Argument[0] // known sink, but still a candidate (ai-modeled, and useful as a candidate in regression testing)
|
||||
OpenOption... options // $ sinkModel=newInputStream(Path,OpenOption[]):Argument[1]
|
||||
) throws IOException {
|
||||
return new FileInputStream(openPath.toFile());
|
||||
|
||||
Reference in New Issue
Block a user