Skip to content

Commit 587d69e

Browse files
author
Max Schaefer
committed
Refactor application-mode candidate-extraction query so we can test its results before sampling.
1 parent 800a78d commit 587d69e

5 files changed

+61
-36
lines changed

java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,32 @@ class ApplicationModeMetadataExtractor extends string {
366366
}
367367
}
368368

369+
/**
370+
* Holds if the given `endpoint` should be considered a candidate for the `extensibleType.
371+
*
372+
* The other parameters record various other properties of interest.
373+
*/
374+
predicate isCandidate(
375+
Endpoint endpoint, string package, string type, string subtypes, string name, string signature,
376+
string input, string output, string isVarargs, string extensibleType, string alreadyAiModeled
377+
) {
378+
exists(ApplicationModeMetadataExtractor meta |
379+
CharacteristicsImpl::isCandidate(endpoint, _) and
380+
not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u |
381+
u.appliesToEndpoint(endpoint)
382+
) and
383+
meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input, output, isVarargs,
384+
alreadyAiModeled, extensibleType) and
385+
// If a node is already modeled in MaD, we don't include it as a candidate. Otherwise, we might include it as a
386+
// candidate for query A, but the model will label it as a sink for one of the sink types of query B, for which it's
387+
// already a known sink. This would result in overlap between our detected sinks and the pre-existing modeling. We
388+
// assume that, if a sink has already been modeled in a MaD model, then it doesn't belong to any additional sink
389+
// types, and we don't need to reexamine it.
390+
alreadyAiModeled.matches(["", "%ai-%"]) and
391+
AutomodelJavaUtil::includeAutomodelCandidate(package, type, name, signature)
392+
)
393+
}
394+
369395
/*
370396
* EndpointCharacteristic classes that are specific to Automodel for Java.
371397
*/

java/ql/automodel/src/AutomodelApplicationModeExtractCandidates.ql

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,15 @@ private Endpoint getSampleForSignature(
5555
}
5656

5757
from
58-
Endpoint endpoint, ApplicationModeMetadataExtractor meta, DollarAtString package,
59-
DollarAtString type, DollarAtString subtypes, DollarAtString name, DollarAtString signature,
60-
DollarAtString input, DollarAtString output, DollarAtString isVarargsArray,
61-
DollarAtString alreadyAiModeled, DollarAtString extensibleType
58+
Endpoint endpoint, DollarAtString package, DollarAtString type, DollarAtString subtypes,
59+
DollarAtString name, DollarAtString signature, DollarAtString input, DollarAtString output,
60+
DollarAtString isVarargsArray, DollarAtString alreadyAiModeled, DollarAtString extensibleType
6261
where
63-
not exists(CharacteristicsImpl::UninterestingToModelCharacteristic u |
64-
u.appliesToEndpoint(endpoint)
65-
) and
66-
CharacteristicsImpl::isCandidate(endpoint, _) and
62+
isCandidate(endpoint, package, type, subtypes, name, signature, input, output, isVarargsArray,
63+
extensibleType, alreadyAiModeled) and
6764
endpoint =
6865
getSampleForSignature(9, package, type, subtypes, name, signature, input, output,
69-
isVarargsArray, extensibleType, alreadyAiModeled) and
70-
meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input, output,
71-
isVarargsArray, alreadyAiModeled, extensibleType) and
72-
// If a node is already modeled in MaD, we don't include it as a candidate. Otherwise, we might include it as a
73-
// candidate for query A, but the model will label it as a sink for one of the sink types of query B, for which it's
74-
// already a known sink. This would result in overlap between our detected sinks and the pre-existing modeling. We
75-
// assume that, if a sink has already been modeled in a MaD model, then it doesn't belong to any additional sink
76-
// types, and we don't need to reexamine it.
77-
alreadyAiModeled.matches(["", "%ai-%"]) and
78-
includeAutomodelCandidate(package, type, name, signature)
66+
isVarargsArray, extensibleType, alreadyAiModeled)
7967
select endpoint.asNode(),
8068
"Related locations: $@, $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@.", //
8169
CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, CallContext()), "CallContext", //
Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
| PluginImpl.java:5:27:5:37 | name | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | PluginImpl.java:5:27:5:37 | name | CallContext | hudson/Plugin.java:5:5:5:31 | /** Configure method doc */ | MethodDoc | hudson/Plugin.java:3:1:3:17 | /** Plugin doc */ | ClassDoc | file://hudson:1:1:1:1 | hudson | package | file://Plugin:1:1:1:1 | Plugin | type | file://true:1:1:1:1 | true | subtypes | file://configure:1:1:1:1 | configure | name | file://(String,String):1:1:1:1 | (String,String) | signature | file://:1:1:1:1 | | input | file://Parameter[0]:1:1:1:1 | Parameter[0] | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
2-
| PluginImpl.java:5:40:5:51 | value | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | PluginImpl.java:5:40:5:51 | value | CallContext | hudson/Plugin.java:5:5:5:31 | /** Configure method doc */ | MethodDoc | hudson/Plugin.java:3:1:3:17 | /** Plugin doc */ | ClassDoc | file://hudson:1:1:1:1 | hudson | package | file://Plugin:1:1:1:1 | Plugin | type | file://true:1:1:1:1 | true | subtypes | file://configure:1:1:1:1 | configure | name | file://(String,String):1:1:1:1 | (String,String) | signature | file://:1:1:1:1 | | input | file://Parameter[1]:1:1:1:1 | Parameter[1] | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
3-
| Test.java:19:3:19:11 | reference | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:19:3:19:24 | set(...) | CallContext | Test.java:19:3:19:11 | reference | MethodDoc | Test.java:19:3:19:11 | reference | ClassDoc | file://java.util.concurrent.atomic:1:1:1:1 | java.util.concurrent.atomic | package | file://AtomicReference:1:1:1:1 | AtomicReference | type | file://false:1:1:1:1 | false | subtypes | file://set:1:1:1:1 | set | name | file://(Object):1:1:1:1 | (Object) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
4-
| Test.java:24:3:24:10 | supplier | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:24:3:24:16 | get(...) | CallContext | Test.java:24:3:24:10 | supplier | MethodDoc | Test.java:24:3:24:10 | supplier | ClassDoc | file://java.util.function:1:1:1:1 | java.util.function | package | file://Supplier:1:1:1:1 | Supplier | type | file://true:1:1:1:1 | true | subtypes | file://get:1:1:1:1 | get | name | file://():1:1:1:1 | () | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
5-
| Test.java:24:3:24:16 | get(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:24:3:24:16 | get(...) | CallContext | Test.java:24:3:24:16 | get(...) | MethodDoc | Test.java:24:3:24:16 | get(...) | ClassDoc | file://java.util.function:1:1:1:1 | java.util.function | package | file://Supplier:1:1:1:1 | Supplier | type | file://true:1:1:1:1 | true | subtypes | file://get:1:1:1:1 | get | 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://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
6-
| Test.java:28:3:32:3 | copy(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:28:3:32:3 | copy(...) | CallContext | Test.java:28:3:32:3 | copy(...) | MethodDoc | Test.java:28:3:32:3 | copy(...) | 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://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
7-
| Test.java:36:10:38:3 | newInputStream(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:36:10:38:3 | newInputStream(...) | CallContext | Test.java:36:10:38:3 | newInputStream(...) | MethodDoc | Test.java:36:10:38:3 | newInputStream(...) | 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://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
8-
| Test.java:37:4:37:11 | openPath | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:36:10:38:3 | newInputStream(...) | CallContext | Test.java:37:4:37:11 | openPath | MethodDoc | Test.java:37:4:37: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://ai-manual:1:1:1:1 | ai-manual | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
9-
| Test.java:43:4:43:22 | get(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:43:4:43:22 | get(...) | CallContext | Test.java:43:4:43:22 | get(...) | MethodDoc | Test.java:43:4:43:22 | get(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Paths:1:1:1:1 | Paths | type | file://false:1:1:1:1 | false | subtypes | file://get:1:1:1:1 | get | name | file://(String,String[]):1:1:1:1 | (String,String[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
10-
| Test.java:54:3:59:3 | walk(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:54:3:59:3 | walk(...) | CallContext | Test.java:54:3:59:3 | walk(...) | MethodDoc | Test.java:54:3:59:3 | walk(...) | 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://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
11-
| Test.java:56:4:56:4 | o | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:54:3:59:3 | walk(...) | CallContext | Test.java:54:3:59:3 | walk(...) | MethodDoc | Test.java:54:3:59:3 | walk(...) | 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://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://:1:1:1:1 | | output | file://true:1:1:1:1 | true | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
12-
| Test.java:63:3:63:3 | c | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:63:3:63:20 | getInputStream(...) | CallContext | Test.java:63:3:63:3 | c | MethodDoc | Test.java:63:3:63:3 | c | 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://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
13-
| Test.java:68:30:68:47 | writer | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:68:30:68:47 | writer | CallContext | Test.java:68:30:68:47 | writer | MethodDoc | Test.java:68:30:68:47 | writer | ClassDoc | file://java.lang:1:1:1:1 | java.lang | package | file://Throwable:1:1:1:1 | Throwable | type | file://true:1:1:1:1 | true | subtypes | file://printStackTrace:1:1:1:1 | printStackTrace | name | file://(PrintWriter):1:1:1:1 | (PrintWriter) | signature | file://:1:1:1:1 | | input | file://Parameter[0]:1:1:1:1 | Parameter[0] | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
14-
| Test.java:86:3:88:3 | list(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:86:3:88:3 | list(...) | CallContext | Test.java:86:3:88:3 | list(...) | MethodDoc | Test.java:86:3:88:3 | list(...) | 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://list:1:1:1:1 | list | name | file://(Path):1:1:1:1 | (Path) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
15-
| Test.java:87:4:87:29 | createDirectories(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:87:4:87:29 | createDirectories(...) | CallContext | Test.java:87:4:87:29 | createDirectories(...) | MethodDoc | Test.java:87:4:87:29 | createDirectories(...) | 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://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
16-
| Test.java:91:4:91:4 | p | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:90:3:92:3 | delete(...) | CallContext | Test.java:91:4:91:4 | p | MethodDoc | Test.java:91:4:91: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://ai-manual:1:1:1:1 | ai-manual | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
17-
| Test.java:95:4:95:4 | p | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:94:3:96:3 | deleteIfExists(...) | CallContext | Test.java:95:4:95:4 | p | MethodDoc | Test.java:95:4:95: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://ai-manual:1:1:1:1 | ai-manual | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
1+
| PluginImpl.java:5:27:5:37 | name | hudson | Plugin | configure | (String,String) | | Parameter[0] | sourceModel |
2+
| PluginImpl.java:5:40:5:51 | value | hudson | Plugin | configure | (String,String) | | Parameter[1] | sourceModel |
3+
| Test.java:19:3:19:11 | reference | java.util.concurrent.atomic | AtomicReference | set | (Object) | Argument[this] | | sinkModel |
4+
| Test.java:19:3:19:24 | set(...) | java.util.concurrent.atomic | AtomicReference | set | (Object) | | ReturnValue | sourceModel |
5+
| Test.java:24:3:24:10 | supplier | java.util.function | Supplier | get | () | Argument[this] | | sinkModel |
6+
| Test.java:24:3:24:16 | get(...) | java.util.function | Supplier | get | () | | ReturnValue | sourceModel |
7+
| Test.java:28:3:32:3 | copy(...) | java.nio.file | Files | copy | (Path,Path,CopyOption[]) | | ReturnValue | sourceModel |
8+
| Test.java:36:10:38:3 | newInputStream(...) | java.nio.file | Files | newInputStream | (Path,OpenOption[]) | | ReturnValue | sourceModel |
9+
| Test.java:37:4:37:11 | openPath | java.nio.file | Files | newInputStream | (Path,OpenOption[]) | Argument[0] | | sinkModel |
10+
| Test.java:43:4:43:22 | get(...) | java.nio.file | Paths | get | (String,String[]) | | ReturnValue | sourceModel |
11+
| Test.java:54:3:59:3 | walk(...) | java.nio.file | Files | walk | (Path,FileVisitOption[]) | | ReturnValue | sourceModel |
12+
| Test.java:54:3:59:3 | walk(...) | java.nio.file | Files | walk | (Path,FileVisitOption[]) | Argument[1] | | sinkModel |
13+
| Test.java:63:3:63:3 | c | java.net | URLConnection | getInputStream | () | Argument[this] | | sinkModel |
14+
| Test.java:68:30:68:47 | writer | java.lang | Throwable | printStackTrace | (PrintWriter) | | Parameter[0] | sourceModel |
15+
| Test.java:86:3:88:3 | list(...) | java.nio.file | Files | list | (Path) | | ReturnValue | sourceModel |
16+
| Test.java:87:4:87:29 | createDirectories(...) | java.nio.file | Files | createDirectories | (Path,FileAttribute[]) | | ReturnValue | sourceModel |
17+
| Test.java:90:3:92:3 | delete(...) | java.nio.file | Files | delete | (Path) | | ReturnValue | sourceModel |
18+
| Test.java:91:4:91:4 | p | java.nio.file | Files | delete | (Path) | Argument[0] | | sinkModel |
19+
| Test.java:95:4:95:4 | p | java.nio.file | Files | deleteIfExists | (Path) | Argument[0] | | sinkModel |
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import java
2+
import AutomodelApplicationModeCharacteristics
3+
4+
from
5+
Endpoint endpoint, Top t, string package, string type, string name, string signature,
6+
string input, string output, string extensibleType
7+
where
8+
isCandidate(endpoint, package, type, _, name, signature, input, output, _, extensibleType, _) and
9+
t = endpoint.asTop()
10+
select t, package, type, name, signature, input, output, extensibleType

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

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

0 commit comments

Comments
 (0)