From 18fe587e751457bd8c8581b6e15d54144925236b Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 21 Jul 2023 13:31:46 +0200 Subject: [PATCH 01/17] Java: tests for automodel framework mode candidate extraction --- ...omodelFrameworkModeExtractCandidates.expected | 3 +++ ...AutomodelFrameworkModeExtractCandidates.qlref | 1 + .../com/github/codeql/test/NonPublicClass.java | 10 ++++++++++ .../com/github/codeql/test/PublicClass.java | 16 ++++++++++++++++ .../java/nio/file/Files.java | 15 +++++++++++++++ 5 files changed, 45 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.expected create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.qlref create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/NonPublicClass.java create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/PublicClass.java create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/java/nio/file/Files.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.expected new file mode 100644 index 000000000000..c09142a5ee7e --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.expected @@ -0,0 +1,3 @@ +| com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | +| com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://false:1:1:1:1 | false | subtypes | file://staticStuff:1:1:1:1 | staticStuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | +| java/nio/file/Files.java:12:42:12:57 | out | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/nio/file/Files.java:12:42:12:57 | out | MethodDoc | java/nio/file/Files.java:12:42:12:57 | out | 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,OutputStream):1:1:1:1 | (Path,OutputStream) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://out:1:1:1:1 | out | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.qlref b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.qlref new file mode 100644 index 000000000000..e68551eb3ec7 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.qlref @@ -0,0 +1 @@ +Telemetry/AutomodelFrameworkModeExtractCandidates.ql diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/NonPublicClass.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/NonPublicClass.java new file mode 100644 index 000000000000..b106d3da5940 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/NonPublicClass.java @@ -0,0 +1,10 @@ +package com.github.codeql.test; + +/** + * No candidates in this class, as it's not public! + */ +class NonPublicClass { + public void noCandidates(String here) { + System.out.println(here); + } +} diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/PublicClass.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/PublicClass.java new file mode 100644 index 000000000000..0405c43a58bb --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/PublicClass.java @@ -0,0 +1,16 @@ +package com.github.codeql.test; + +public class PublicClass { + public void stuff(String arg) { // arg is a candidate + System.out.println(arg); + } + + public static void staticStuff(String arg) { // arg is a candidate + System.out.println(arg); + } + + // arg is not a candidate because the method is not public: + protected void nonPublicStuff(String arg) { + System.out.println(arg); + } +} diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/java/nio/file/Files.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/java/nio/file/Files.java new file mode 100644 index 000000000000..663dc945a152 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/java/nio/file/Files.java @@ -0,0 +1,15 @@ +package java.nio.file; + +import java.nio.file.Path; +import java.io.IOException; +import java.io.OutputStream; + +public class Files { + // - source is not a candidate because a manual model exists: + // ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "path-injection", "manual"] + // - out is a candidate. NB: may be worthwile to implement the same behaviour as in application mode where out + // would not be a candidate because another param is already modeled. + public static void copy(Path source, OutputStream out) throws IOException { + // ... + } +} From 2e89a11949f3c26c732937164b353d98e2eb43db Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 21 Jul 2023 14:41:29 +0200 Subject: [PATCH 02/17] Java: tests for automodel application mode candidate extraction --- ...lApplicationModeExtractCandidates.expected | 2 ++ ...odelApplicationModeExtractCandidates.qlref | 1 + .../Test.java | 36 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.expected create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.qlref create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.expected new file mode 100644 index 000000000000..07e9896dafb8 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.expected @@ -0,0 +1,2 @@ +| Test.java:14:3:14:11 | reference | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:14:3:14:24 | set(...) | CallContext | 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://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | +| Test.java:20:3:20:10 | supplier | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:20:3:20:16 | get(...) | CallContext | 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 | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.qlref b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.qlref new file mode 100644 index 000000000000..b97c87be55fd --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.qlref @@ -0,0 +1 @@ +Telemetry/AutomodelApplicationModeExtractCandidates.ql diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java new file mode 100644 index 000000000000..2c14be85dbb3 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java @@ -0,0 +1,36 @@ +package com.github.codeql.test; + +import java.io.InputStream; +import java.nio.file.CopyOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; + +class AutomodelApplicationModeExtractCandidates { + public static void main(String[] args) throws Exception { + AtomicReference reference = new AtomicReference<>(); // uninteresting (parameterless constructor) + reference.set(args[0]); // arg[0] is not a candidate (modeled as value flow step) + // ^^^^^^ Argument[this] is a candidate (should no longer be, once a recent PR + // is merged) + } + + public static void callSupplier(Supplier supplier) { + supplier.get(); // Argument[this] is a candidate + } + + public static void copyFiles(Path source, Path target, CopyOption option) throws Exception { + Files.copy( + source, // no candidate (modeled) + target, // no candidate (modeled) + option // no candidate (not modeled, but source and target are modeled) + ); + } + + public static InputStream getInputStream(Path openPath) throws Exception { + return Files.newInputStream( + openPath // no candidate (known sink) + ); + } +} From 1bc222ec402cc7bd97721e188f656051c50fa944 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 21 Jul 2023 15:30:05 +0200 Subject: [PATCH 03/17] Java: tests for automodel application mode positive example extraction --- ...cationModeExtractPositiveExamples.expected | 2 ++ ...plicationModeExtractPositiveExamples.qlref | 1 + .../Test.java | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.expected create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.qlref create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/Test.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.expected new file mode 100644 index 000000000000..9c6775df3bee --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.expected @@ -0,0 +1,2 @@ +| Test.java:17:4:17:9 | source | path-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:16:3:20:3 | copy(...) | CallContext | 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 | +| Test.java:18:4:18:9 | target | path-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:16:3:20:3 | copy(...) | CallContext | 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 | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.qlref b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.qlref new file mode 100644 index 000000000000..585a78f94f92 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.qlref @@ -0,0 +1 @@ +Telemetry/AutomodelApplicationModeExtractPositiveExamples.ql diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/Test.java new file mode 100644 index 000000000000..5e6943fd7787 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/Test.java @@ -0,0 +1,22 @@ +package com.github.codeql.test; + +import java.nio.file.CopyOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; + +class AutomodelApplicationModeExtractPositiveExamples { + public static void callSupplier(Supplier supplier) { + supplier.get(); // not an example + } + + public static void copyFiles(Path source, Path target, CopyOption option) throws Exception { + Files.copy( + source, // positive example + target, // positive example + option // no example + ); + } +} From abed936556f65b08d6ed07f7a3ec39f0e58d5dd9 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 21 Jul 2023 16:52:26 +0200 Subject: [PATCH 04/17] Java: tests for automodel framework mode positive example extraction --- ...odelFrameworkModeExtractPositiveExamples.expected | 1 + ...tomodelFrameworkModeExtractPositiveExamples.qlref | 1 + .../java/nio/file/Files.java | 12 ++++++++++++ 3 files changed, 14 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.expected create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.qlref create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/java/nio/file/Files.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.expected new file mode 100644 index 000000000000..dc07c210155e --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.expected @@ -0,0 +1 @@ +| java/nio/file/Files.java:9:29:9:39 | source | path-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/nio/file/Files.java:9:29:9:39 | source | MethodDoc | java/nio/file/Files.java:9:29:9:39 | 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,OutputStream):1:1:1:1 | (Path,OutputStream) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://source:1:1:1:1 | source | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.qlref b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.qlref new file mode 100644 index 000000000000..ae52dc664968 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.qlref @@ -0,0 +1 @@ +Telemetry/AutomodelFrameworkModeExtractPositiveExamples.ql diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/java/nio/file/Files.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/java/nio/file/Files.java new file mode 100644 index 000000000000..896a454395b5 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/java/nio/file/Files.java @@ -0,0 +1,12 @@ +package java.nio.file; + +import java.nio.file.Path; +import java.io.IOException; +import java.io.OutputStream; + +public class Files { + // source is a positive example because there's a model for it + public static void copy(Path source, OutputStream out) throws IOException { + // ... + } +} From 938a7a788fa22e2cce15ef5f0445f7f3bed96172 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 21 Jul 2023 17:04:56 +0200 Subject: [PATCH 05/17] Java: tests for automodel application mode negative example extraction --- ...odelApplicationModeExtractNegativeExamples.expected | 2 ++ ...tomodelApplicationModeExtractNegativeExamples.qlref | 1 + .../Test.java | 10 ++++++++++ 3 files changed, 13 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.qlref create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/Test.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected new file mode 100644 index 000000000000..dd8d8fe52170 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected @@ -0,0 +1,2 @@ +| Test.java:7:10:7:19 | ByteBuffer | class qualifier\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:7:10:8:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | +| Test.java:8:15:8:18 | size | external\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:7:10:8:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.qlref b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.qlref new file mode 100644 index 000000000000..43610d3cc1a5 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.qlref @@ -0,0 +1 @@ +Telemetry/AutomodelApplicationModeExtractNegativeExamples.ql diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/Test.java new file mode 100644 index 000000000000..ac83546fabfc --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/Test.java @@ -0,0 +1,10 @@ +package com.github.codeql.test; + +import java.nio.ByteBuffer; + +class AutomodelApplicationModeExtractNegativeExamples { + public static ByteBuffer getBuffer(int size) { + return ByteBuffer // negative example, modeled as a neutral model + .allocate(size); // negative example, modeled as a neutral model + } +} From 457604e37eccedf93decbe7ed17fc8a244dbebcf Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Mon, 24 Jul 2023 10:00:38 +0200 Subject: [PATCH 06/17] Java: tests for automodel framework mode negative example extraction --- ...utomodelFrameworkModeExtractNegativeExamples.expected | 1 + .../AutomodelFrameworkModeExtractNegativeExamples.qlref | 1 + .../java/io/File.java | 9 +++++++++ 3 files changed, 11 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.expected create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.qlref create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/java/io/File.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.expected new file mode 100644 index 000000000000..44e3026415b5 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.expected @@ -0,0 +1 @@ +| java/io/File.java:5:9:5:21 | pathname | known non-sink\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/io/File.java:5:9:5:21 | pathname | MethodDoc | java/io/File.java:5:9:5:21 | pathname | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://pathname:1:1:1:1 | pathname | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.qlref b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.qlref new file mode 100644 index 000000000000..d58a0997fdc5 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.qlref @@ -0,0 +1 @@ +Telemetry/AutomodelFrameworkModeExtractNegativeExamples.ql diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/java/io/File.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/java/io/File.java new file mode 100644 index 000000000000..c84da33bdf23 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/java/io/File.java @@ -0,0 +1,9 @@ +package java.io; + +public class File { + int compareTo( + File pathname // negative example - this is modeled as a neutral model + ) { + return 0; + } +} From 50603102d1c645f2674962c30e552bbfb1388b78 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Mon, 24 Jul 2023 13:05:13 +0200 Subject: [PATCH 07/17] Java: tests for automodel application mode, test that local calls are not candidates --- .../AutomodelApplicationModeExtractCandidates/Test.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java index 2c14be85dbb3..aad7410d0d78 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java @@ -33,4 +33,10 @@ public static InputStream getInputStream(Path openPath) throws Exception { openPath // no candidate (known sink) ); } + + public static InputStream getInputStream(String openPath) throws Exception { + return AutomodelApplicationModeExtractCandidates.getInputStream( + Paths.get(openPath) // no candidate (argument to local call) + ); + } } From 37b6b46dbf5a6a99d26b27657e97eb0e069cc153 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Mon, 24 Jul 2023 17:05:28 +0200 Subject: [PATCH 08/17] Java: update extraction query tests after merging PR #13747 --- java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll | 2 +- .../AutomodelApplicationModeExtractCandidates/Test.java | 3 +-- .../AutomodelApplicationModeExtractNegativeExamples.expected | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll b/java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll index b9d631e9deb8..c1a9a14a10a5 100644 --- a/java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll @@ -303,7 +303,7 @@ module SharedCharacteristics { * analyzed. */ private class IsSanitizerCharacteristic extends NotASinkCharacteristic { - IsSanitizerCharacteristic() { this = "external" } + IsSanitizerCharacteristic() { this = "known sanitizer" } override predicate appliesToEndpoint(Candidate::Endpoint e) { Candidate::isSanitizer(e, _) } } diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java index aad7410d0d78..252c40ff6172 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java @@ -12,8 +12,7 @@ class AutomodelApplicationModeExtractCandidates { public static void main(String[] args) throws Exception { AtomicReference reference = new AtomicReference<>(); // uninteresting (parameterless constructor) reference.set(args[0]); // arg[0] is not a candidate (modeled as value flow step) - // ^^^^^^ Argument[this] is a candidate (should no longer be, once a recent PR - // is merged) + // ^^^^^^ Argument[this] is a candidate } public static void callSupplier(Supplier supplier) { diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected index dd8d8fe52170..9e04180fe0e4 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected @@ -1,2 +1,2 @@ -| Test.java:7:10:7:19 | ByteBuffer | class qualifier\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:7:10:8:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | -| Test.java:8:15:8:18 | size | external\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:7:10:8:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | +| Test.java:8:15:8:18 | size | known non-sink\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:7:10:8:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | +| Test.java:8:15:8:18 | size | known sanitizer\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:7:10:8:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | From 8cc367c45e9cdf2a20c33090f71967edb386bd4a Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Tue, 25 Jul 2023 12:39:15 +0200 Subject: [PATCH 09/17] Java: merge application mode tests into one --- ...cationModeExtractNegativeExamples.expected | 2 -- .../Test.java | 10 --------- ...cationModeExtractPositiveExamples.expected | 2 -- .../Test.java | 22 ------------------- ...lApplicationModeExtractCandidates.expected | 4 ++-- ...odelApplicationModeExtractCandidates.qlref | 0 ...cationModeExtractNegativeExamples.expected | 3 +++ ...plicationModeExtractNegativeExamples.qlref | 0 ...cationModeExtractPositiveExamples.expected | 3 +++ ...plicationModeExtractPositiveExamples.qlref | 0 .../Test.java | 18 ++++++++++----- 11 files changed, 21 insertions(+), 43 deletions(-) delete mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected delete mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/Test.java delete mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.expected delete mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/Test.java rename java/ql/test/query-tests/Telemetry/{AutomodelApplicationModeExtractCandidates => AutomodelApplicationModeExtraction}/AutomodelApplicationModeExtractCandidates.expected (75%) rename java/ql/test/query-tests/Telemetry/{AutomodelApplicationModeExtractCandidates => AutomodelApplicationModeExtraction}/AutomodelApplicationModeExtractCandidates.qlref (100%) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected rename java/ql/test/query-tests/Telemetry/{AutomodelApplicationModeExtractNegativeExamples => AutomodelApplicationModeExtraction}/AutomodelApplicationModeExtractNegativeExamples.qlref (100%) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.expected rename java/ql/test/query-tests/Telemetry/{AutomodelApplicationModeExtractPositiveExamples => AutomodelApplicationModeExtraction}/AutomodelApplicationModeExtractPositiveExamples.qlref (100%) rename java/ql/test/query-tests/Telemetry/{AutomodelApplicationModeExtractCandidates => AutomodelApplicationModeExtraction}/Test.java (74%) diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected deleted file mode 100644 index 9e04180fe0e4..000000000000 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.expected +++ /dev/null @@ -1,2 +0,0 @@ -| Test.java:8:15:8:18 | size | known non-sink\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:7:10:8:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | -| Test.java:8:15:8:18 | size | known sanitizer\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:7:10:8:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/Test.java deleted file mode 100644 index ac83546fabfc..000000000000 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/Test.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.codeql.test; - -import java.nio.ByteBuffer; - -class AutomodelApplicationModeExtractNegativeExamples { - public static ByteBuffer getBuffer(int size) { - return ByteBuffer // negative example, modeled as a neutral model - .allocate(size); // negative example, modeled as a neutral model - } -} diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.expected deleted file mode 100644 index 9c6775df3bee..000000000000 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.expected +++ /dev/null @@ -1,2 +0,0 @@ -| Test.java:17:4:17:9 | source | path-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:16:3:20:3 | copy(...) | CallContext | 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 | -| Test.java:18:4:18:9 | target | path-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:16:3:20:3 | copy(...) | CallContext | 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 | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/Test.java deleted file mode 100644 index 5e6943fd7787..000000000000 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/Test.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.github.codeql.test; - -import java.nio.file.CopyOption; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; - -class AutomodelApplicationModeExtractPositiveExamples { - public static void callSupplier(Supplier supplier) { - supplier.get(); // not an example - } - - public static void copyFiles(Path source, Path target, CopyOption option) throws Exception { - Files.copy( - source, // positive example - target, // positive example - option // no example - ); - } -} diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.expected similarity index 75% rename from java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.expected rename to java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.expected index 07e9896dafb8..8b6f95795b0e 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.expected +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.expected @@ -1,2 +1,2 @@ -| Test.java:14:3:14:11 | reference | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:14:3:14:24 | set(...) | CallContext | 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://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | -| Test.java:20:3:20:10 | supplier | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:20:3:20:16 | get(...) | CallContext | 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 | +| Test.java:16:3:16:11 | reference | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:16:3:16:24 | set(...) | CallContext | 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://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | +| Test.java:21:3:21:10 | supplier | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:21:3:21:16 | get(...) | CallContext | 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 | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.qlref b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.qlref similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/AutomodelApplicationModeExtractCandidates.qlref rename to java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.qlref diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected new file mode 100644 index 000000000000..f241157c6f1b --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected @@ -0,0 +1,3 @@ +| Test.java:40:14:40:21 | openPath | taint step\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:40:4:40:22 | get(...) | CallContext | 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://Argument[0]:1:1:1:1 | Argument[0] | input | +| Test.java:46:15:46:18 | size | known non-sink\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:45:10:46:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | +| Test.java:46:15:46:18 | size | known sanitizer\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:45:10:46:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.qlref b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.qlref similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractNegativeExamples/AutomodelApplicationModeExtractNegativeExamples.qlref rename to java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.qlref diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.expected new file mode 100644 index 000000000000..841599ce0217 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.expected @@ -0,0 +1,3 @@ +| Test.java:26:4:26:9 | source | path-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:25:3:29:3 | copy(...) | CallContext | 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 | +| Test.java:27:4:27:9 | target | path-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:25:3:29:3 | copy(...) | CallContext | 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 | +| Test.java:34:4:34:11 | openPath | path-injection\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:33:10:35:3 | newInputStream(...) | CallContext | 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 | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.qlref b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.qlref similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractPositiveExamples/AutomodelApplicationModeExtractPositiveExamples.qlref rename to java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.qlref diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/Test.java similarity index 74% rename from java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java rename to java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/Test.java index 252c40ff6172..a141a21bb36c 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtractCandidates/Test.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/Test.java @@ -7,8 +7,10 @@ import java.nio.file.Paths; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import java.nio.ByteBuffer; -class AutomodelApplicationModeExtractCandidates { + +class Test { public static void main(String[] args) throws Exception { AtomicReference reference = new AtomicReference<>(); // uninteresting (parameterless constructor) reference.set(args[0]); // arg[0] is not a candidate (modeled as value flow step) @@ -21,21 +23,27 @@ public static void callSupplier(Supplier supplier) { public static void copyFiles(Path source, Path target, CopyOption option) throws Exception { Files.copy( - source, // no candidate (modeled) - target, // no candidate (modeled) + source, // positive example (known sink) + target, // positive example (known sink) option // no candidate (not modeled, but source and target are modeled) ); } public static InputStream getInputStream(Path openPath) throws Exception { return Files.newInputStream( - openPath // no candidate (known sink) + openPath // positive example (known sink) ); } public static InputStream getInputStream(String openPath) throws Exception { - return AutomodelApplicationModeExtractCandidates.getInputStream( + return Test.getInputStream( Paths.get(openPath) // no candidate (argument to local call) ); } + + public static ByteBuffer getBuffer(int size) { + return ByteBuffer // negative example, modeled as a neutral model + .allocate(size); // negative example, modeled as a neutral model + } } + From 44b8ec642ecfd1050f2fb3bcb90af4458a680bd7 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Tue, 25 Jul 2023 12:57:23 +0200 Subject: [PATCH 10/17] Java: merge framework mode tests into one --- .../java/nio/file/Files.java | 15 --------------- ...lFrameworkModeExtractPositiveExamples.expected | 1 - .../java/nio/file/Files.java | 12 ------------ ...tomodelFrameworkModeExtractCandidates.expected | 2 +- .../AutomodelFrameworkModeExtractCandidates.qlref | 0 ...lFrameworkModeExtractNegativeExamples.expected | 0 ...odelFrameworkModeExtractNegativeExamples.qlref | 0 ...lFrameworkModeExtractPositiveExamples.expected | 1 + ...odelFrameworkModeExtractPositiveExamples.qlref | 0 .../com/github/codeql/test/NonPublicClass.java | 0 .../com/github/codeql/test/PublicClass.java | 0 .../java/io/File.java | 2 +- .../java/nio/file/Files.java | 14 ++++++++++++++ 13 files changed, 17 insertions(+), 30 deletions(-) delete mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/java/nio/file/Files.java delete mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.expected delete mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/java/nio/file/Files.java rename java/ql/test/query-tests/Telemetry/{AutomodelFrameworkModeExtractCandidates => AutomodelFrameworkModeExtraction}/AutomodelFrameworkModeExtractCandidates.expected (68%) rename java/ql/test/query-tests/Telemetry/{AutomodelFrameworkModeExtractCandidates => AutomodelFrameworkModeExtraction}/AutomodelFrameworkModeExtractCandidates.qlref (100%) rename java/ql/test/query-tests/Telemetry/{AutomodelFrameworkModeExtractNegativeExamples => AutomodelFrameworkModeExtraction}/AutomodelFrameworkModeExtractNegativeExamples.expected (100%) rename java/ql/test/query-tests/Telemetry/{AutomodelFrameworkModeExtractNegativeExamples => AutomodelFrameworkModeExtraction}/AutomodelFrameworkModeExtractNegativeExamples.qlref (100%) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractPositiveExamples.expected rename java/ql/test/query-tests/Telemetry/{AutomodelFrameworkModeExtractPositiveExamples => AutomodelFrameworkModeExtraction}/AutomodelFrameworkModeExtractPositiveExamples.qlref (100%) rename java/ql/test/query-tests/Telemetry/{AutomodelFrameworkModeExtractCandidates => AutomodelFrameworkModeExtraction}/com/github/codeql/test/NonPublicClass.java (100%) rename java/ql/test/query-tests/Telemetry/{AutomodelFrameworkModeExtractCandidates => AutomodelFrameworkModeExtraction}/com/github/codeql/test/PublicClass.java (100%) rename java/ql/test/query-tests/Telemetry/{AutomodelFrameworkModeExtractNegativeExamples => AutomodelFrameworkModeExtraction}/java/io/File.java (93%) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/nio/file/Files.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/java/nio/file/Files.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/java/nio/file/Files.java deleted file mode 100644 index 663dc945a152..000000000000 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/java/nio/file/Files.java +++ /dev/null @@ -1,15 +0,0 @@ -package java.nio.file; - -import java.nio.file.Path; -import java.io.IOException; -import java.io.OutputStream; - -public class Files { - // - source is not a candidate because a manual model exists: - // ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "path-injection", "manual"] - // - out is a candidate. NB: may be worthwile to implement the same behaviour as in application mode where out - // would not be a candidate because another param is already modeled. - public static void copy(Path source, OutputStream out) throws IOException { - // ... - } -} diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.expected deleted file mode 100644 index dc07c210155e..000000000000 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.expected +++ /dev/null @@ -1 +0,0 @@ -| java/nio/file/Files.java:9:29:9:39 | source | path-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/nio/file/Files.java:9:29:9:39 | source | MethodDoc | java/nio/file/Files.java:9:29:9:39 | 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,OutputStream):1:1:1:1 | (Path,OutputStream) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://source:1:1:1:1 | source | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/java/nio/file/Files.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/java/nio/file/Files.java deleted file mode 100644 index 896a454395b5..000000000000 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/java/nio/file/Files.java +++ /dev/null @@ -1,12 +0,0 @@ -package java.nio.file; - -import java.nio.file.Path; -import java.io.IOException; -import java.io.OutputStream; - -public class Files { - // source is a positive example because there's a model for it - public static void copy(Path source, OutputStream out) throws IOException { - // ... - } -} diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected similarity index 68% rename from java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.expected rename to java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected index c09142a5ee7e..214eb1029a3f 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.expected +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected @@ -1,3 +1,3 @@ | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://false:1:1:1:1 | false | subtypes | file://staticStuff:1:1:1:1 | staticStuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | -| java/nio/file/Files.java:12:42:12:57 | out | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/nio/file/Files.java:12:42:12:57 | out | MethodDoc | java/nio/file/Files.java:12:42:12:57 | out | 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,OutputStream):1:1:1:1 | (Path,OutputStream) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://out:1:1:1:1 | out | parameterName | +| java/nio/file/Files.java:10:9:10:24 | out | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/nio/file/Files.java:10:9:10:24 | out | MethodDoc | java/nio/file/Files.java:10:9:10:24 | out | 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,OutputStream):1:1:1:1 | (Path,OutputStream) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://out:1:1:1:1 | out | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.qlref b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.qlref similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/AutomodelFrameworkModeExtractCandidates.qlref rename to java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.qlref diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractNegativeExamples.expected similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.expected rename to java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractNegativeExamples.expected diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.qlref b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractNegativeExamples.qlref similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/AutomodelFrameworkModeExtractNegativeExamples.qlref rename to java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractNegativeExamples.qlref diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractPositiveExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractPositiveExamples.expected new file mode 100644 index 000000000000..b3326654de1b --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractPositiveExamples.expected @@ -0,0 +1 @@ +| java/nio/file/Files.java:9:9:9:19 | source | path-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/nio/file/Files.java:9:9:9:19 | source | MethodDoc | java/nio/file/Files.java:9:9:9:19 | 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,OutputStream):1:1:1:1 | (Path,OutputStream) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://source:1:1:1:1 | source | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.qlref b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractPositiveExamples.qlref similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractPositiveExamples/AutomodelFrameworkModeExtractPositiveExamples.qlref rename to java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractPositiveExamples.qlref diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/NonPublicClass.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/NonPublicClass.java similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/NonPublicClass.java rename to java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/NonPublicClass.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/PublicClass.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java similarity index 100% rename from java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractCandidates/com/github/codeql/test/PublicClass.java rename to java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/java/io/File.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/io/File.java similarity index 93% rename from java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/java/io/File.java rename to java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/io/File.java index c84da33bdf23..0ad819ae3636 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtractNegativeExamples/java/io/File.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/io/File.java @@ -3,7 +3,7 @@ public class File { int compareTo( File pathname // negative example - this is modeled as a neutral model - ) { + ) { return 0; } } diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/nio/file/Files.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/nio/file/Files.java new file mode 100644 index 000000000000..a5562902522e --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/nio/file/Files.java @@ -0,0 +1,14 @@ +package java.nio.file; + +import java.nio.file.Path; +import java.io.IOException; +import java.io.OutputStream; + +public class Files { + public static void copy( + Path source, // a positive example because a manual model exists + OutputStream out // a candidate. NB: may be worthwhile to implement the same behavior as in application mode where out + ) throws IOException { + // ... + } +} From f5c4155d63a23fb54fe93bf04ee5f7f2e4ca7bfe Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Wed, 26 Jul 2023 13:40:15 +0200 Subject: [PATCH 11/17] Java: Automodel tests: update after merging #13818 --- ...omodelApplicationModeExtractNegativeExamples.expected | 3 +-- .../AutomodelApplicationModeExtraction/Test.java | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected index f241157c6f1b..0c626ca2d0b2 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected @@ -1,3 +1,2 @@ | Test.java:40:14:40:21 | openPath | taint step\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:40:4:40:22 | get(...) | CallContext | 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://Argument[0]:1:1:1:1 | Argument[0] | input | -| Test.java:46:15:46:18 | size | known non-sink\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:45:10:46:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | -| Test.java:46:15:46:18 | size | known sanitizer\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:45:10:46:19 | allocate(...) | CallContext | file://java.nio:1:1:1:1 | java.nio | package | file://ByteBuffer:1:1:1:1 | ByteBuffer | type | file://false:1:1:1:1 | false | subtypes | file://allocate:1:1:1:1 | allocate | name | file://(int):1:1:1:1 | (int) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | +| Test.java:46:4:46:5 | f2 | known non-sink\nrelated locations: $@.\nmetadata: $@, $@, $@, $@, $@, $@. | Test.java:45:10:47:3 | compareTo(...) | CallContext | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/Test.java b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/Test.java index a141a21bb36c..67423855a8bb 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/Test.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelApplicationModeExtraction/Test.java @@ -7,7 +7,7 @@ import java.nio.file.Paths; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; -import java.nio.ByteBuffer; +import java.io.File; class Test { @@ -41,9 +41,10 @@ public static InputStream getInputStream(String openPath) throws Exception { ); } - public static ByteBuffer getBuffer(int size) { - return ByteBuffer // negative example, modeled as a neutral model - .allocate(size); // negative example, modeled as a neutral model + public static int compareFiles(File f1, File f2) { + return f1.compareTo( + f2 // negative example (modeled as not a sink) + ); } } From be629b27ed074c685743080b11deb25a5f64ba49 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 28 Jul 2023 14:18:03 +0200 Subject: [PATCH 12/17] Java: Automodel package private test case --- .../com/github/codeql/test/PublicClass.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java index 0405c43a58bb..bfa76902184f 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java @@ -13,4 +13,9 @@ public static void staticStuff(String arg) { // arg is a candidate protected void nonPublicStuff(String arg) { System.out.println(arg); } + + // arg is not a candidate because the method is not public: + void packagePrivateStuff(String arg) { + System.out.println(arg); + } } From da87d82d08caebf1599878094afa0d6887892a54 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 28 Jul 2023 14:38:27 +0200 Subject: [PATCH 13/17] Java: fix a comment --- .../java/nio/file/Files.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/nio/file/Files.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/nio/file/Files.java index a5562902522e..76bfdfcf4185 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/nio/file/Files.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/nio/file/Files.java @@ -7,7 +7,12 @@ public class Files { public static void copy( Path source, // a positive example because a manual model exists - OutputStream out // a candidate. NB: may be worthwhile to implement the same behavior as in application mode where out + OutputStream out /* a candidate. NB: may be worthwhile to implement the + same behavior as in application mode where out would not be a + candidate because there already is a model for another parameter of + the same method and we assume that methods are always modeled + completely. + */ ) throws IOException { // ... } From 5ad984f22f611b7156a9f9786ac6097abfac0c40 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 28 Jul 2023 18:10:50 +0200 Subject: [PATCH 14/17] Java: update text expectations after merging #13823 --- .../AutomodelFrameworkModeExtractCandidates.expected | 1 + ...AutomodelFrameworkModeExtractNegativeExamples.expected | 1 + .../com/github/codeql/test/PublicClass.java | 8 ++++---- .../AutomodelFrameworkModeExtraction/java/io/File.java | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected index 214eb1029a3f..b1421cad9ec9 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected @@ -1,3 +1,4 @@ +| com/github/codeql/test/PublicClass.java:4:15:4:19 | stuff | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:4:15:4:19 | stuff | MethodDoc | com/github/codeql/test/PublicClass.java:4:15:4:19 | stuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://this:1:1:1:1 | this | parameterName | | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://false:1:1:1:1 | false | subtypes | file://staticStuff:1:1:1:1 | staticStuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | | java/nio/file/Files.java:10:9:10:24 | out | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/nio/file/Files.java:10:9:10:24 | out | MethodDoc | java/nio/file/Files.java:10:9:10:24 | out | 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,OutputStream):1:1:1:1 | (Path,OutputStream) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://out:1:1:1:1 | out | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractNegativeExamples.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractNegativeExamples.expected index 44e3026415b5..6547f2544013 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractNegativeExamples.expected +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractNegativeExamples.expected @@ -1 +1,2 @@ +| java/io/File.java:4:9:4:17 | compareTo | known non-sink\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/io/File.java:4:9:4:17 | compareTo | MethodDoc | java/io/File.java:4:9:4:17 | compareTo | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://this:1:1:1:1 | this | parameterName | | java/io/File.java:5:9:5:21 | pathname | known non-sink\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/io/File.java:5:9:5:21 | pathname | MethodDoc | java/io/File.java:5:9:5:21 | pathname | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://pathname:1:1:1:1 | pathname | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java index bfa76902184f..bf858b49163f 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java @@ -1,20 +1,20 @@ package com.github.codeql.test; public class PublicClass { - public void stuff(String arg) { // arg is a candidate + public void stuff(String arg) { // `arg` is a candidate, `this` is a candidate System.out.println(arg); } - public static void staticStuff(String arg) { // arg is a candidate + public static void staticStuff(String arg) { // `arg` is a candidate, `this` is not a candidate (static method) System.out.println(arg); } - // arg is not a candidate because the method is not public: + // `arg` and `this` are not a candidate because the method is not public: protected void nonPublicStuff(String arg) { System.out.println(arg); } - // arg is not a candidate because the method is not public: + // `arg` and `this are not candidates because the method is not public: void packagePrivateStuff(String arg) { System.out.println(arg); } diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/io/File.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/io/File.java index 0ad819ae3636..fa812d47efd0 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/io/File.java +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/java/io/File.java @@ -1,7 +1,7 @@ package java.io; public class File { - int compareTo( + int compareTo( // `this` is a negative example - this is modeled as a neutral model File pathname // negative example - this is modeled as a neutral model ) { return 0; From 058236877e8359da66300e9522fff833464c7109 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 28 Jul 2023 18:11:09 +0200 Subject: [PATCH 15/17] Java: Drive-by: fix oversight in #13823 In PR #13823, we had rewritten the endpoints that are being considered for framework mode. We used to use `DataFlow::ParameterNode` as endpoints. However, `ParameterNode`s do not exist for the implicit `this` parameter; they also do not exist for bodiless interface-methods. In PR #13823, we forgot to model that `this` only exists for non-static methods and to only consider parameters that we have source code for. --- .../src/Telemetry/AutomodelFrameworkModeCharacteristics.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index 1275f3e71a77..b8d3d307edaa 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -56,7 +56,7 @@ abstract class FrameworkModeEndpoint extends TFrameworkModeEndpoint { class ExplicitParameterEndpoint extends FrameworkModeEndpoint, TExplicitParameter { Parameter param; - ExplicitParameterEndpoint() { this = TExplicitParameter(param) } + ExplicitParameterEndpoint() { this = TExplicitParameter(param) and param.fromSource() } override int getIndex() { result = param.getPosition() } @@ -70,7 +70,7 @@ class ExplicitParameterEndpoint extends FrameworkModeEndpoint, TExplicitParamete class QualifierEndpoint extends FrameworkModeEndpoint, TQualifier { Callable callable; - QualifierEndpoint() { this = TQualifier(callable) } + QualifierEndpoint() { this = TQualifier(callable) and not callable.isStatic() and callable.fromSource() } override int getIndex() { result = -1 } From bc3e78f034189f2a4733d39ecf0a9c4a4ef38e2c Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 28 Jul 2023 18:27:08 +0200 Subject: [PATCH 16/17] Java: add automodel framework mode test case for newly supported interface-method parameter extraction --- .../AutomodelFrameworkModeExtractCandidates.expected | 3 +++ .../com/github/codeql/test/PublicInterface.java | 9 +++++++++ 2 files changed, 12 insertions(+) create mode 100644 java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicInterface.java diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected index b1421cad9ec9..6fc824618692 100644 --- a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected @@ -1,4 +1,7 @@ | com/github/codeql/test/PublicClass.java:4:15:4:19 | stuff | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:4:15:4:19 | stuff | MethodDoc | com/github/codeql/test/PublicClass.java:4:15:4:19 | stuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://this:1:1:1:1 | this | parameterName | | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:4:21:4:30 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:8:34:8:43 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://false:1:1:1:1 | false | subtypes | file://staticStuff:1:1:1:1 | staticStuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | +| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | MethodDoc | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicInterface:1:1:1:1 | PublicInterface | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://this:1:1:1:1 | this | parameterName | +| com/github/codeql/test/PublicInterface.java:4:23:4:32 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicInterface.java:4:23:4:32 | arg | MethodDoc | com/github/codeql/test/PublicInterface.java:4:23:4:32 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicInterface:1:1:1:1 | PublicInterface | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | +| com/github/codeql/test/PublicInterface.java:6:36:6:45 | arg | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicInterface.java:6:36:6:45 | arg | MethodDoc | com/github/codeql/test/PublicInterface.java:6:36:6:45 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicInterface:1:1:1:1 | PublicInterface | type | file://false:1:1:1:1 | false | subtypes | file://staticStuff:1:1:1:1 | staticStuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://arg:1:1:1:1 | arg | parameterName | | java/nio/file/Files.java:10:9:10:24 | out | command-injection, path-injection, request-forgery, sql-injection\nrelated locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@. | java/nio/file/Files.java:10:9:10:24 | out | MethodDoc | java/nio/file/Files.java:10:9:10:24 | out | 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,OutputStream):1:1:1:1 | (Path,OutputStream) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://out:1:1:1:1 | out | parameterName | diff --git a/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicInterface.java b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicInterface.java new file mode 100644 index 000000000000..e28e0559e0c7 --- /dev/null +++ b/java/ql/test/query-tests/Telemetry/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicInterface.java @@ -0,0 +1,9 @@ +package com.github.codeql.test; + +public interface PublicInterface { + public void stuff(String arg); // `arg` is a candidate, `this` is a candidate + + public static void staticStuff(String arg) { // `arg` is a candidate, `this` is not a candidate (static method) + System.out.println(arg); + } +} From 621c05dc4b366cd7d527f3c6e7e1698cd2d9c25c Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Fri, 28 Jul 2023 18:54:07 +0200 Subject: [PATCH 17/17] Java: format --- .../src/Telemetry/AutomodelFrameworkModeCharacteristics.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll index b8d3d307edaa..02d945437e3f 100644 --- a/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll +++ b/java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll @@ -70,7 +70,9 @@ class ExplicitParameterEndpoint extends FrameworkModeEndpoint, TExplicitParamete class QualifierEndpoint extends FrameworkModeEndpoint, TQualifier { Callable callable; - QualifierEndpoint() { this = TQualifier(callable) and not callable.isStatic() and callable.fromSource() } + QualifierEndpoint() { + this = TQualifier(callable) and not callable.isStatic() and callable.fromSource() + } override int getIndex() { result = -1 }