Skip to content

Commit 7bc0304

Browse files
author
Max Schaefer
committed
Make tags for positive and negative examples more precise.
1 parent ae23920 commit 7bc0304

File tree

5 files changed

+41
-28
lines changed

5 files changed

+41
-28
lines changed

java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ class Test {
1717
public static void main(String[] args) throws Exception {
1818
AtomicReference<String> reference = new AtomicReference<>(); // uninteresting (parameterless constructor)
1919
reference.set( // $ sinkModel=set(Object):Argument[this]
20-
args[0] // $ negativeExample=set(Object):Argument[0] // modeled as a flow step
21-
); // $ negativeExample=set(Object):ReturnValue // return type is void
20+
args[0] // $ negativeSinkExample=set(Object):Argument[0] // modeled as a flow step
21+
); // $ negativeSourceExample=set(Object):ReturnValue // return type is void
2222
}
2323

2424
public static void callSupplier(Supplier<String> supplier) {
@@ -27,43 +27,43 @@ public static void callSupplier(Supplier<String> supplier) {
2727

2828
public static void copyFiles(Path source, Path target, CopyOption option) throws Exception {
2929
Files.copy(
30-
source, // $ positiveExample=copy(Path,Path,CopyOption[]):Argument[0](path-injection)
31-
target, // $ positiveExample=copy(Path,Path,CopyOption[]):Argument[1](path-injection)
30+
source, // $ positiveSinkExample=copy(Path,Path,CopyOption[]):Argument[0](path-injection)
31+
target, // $ positiveSinkExample=copy(Path,Path,CopyOption[]):Argument[1](path-injection)
3232
option // no candidate (not modeled, but source and target are modeled)
3333
); // $ sourceModel=copy(Path,Path,CopyOption[]):ReturnValue
3434
}
3535

3636
public static InputStream getInputStream(Path openPath) throws Exception {
3737
return Files.newInputStream(
38-
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
38+
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
3939
); // $ sourceModel=newInputStream(Path,OpenOption[]):ReturnValue
4040
}
4141

4242
public static InputStream getInputStream(String openPath) throws Exception {
4343
return Test.getInputStream( // the call is not a source candidate (argument to local call)
4444
Paths.get(
45-
openPath // $ negativeExample=get(String,String[]):Argument[0] // modeled as a flow step
45+
openPath // $ negativeSinkExample=get(String,String[]):Argument[0] // modeled as a flow step
4646
) // $ sourceModel=get(String,String[]):ReturnValue
4747
);
4848
}
4949

5050
public static int compareFiles(File f1, File f2) {
51-
return f1.compareTo( // $ negativeExample=compareTo(File):Argument[this]
52-
f2 // $ negativeExample=compareTo(File):Argument[0] // modeled as not a sink
53-
); // $ negativeExample=compareTo(File):ReturnValue // return type is int
51+
return f1.compareTo( // $ negativeSinkExample=compareTo(File):Argument[this]
52+
f2 // $ negativeSinkExample=compareTo(File):Argument[0] // modeled as not a sink
53+
); // $ negativeSourceExample=compareTo(File):ReturnValue // return type is int
5454
}
5555

5656
public static void FilesWalkExample(Path p, FileVisitOption o) throws Exception {
5757
Files.walk(
58-
p, // $ negativeExample=walk(Path,FileVisitOption[]):Argument[0] // modeled as a flow step
58+
p, // $ negativeSinkExample=walk(Path,FileVisitOption[]):Argument[0] // modeled as a flow step
5959
o, // the implicit varargs array is a candidate, annotated on the last line of the call
6060
o // not a candidate (only the first arg corresponding to a varargs array
6161
// is extracted)
6262
); // $ sourceModel=walk(Path,FileVisitOption[]):ReturnValue sinkModel=walk(Path,FileVisitOption[]):Argument[1]
6363
}
6464

6565
public static void WebSocketExample(URLConnection c) throws Exception {
66-
c.getInputStream(); // $ sinkModel=getInputStream():Argument[this] positiveExample=getInputStream():ReturnValue(remote) // not a source candidate (manual modeling)
66+
c.getInputStream(); // $ sinkModel=getInputStream():Argument[this] positiveSourceExample=getInputStream():ReturnValue(remote) // not a source candidate (manual modeling)
6767
}
6868
}
6969

@@ -88,16 +88,16 @@ class MoreTests {
8888
public static void FilesListExample(Path p) throws Exception {
8989
Files.list(
9090
Files.createDirectories(
91-
p // $ positiveExample=createDirectories(Path,FileAttribute[]):Argument[0](path-injection)
92-
) // $ sourceModel=createDirectories(Path,FileAttribute[]):ReturnValue negativeExample=list(Path):Argument[0] // modeled as a flow step
91+
p // $ positiveSinkExample=createDirectories(Path,FileAttribute[]):Argument[0](path-injection)
92+
) // $ sourceModel=createDirectories(Path,FileAttribute[]):ReturnValue negativeSinkExample=list(Path):Argument[0] // modeled as a flow step
9393
); // $ sourceModel=list(Path):ReturnValue
9494

9595
Files.delete(
96-
p // $ sinkModel=delete(Path):Argument[0] positiveExample=delete(Path):Argument[0](path-injection)
97-
); // $ negativeExample=delete(Path):ReturnValue // return type is void
96+
p // $ sinkModel=delete(Path):Argument[0] positiveSinkExample=delete(Path):Argument[0](path-injection)
97+
); // $ negativeSourceExample=delete(Path):ReturnValue // return type is void
9898

9999
Files.deleteIfExists(
100-
p // $ sinkModel=deleteIfExists(Path):Argument[0] positiveExample=deleteIfExists(Path):Argument[0](path-injection)
101-
); // $ negativeExample=deleteIfExists(Path):ReturnValue // return type is boolean
100+
p // $ sinkModel=deleteIfExists(Path):Argument[0] positiveSinkExample=deleteIfExists(Path):Argument[0](path-injection)
101+
); // $ negativeSourceExample=deleteIfExists(Path):ReturnValue // return type is boolean
102102
}
103103
}

java/ql/automodel/test/AutomodelExtractionTests.qll

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,22 @@ signature module TestHelperSig<CandidateSig Candidate> {
2323

2424
module Extraction<CandidateSig Candidate, TestHelperSig<Candidate> TestHelper> implements TestSig {
2525
string getARelevantTag() {
26-
result in ["sourceModel", "sinkModel", "positiveExample", "negativeExample"]
26+
result in [
27+
"sourceModel", "sinkModel", // a candidate source/sink
28+
"positiveSourceExample", "positiveSinkExample", // a known source/sink
29+
"negativeSourceExample", "negativeSinkExample" // a known non-source/non-sink
30+
]
31+
}
32+
33+
/**
34+
* If `extensibleType` is `sourceModel` then the result is `ifSource`, if it
35+
* is `sinkModel` then the result is `ifSink`.
36+
*/
37+
bindingset[extensibleType, ifSource, ifSink]
38+
private string ifSource(string extensibleType, string ifSource, string ifSink) {
39+
extensibleType = "sourceModel" and result = ifSource
40+
or
41+
extensibleType = "sinkModel" and result = ifSink
2742
}
2843

2944
additional predicate selectEndpoint(
@@ -35,13 +50,13 @@ module Extraction<CandidateSig Candidate, TestHelperSig<Candidate> TestHelper> i
3550
suffix = ""
3651
or
3752
TestHelper::isNegativeExample(endpoint, name, signature, input, output, extensibleType) and
38-
tag = "negativeExample" and
53+
tag = "negative" + ifSource(extensibleType, "Source", "Sink") + "Example" and
3954
suffix = ""
4055
or
4156
exists(string endpointType |
4257
TestHelper::isPositiveExample(endpoint, endpointType, name, signature, input, output,
4358
extensibleType) and
44-
tag = "positiveExample" and
59+
tag = "positive" + ifSource(extensibleType, "Source", "Sink") + "Example" and
4560
suffix = "(" + endpointType + ")"
4661
)
4762
}
@@ -56,9 +71,7 @@ module Extraction<CandidateSig Candidate, TestHelperSig<Candidate> TestHelper> i
5671
TestHelper::getEndpointLocation(endpoint) = location and
5772
endpoint.toString() = element and
5873
// for source models only the output is relevant, and vice versa for sink models
59-
if extensibleType = "sourceModel"
60-
then value = name + signature + ":" + output + suffix
61-
else value = name + signature + ":" + input + suffix
74+
value = name + signature + ":" + ifSource(extensibleType, output, input) + suffix
6275
)
6376
}
6477
}

java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public PublicClass(Object input) { // $ sourceModel=PublicClass(Object):ReturnVa
2121
}
2222

2323
// `input` and `input` are source candidates, but not sink candidates (is-style method)
24-
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]
24+
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]
2525
return false;
2626
}
2727
}

java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/io/File.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package java.io;
22

33
public class File {
4-
public int compareTo( // $ negativeExample=compareTo(File):Argument[this] negativeExample=compareTo(File):Parameter[this] // modeled as neutral
5-
File pathname // $ negativeExample=compareTo(File):Argument[0] negativeExample=compareTo(File):Parameter[0] // modeled as neutral
4+
public int compareTo( // $ negativeSinkExample=compareTo(File):Argument[this] negativeSourceExample=compareTo(File):Parameter[this] // modeled as neutral
5+
File pathname // $ negativeSinkExample=compareTo(File):Argument[0] negativeSourceExample=compareTo(File):Parameter[0] // modeled as neutral
66
) {
77
return 0;
88
}

java/ql/automodel/test/AutomodelFrameworkModeExtraction/java/nio/file/Files.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
public class Files {
1212
public static void copy( // method result is not a candidate source (void)
13-
Path source, // $ positiveExample=copy(Path,OutputStream):Argument[0](path-injection) // manual model exists
13+
Path source, // $ positiveSinkExample=copy(Path,OutputStream):Argument[0](path-injection) // manual model exists
1414
OutputStream out // $ sinkModel=copy(Path,OutputStream):Argument[1]
1515
/* NB: may be worthwhile to implement the
1616
same behavior as in application mode where out would not be a
@@ -23,7 +23,7 @@ public static void copy( // method result is not a candidate source (void)
2323
}
2424

2525
public static InputStream newInputStream( // $ sourceModel=newInputStream(Path,OpenOption[]):ReturnValue
26-
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)
26+
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)
2727
OpenOption... options // $ sinkModel=newInputStream(Path,OpenOption[]):Argument[1]
2828
) throws IOException {
2929
return new FileInputStream(openPath.toFile());

0 commit comments

Comments
 (0)