Skip to content

Commit 692d5e5

Browse files
author
Max Schaefer
committed
Use inline expectations for positive examples.
1 parent 83c5673 commit 692d5e5

6 files changed

+56
-19
lines changed

java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,22 @@ predicate isNegativeExample(
436436
)
437437
}
438438

439+
/**
440+
* Holds if the given `endpoint` is a positive example for the `endpointType`.
441+
*
442+
* The other parameters record various other properties of interest.
443+
*/
444+
predicate isPositiveExample(
445+
Endpoint endpoint, string endpointType, string package, string type, string subtypes, string name,
446+
string signature, string input, string output, string isVarargsArray, string extensibleType
447+
) {
448+
any(ApplicationModeMetadataExtractor meta)
449+
.hasMetadata(endpoint, package, type, subtypes, name, signature, input, output,
450+
isVarargsArray, _, extensibleType) and
451+
CharacteristicsImpl::isKnownAs(endpoint, endpointType, _) and
452+
exists(CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()))
453+
}
454+
439455
/*
440456
* EndpointCharacteristic classes that are specific to Automodel for Java.
441457
*/

java/ql/automodel/src/AutomodelApplicationModeExtractPositiveExamples.ql

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@ from
1818
DollarAtString signature, DollarAtString input, DollarAtString output,
1919
DollarAtString isVarargsArray, DollarAtString extensibleType
2020
where
21-
meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input, output,
22-
isVarargsArray, _, extensibleType) and
23-
CharacteristicsImpl::isKnownAs(endpoint, endpointType, _) and
24-
exists(CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()))
21+
isPositiveExample(endpoint, endpointType, package, type, subtypes, name, signature, input, output,
22+
isVarargsArray, extensibleType)
2523
select endpoint.asNode(),
2624
endpointType + "\nrelated locations: $@, $@, $@." +
2725
"\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@.", //
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
1-
| Test.java:30:4:30:9 | source | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:29:3:33:3 | copy(...) | CallContext | Test.java:30:4:30:9 | source | MethodDoc | Test.java:30:4:30:9 | source | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://copy:1:1:1:1 | copy | name | file://(Path,Path,CopyOption[]):1:1:1:1 | (Path,Path,CopyOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
2-
| Test.java:31:4:31:9 | target | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:29:3:33:3 | copy(...) | CallContext | Test.java:31:4:31:9 | target | MethodDoc | Test.java:31:4:31:9 | target | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://copy:1:1:1:1 | copy | name | file://(Path,Path,CopyOption[]):1:1:1:1 | (Path,Path,CopyOption[]) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
3-
| Test.java:38:4:38:11 | openPath | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:37:10:39:3 | newInputStream(...) | CallContext | Test.java:38:4:38:11 | openPath | MethodDoc | Test.java:38:4:38:11 | openPath | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://newInputStream:1:1:1:1 | newInputStream | name | file://(Path,OpenOption[]):1:1:1:1 | (Path,OpenOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
4-
| Test.java:66:3:66:20 | getInputStream(...) | remote\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:66:3:66:20 | getInputStream(...) | CallContext | Test.java:66:3:66:20 | getInputStream(...) | MethodDoc | Test.java:66:3:66:20 | getInputStream(...) | ClassDoc | file://java.net:1:1:1:1 | java.net | package | file://URLConnection:1:1:1:1 | URLConnection | type | file://true:1:1:1:1 | true | subtypes | file://getInputStream:1:1:1:1 | getInputStream | name | file://():1:1:1:1 | () | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
5-
| Test.java:90:28:90:28 | p | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:90:4:90:29 | createDirectories(...) | CallContext | Test.java:90:28:90:28 | p | MethodDoc | Test.java:90:28:90:28 | p | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://createDirectories:1:1:1:1 | createDirectories | name | file://(Path,FileAttribute[]):1:1:1:1 | (Path,FileAttribute[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
6-
| Test.java:94:4:94:4 | p | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:93:3:95:3 | delete(...) | CallContext | Test.java:94:4:94:4 | p | MethodDoc | Test.java:94:4:94:4 | p | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://delete:1:1:1:1 | delete | name | file://(Path):1:1:1:1 | (Path) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
7-
| Test.java:98:4:98:4 | p | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:97:3:99:3 | deleteIfExists(...) | CallContext | Test.java:98:4:98:4 | p | MethodDoc | Test.java:98:4:98:4 | p | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://deleteIfExists:1:1:1:1 | deleteIfExists | name | file://(Path):1:1:1:1 | (Path) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
1+
testFailures
2+
failures
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import java
2+
import AutomodelApplicationModeCharacteristics
3+
import TestUtilities.InlineExpectationsTest
4+
5+
module PositiveExampleTest implements TestSig {
6+
string getARelevantTag() { result = "positiveExample" }
7+
8+
predicate hasActualResult(Location location, string element, string tag, string value) {
9+
exists(
10+
Endpoint endpoint, string endpointType, string name, string signature, string input,
11+
string output, string extensibleType
12+
|
13+
isPositiveExample(endpoint, endpointType, _, _, _, name, signature, input, output, _,
14+
extensibleType)
15+
|
16+
endpoint.asTop().getLocation() = location and
17+
endpoint.toString() = element and
18+
tag = "positiveExample" and
19+
// for source models only the output is relevant, and vice versa for sink models
20+
if extensibleType = "sourceModel"
21+
then value = name + signature + ":" + output + "(" + endpointType + ")"
22+
else value = name + signature + ":" + input + "(" + endpointType + ")"
23+
)
24+
}
25+
}
26+
27+
import MakeTest<PositiveExampleTest>

java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ 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, // positive example (known sink)
31-
target, // positive example (known sink)
30+
source, // $ positiveExample=copy(Path,Path,CopyOption[]):Argument[0](path-injection)
31+
target, // $ positiveExample=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] // positive example (known sink), candidate ("only" ai-modeled, and useful as a candidate in regression testing)
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
3939
); // $ sourceModel=newInputStream(Path,OpenOption[]):ReturnValue
4040
}
4141

@@ -63,7 +63,7 @@ public static void FilesWalkExample(Path p, FileVisitOption o) throws Exception
6363
}
6464

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

@@ -87,15 +87,17 @@ public FutureTask getTask() {
8787
class MoreTests {
8888
public static void FilesListExample(Path p) throws Exception {
8989
Files.list(
90-
Files.createDirectories(p) // $ sourceModel=createDirectories(Path,FileAttribute[]):ReturnValue negativeExample=list(Path):Argument[0] // modeled as a flow step
90+
Files.createDirectories( // $ negativeExample=list(Path):Argument[0] // modeled as a flow step
91+
p // $ positiveExample=createDirectories(Path,FileAttribute[]):Argument[0](path-injection)
92+
) // $ sourceModel=createDirectories(Path,FileAttribute[]):ReturnValue
9193
); // $ sourceModel=list(Path):ReturnValue
9294

9395
Files.delete(
94-
p // $ sinkModel=delete(Path):Argument[0]
96+
p // $ sinkModel=delete(Path):Argument[0] positiveExample=delete(Path):Argument[0](path-injection)
9597
); // $ negativeExample=delete(Path):ReturnValue // return type is void
9698

9799
Files.deleteIfExists(
98-
p // $ sinkModel=deleteIfExists(Path):Argument[0]
100+
p // $ sinkModel=deleteIfExists(Path):Argument[0] positiveExample=deleteIfExists(Path):Argument[0](path-injection)
99101
); // $ negativeExample=deleteIfExists(Path):ReturnValue // return type is boolean
100102
}
101103
}

0 commit comments

Comments
 (0)