From 7db082f3fd8a9362a6ec76393a2563daf879707c Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 13 Sep 2023 13:04:26 +0200 Subject: [PATCH 01/15] Java: Add VS Code model editor queries --- .../dataflow/internal/ModelExclusions.qll | 2 +- .../src/utils/modeleditor/AutomodelVsCode.qll | 139 ++++++++++++++++++ .../FetchApplicationModeMethods.ql | 29 ++++ .../modeleditor/FetchFrameworkModeMethods.ql | 23 +++ .../FetchApplicationModeMethods.expected | 8 + .../FetchApplicationModeMethods.qlref | 1 + .../FetchFrameworkModeMethods.expected | 5 + .../FetchFrameworkModeMethods.qlref | 1 + .../github/codeql/test/NonPublicClass.java | 7 + .../com/github/codeql/test/PublicClass.java | 21 +++ .../github/codeql/test/PublicInterface.java | 9 ++ .../suite-helpers/code-scanning-selectors.yml | 1 + .../security-and-quality-selectors.yml | 1 + .../security-experimental-selectors.yml | 1 + .../security-extended-selectors.yml | 1 + 15 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 java/ql/src/utils/modeleditor/AutomodelVsCode.qll create mode 100644 java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql create mode 100644 java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql create mode 100644 java/ql/test/utils/modeleditor/FetchApplicationModeMethods.expected create mode 100644 java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref create mode 100644 java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.expected create mode 100644 java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref create mode 100644 java/ql/test/utils/modeleditor/com/github/codeql/test/NonPublicClass.java create mode 100644 java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java create mode 100644 java/ql/test/utils/modeleditor/com/github/codeql/test/PublicInterface.java diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll index 5f1996989ade..b797cf5d9391 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll @@ -25,7 +25,7 @@ class TestLibrary extends RefType { } /** Holds if the given file is a test file. */ -private predicate isInTestFile(File file) { +predicate isInTestFile(File file) { file.getAbsolutePath().matches(["%/test/%", "%/guava-tests/%", "%/guava-testlib/%"]) and not file.getAbsolutePath().matches(["%/ql/test/%", "%/ql/automodel/test/%"]) // allows our test cases to work } diff --git a/java/ql/src/utils/modeleditor/AutomodelVsCode.qll b/java/ql/src/utils/modeleditor/AutomodelVsCode.qll new file mode 100644 index 000000000000..2e8fe70c29ee --- /dev/null +++ b/java/ql/src/utils/modeleditor/AutomodelVsCode.qll @@ -0,0 +1,139 @@ +/** Provides classes and predicates related to handling APIs for the VS Code extension. */ + +private import java +private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.FlowSummary +private import semmle.code.java.dataflow.internal.DataFlowPrivate +private import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl +private import semmle.code.java.dataflow.TaintTracking +private import semmle.code.java.dataflow.internal.ModelExclusions + +/** Holds if the given callable/method is not worth supporting. */ +private predicate isUninteresting(Callable c) { + c.getDeclaringType() instanceof TestLibrary or + c.(Constructor).isParameterless() or + c.getDeclaringType() instanceof AnonymousClass +} + +/** + * A callable method from either the Standard Library, a 3rd party library or from the source. + */ +class CallableMethod extends Callable { + CallableMethod() { not isUninteresting(this) } + + /** + * Gets information about the external API in the form expected by the MaD modeling framework. + */ + string getApiName() { + result = + this.getDeclaringType().getPackage() + "." + this.getDeclaringType().nestedName() + "#" + + this.getName() + paramsString(this) + } + + private string getJarName() { + result = this.getCompilationUnit().getParentContainer*().(JarFile).getBaseName() + } + + private string getJarVersion() { + result = this.getCompilationUnit().getParentContainer*().(JarFile).getSpecificationVersion() + } + + /** + * Gets the jar file containing this API. Normalizes the Java Runtime to "rt.jar" despite the presence of modules. + */ + string jarContainer() { + result = this.getJarName() + or + not exists(this.getJarName()) and result = "rt.jar" + } + + /** + * Gets the version of the JAR file containing this API. Empty if no version is found in the JAR. + */ + string jarVersion() { + result = this.getJarVersion() + or + not exists(this.getJarVersion()) and result = "" + } + + /** Gets a node that is an input to a call to this API. */ + private DataFlow::Node getAnInput() { + exists(Call call | call.getCallee().getSourceDeclaration() = this | + result.asExpr().(Argument).getCall() = call or + result.(ArgumentNode).getCall().asCall() = call + ) + } + + /** Gets a node that is an output from a call to this API. */ + private DataFlow::Node getAnOutput() { + exists(Call call | call.getCallee().getSourceDeclaration() = this | + result.asExpr() = call or + result.(DataFlow::PostUpdateNode).getPreUpdateNode().(ArgumentNode).getCall().asCall() = call + ) + } + + /** Holds if this API has a supported summary. */ + pragma[nomagic] + predicate hasSummary() { + this = any(SummarizedCallable sc).asCallable() or + TaintTracking::localAdditionalTaintStep(this.getAnInput(), _) + } + + pragma[nomagic] + predicate isSource() { + this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _) + } + + /** Holds if this API is a known sink. */ + pragma[nomagic] + predicate isSink() { sinkNode(this.getAnInput(), _) } + + /** Holds if this API is a known neutral. */ + pragma[nomagic] + predicate isNeutral() { + exists( + string namespace, string type, string name, string signature, string kind, string provenance + | + neutralModel(namespace, type, name, signature, kind, provenance) and + this = interpretElement(namespace, type, false, name, signature, "") + ) + } + + /** + * Holds if this API is supported by existing CodeQL libraries, that is, it is either a + * recognized source, sink or neutral or it has a flow summary. + */ + predicate isSupported() { + this.hasSummary() or this.isSource() or this.isSink() or this.isNeutral() + } +} + +boolean isSupported(CallableMethod method) { + method.isSupported() and result = true + or + not method.isSupported() and result = false +} + +string supportedType(CallableMethod method) { + method.isSink() and result = "sink" + or + method.isSource() and result = "source" + or + method.hasSummary() and result = "summary" + or + method.isNeutral() and result = "neutral" + or + not method.isSupported() and result = "" +} + +string methodClassification(Call method) { + isInTestFile(method.getLocation().getFile()) and result = "test" + or + method.getFile() instanceof GeneratedFile and result = "generated" + or + not isInTestFile(method.getLocation().getFile()) and + not method.getFile() instanceof GeneratedFile and + result = "source" +} diff --git a/java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql b/java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql new file mode 100644 index 000000000000..c49770e94afc --- /dev/null +++ b/java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql @@ -0,0 +1,29 @@ +/** + * @name Fetch model editor methods (application mode) + * @description A list of 3rd party APIs used in the codebase. Excludes test and generated code. + * @kind problem + * @problem.severity recommendation + * @id java/utils/modeleditor/fetch-application-mode-methods + * @tags modeleditor fetch methods application-mode + */ + +private import java +private import AutomodelVsCode + +class ExternalApi extends CallableMethod { + ExternalApi() { not this.fromSource() } +} + +private Call aUsage(ExternalApi api) { result.getCallee().getSourceDeclaration() = api } + +from + ExternalApi externalApi, string apiName, boolean supported, Call usage, string type, + string classification +where + apiName = externalApi.getApiName() and + supported = isSupported(externalApi) and + usage = aUsage(externalApi) and + type = supportedType(externalApi) and + classification = methodClassification(usage) +select usage, apiName, supported.toString(), "supported", externalApi.jarContainer(), + externalApi.jarVersion(), type, "type", classification, "classification" diff --git a/java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql b/java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql new file mode 100644 index 000000000000..d115105d1907 --- /dev/null +++ b/java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql @@ -0,0 +1,23 @@ +/** + * @name Fetch model editor methods (framework mode) + * @description A list of APIs callable by consumers. Excludes test and generated code. + * @kind problem + * @problem.severity recommendation + * @id java/utils/modeleditor/fetch-framework-mode-methods + * @tags modeleditor fetch methods framework-mode + */ + +private import java +private import semmle.code.java.dataflow.internal.ModelExclusions +private import AutomodelVsCode + +class PublicMethodFromSource extends CallableMethod, ModelApi { } + +from PublicMethodFromSource publicMethod, string apiName, boolean supported, string type +where + apiName = publicMethod.getApiName() and + supported = isSupported(publicMethod) and + type = supportedType(publicMethod) +select publicMethod, apiName, supported.toString(), "supported", + publicMethod.getCompilationUnit().getParentContainer().getBaseName(), "library", type, "type", + "unknown", "classification" diff --git a/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.expected b/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.expected new file mode 100644 index 000000000000..22273baa31e0 --- /dev/null +++ b/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.expected @@ -0,0 +1,8 @@ +| com/github/codeql/test/NonPublicClass.java:5:5:5:28 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:7:5:7:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:11:5:11:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:15:5:15:45 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:15:24:15:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:15:24:15:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | summary | type | source | classification | +| com/github/codeql/test/PublicClass.java:19:5:19:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicInterface.java:7:7:7:29 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | diff --git a/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref b/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref new file mode 100644 index 000000000000..9d2454657314 --- /dev/null +++ b/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref @@ -0,0 +1 @@ +utils/modeleditor/FetchApplicationModeMethods.ql \ No newline at end of file diff --git a/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.expected b/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.expected new file mode 100644 index 000000000000..9586e695a162 --- /dev/null +++ b/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.expected @@ -0,0 +1,5 @@ +| com/github/codeql/test/PublicClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicClass#stuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:10:22:10:32 | staticStuff | com.github.codeql.test.PublicClass#staticStuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:14:18:14:31 | nonPublicStuff | com.github.codeql.test.PublicClass#nonPublicStuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicInterface#stuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicInterface.java:6:24:6:34 | staticStuff | com.github.codeql.test.PublicInterface#staticStuff(String) | false | supported | test | library | | type | unknown | classification | diff --git a/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref b/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref new file mode 100644 index 000000000000..39bdee5a08d5 --- /dev/null +++ b/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref @@ -0,0 +1 @@ +utils/modeleditor/FetchFrameworkModeMethods.ql \ No newline at end of file diff --git a/java/ql/test/utils/modeleditor/com/github/codeql/test/NonPublicClass.java b/java/ql/test/utils/modeleditor/com/github/codeql/test/NonPublicClass.java new file mode 100644 index 000000000000..5ad1f42123ac --- /dev/null +++ b/java/ql/test/utils/modeleditor/com/github/codeql/test/NonPublicClass.java @@ -0,0 +1,7 @@ +package com.github.codeql.test; + +class NonPublicClass { + public void noCandidates(String here) { + System.out.println(here); + } +} diff --git a/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java new file mode 100644 index 000000000000..4e9228c167a6 --- /dev/null +++ b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java @@ -0,0 +1,21 @@ +package com.github.codeql.test; + +import java.nio.file.Paths; + +public class PublicClass { + public void stuff(String arg) { + System.out.println(arg); + } + + public static void staticStuff(String arg) { + System.out.println(arg); + } + + protected void nonPublicStuff(String arg) { + System.out.println(Paths.get("foo", arg)); + } + + void packagePrivateStuff(String arg) { + System.out.println(arg); + } +} diff --git a/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicInterface.java b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicInterface.java new file mode 100644 index 000000000000..cde005d4c4a4 --- /dev/null +++ b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicInterface.java @@ -0,0 +1,9 @@ +package com.github.codeql.test; + +public interface PublicInterface { + public void stuff(String arg); + + public static void staticStuff(String arg) { + System.out.println(arg); + } +} diff --git a/misc/suite-helpers/code-scanning-selectors.yml b/misc/suite-helpers/code-scanning-selectors.yml index a237728316b9..37f4243fc6ac 100644 --- a/misc/suite-helpers/code-scanning-selectors.yml +++ b/misc/suite-helpers/code-scanning-selectors.yml @@ -30,4 +30,5 @@ - /Diagnostics/Internal/.*/ - exclude: tags contain: + - modeleditor - modelgenerator diff --git a/misc/suite-helpers/security-and-quality-selectors.yml b/misc/suite-helpers/security-and-quality-selectors.yml index 90a22352b80d..da45710e0b76 100644 --- a/misc/suite-helpers/security-and-quality-selectors.yml +++ b/misc/suite-helpers/security-and-quality-selectors.yml @@ -31,4 +31,5 @@ - /Diagnostics/Internal/.*/ - exclude: tags contain: + - modeleditor - modelgenerator diff --git a/misc/suite-helpers/security-experimental-selectors.yml b/misc/suite-helpers/security-experimental-selectors.yml index 1ea42707b751..cf881a864f95 100644 --- a/misc/suite-helpers/security-experimental-selectors.yml +++ b/misc/suite-helpers/security-experimental-selectors.yml @@ -42,4 +42,5 @@ - /Diagnostics/Internal/.*/ - exclude: tags contain: + - modeleditor - model-generator diff --git a/misc/suite-helpers/security-extended-selectors.yml b/misc/suite-helpers/security-extended-selectors.yml index aff154d0d306..8e5845b70e65 100644 --- a/misc/suite-helpers/security-extended-selectors.yml +++ b/misc/suite-helpers/security-extended-selectors.yml @@ -36,4 +36,5 @@ - /Diagnostics/Internal/.*/ - exclude: tags contain: + - modeleditor - modelgenerator From 95296f15182c1abc939ed29b2eea4b589a952441 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 13 Sep 2023 14:45:47 +0200 Subject: [PATCH 02/15] Java: Use don't care expression for kind and provenance --- java/ql/src/utils/modeleditor/AutomodelVsCode.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/utils/modeleditor/AutomodelVsCode.qll b/java/ql/src/utils/modeleditor/AutomodelVsCode.qll index 2e8fe70c29ee..d5a5b9a8111f 100644 --- a/java/ql/src/utils/modeleditor/AutomodelVsCode.qll +++ b/java/ql/src/utils/modeleditor/AutomodelVsCode.qll @@ -94,9 +94,9 @@ class CallableMethod extends Callable { pragma[nomagic] predicate isNeutral() { exists( - string namespace, string type, string name, string signature, string kind, string provenance + string namespace, string type, string name, string signature | - neutralModel(namespace, type, name, signature, kind, provenance) and + neutralModel(namespace, type, name, signature, _, _) and this = interpretElement(namespace, type, false, name, signature, "") ) } From 0434cce4c3f4af451b49923203f77451726f2737 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 13 Sep 2023 14:54:03 +0200 Subject: [PATCH 03/15] Java: Fix formatting of AutomodelVsCode.qll file --- java/ql/src/utils/modeleditor/AutomodelVsCode.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/ql/src/utils/modeleditor/AutomodelVsCode.qll b/java/ql/src/utils/modeleditor/AutomodelVsCode.qll index d5a5b9a8111f..ed67e2ace35c 100644 --- a/java/ql/src/utils/modeleditor/AutomodelVsCode.qll +++ b/java/ql/src/utils/modeleditor/AutomodelVsCode.qll @@ -93,9 +93,7 @@ class CallableMethod extends Callable { /** Holds if this API is a known neutral. */ pragma[nomagic] predicate isNeutral() { - exists( - string namespace, string type, string name, string signature - | + exists(string namespace, string type, string name, string signature | neutralModel(namespace, type, name, signature, _, _) and this = interpretElement(namespace, type, false, name, signature, "") ) From 082a45400de4da765da21d5c7b80fdb69057d7e6 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 13:51:05 +0200 Subject: [PATCH 04/15] Java: Rename AutomodelVsCode to ModelEditor --- java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql | 2 +- java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql | 2 +- .../utils/modeleditor/{AutomodelVsCode.qll => ModelEditor.qll} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename java/ql/src/utils/modeleditor/{AutomodelVsCode.qll => ModelEditor.qll} (100%) diff --git a/java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql b/java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql index c49770e94afc..6ae032033725 100644 --- a/java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql +++ b/java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql @@ -8,7 +8,7 @@ */ private import java -private import AutomodelVsCode +private import ModelEditor class ExternalApi extends CallableMethod { ExternalApi() { not this.fromSource() } diff --git a/java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql b/java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql index d115105d1907..3ebf2e50f395 100644 --- a/java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql +++ b/java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql @@ -9,7 +9,7 @@ private import java private import semmle.code.java.dataflow.internal.ModelExclusions -private import AutomodelVsCode +private import ModelEditor class PublicMethodFromSource extends CallableMethod, ModelApi { } diff --git a/java/ql/src/utils/modeleditor/AutomodelVsCode.qll b/java/ql/src/utils/modeleditor/ModelEditor.qll similarity index 100% rename from java/ql/src/utils/modeleditor/AutomodelVsCode.qll rename to java/ql/src/utils/modeleditor/ModelEditor.qll From fe7ce0ae0b959ccb0a7875a095c344dfb1be7da3 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 13:52:49 +0200 Subject: [PATCH 05/15] Java: Rename queries from fetch methods to endpoints --- ...etchApplicationModeMethods.ql => ApplicationModeEndpoints.ql} | 0 .../{FetchFrameworkModeMethods.ql => FrameworkModeEndpoints.ql} | 0 ...ionModeMethods.expected => ApplicationModeEndpoints.expected} | 0 java/ql/test/utils/modeleditor/ApplicationModeEndpoints.qlref | 1 + java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref | 1 - java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref | 1 - ...eworkModeMethods.expected => FrameworkModeEndpoints.expected} | 0 java/ql/test/utils/modeleditor/FrameworkModeEndpoints.qlref | 1 + 8 files changed, 2 insertions(+), 2 deletions(-) rename java/ql/src/utils/modeleditor/{FetchApplicationModeMethods.ql => ApplicationModeEndpoints.ql} (100%) rename java/ql/src/utils/modeleditor/{FetchFrameworkModeMethods.ql => FrameworkModeEndpoints.ql} (100%) rename java/ql/test/utils/modeleditor/{FetchApplicationModeMethods.expected => ApplicationModeEndpoints.expected} (100%) create mode 100644 java/ql/test/utils/modeleditor/ApplicationModeEndpoints.qlref delete mode 100644 java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref delete mode 100644 java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref rename java/ql/test/utils/modeleditor/{FetchFrameworkModeMethods.expected => FrameworkModeEndpoints.expected} (100%) create mode 100644 java/ql/test/utils/modeleditor/FrameworkModeEndpoints.qlref diff --git a/java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql similarity index 100% rename from java/ql/src/utils/modeleditor/FetchApplicationModeMethods.ql rename to java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql diff --git a/java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql similarity index 100% rename from java/ql/src/utils/modeleditor/FetchFrameworkModeMethods.ql rename to java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql diff --git a/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.expected b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected similarity index 100% rename from java/ql/test/utils/modeleditor/FetchApplicationModeMethods.expected rename to java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected diff --git a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.qlref b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.qlref new file mode 100644 index 000000000000..4787fa5d4b2e --- /dev/null +++ b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.qlref @@ -0,0 +1 @@ +utils/modeleditor/ApplicationModeEndpoints.ql \ No newline at end of file diff --git a/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref b/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref deleted file mode 100644 index 9d2454657314..000000000000 --- a/java/ql/test/utils/modeleditor/FetchApplicationModeMethods.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modeleditor/FetchApplicationModeMethods.ql \ No newline at end of file diff --git a/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref b/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref deleted file mode 100644 index 39bdee5a08d5..000000000000 --- a/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.qlref +++ /dev/null @@ -1 +0,0 @@ -utils/modeleditor/FetchFrameworkModeMethods.ql \ No newline at end of file diff --git a/java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.expected b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected similarity index 100% rename from java/ql/test/utils/modeleditor/FetchFrameworkModeMethods.expected rename to java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected diff --git a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.qlref b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.qlref new file mode 100644 index 000000000000..5ae87455edd6 --- /dev/null +++ b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.qlref @@ -0,0 +1 @@ +utils/modeleditor/FrameworkModeEndpoints.ql \ No newline at end of file From fee964007771d182413b0503d8af397337832281 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 13:54:35 +0200 Subject: [PATCH 06/15] Java: Update query id/tags and documentation --- java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql | 8 ++++---- java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql index 6ae032033725..20e989ffeba7 100644 --- a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql @@ -1,10 +1,10 @@ /** - * @name Fetch model editor methods (application mode) - * @description A list of 3rd party APIs used in the codebase. Excludes test and generated code. + * @name Fetch endpoints for use in the model editor (application mode) + * @description A list of 3rd party endpoints (methods) used in the codebase. Excludes test and generated code. * @kind problem * @problem.severity recommendation - * @id java/utils/modeleditor/fetch-application-mode-methods - * @tags modeleditor fetch methods application-mode + * @id java/utils/modeleditor/application-mode-endpoints + * @tags modeleditor endpoints application-mode */ private import java diff --git a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql index 3ebf2e50f395..102015a08af5 100644 --- a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql @@ -1,10 +1,10 @@ /** - * @name Fetch model editor methods (framework mode) - * @description A list of APIs callable by consumers. Excludes test and generated code. + * @name Fetch endpoints for use in the model editor (framework mode) + * @description A list of endpoints accessible (methods) for consumers of the library. Excludes test and generated code. * @kind problem * @problem.severity recommendation - * @id java/utils/modeleditor/fetch-framework-mode-methods - * @tags modeleditor fetch methods framework-mode + * @id java/utils/modeleditor/framework-mode-endpoints + * @tags modeleditor endpoints framework-mode */ private import java From 6e78aac6cc61f637da21a6f7dc94abd8a46213f5 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 13:57:27 +0200 Subject: [PATCH 07/15] Java: Rename CallableMethod to Endpoint --- .../modeleditor/ApplicationModeEndpoints.ql | 24 +++++++------- .../modeleditor/FrameworkModeEndpoints.ql | 14 ++++---- java/ql/src/utils/modeleditor/ModelEditor.qll | 32 +++++++++---------- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql index 20e989ffeba7..f8216ea6bcb5 100644 --- a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql @@ -10,20 +10,22 @@ private import java private import ModelEditor -class ExternalApi extends CallableMethod { - ExternalApi() { not this.fromSource() } +class ExternalEndpoint extends Endpoint { + ExternalEndpoint() { not this.fromSource() } } -private Call aUsage(ExternalApi api) { result.getCallee().getSourceDeclaration() = api } +private Call aUsage(ExternalEndpoint endpoint) { + result.getCallee().getSourceDeclaration() = endpoint +} from - ExternalApi externalApi, string apiName, boolean supported, Call usage, string type, + ExternalEndpoint endpoint, string apiName, boolean supported, Call usage, string type, string classification where - apiName = externalApi.getApiName() and - supported = isSupported(externalApi) and - usage = aUsage(externalApi) and - type = supportedType(externalApi) and - classification = methodClassification(usage) -select usage, apiName, supported.toString(), "supported", externalApi.jarContainer(), - externalApi.jarVersion(), type, "type", classification, "classification" + apiName = endpoint.getApiName() and + supported = isSupported(endpoint) and + usage = aUsage(endpoint) and + type = supportedType(endpoint) and + classification = usageClassification(usage) +select usage, apiName, supported.toString(), "supported", endpoint.jarContainer(), + endpoint.jarVersion(), type, "type", classification, "classification" diff --git a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql index 102015a08af5..d0e55f5145e2 100644 --- a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql @@ -11,13 +11,13 @@ private import java private import semmle.code.java.dataflow.internal.ModelExclusions private import ModelEditor -class PublicMethodFromSource extends CallableMethod, ModelApi { } +class PublicEndpointFromSource extends Endpoint, ModelApi { } -from PublicMethodFromSource publicMethod, string apiName, boolean supported, string type +from PublicEndpointFromSource endpoint, string apiName, boolean supported, string type where - apiName = publicMethod.getApiName() and - supported = isSupported(publicMethod) and - type = supportedType(publicMethod) -select publicMethod, apiName, supported.toString(), "supported", - publicMethod.getCompilationUnit().getParentContainer().getBaseName(), "library", type, "type", + apiName = endpoint.getApiName() and + supported = isSupported(endpoint) and + type = supportedType(endpoint) +select endpoint, apiName, supported.toString(), "supported", + endpoint.getCompilationUnit().getParentContainer().getBaseName(), "library", type, "type", "unknown", "classification" diff --git a/java/ql/src/utils/modeleditor/ModelEditor.qll b/java/ql/src/utils/modeleditor/ModelEditor.qll index ed67e2ace35c..562d6e8a2062 100644 --- a/java/ql/src/utils/modeleditor/ModelEditor.qll +++ b/java/ql/src/utils/modeleditor/ModelEditor.qll @@ -20,8 +20,8 @@ private predicate isUninteresting(Callable c) { /** * A callable method from either the Standard Library, a 3rd party library or from the source. */ -class CallableMethod extends Callable { - CallableMethod() { not isUninteresting(this) } +class Endpoint extends Callable { + Endpoint() { not isUninteresting(this) } /** * Gets information about the external API in the form expected by the MaD modeling framework. @@ -108,30 +108,30 @@ class CallableMethod extends Callable { } } -boolean isSupported(CallableMethod method) { - method.isSupported() and result = true +boolean isSupported(Endpoint endpoint) { + endpoint.isSupported() and result = true or - not method.isSupported() and result = false + not endpoint.isSupported() and result = false } -string supportedType(CallableMethod method) { - method.isSink() and result = "sink" +string supportedType(Endpoint endpoint) { + endpoint.isSink() and result = "sink" or - method.isSource() and result = "source" + endpoint.isSource() and result = "source" or - method.hasSummary() and result = "summary" + endpoint.hasSummary() and result = "summary" or - method.isNeutral() and result = "neutral" + endpoint.isNeutral() and result = "neutral" or - not method.isSupported() and result = "" + not endpoint.isSupported() and result = "" } -string methodClassification(Call method) { - isInTestFile(method.getLocation().getFile()) and result = "test" +string usageClassification(Call usage) { + isInTestFile(usage.getLocation().getFile()) and result = "test" or - method.getFile() instanceof GeneratedFile and result = "generated" + usage.getFile() instanceof GeneratedFile and result = "generated" or - not isInTestFile(method.getLocation().getFile()) and - not method.getFile() instanceof GeneratedFile and + not isInTestFile(usage.getLocation().getFile()) and + not usage.getFile() instanceof GeneratedFile and result = "source" } From 8e55189b8411ae182cf9b16addfde2bb833383e0 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 14:02:34 +0200 Subject: [PATCH 08/15] Java: Add tests for generic interfaces/classes/methods --- .../modeleditor/ApplicationModeEndpoints.expected | 3 +++ .../modeleditor/FrameworkModeEndpoints.expected | 5 +++++ .../com/github/codeql/test/PublicGenericClass.java | 13 +++++++++++++ .../github/codeql/test/PublicGenericInterface.java | 10 ++++++++++ 4 files changed, 31 insertions(+) create mode 100644 java/ql/test/utils/modeleditor/com/github/codeql/test/PublicGenericClass.java create mode 100644 java/ql/test/utils/modeleditor/com/github/codeql/test/PublicGenericInterface.java diff --git a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected index 22273baa31e0..24e411a6f7f9 100644 --- a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected @@ -5,4 +5,7 @@ | com/github/codeql/test/PublicClass.java:15:24:15:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | sink | type | source | classification | | com/github/codeql/test/PublicClass.java:15:24:15:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | summary | type | source | classification | | com/github/codeql/test/PublicClass.java:19:5:19:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicGenericClass.java:7:5:7:27 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicGenericClass.java:11:5:11:27 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicGenericInterface.java:8:7:8:29 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | | com/github/codeql/test/PublicInterface.java:7:7:7:29 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | diff --git a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected index 9586e695a162..e96f3c74791c 100644 --- a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected @@ -1,5 +1,10 @@ | com/github/codeql/test/PublicClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicClass#stuff(String) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicClass.java:10:22:10:32 | staticStuff | com.github.codeql.test.PublicClass#staticStuff(String) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicClass.java:14:18:14:31 | nonPublicStuff | com.github.codeql.test.PublicClass#nonPublicStuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicGenericClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicGenericClass#stuff(Object) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicGenericClass.java:10:20:10:25 | stuff2 | com.github.codeql.test.PublicGenericClass#stuff2(Object) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicGenericInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicGenericInterface#stuff(Object) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicGenericInterface.java:5:22:5:27 | stuff2 | com.github.codeql.test.PublicGenericInterface#stuff2(Object) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicGenericInterface.java:7:24:7:34 | staticStuff | com.github.codeql.test.PublicGenericInterface#staticStuff(String) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicInterface#stuff(String) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicInterface.java:6:24:6:34 | staticStuff | com.github.codeql.test.PublicInterface#staticStuff(String) | false | supported | test | library | | type | unknown | classification | diff --git a/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicGenericClass.java b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicGenericClass.java new file mode 100644 index 000000000000..a14dd64a5b97 --- /dev/null +++ b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicGenericClass.java @@ -0,0 +1,13 @@ +package com.github.codeql.test; + +import java.nio.file.Paths; + +public class PublicGenericClass implements PublicGenericInterface { + public void stuff(T arg) { + System.out.println(arg); + } + + public void stuff2(T3 arg) { + System.out.println(arg); + } +} diff --git a/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicGenericInterface.java b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicGenericInterface.java new file mode 100644 index 000000000000..030de29b6816 --- /dev/null +++ b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicGenericInterface.java @@ -0,0 +1,10 @@ +package com.github.codeql.test; + +public interface PublicGenericInterface { + public void stuff(T arg); + public void stuff2(T2 arg); + + public static void staticStuff(String arg) { + System.out.println(arg); + } +} From 6adbc406a7ca076728bf8633b8df89e867063f67 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 14:05:28 +0200 Subject: [PATCH 09/15] Java: Add tests for private methods --- .../ApplicationModeEndpoints.expected | 16 ++++++++++------ .../modeleditor/FrameworkModeEndpoints.expected | 6 +++--- .../com/github/codeql/test/PublicClass.java | 7 ++++++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected index 24e411a6f7f9..a8e696c25144 100644 --- a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected @@ -1,10 +1,14 @@ | com/github/codeql/test/NonPublicClass.java:5:5:5:28 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:7:5:7:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:11:5:11:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:15:5:15:45 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:15:24:15:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:15:24:15:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | summary | type | source | classification | -| com/github/codeql/test/PublicClass.java:19:5:19:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:8:5:8:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:12:5:12:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:16:5:16:45 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | summary | type | source | classification | +| com/github/codeql/test/PublicClass.java:20:5:20:68 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:20:24:20:47 | getDefault(...) | java.nio.file.FileSystems#getDefault() | false | supported | rt.jar | | | type | source | classification | +| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file.FileSystem#getPath(String,String[]) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file.FileSystem#getPath(String,String[]) | true | supported | rt.jar | | summary | type | source | classification | +| com/github/codeql/test/PublicClass.java:24:5:24:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | | com/github/codeql/test/PublicGenericClass.java:7:5:7:27 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | | com/github/codeql/test/PublicGenericClass.java:11:5:11:27 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | | com/github/codeql/test/PublicGenericInterface.java:8:7:8:29 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | diff --git a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected index e96f3c74791c..249901014151 100644 --- a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected @@ -1,6 +1,6 @@ -| com/github/codeql/test/PublicClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicClass#stuff(String) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicClass.java:10:22:10:32 | staticStuff | com.github.codeql.test.PublicClass#staticStuff(String) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicClass.java:14:18:14:31 | nonPublicStuff | com.github.codeql.test.PublicClass#nonPublicStuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:7:15:7:19 | stuff | com.github.codeql.test.PublicClass#stuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:11:22:11:32 | staticStuff | com.github.codeql.test.PublicClass#staticStuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:15:18:15:31 | protectedStuff | com.github.codeql.test.PublicClass#protectedStuff(String) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicGenericClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicGenericClass#stuff(Object) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicGenericClass.java:10:20:10:25 | stuff2 | com.github.codeql.test.PublicGenericClass#stuff2(Object) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicGenericInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicGenericInterface#stuff(Object) | false | supported | test | library | | type | unknown | classification | diff --git a/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java index 4e9228c167a6..83fe2a1d6ed6 100644 --- a/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java +++ b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java @@ -1,5 +1,6 @@ package com.github.codeql.test; +import java.nio.file.FileSystems; import java.nio.file.Paths; public class PublicClass { @@ -11,10 +12,14 @@ public static void staticStuff(String arg) { System.out.println(arg); } - protected void nonPublicStuff(String arg) { + protected void protectedStuff(String arg) { System.out.println(Paths.get("foo", arg)); } + private void privateStuff(String arg) { + System.out.println(FileSystems.getDefault().getPath("foo", arg)); + } + void packagePrivateStuff(String arg) { System.out.println(arg); } From 509b7fe0f86f9ed0345a316900b333f1052a4ea8 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 14:11:00 +0200 Subject: [PATCH 10/15] Java: Add tests for supported framework methods --- .../FrameworkModeEndpoints.expected | 4 ++++ .../FrameworkModeEndpoints.ext.yml | 24 +++++++++++++++++++ .../com/github/codeql/test/PublicClass.java | 16 +++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 java/ql/test/utils/modeleditor/FrameworkModeEndpoints.ext.yml diff --git a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected index 249901014151..f5d435ae7b33 100644 --- a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected @@ -1,6 +1,10 @@ | com/github/codeql/test/PublicClass.java:7:15:7:19 | stuff | com.github.codeql.test.PublicClass#stuff(String) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicClass.java:11:22:11:32 | staticStuff | com.github.codeql.test.PublicClass#staticStuff(String) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicClass.java:15:18:15:31 | protectedStuff | com.github.codeql.test.PublicClass#protectedStuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:27:17:27:28 | summaryStuff | com.github.codeql.test.PublicClass#summaryStuff(String) | true | supported | test | library | summary | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:31:17:31:27 | sourceStuff | com.github.codeql.test.PublicClass#sourceStuff() | true | supported | test | library | source | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:35:15:35:23 | sinkStuff | com.github.codeql.test.PublicClass#sinkStuff(String) | true | supported | test | library | sink | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:39:15:39:26 | neutralStuff | com.github.codeql.test.PublicClass#neutralStuff(String) | true | supported | test | library | neutral | type | unknown | classification | | com/github/codeql/test/PublicGenericClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicGenericClass#stuff(Object) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicGenericClass.java:10:20:10:25 | stuff2 | com.github.codeql.test.PublicGenericClass#stuff2(Object) | false | supported | test | library | | type | unknown | classification | | com/github/codeql/test/PublicGenericInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicGenericInterface#stuff(Object) | false | supported | test | library | | type | unknown | classification | diff --git a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.ext.yml b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.ext.yml new file mode 100644 index 000000000000..93ad471385ab --- /dev/null +++ b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.ext.yml @@ -0,0 +1,24 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["com.github.codeql.test","PublicClass",true,"sourceStuff","()","","ReturnValue","remote","manual"] + + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["com.github.codeql.test","PublicClass",true,"sinkStuff","(String)","","Argument[0]","sql-injection","manual"] + + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["com.github.codeql.test","PublicClass",true,"summaryStuff","(String)","","Argument[0]","ReturnValue","taint","manual"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["com.github.codeql.test","PublicClass","neutralStuff","(String)","summary","manual"] diff --git a/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java index 83fe2a1d6ed6..b53f70eaf155 100644 --- a/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java +++ b/java/ql/test/utils/modeleditor/com/github/codeql/test/PublicClass.java @@ -23,4 +23,20 @@ private void privateStuff(String arg) { void packagePrivateStuff(String arg) { System.out.println(arg); } + + public String summaryStuff(String arg) { + return arg; + } + + public String sourceStuff() { + return "stuff"; + } + + public void sinkStuff(String arg) { + // do nothing + } + + public void neutralStuff(String arg) { + // do nothing + } } From 73ebd21c334dd9ae7d815bb914f35593263a0fbc Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 14:13:28 +0200 Subject: [PATCH 11/15] Java: Refactor most of the logic out of the model editor query files --- .../ql/src/utils/modeleditor/ApplicationModeEndpoints.ql | 5 +---- .../utils/modeleditor/ApplicationModeEndpointsQuery.qll | 9 +++++++++ java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql | 4 +--- .../utils/modeleditor/FrameworkModeEndpointsQuery.qll | 8 ++++++++ 4 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 java/ql/src/utils/modeleditor/ApplicationModeEndpointsQuery.qll create mode 100644 java/ql/src/utils/modeleditor/FrameworkModeEndpointsQuery.qll diff --git a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql index f8216ea6bcb5..0b3d4d42f85d 100644 --- a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql @@ -8,12 +8,9 @@ */ private import java +private import ApplicationModeEndpointsQuery private import ModelEditor -class ExternalEndpoint extends Endpoint { - ExternalEndpoint() { not this.fromSource() } -} - private Call aUsage(ExternalEndpoint endpoint) { result.getCallee().getSourceDeclaration() = endpoint } diff --git a/java/ql/src/utils/modeleditor/ApplicationModeEndpointsQuery.qll b/java/ql/src/utils/modeleditor/ApplicationModeEndpointsQuery.qll new file mode 100644 index 000000000000..9ca9c25d1a83 --- /dev/null +++ b/java/ql/src/utils/modeleditor/ApplicationModeEndpointsQuery.qll @@ -0,0 +1,9 @@ +private import java +private import ModelEditor + +/** + * A class of effectively public callables in library code. + */ +class ExternalEndpoint extends Endpoint { + ExternalEndpoint() { not this.fromSource() } +} diff --git a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql index d0e55f5145e2..d46d13c0b812 100644 --- a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql @@ -8,11 +8,9 @@ */ private import java -private import semmle.code.java.dataflow.internal.ModelExclusions +private import FrameworkModeEndpointsQuery private import ModelEditor -class PublicEndpointFromSource extends Endpoint, ModelApi { } - from PublicEndpointFromSource endpoint, string apiName, boolean supported, string type where apiName = endpoint.getApiName() and diff --git a/java/ql/src/utils/modeleditor/FrameworkModeEndpointsQuery.qll b/java/ql/src/utils/modeleditor/FrameworkModeEndpointsQuery.qll new file mode 100644 index 000000000000..6cdea482ae6c --- /dev/null +++ b/java/ql/src/utils/modeleditor/FrameworkModeEndpointsQuery.qll @@ -0,0 +1,8 @@ +private import java +private import semmle.code.java.dataflow.internal.ModelExclusions +private import ModelEditor + +/** + * A class of effectively public callables from source code. + */ +class PublicEndpointFromSource extends Endpoint, ModelApi { } From 9e2984770faf1ea6d2ddab25ad26a7d08836fdc4 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Wed, 20 Sep 2023 14:25:06 +0200 Subject: [PATCH 12/15] Java: Fix identification of supported endpoints in framework mode --- .../ApplicationModeEndpointsQuery.qll | 31 ++++++++++++++++++ .../FrameworkModeEndpointsQuery.qll | 8 ++++- java/ql/src/utils/modeleditor/ModelEditor.qll | 32 +++---------------- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/java/ql/src/utils/modeleditor/ApplicationModeEndpointsQuery.qll b/java/ql/src/utils/modeleditor/ApplicationModeEndpointsQuery.qll index 9ca9c25d1a83..1b26eba5685c 100644 --- a/java/ql/src/utils/modeleditor/ApplicationModeEndpointsQuery.qll +++ b/java/ql/src/utils/modeleditor/ApplicationModeEndpointsQuery.qll @@ -1,4 +1,7 @@ private import java +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.internal.DataFlowPrivate private import ModelEditor /** @@ -6,4 +9,32 @@ private import ModelEditor */ class ExternalEndpoint extends Endpoint { ExternalEndpoint() { not this.fromSource() } + + /** Gets a node that is an input to a call to this API. */ + private DataFlow::Node getAnInput() { + exists(Call call | call.getCallee().getSourceDeclaration() = this | + result.asExpr().(Argument).getCall() = call or + result.(ArgumentNode).getCall().asCall() = call + ) + } + + /** Gets a node that is an output from a call to this API. */ + private DataFlow::Node getAnOutput() { + exists(Call call | call.getCallee().getSourceDeclaration() = this | + result.asExpr() = call or + result.(DataFlow::PostUpdateNode).getPreUpdateNode().(ArgumentNode).getCall().asCall() = call + ) + } + + override predicate hasSummary() { + Endpoint.super.hasSummary() + or + TaintTracking::localAdditionalTaintStep(this.getAnInput(), _) + } + + override predicate isSource() { + this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _) + } + + override predicate isSink() { sinkNode(this.getAnInput(), _) } } diff --git a/java/ql/src/utils/modeleditor/FrameworkModeEndpointsQuery.qll b/java/ql/src/utils/modeleditor/FrameworkModeEndpointsQuery.qll index 6cdea482ae6c..4920ed4f011a 100644 --- a/java/ql/src/utils/modeleditor/FrameworkModeEndpointsQuery.qll +++ b/java/ql/src/utils/modeleditor/FrameworkModeEndpointsQuery.qll @@ -1,8 +1,14 @@ private import java +private import semmle.code.java.dataflow.internal.DataFlowPrivate +private import semmle.code.java.dataflow.internal.FlowSummaryImplSpecific private import semmle.code.java.dataflow.internal.ModelExclusions private import ModelEditor /** * A class of effectively public callables from source code. */ -class PublicEndpointFromSource extends Endpoint, ModelApi { } +class PublicEndpointFromSource extends Endpoint, ModelApi { + override predicate isSource() { sourceElement(this, _, _, _) } + + override predicate isSink() { sinkElement(this, _, _, _) } +} diff --git a/java/ql/src/utils/modeleditor/ModelEditor.qll b/java/ql/src/utils/modeleditor/ModelEditor.qll index 562d6e8a2062..85ac8b3fc741 100644 --- a/java/ql/src/utils/modeleditor/ModelEditor.qll +++ b/java/ql/src/utils/modeleditor/ModelEditor.qll @@ -1,12 +1,8 @@ /** Provides classes and predicates related to handling APIs for the VS Code extension. */ private import java -private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow -private import semmle.code.java.dataflow.FlowSources private import semmle.code.java.dataflow.FlowSummary -private import semmle.code.java.dataflow.internal.DataFlowPrivate -private import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.dataflow.internal.ModelExclusions @@ -58,37 +54,17 @@ class Endpoint extends Callable { not exists(this.getJarVersion()) and result = "" } - /** Gets a node that is an input to a call to this API. */ - private DataFlow::Node getAnInput() { - exists(Call call | call.getCallee().getSourceDeclaration() = this | - result.asExpr().(Argument).getCall() = call or - result.(ArgumentNode).getCall().asCall() = call - ) - } - - /** Gets a node that is an output from a call to this API. */ - private DataFlow::Node getAnOutput() { - exists(Call call | call.getCallee().getSourceDeclaration() = this | - result.asExpr() = call or - result.(DataFlow::PostUpdateNode).getPreUpdateNode().(ArgumentNode).getCall().asCall() = call - ) - } - /** Holds if this API has a supported summary. */ pragma[nomagic] - predicate hasSummary() { - this = any(SummarizedCallable sc).asCallable() or - TaintTracking::localAdditionalTaintStep(this.getAnInput(), _) - } + predicate hasSummary() { this = any(SummarizedCallable sc).asCallable() } + /** Holds if this API is a known source. */ pragma[nomagic] - predicate isSource() { - this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _) - } + abstract predicate isSource(); /** Holds if this API is a known sink. */ pragma[nomagic] - predicate isSink() { sinkNode(this.getAnInput(), _) } + abstract predicate isSink(); /** Holds if this API is a known neutral. */ pragma[nomagic] From 7dc22e47d6b7394c891db279c2205843e8bd33b9 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Fri, 22 Sep 2023 16:08:20 +0200 Subject: [PATCH 13/15] Java: Switch from problem to table query --- java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql | 3 +-- java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql index 0b3d4d42f85d..66a7074db674 100644 --- a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql @@ -1,8 +1,7 @@ /** * @name Fetch endpoints for use in the model editor (application mode) * @description A list of 3rd party endpoints (methods) used in the codebase. Excludes test and generated code. - * @kind problem - * @problem.severity recommendation + * @kind table * @id java/utils/modeleditor/application-mode-endpoints * @tags modeleditor endpoints application-mode */ diff --git a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql index d46d13c0b812..c5c30126a23b 100644 --- a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql @@ -1,8 +1,7 @@ /** * @name Fetch endpoints for use in the model editor (framework mode) * @description A list of endpoints accessible (methods) for consumers of the library. Excludes test and generated code. - * @kind problem - * @problem.severity recommendation + * @kind table * @id java/utils/modeleditor/framework-mode-endpoints * @tags modeleditor endpoints framework-mode */ From f4522edc95966fabfb5c538bebbf2888984afd81 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Fri, 22 Sep 2023 16:11:30 +0200 Subject: [PATCH 14/15] Java: Remove unnecessary columns --- .../modeleditor/ApplicationModeEndpoints.ql | 4 +-- .../modeleditor/FrameworkModeEndpoints.ql | 5 ++-- .../ApplicationModeEndpoints.expected | 30 +++++++++---------- .../FrameworkModeEndpoints.expected | 28 ++++++++--------- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql index 66a7074db674..8b3d034bb3e4 100644 --- a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql @@ -23,5 +23,5 @@ where usage = aUsage(endpoint) and type = supportedType(endpoint) and classification = usageClassification(usage) -select usage, apiName, supported.toString(), "supported", endpoint.jarContainer(), - endpoint.jarVersion(), type, "type", classification, "classification" +select usage, apiName, supported, endpoint.jarContainer(), endpoint.jarVersion(), type, + classification diff --git a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql index c5c30126a23b..3350d55e9e6b 100644 --- a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql @@ -15,6 +15,5 @@ where apiName = endpoint.getApiName() and supported = isSupported(endpoint) and type = supportedType(endpoint) -select endpoint, apiName, supported.toString(), "supported", - endpoint.getCompilationUnit().getParentContainer().getBaseName(), "library", type, "type", - "unknown", "classification" +select endpoint, apiName, supported, + endpoint.getCompilationUnit().getParentContainer().getBaseName(), type diff --git a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected index a8e696c25144..f6d6cb586084 100644 --- a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected @@ -1,15 +1,15 @@ -| com/github/codeql/test/NonPublicClass.java:5:5:5:28 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:8:5:8:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:12:5:12:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:16:5:16:45 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | supported | rt.jar | | summary | type | source | classification | -| com/github/codeql/test/PublicClass.java:20:5:20:68 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:20:24:20:47 | getDefault(...) | java.nio.file.FileSystems#getDefault() | false | supported | rt.jar | | | type | source | classification | -| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file.FileSystem#getPath(String,String[]) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file.FileSystem#getPath(String,String[]) | true | supported | rt.jar | | summary | type | source | classification | -| com/github/codeql/test/PublicClass.java:24:5:24:27 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicGenericClass.java:7:5:7:27 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicGenericClass.java:11:5:11:27 | println(...) | java.io.PrintStream#println(Object) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicGenericInterface.java:8:7:8:29 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | -| com/github/codeql/test/PublicInterface.java:7:7:7:29 | println(...) | java.io.PrintStream#println(String) | true | supported | rt.jar | | sink | type | source | classification | +| com/github/codeql/test/NonPublicClass.java:5:5:5:28 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:8:5:8:27 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:12:5:12:27 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:16:5:16:45 | println(...) | java.io.PrintStream#println(Object) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | rt.jar | | summary | source | +| com/github/codeql/test/PublicClass.java:20:5:20:68 | println(...) | java.io.PrintStream#println(Object) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:20:24:20:47 | getDefault(...) | java.nio.file.FileSystems#getDefault() | false | rt.jar | | | source | +| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file.FileSystem#getPath(String,String[]) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file.FileSystem#getPath(String,String[]) | true | rt.jar | | summary | source | +| com/github/codeql/test/PublicClass.java:24:5:24:27 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicGenericClass.java:7:5:7:27 | println(...) | java.io.PrintStream#println(Object) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicGenericClass.java:11:5:11:27 | println(...) | java.io.PrintStream#println(Object) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicGenericInterface.java:8:7:8:29 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicInterface.java:7:7:7:29 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | diff --git a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected index f5d435ae7b33..ed2522fb977e 100644 --- a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected @@ -1,14 +1,14 @@ -| com/github/codeql/test/PublicClass.java:7:15:7:19 | stuff | com.github.codeql.test.PublicClass#stuff(String) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicClass.java:11:22:11:32 | staticStuff | com.github.codeql.test.PublicClass#staticStuff(String) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicClass.java:15:18:15:31 | protectedStuff | com.github.codeql.test.PublicClass#protectedStuff(String) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicClass.java:27:17:27:28 | summaryStuff | com.github.codeql.test.PublicClass#summaryStuff(String) | true | supported | test | library | summary | type | unknown | classification | -| com/github/codeql/test/PublicClass.java:31:17:31:27 | sourceStuff | com.github.codeql.test.PublicClass#sourceStuff() | true | supported | test | library | source | type | unknown | classification | -| com/github/codeql/test/PublicClass.java:35:15:35:23 | sinkStuff | com.github.codeql.test.PublicClass#sinkStuff(String) | true | supported | test | library | sink | type | unknown | classification | -| com/github/codeql/test/PublicClass.java:39:15:39:26 | neutralStuff | com.github.codeql.test.PublicClass#neutralStuff(String) | true | supported | test | library | neutral | type | unknown | classification | -| com/github/codeql/test/PublicGenericClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicGenericClass#stuff(Object) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicGenericClass.java:10:20:10:25 | stuff2 | com.github.codeql.test.PublicGenericClass#stuff2(Object) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicGenericInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicGenericInterface#stuff(Object) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicGenericInterface.java:5:22:5:27 | stuff2 | com.github.codeql.test.PublicGenericInterface#stuff2(Object) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicGenericInterface.java:7:24:7:34 | staticStuff | com.github.codeql.test.PublicGenericInterface#staticStuff(String) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicInterface#stuff(String) | false | supported | test | library | | type | unknown | classification | -| com/github/codeql/test/PublicInterface.java:6:24:6:34 | staticStuff | com.github.codeql.test.PublicInterface#staticStuff(String) | false | supported | test | library | | type | unknown | classification | +| com/github/codeql/test/PublicClass.java:7:15:7:19 | stuff | com.github.codeql.test.PublicClass#stuff(String) | false | test | | +| com/github/codeql/test/PublicClass.java:11:22:11:32 | staticStuff | com.github.codeql.test.PublicClass#staticStuff(String) | false | test | | +| com/github/codeql/test/PublicClass.java:15:18:15:31 | protectedStuff | com.github.codeql.test.PublicClass#protectedStuff(String) | false | test | | +| com/github/codeql/test/PublicClass.java:27:17:27:28 | summaryStuff | com.github.codeql.test.PublicClass#summaryStuff(String) | true | test | summary | +| com/github/codeql/test/PublicClass.java:31:17:31:27 | sourceStuff | com.github.codeql.test.PublicClass#sourceStuff() | true | test | source | +| com/github/codeql/test/PublicClass.java:35:15:35:23 | sinkStuff | com.github.codeql.test.PublicClass#sinkStuff(String) | true | test | sink | +| com/github/codeql/test/PublicClass.java:39:15:39:26 | neutralStuff | com.github.codeql.test.PublicClass#neutralStuff(String) | true | test | neutral | +| com/github/codeql/test/PublicGenericClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicGenericClass#stuff(Object) | false | test | | +| com/github/codeql/test/PublicGenericClass.java:10:20:10:25 | stuff2 | com.github.codeql.test.PublicGenericClass#stuff2(Object) | false | test | | +| com/github/codeql/test/PublicGenericInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicGenericInterface#stuff(Object) | false | test | | +| com/github/codeql/test/PublicGenericInterface.java:5:22:5:27 | stuff2 | com.github.codeql.test.PublicGenericInterface#stuff2(Object) | false | test | | +| com/github/codeql/test/PublicGenericInterface.java:7:24:7:34 | staticStuff | com.github.codeql.test.PublicGenericInterface#staticStuff(String) | false | test | | +| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicInterface#stuff(String) | false | test | | +| com/github/codeql/test/PublicInterface.java:6:24:6:34 | staticStuff | com.github.codeql.test.PublicInterface#staticStuff(String) | false | test | | From ced95e0f45c9f94d91bfffdb7a56190fa5909bed Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Mon, 25 Sep 2023 10:16:59 +0200 Subject: [PATCH 15/15] Java: Split API name column into separate columns --- .../modeleditor/ApplicationModeEndpoints.ql | 8 ++--- .../modeleditor/FrameworkModeEndpoints.ql | 6 ++-- java/ql/src/utils/modeleditor/ModelEditor.qll | 18 +++++++---- .../ApplicationModeEndpoints.expected | 30 +++++++++---------- .../FrameworkModeEndpoints.expected | 28 ++++++++--------- 5 files changed, 47 insertions(+), 43 deletions(-) diff --git a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql index 8b3d034bb3e4..653fdc0c8246 100644 --- a/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/ApplicationModeEndpoints.ql @@ -14,14 +14,12 @@ private Call aUsage(ExternalEndpoint endpoint) { result.getCallee().getSourceDeclaration() = endpoint } -from - ExternalEndpoint endpoint, string apiName, boolean supported, Call usage, string type, - string classification +from ExternalEndpoint endpoint, boolean supported, Call usage, string type, string classification where - apiName = endpoint.getApiName() and supported = isSupported(endpoint) and usage = aUsage(endpoint) and type = supportedType(endpoint) and classification = usageClassification(usage) -select usage, apiName, supported, endpoint.jarContainer(), endpoint.jarVersion(), type, +select usage, endpoint.getPackageName(), endpoint.getTypeName(), endpoint.getName(), + endpoint.getParameterTypes(), supported, endpoint.jarContainer(), endpoint.jarVersion(), type, classification diff --git a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql index 3350d55e9e6b..9dfe57c53a95 100644 --- a/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql +++ b/java/ql/src/utils/modeleditor/FrameworkModeEndpoints.ql @@ -10,10 +10,10 @@ private import java private import FrameworkModeEndpointsQuery private import ModelEditor -from PublicEndpointFromSource endpoint, string apiName, boolean supported, string type +from PublicEndpointFromSource endpoint, boolean supported, string type where - apiName = endpoint.getApiName() and supported = isSupported(endpoint) and type = supportedType(endpoint) -select endpoint, apiName, supported, +select endpoint, endpoint.getPackageName(), endpoint.getTypeName(), endpoint.getName(), + endpoint.getParameterTypes(), supported, endpoint.getCompilationUnit().getParentContainer().getBaseName(), type diff --git a/java/ql/src/utils/modeleditor/ModelEditor.qll b/java/ql/src/utils/modeleditor/ModelEditor.qll index 85ac8b3fc741..2c1a56823f16 100644 --- a/java/ql/src/utils/modeleditor/ModelEditor.qll +++ b/java/ql/src/utils/modeleditor/ModelEditor.qll @@ -20,13 +20,19 @@ class Endpoint extends Callable { Endpoint() { not isUninteresting(this) } /** - * Gets information about the external API in the form expected by the MaD modeling framework. + * Gets the package name of this endpoint. */ - string getApiName() { - result = - this.getDeclaringType().getPackage() + "." + this.getDeclaringType().nestedName() + "#" + - this.getName() + paramsString(this) - } + string getPackageName() { result = this.getDeclaringType().getPackage().getName() } + + /** + * Gets the type name of this endpoint. + */ + string getTypeName() { result = this.getDeclaringType().nestedName() } + + /** + * Gets the parameter types of this endpoint. + */ + string getParameterTypes() { result = paramsString(this) } private string getJarName() { result = this.getCompilationUnit().getParentContainer*().(JarFile).getBaseName() diff --git a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected index f6d6cb586084..919fc09b2610 100644 --- a/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/ApplicationModeEndpoints.expected @@ -1,15 +1,15 @@ -| com/github/codeql/test/NonPublicClass.java:5:5:5:28 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicClass.java:8:5:8:27 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicClass.java:12:5:12:27 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicClass.java:16:5:16:45 | println(...) | java.io.PrintStream#println(Object) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file.Paths#get(String,String[]) | true | rt.jar | | summary | source | -| com/github/codeql/test/PublicClass.java:20:5:20:68 | println(...) | java.io.PrintStream#println(Object) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicClass.java:20:24:20:47 | getDefault(...) | java.nio.file.FileSystems#getDefault() | false | rt.jar | | | source | -| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file.FileSystem#getPath(String,String[]) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file.FileSystem#getPath(String,String[]) | true | rt.jar | | summary | source | -| com/github/codeql/test/PublicClass.java:24:5:24:27 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicGenericClass.java:7:5:7:27 | println(...) | java.io.PrintStream#println(Object) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicGenericClass.java:11:5:11:27 | println(...) | java.io.PrintStream#println(Object) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicGenericInterface.java:8:7:8:29 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | -| com/github/codeql/test/PublicInterface.java:7:7:7:29 | println(...) | java.io.PrintStream#println(String) | true | rt.jar | | sink | source | +| com/github/codeql/test/NonPublicClass.java:5:5:5:28 | println(...) | java.io | PrintStream | println | (String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:8:5:8:27 | println(...) | java.io | PrintStream | println | (String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:12:5:12:27 | println(...) | java.io | PrintStream | println | (String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:16:5:16:45 | println(...) | java.io | PrintStream | println | (Object) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file | Paths | get | (String,String[]) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:16:24:16:44 | get(...) | java.nio.file | Paths | get | (String,String[]) | true | rt.jar | | summary | source | +| com/github/codeql/test/PublicClass.java:20:5:20:68 | println(...) | java.io | PrintStream | println | (Object) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:20:24:20:47 | getDefault(...) | java.nio.file | FileSystems | getDefault | () | false | rt.jar | | | source | +| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file | FileSystem | getPath | (String,String[]) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicClass.java:20:24:20:67 | getPath(...) | java.nio.file | FileSystem | getPath | (String,String[]) | true | rt.jar | | summary | source | +| com/github/codeql/test/PublicClass.java:24:5:24:27 | println(...) | java.io | PrintStream | println | (String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicGenericClass.java:7:5:7:27 | println(...) | java.io | PrintStream | println | (Object) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicGenericClass.java:11:5:11:27 | println(...) | java.io | PrintStream | println | (Object) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicGenericInterface.java:8:7:8:29 | println(...) | java.io | PrintStream | println | (String) | true | rt.jar | | sink | source | +| com/github/codeql/test/PublicInterface.java:7:7:7:29 | println(...) | java.io | PrintStream | println | (String) | true | rt.jar | | sink | source | diff --git a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected index ed2522fb977e..444165791caf 100644 --- a/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected +++ b/java/ql/test/utils/modeleditor/FrameworkModeEndpoints.expected @@ -1,14 +1,14 @@ -| com/github/codeql/test/PublicClass.java:7:15:7:19 | stuff | com.github.codeql.test.PublicClass#stuff(String) | false | test | | -| com/github/codeql/test/PublicClass.java:11:22:11:32 | staticStuff | com.github.codeql.test.PublicClass#staticStuff(String) | false | test | | -| com/github/codeql/test/PublicClass.java:15:18:15:31 | protectedStuff | com.github.codeql.test.PublicClass#protectedStuff(String) | false | test | | -| com/github/codeql/test/PublicClass.java:27:17:27:28 | summaryStuff | com.github.codeql.test.PublicClass#summaryStuff(String) | true | test | summary | -| com/github/codeql/test/PublicClass.java:31:17:31:27 | sourceStuff | com.github.codeql.test.PublicClass#sourceStuff() | true | test | source | -| com/github/codeql/test/PublicClass.java:35:15:35:23 | sinkStuff | com.github.codeql.test.PublicClass#sinkStuff(String) | true | test | sink | -| com/github/codeql/test/PublicClass.java:39:15:39:26 | neutralStuff | com.github.codeql.test.PublicClass#neutralStuff(String) | true | test | neutral | -| com/github/codeql/test/PublicGenericClass.java:6:15:6:19 | stuff | com.github.codeql.test.PublicGenericClass#stuff(Object) | false | test | | -| com/github/codeql/test/PublicGenericClass.java:10:20:10:25 | stuff2 | com.github.codeql.test.PublicGenericClass#stuff2(Object) | false | test | | -| com/github/codeql/test/PublicGenericInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicGenericInterface#stuff(Object) | false | test | | -| com/github/codeql/test/PublicGenericInterface.java:5:22:5:27 | stuff2 | com.github.codeql.test.PublicGenericInterface#stuff2(Object) | false | test | | -| com/github/codeql/test/PublicGenericInterface.java:7:24:7:34 | staticStuff | com.github.codeql.test.PublicGenericInterface#staticStuff(String) | false | test | | -| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | com.github.codeql.test.PublicInterface#stuff(String) | false | test | | -| com/github/codeql/test/PublicInterface.java:6:24:6:34 | staticStuff | com.github.codeql.test.PublicInterface#staticStuff(String) | false | test | | +| com/github/codeql/test/PublicClass.java:7:15:7:19 | stuff | com.github.codeql.test | PublicClass | stuff | (String) | false | test | | +| com/github/codeql/test/PublicClass.java:11:22:11:32 | staticStuff | com.github.codeql.test | PublicClass | staticStuff | (String) | false | test | | +| com/github/codeql/test/PublicClass.java:15:18:15:31 | protectedStuff | com.github.codeql.test | PublicClass | protectedStuff | (String) | false | test | | +| com/github/codeql/test/PublicClass.java:27:17:27:28 | summaryStuff | com.github.codeql.test | PublicClass | summaryStuff | (String) | true | test | summary | +| com/github/codeql/test/PublicClass.java:31:17:31:27 | sourceStuff | com.github.codeql.test | PublicClass | sourceStuff | () | true | test | source | +| com/github/codeql/test/PublicClass.java:35:15:35:23 | sinkStuff | com.github.codeql.test | PublicClass | sinkStuff | (String) | true | test | sink | +| com/github/codeql/test/PublicClass.java:39:15:39:26 | neutralStuff | com.github.codeql.test | PublicClass | neutralStuff | (String) | true | test | neutral | +| com/github/codeql/test/PublicGenericClass.java:6:15:6:19 | stuff | com.github.codeql.test | PublicGenericClass | stuff | (Object) | false | test | | +| com/github/codeql/test/PublicGenericClass.java:10:20:10:25 | stuff2 | com.github.codeql.test | PublicGenericClass | stuff2 | (Object) | false | test | | +| com/github/codeql/test/PublicGenericInterface.java:4:17:4:21 | stuff | com.github.codeql.test | PublicGenericInterface | stuff | (Object) | false | test | | +| com/github/codeql/test/PublicGenericInterface.java:5:22:5:27 | stuff2 | com.github.codeql.test | PublicGenericInterface | stuff2 | (Object) | false | test | | +| com/github/codeql/test/PublicGenericInterface.java:7:24:7:34 | staticStuff | com.github.codeql.test | PublicGenericInterface | staticStuff | (String) | false | test | | +| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | com.github.codeql.test | PublicInterface | stuff | (String) | false | test | | +| com/github/codeql/test/PublicInterface.java:6:24:6:34 | staticStuff | com.github.codeql.test | PublicInterface | staticStuff | (String) | false | test | |