From bde47836d079178d8ef59fca390000b03acb6c99 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 19 Jul 2022 12:25:10 +0000 Subject: [PATCH 001/659] Python: Add `Str` class This makes the AST viewer (which annotates string constant nodes as `Str`) a bit more consistent. --- python/ql/lib/semmle/python/Exprs.qll | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/Exprs.qll b/python/ql/lib/semmle/python/Exprs.qll index 360408cecef..288793386ca 100644 --- a/python/ql/lib/semmle/python/Exprs.qll +++ b/python/ql/lib/semmle/python/Exprs.qll @@ -616,8 +616,11 @@ private string non_byte_prefix() { not result.charAt(_) in ["b", "B"] } +/** A string constant. This is a placeholder class -- use `StrConst` instead. */ +class Str extends Str_ { } + /** A string constant. */ -class StrConst extends Str_, ImmutableLiteral { +class StrConst extends Str, ImmutableLiteral { /* syntax: "hello" */ predicate isUnicode() { this.getPrefix() = unicode_prefix() From 48f143e7d47be35e9d8f04d881544dabd1f57226 Mon Sep 17 00:00:00 2001 From: luchua-bc Date: Wed, 20 Jul 2022 22:39:24 +0000 Subject: [PATCH 002/659] Query to detect regex dot bypass --- .../Security/CWE/CWE-625/DotRegex.java | 32 +++++ .../CWE/CWE-625/PermissiveDotRegex.qhelp | 40 ++++++ .../CWE/CWE-625/PermissiveDotRegex.ql | 118 ++++++++++++++++++ .../Security/CWE/CWE-625/Regex.qll | 98 +++++++++++++++ .../security/CWE-625/DotRegexServlet.java | 87 +++++++++++++ .../CWE-625/PermissiveDotRegex.expected | 31 +++++ .../security/CWE-625/PermissiveDotRegex.qlref | 1 + .../query-tests/security/CWE-625/options | 1 + 8 files changed, 408 insertions(+) create mode 100644 java/ql/src/experimental/Security/CWE/CWE-625/DotRegex.java create mode 100644 java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.qhelp create mode 100644 java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql create mode 100644 java/ql/src/experimental/Security/CWE/CWE-625/Regex.qll create mode 100644 java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java create mode 100644 java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected create mode 100644 java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.qlref create mode 100644 java/ql/test/experimental/query-tests/security/CWE-625/options diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/DotRegex.java b/java/ql/src/experimental/Security/CWE/CWE-625/DotRegex.java new file mode 100644 index 00000000000..c5fcb13ec78 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-625/DotRegex.java @@ -0,0 +1,32 @@ +String PROTECTED_PATTERN = "/protected/.*"; +String CONSTRAINT_PATTERN = "/protected/xyz\\.xml"; + +// BAD: A string with line return e.g. `/protected/%0dxyz` can bypass the path check +Pattern p = Pattern.compile(PROTECTED_PATTERN); +Matcher m = p.matcher(path); + +// GOOD: A string with line return e.g. `/protected/%0dxyz` cannot bypass the path check +Pattern p = Pattern.compile(PROTECTED_PATTERN, Pattern.DOTALL); +Matcher m = p.matcher(path); + +// GOOD: Only a specific path can pass the validation +Pattern p = Pattern.compile(CONSTRAINT_PATTERN); +Matcher m = p.matcher(path); + +if (m.matches()) { + // Protected page - check access token and redirect to login page +} else { + // Not protected page - render content +} + +// BAD: A string with line return e.g. `/protected/%0axyz` can bypass the path check +boolean matches = path.matches(PROTECTED_PATTERN); + +// BAD: A string with line return e.g. `/protected/%0axyz` can bypass the path check +boolean matches = Pattern.matches(PROTECTED_PATTERN, path); + +if (matches) { + // Protected page - check access token and redirect to login page +} else { + // Not protected page - render content +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.qhelp b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.qhelp new file mode 100644 index 00000000000..998edb38c21 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.qhelp @@ -0,0 +1,40 @@ + + + + +

By default, "dot" (.) in regular expressions matches all characters except newline characters \n and +\r. Regular expressions containing a dot can be bypassed with the characters \r(%0a) , \n(%0d) when the default regex +matching implementations of Java are used. When regular expressions serve to match protected resource patterns to grant access +to protected application resources, attackers can gain access to unauthorized paths.

+
+ + +

To guard against unauthorized access, it is advisable to properly specify regex patterns for validating user input. The Java +Pattern Matcher API Pattern.compile(PATTERN, Pattern.DOTALL) with the DOTALL flag set can be adopted +to address this vulnerability.

+
+ + +

The following examples show the bad case and the good case respectively. The bad methods show a regex pattern allowing +bypass. In the good methods, it is shown how to solve this problem by either specifying the regex pattern correctly or +use the Java API that can detect new line characters. +

+ + +
+ + +
  • Lay0us1: + CVE 2022-22978: Authorization Bypass in RegexRequestMatcher. +
  • +
  • Apache Shiro: + Address the RegexRequestMatcher issue in 1.9.1. +
  • +
  • CVE-2022-32532: + Applications using RegExPatternMatcher with "." in the regular expression are possibly vulnerable to an authorization bypass. +
  • +
    + +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql new file mode 100644 index 00000000000..33b62d22396 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql @@ -0,0 +1,118 @@ +/** + * @name URL matched by permissive `.` in the regular expression + * @description URL validated with permissive `.` in regex are possibly vulnerable + * to an authorization bypass. + * @kind path-problem + * @problem.severity warning + * @precision high + * @id java/permissive-dot-regex + * @tags security + * external/cwe-625 + * external/cwe-863 + */ + +import java +import semmle.code.java.dataflow.ExternalFlow +import semmle.code.java.dataflow.FlowSources +import DataFlow::PathGraph +import Regex + +/** + * `.` without a `\` prefix, which is likely not a character literal in regex + */ +class PermissiveDotStr extends StringLiteral { + PermissiveDotStr() { + // Find `.` in a string that is not prefixed with `\` + exists(string s, int i | this.getValue() = s | + s.indexOf(".") = i and + not s.charAt(i - 1) = "\\" + ) + } +} + +/** + * Permissive `.` in a regular expression. + */ +class PermissiveDotEx extends Expr { + PermissiveDotEx() { this instanceof PermissiveDotStr } +} + +/** + * A data flow sink to construct regular expressions. + */ +class CompileRegexSink extends DataFlow::ExprNode { + CompileRegexSink() { + exists(MethodAccess ma, Method m | m = ma.getMethod() | + ( + ma.getArgument(0) = this.asExpr() and + ( + m instanceof StringMatchMethod // input.matches(regexPattern) + or + m instanceof PatternCompileMethod // p = Pattern.compile(regexPattern) + or + m instanceof PatternMatchMethod // p = Pattern.matches(regexPattern, input) + ) + ) + ) + } +} + +/** + * A flow configuration for permissive dot regex. + */ +class PermissiveDotRegexConfig extends DataFlow::Configuration { + PermissiveDotRegexConfig() { this = "PermissiveDotRegex::PermissiveDotRegexConfig" } + + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof PermissiveDotEx } + + override predicate isSink(DataFlow::Node sink) { sink instanceof CompileRegexSink } + + override predicate isBarrier(DataFlow::Node node) { + exists( + MethodAccess ma, Field f // Pattern.compile(PATTERN, Pattern.DOTALL) + | + ma.getMethod() instanceof PatternCompileMethod and + ma.getArgument(1) = f.getAnAccess() and + f.hasName("DOTALL") and + f.getDeclaringType() instanceof Pattern and + node.asExpr() = ma.getArgument(0) + ) + } +} + +/** + * A taint-tracking configuration for untrusted user input used to match regular expressions. + */ +class MatchRegexConfiguration extends TaintTracking::Configuration { + MatchRegexConfiguration() { this = "PermissiveDotRegex::MatchRegexConfiguration" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof MatchRegexSink } +} + +from + DataFlow::PathNode source, DataFlow::PathNode sink, MatchRegexConfiguration conf, + DataFlow::PathNode source2, DataFlow::PathNode sink2, PermissiveDotRegexConfig conf2 +where + conf.hasFlowPath(source, sink) and + conf2.hasFlowPath(source2, sink2) and + exists(MethodAccess ma | ma.getArgument(0) = sink2.getNode().asExpr() | + // input.matches(regexPattern) + ma.getMethod() instanceof StringMatchMethod and + ma.getQualifier() = sink.getNode().asExpr() + or + // p = Pattern.compile(regexPattern); p.matcher(input) + ma.getMethod() instanceof PatternCompileMethod and + exists(MethodAccess pma | + pma.getMethod() instanceof PatternMatcherMethod and + sink.getNode().asExpr() = pma.getArgument(0) and + DataFlow::localExprFlow(ma, pma.getQualifier()) + ) + or + // p = Pattern.matches(regexPattern, input) + ma.getMethod() instanceof PatternMatchMethod and + sink.getNode().asExpr() = ma.getArgument(1) + ) +select sink.getNode(), source, sink, "Potentially authentication bypass due to $@.", + source.getNode(), "user-provided value" diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/Regex.qll b/java/ql/src/experimental/Security/CWE/CWE-625/Regex.qll new file mode 100644 index 00000000000..ea1c96b3194 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-625/Regex.qll @@ -0,0 +1,98 @@ +/** Provides methods related to regular expression matching. */ + +import java +private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.TaintTracking2 + +/** + * The class `Pattern` for pattern match. + */ +class Pattern extends RefType { + Pattern() { this.hasQualifiedName("java.util.regex", "Pattern") } +} + +/** + * The method `compile` for `Pattern`. + */ +class PatternCompileMethod extends Method { + PatternCompileMethod() { + this.getDeclaringType().getASupertype*() instanceof Pattern and + this.hasName("compile") + } +} + +/** + * The method `matches` for `Pattern`. + */ +class PatternMatchMethod extends Method { + PatternMatchMethod() { + this.getDeclaringType().getASupertype*() instanceof Pattern and + this.hasName("matches") + } +} + +/** + * The method `matcher` for `Pattern`. + */ +class PatternMatcherMethod extends Method { + PatternMatcherMethod() { + this.getDeclaringType().getASupertype*() instanceof Pattern and + this.hasName("matcher") + } +} + +/** + * The method `matches` for `String`. + */ +class StringMatchMethod extends Method { + StringMatchMethod() { + this.getDeclaringType().getASupertype*() instanceof TypeString and + this.hasName("matches") + } +} + +abstract class MatchRegexSink extends DataFlow::ExprNode { } + +/** + * A data flow sink to string match regular expressions. + */ +class StringMatchRegexSink extends MatchRegexSink { + StringMatchRegexSink() { + exists(MethodAccess ma, Method m | m = ma.getMethod() | + ( + m instanceof StringMatchMethod and + ma.getQualifier() = this.asExpr() + ) + ) + } +} + +/** + * A data flow sink to `pattern.matches` regular expressions. + */ +class PatternMatchRegexSink extends MatchRegexSink { + PatternMatchRegexSink() { + exists(MethodAccess ma, Method m | m = ma.getMethod() | + ( + m instanceof PatternMatchMethod and + ma.getArgument(1) = this.asExpr() + ) + ) + } +} + +/** + * A data flow sink to `pattern.matcher` match regular expressions. + */ +class PatternMatcherRegexSink extends MatchRegexSink { + PatternMatcherRegexSink() { + exists(MethodAccess ma, Method m | m = ma.getMethod() | + ( + m instanceof PatternMatcherMethod and + ma.getArgument(0) = this.asExpr() + ) + ) + } +} + diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java new file mode 100644 index 00000000000..6d35ace9706 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java @@ -0,0 +1,87 @@ +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletException; + +public class DotRegexServlet extends HttpServlet { + private static final String PROTECTED_PATTERN = "/protected/.*"; + private static final String CONSTRAINT_PATTERN = "/protected/xyz\\.xml"; + + @Override + // BAD: A string with line return e.g. `/protected/%0dxyz` can bypass the path check + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String source = request.getPathInfo(); + + Pattern p = Pattern.compile(PROTECTED_PATTERN); + Matcher m = p.matcher(source); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + } else { + // Not protected page - render content + } + } + + // GOOD: A string with line return e.g. `/protected/%0dxyz` cannot bypass the path check + protected void doGet2(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String source = request.getPathInfo(); + + Pattern p = Pattern.compile(PROTECTED_PATTERN, Pattern.DOTALL); + Matcher m = p.matcher(source); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + } else { + // Not protected page - render content + } + } + + // BAD: A string with line return e.g. `/protected/%0axyz` can bypass the path check + protected void doGet3(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String source = request.getPathInfo(); + + boolean matches = source.matches(PROTECTED_PATTERN); + + if (matches) { + // Protected page - check access token and redirect to login page + } else { + // Not protected page - render content + } + } + + // BAD: A string with line return e.g. `/protected/%0axyz` can bypass the path check + protected void doGet4(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String source = request.getPathInfo(); + + boolean matches = Pattern.matches(PROTECTED_PATTERN, source); + + if (matches) { + // Protected page - check access token and redirect to login page + } else { + // Not protected page - render content + } + } + + // GOOD: Only a specific path can pass the validation + protected void doGet5(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String source = request.getPathInfo(); + + Pattern p = Pattern.compile(CONSTRAINT_PATTERN); + Matcher m = p.matcher(source); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + } else { + // Not protected page - render content + } + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected new file mode 100644 index 00000000000..07d6901c193 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected @@ -0,0 +1,31 @@ +edges +| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:20:31:20:47 | PROTECTED_PATTERN | +| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:50:36:50:52 | PROTECTED_PATTERN | +| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:64:37:64:53 | PROTECTED_PATTERN | +| DotRegexServlet.java:11:50:11:64 | "/protected/.*" : String | DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | +| DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | DotRegexServlet.java:21:25:21:30 | source | +| DotRegexServlet.java:33:19:33:39 | getPathInfo(...) : String | DotRegexServlet.java:36:25:36:30 | source | +| DotRegexServlet.java:48:19:48:39 | getPathInfo(...) : String | DotRegexServlet.java:50:21:50:26 | source | +| DotRegexServlet.java:62:19:62:39 | getPathInfo(...) : String | DotRegexServlet.java:64:56:64:61 | source | +| DotRegexServlet.java:76:19:76:39 | getPathInfo(...) : String | DotRegexServlet.java:79:25:79:30 | source | +nodes +| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | semmle.label | PROTECTED_PATTERN : String | +| DotRegexServlet.java:11:50:11:64 | "/protected/.*" : String | semmle.label | "/protected/.*" : String | +| DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:20:31:20:47 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:21:25:21:30 | source | semmle.label | source | +| DotRegexServlet.java:33:19:33:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:36:25:36:30 | source | semmle.label | source | +| DotRegexServlet.java:48:19:48:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:50:21:50:26 | source | semmle.label | source | +| DotRegexServlet.java:50:36:50:52 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:62:19:62:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:64:37:64:53 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:64:56:64:61 | source | semmle.label | source | +| DotRegexServlet.java:76:19:76:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:79:25:79:30 | source | semmle.label | source | +subpaths +#select +| DotRegexServlet.java:21:25:21:30 | source | DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | DotRegexServlet.java:21:25:21:30 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:18:19:18:39 | getPathInfo(...) | user-provided value | +| DotRegexServlet.java:50:21:50:26 | source | DotRegexServlet.java:48:19:48:39 | getPathInfo(...) : String | DotRegexServlet.java:50:21:50:26 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:48:19:48:39 | getPathInfo(...) | user-provided value | +| DotRegexServlet.java:64:56:64:61 | source | DotRegexServlet.java:62:19:62:39 | getPathInfo(...) : String | DotRegexServlet.java:64:56:64:61 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:62:19:62:39 | getPathInfo(...) | user-provided value | diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.qlref b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.qlref new file mode 100644 index 00000000000..c1c303b93b0 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/options b/java/ql/test/experimental/query-tests/security/CWE-625/options new file mode 100644 index 00000000000..79df30ff8e9 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-625/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4 From 962069ccff8434efccda70d3804262e054fb9689 Mon Sep 17 00:00:00 2001 From: luchua-bc Date: Fri, 22 Jul 2022 23:10:52 +0000 Subject: [PATCH 003/659] Add path check in a security context (redirect) --- .../CWE/CWE-625/PermissiveDotRegex.ql | 44 ++++++++++++++++--- .../Security/CWE/CWE-625/Regex.qll | 1 - .../security/CWE-625/DotRegexServlet.java | 42 +++++++++++++----- .../CWE-625/PermissiveDotRegex.expected | 36 +++++++-------- 4 files changed, 88 insertions(+), 35 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql index 33b62d22396..3048c1e4198 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql @@ -12,20 +12,37 @@ */ import java +import semmle.code.java.controlflow.Guards import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.FlowSources +import semmle.code.java.security.UrlRedirect import DataFlow::PathGraph import Regex +/** Source model of remote flow source with servlets. */ +private class GetServletUriSource extends SourceModelCsv { + override predicate row(string row) { + row = + [ + "javax.servlet.http;HttpServletRequest;false;getPathInfo;();;ReturnValue;uri-path;manual", + "javax.servlet.http;HttpServletRequest;false;getPathTranslated;();;ReturnValue;uri-path;manual", + "javax.servlet.http;HttpServletRequest;false;getRequestURI;();;ReturnValue;uri-path;manual", + "javax.servlet.http;HttpServletRequest;false;getRequestURL;();;ReturnValue;uri-path;manual", + "javax.servlet.http;HttpServletRequest;false;getServletPath;();;ReturnValue;uri-path;manual" + ] + } +} + /** * `.` without a `\` prefix, which is likely not a character literal in regex */ class PermissiveDotStr extends StringLiteral { PermissiveDotStr() { - // Find `.` in a string that is not prefixed with `\` + // Find `.` in a string that is not prefixed with `\` and ends with `.*` (no suffix like file extension) exists(string s, int i | this.getValue() = s | - s.indexOf(".") = i and - not s.charAt(i - 1) = "\\" + s.indexOf(".*") = i and + not s.charAt(i - 1) = "\\" and + s.length() = i + 2 ) } } @@ -86,9 +103,26 @@ class PermissiveDotRegexConfig extends DataFlow::Configuration { class MatchRegexConfiguration extends TaintTracking::Configuration { MatchRegexConfiguration() { this = "PermissiveDotRegex::MatchRegexConfiguration" } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + override predicate isSource(DataFlow::Node source) { sourceNode(source, "uri-path") } - override predicate isSink(DataFlow::Node sink) { sink instanceof MatchRegexSink } + override predicate isSink(DataFlow::Node sink) { + sink instanceof MatchRegexSink and + exists( + Guard guard, Expr se, Expr ce // used in a condition to control url redirect, which is a typical security enforcement + | + ( + sink.asExpr() = ce.(MethodAccess).getQualifier() or + sink.asExpr() = ce.(MethodAccess).getAnArgument() or + sink.asExpr() = ce + ) and + ( + DataFlow::localExprFlow(ce, guard.(MethodAccess).getQualifier()) or + DataFlow::localExprFlow(ce, guard.(MethodAccess).getAnArgument()) + ) and + DataFlow::exprNode(se) instanceof UrlRedirectSink and + guard.controls(se.getBasicBlock(), true) + ) + } } from diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/Regex.qll b/java/ql/src/experimental/Security/CWE/CWE-625/Regex.qll index ea1c96b3194..571cc419820 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/Regex.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-625/Regex.qll @@ -95,4 +95,3 @@ class PatternMatcherRegexSink extends MatchRegexSink { ) } } - diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java index 6d35ace9706..4db8d45bc18 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java +++ b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java @@ -22,8 +22,12 @@ public class DotRegexServlet extends HttpServlet { if (m.matches()) { // Protected page - check access token and redirect to login page - } else { - // Not protected page - render content + if (!request.getSession().getAttribute("secAttr").equals("secValue")) { + response.sendRedirect("/login.html"); + return; + } else { + // Not protected page - render content + } } } @@ -37,22 +41,30 @@ public class DotRegexServlet extends HttpServlet { if (m.matches()) { // Protected page - check access token and redirect to login page - } else { - // Not protected page - render content + if (!request.getSession().getAttribute("secAttr").equals("secValue")) { + response.sendRedirect("/login.html"); + return; + } else { + // Not protected page - render content + } } } // BAD: A string with line return e.g. `/protected/%0axyz` can bypass the path check protected void doGet3(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - String source = request.getPathInfo(); + String source = request.getRequestURI(); boolean matches = source.matches(PROTECTED_PATTERN); if (matches) { // Protected page - check access token and redirect to login page - } else { - // Not protected page - render content + if (!request.getSession().getAttribute("secAttr").equals("secValue")) { + response.sendRedirect("/login.html"); + return; + } else { + // Not protected page - render content + } } } @@ -65,8 +77,12 @@ public class DotRegexServlet extends HttpServlet { if (matches) { // Protected page - check access token and redirect to login page - } else { - // Not protected page - render content + if (!request.getSession().getAttribute("secAttr").equals("secValue")) { + response.sendRedirect("/login.html"); + return; + } else { + // Not protected page - render content + } } } @@ -80,8 +96,12 @@ public class DotRegexServlet extends HttpServlet { if (m.matches()) { // Protected page - check access token and redirect to login page - } else { - // Not protected page - render content + if (!request.getSession().getAttribute("secAttr").equals("secValue")) { + response.sendRedirect("/login.html"); + return; + } else { + // Not protected page - render content + } } } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected index 07d6901c193..5449a1d96b9 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected @@ -1,31 +1,31 @@ edges | DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:20:31:20:47 | PROTECTED_PATTERN | -| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:50:36:50:52 | PROTECTED_PATTERN | -| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:64:37:64:53 | PROTECTED_PATTERN | +| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:58:36:58:52 | PROTECTED_PATTERN | +| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:76:37:76:53 | PROTECTED_PATTERN | | DotRegexServlet.java:11:50:11:64 | "/protected/.*" : String | DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | | DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | DotRegexServlet.java:21:25:21:30 | source | -| DotRegexServlet.java:33:19:33:39 | getPathInfo(...) : String | DotRegexServlet.java:36:25:36:30 | source | -| DotRegexServlet.java:48:19:48:39 | getPathInfo(...) : String | DotRegexServlet.java:50:21:50:26 | source | -| DotRegexServlet.java:62:19:62:39 | getPathInfo(...) : String | DotRegexServlet.java:64:56:64:61 | source | -| DotRegexServlet.java:76:19:76:39 | getPathInfo(...) : String | DotRegexServlet.java:79:25:79:30 | source | +| DotRegexServlet.java:37:19:37:39 | getPathInfo(...) : String | DotRegexServlet.java:40:25:40:30 | source | +| DotRegexServlet.java:56:19:56:41 | getRequestURI(...) : String | DotRegexServlet.java:58:21:58:26 | source | +| DotRegexServlet.java:74:19:74:39 | getPathInfo(...) : String | DotRegexServlet.java:76:56:76:61 | source | +| DotRegexServlet.java:92:19:92:39 | getPathInfo(...) : String | DotRegexServlet.java:95:25:95:30 | source | nodes | DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | semmle.label | PROTECTED_PATTERN : String | | DotRegexServlet.java:11:50:11:64 | "/protected/.*" : String | semmle.label | "/protected/.*" : String | | DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | | DotRegexServlet.java:20:31:20:47 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | | DotRegexServlet.java:21:25:21:30 | source | semmle.label | source | -| DotRegexServlet.java:33:19:33:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | -| DotRegexServlet.java:36:25:36:30 | source | semmle.label | source | -| DotRegexServlet.java:48:19:48:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | -| DotRegexServlet.java:50:21:50:26 | source | semmle.label | source | -| DotRegexServlet.java:50:36:50:52 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | -| DotRegexServlet.java:62:19:62:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | -| DotRegexServlet.java:64:37:64:53 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | -| DotRegexServlet.java:64:56:64:61 | source | semmle.label | source | -| DotRegexServlet.java:76:19:76:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | -| DotRegexServlet.java:79:25:79:30 | source | semmle.label | source | +| DotRegexServlet.java:37:19:37:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:40:25:40:30 | source | semmle.label | source | +| DotRegexServlet.java:56:19:56:41 | getRequestURI(...) : String | semmle.label | getRequestURI(...) : String | +| DotRegexServlet.java:58:21:58:26 | source | semmle.label | source | +| DotRegexServlet.java:58:36:58:52 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:74:19:74:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:76:37:76:53 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:76:56:76:61 | source | semmle.label | source | +| DotRegexServlet.java:92:19:92:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:95:25:95:30 | source | semmle.label | source | subpaths #select | DotRegexServlet.java:21:25:21:30 | source | DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | DotRegexServlet.java:21:25:21:30 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:18:19:18:39 | getPathInfo(...) | user-provided value | -| DotRegexServlet.java:50:21:50:26 | source | DotRegexServlet.java:48:19:48:39 | getPathInfo(...) : String | DotRegexServlet.java:50:21:50:26 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:48:19:48:39 | getPathInfo(...) | user-provided value | -| DotRegexServlet.java:64:56:64:61 | source | DotRegexServlet.java:62:19:62:39 | getPathInfo(...) : String | DotRegexServlet.java:64:56:64:61 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:62:19:62:39 | getPathInfo(...) | user-provided value | +| DotRegexServlet.java:58:21:58:26 | source | DotRegexServlet.java:56:19:56:41 | getRequestURI(...) : String | DotRegexServlet.java:58:21:58:26 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:56:19:56:41 | getRequestURI(...) | user-provided value | +| DotRegexServlet.java:76:56:76:61 | source | DotRegexServlet.java:74:19:74:39 | getPathInfo(...) : String | DotRegexServlet.java:76:56:76:61 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:74:19:74:39 | getPathInfo(...) | user-provided value | From 6356b20928ab61f44f458f575572166ef3879763 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Tue, 26 Jul 2022 15:22:46 +0100 Subject: [PATCH 004/659] Ruby: port js/hardcoded-data-interpreted-as-code --- ...dedDataInterpretedAsCodeCustomizations.qll | 93 +++++++++++++++++++ .../HardcodedDataInterpretedAsCodeQuery.qll | 48 ++++++++++ .../change-notes/2022-07-26-hardcoded-data.md | 4 + .../HardcodedDataInterpretedAsCode.qhelp | 47 ++++++++++ .../cwe-506/HardcodedDataInterpretedAsCode.ql | 23 +++++ .../HardcodedDataInterpretedAsCode.rb | 6 ++ .../HardcodedDataInterpretedAsCode.expected | 23 +++++ .../HardcodedDataInterpretedAsCode.qlref | 1 + .../test/query-tests/security/cwe-506/tst.rb | 14 +++ 9 files changed, 259 insertions(+) create mode 100644 ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll create mode 100644 ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll create mode 100644 ruby/ql/src/change-notes/2022-07-26-hardcoded-data.md create mode 100644 ruby/ql/src/queries/security/cwe-506/HardcodedDataInterpretedAsCode.qhelp create mode 100644 ruby/ql/src/queries/security/cwe-506/HardcodedDataInterpretedAsCode.ql create mode 100644 ruby/ql/src/queries/security/cwe-506/examples/HardcodedDataInterpretedAsCode.rb create mode 100644 ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected create mode 100644 ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.qlref create mode 100644 ruby/ql/test/query-tests/security/cwe-506/tst.rb diff --git a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll new file mode 100644 index 00000000000..e0c1e71f017 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeCustomizations.qll @@ -0,0 +1,93 @@ +/** + * Provides default sources, sinks and sanitizers for reasoning about hard-coded + * data being interpreted as code, as well as extension points for adding your + * own. + */ + +private import codeql.ruby.DataFlow +private import codeql.ruby.security.CodeInjectionCustomizations +private import codeql.ruby.AST as AST + +/** + * Provides default sources, sinks and sanitizers for reasoning about hard-coded + * data being interpreted as code, as well as extension points for adding your + * own. + */ +module HardcodedDataInterpretedAsCode { + /** + * Flow states used to distinguish value-preserving flow from taint flow. + */ + module FlowState { + /** Flow state used to track value-preserving flow. */ + DataFlow::FlowState data() { result = "data" } + + /** Flow state used to tainted data (non-value preserving flow). */ + DataFlow::FlowState taint() { result = "taint" } + } + + /** + * A data flow source for hard-coded data. + */ + abstract class Source extends DataFlow::Node { + /** Gets a flow label for which this is a source. */ + DataFlow::FlowState getLabel() { result = FlowState::data() } + } + + /** + * A data flow sink for code injection. + */ + abstract class Sink extends DataFlow::Node { + /** Gets a description of what kind of sink this is. */ + abstract string getKind(); + + /** Gets a flow label for which this is a sink. */ + DataFlow::FlowState getLabel() { + // We want to ignore value-flow and only consider taint-flow, since the + // source is just a hex string, and evaluating that directly will just + // cause a syntax error. + result = FlowState::taint() + } + } + + /** A sanitizer for hard-coded data. */ + abstract class Sanitizer extends DataFlow::Node { } + + /** + * A constant string consisting of eight or more hexadecimal characters (including at + * least one digit), viewed as a source of hard-coded data that should not be + * interpreted as code. + */ + private class DefaultSource extends Source, DataFlow::LocalSourceNode { + DefaultSource() { + exists(string val | this.asExpr().getConstantValue().isString(val) | + val.regexpMatch("[0-9a-fA-F]{8,}") and + val.regexpMatch(".*[0-9].*") + ) + } + } + + /** + * A code injection sink; hard-coded data should not flow here. + */ + private class DefaultCodeInjectionSink extends Sink { + DefaultCodeInjectionSink() { this instanceof CodeInjection::Sink } + + override string getKind() { result = "code" } + } + + /** + * An argument to `require` path; hard-coded data should not flow here. + */ + private class RequireArgumentSink extends Sink { + RequireArgumentSink() { + exists(DataFlow::CallNode require | + require.getReceiver().getExprNode().getExpr() instanceof AST::SelfVariableAccess and + require.getMethodName() = "require" + | + this = require.getArgument(0) + ) + } + + override string getKind() { result = "an import path" } + } +} diff --git a/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll new file mode 100644 index 00000000000..98fb0542815 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/security/HardcodedDataInterpretedAsCodeQuery.qll @@ -0,0 +1,48 @@ +/** + * Provides a taint-tracking configuration for reasoning about hard-coded data + * being interpreted as code. + * + * Note, for performance reasons: only import this file if + * `HardcodedDataInterpretedAsCode::Configuration` is needed, otherwise + * `HardcodedDataInterpretedAsCodeCustomizations` should be imported instead. + */ + +private import codeql.ruby.DataFlow +private import codeql.ruby.TaintTracking +private import codeql.ruby.dataflow.internal.TaintTrackingPrivate +import HardcodedDataInterpretedAsCodeCustomizations::HardcodedDataInterpretedAsCode + +/** + * A taint-tracking configuration for reasoning about hard-coded data + * being interpreted as code. + * + * We extend `DataFlow::Configuration` rather than + * `TaintTracking::Configuration`, so that we can set the flow state to + * `"taint"` on a taint step. + */ +class Configuration extends DataFlow::Configuration { + Configuration() { this = "HardcodedDataInterpretedAsCode" } + + override predicate isSource(DataFlow::Node source, DataFlow::FlowState label) { + source.(Source).getLabel() = label + } + + override predicate isSink(DataFlow::Node sink, DataFlow::FlowState label) { + sink.(Sink).getLabel() = label + } + + override predicate isBarrier(DataFlow::Node node) { + super.isBarrier(node) or + node instanceof Sanitizer + } + + override predicate isAdditionalFlowStep( + DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo, + DataFlow::FlowState stateTo + ) { + defaultAdditionalTaintStep(nodeFrom, nodeTo) and + // This is a taint step, so the flow state becomes `taint`. + stateFrom = [FlowState::data(), FlowState::taint()] and + stateTo = FlowState::taint() + } +} diff --git a/ruby/ql/src/change-notes/2022-07-26-hardcoded-data.md b/ruby/ql/src/change-notes/2022-07-26-hardcoded-data.md new file mode 100644 index 00000000000..4878b51992f --- /dev/null +++ b/ruby/ql/src/change-notes/2022-07-26-hardcoded-data.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `rb/hardcoded-data-interpreted-as-code`, to detect cases where hardcoded data is executed as code, a technique associated with backdoors. diff --git a/ruby/ql/src/queries/security/cwe-506/HardcodedDataInterpretedAsCode.qhelp b/ruby/ql/src/queries/security/cwe-506/HardcodedDataInterpretedAsCode.qhelp new file mode 100644 index 00000000000..236cadc1742 --- /dev/null +++ b/ruby/ql/src/queries/security/cwe-506/HardcodedDataInterpretedAsCode.qhelp @@ -0,0 +1,47 @@ + + + + +

    +Interpreting hard-coded data (such as string literals containing hexadecimal numbers) +as code or as an import path is typical of malicious backdoor code that has been +implanted into an otherwise trusted code base and is trying to hide its true purpose +from casual readers or automated scanning tools. +

    +
    + + +

    +Examine the code in question carefully to ascertain its provenance and its true purpose. +If the code is benign, it should always be possible to rewrite it without relying +on dynamically interpreting data as code, improving both clarity and safety. +

    +
    + + +

    +As an example of malicious code using this obfuscation technique, consider the +following simplified Ruby version of a snippet of backdoor code that was +discovered in a dependency of the popular JavaScript event-stream +npm package: +

    + +

    +While this shows only the first few lines of code, it already looks very suspicious +since it takes a hard-coded string literal, hex-decodes it and then uses it as an +import path. The only reason to do so is to hide the name of the file being imported. +

    +
    + + +
  • +OWASP: +Trojan Horse. +
  • +
  • +The npm Blog: +Details about the event-stream incident. +
  • +
    + +
    diff --git a/ruby/ql/src/queries/security/cwe-506/HardcodedDataInterpretedAsCode.ql b/ruby/ql/src/queries/security/cwe-506/HardcodedDataInterpretedAsCode.ql new file mode 100644 index 00000000000..ead7dbeda08 --- /dev/null +++ b/ruby/ql/src/queries/security/cwe-506/HardcodedDataInterpretedAsCode.ql @@ -0,0 +1,23 @@ +/** + * @name Hard-coded data interpreted as code + * @description Transforming hard-coded data (such as hexadecimal constants) into code + * to be executed is a technique often associated with backdoors and should + * be avoided. + * @kind path-problem + * @problem.severity error + * @security-severity 9.1 + * @precision medium + * @id rb/hardcoded-data-interpreted-as-code + * @tags security + * external/cwe/cwe-506 + */ + +import codeql.ruby.security.HardcodedDataInterpretedAsCodeQuery +import codeql.ruby.DataFlow +import DataFlow::PathGraph + +from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +where cfg.hasFlowPath(source, sink) +select sink.getNode(), source, sink, + "Hard-coded data from $@ is interpreted as " + sink.getNode().(Sink).getKind() + ".", + source.getNode(), "here" diff --git a/ruby/ql/src/queries/security/cwe-506/examples/HardcodedDataInterpretedAsCode.rb b/ruby/ql/src/queries/security/cwe-506/examples/HardcodedDataInterpretedAsCode.rb new file mode 100644 index 00000000000..96f82a6ff1f --- /dev/null +++ b/ruby/ql/src/queries/security/cwe-506/examples/HardcodedDataInterpretedAsCode.rb @@ -0,0 +1,6 @@ +def e(r) + [r].pack 'H*' +end + +# BAD: hexadecimal constant decoded and interpreted as import path +require e("2e2f746573742f64617461") diff --git a/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected new file mode 100644 index 00000000000..8bf092c3d04 --- /dev/null +++ b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected @@ -0,0 +1,23 @@ +edges +| tst.rb:1:7:1:7 | r : | tst.rb:2:4:2:4 | r : | +| tst.rb:2:4:2:4 | r : | tst.rb:2:3:2:15 | call to pack : | +| tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." : | tst.rb:7:8:7:30 | totally_harmless_string : | +| tst.rb:7:8:7:30 | totally_harmless_string : | tst.rb:1:7:1:7 | r : | +| tst.rb:7:8:7:30 | totally_harmless_string : | tst.rb:7:6:7:31 | call to e | +| tst.rb:10:11:10:24 | "666f6f626172" : | tst.rb:1:7:1:7 | r : | +| tst.rb:10:11:10:24 | "666f6f626172" : | tst.rb:10:9:10:25 | call to e | +nodes +| tst.rb:1:7:1:7 | r : | semmle.label | r : | +| tst.rb:2:3:2:15 | call to pack : | semmle.label | call to pack : | +| tst.rb:2:4:2:4 | r : | semmle.label | r : | +| tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." : | semmle.label | "707574732822636f646520696e6a6..." : | +| tst.rb:7:6:7:31 | call to e | semmle.label | call to e | +| tst.rb:7:8:7:30 | totally_harmless_string : | semmle.label | totally_harmless_string : | +| tst.rb:10:9:10:25 | call to e | semmle.label | call to e | +| tst.rb:10:11:10:24 | "666f6f626172" : | semmle.label | "666f6f626172" : | +subpaths +| tst.rb:7:8:7:30 | totally_harmless_string : | tst.rb:1:7:1:7 | r : | tst.rb:2:3:2:15 | call to pack : | tst.rb:7:6:7:31 | call to e | +| tst.rb:10:11:10:24 | "666f6f626172" : | tst.rb:1:7:1:7 | r : | tst.rb:2:3:2:15 | call to pack : | tst.rb:10:9:10:25 | call to e | +#select +| tst.rb:7:6:7:31 | call to e | tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." : | tst.rb:7:6:7:31 | call to e | Hard-coded data from $@ is interpreted as code. | tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." | here | +| tst.rb:10:9:10:25 | call to e | tst.rb:10:11:10:24 | "666f6f626172" : | tst.rb:10:9:10:25 | call to e | Hard-coded data from $@ is interpreted as an import path. | tst.rb:10:11:10:24 | "666f6f626172" | here | diff --git a/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.qlref b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.qlref new file mode 100644 index 00000000000..afa4fec282c --- /dev/null +++ b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.qlref @@ -0,0 +1 @@ +queries/security/cwe-506/HardcodedDataInterpretedAsCode.ql diff --git a/ruby/ql/test/query-tests/security/cwe-506/tst.rb b/ruby/ql/test/query-tests/security/cwe-506/tst.rb new file mode 100644 index 00000000000..73c86b4bd45 --- /dev/null +++ b/ruby/ql/test/query-tests/security/cwe-506/tst.rb @@ -0,0 +1,14 @@ +def e(r) + [r].pack 'H*' +end + +totally_harmless_string = '707574732822636f646520696e6a656374696f6e2229' + +eval(e(totally_harmless_string)) # NOT OK: eval("puts('hello'") +eval(totally_harmless_string) # OK: throws parse error + +require e('666f6f626172') # NOT OK: require 'foobar' +require '666f6f626172' # OK: no taint step between source and sink + +x = 'deadbeef' +require e(x) # OK: doesn't meet our criteria for being a source \ No newline at end of file From 1ce31ec32cc8086abd192bf429cfc35e986e20d5 Mon Sep 17 00:00:00 2001 From: luchua-bc Date: Tue, 26 Jul 2022 23:05:25 +0000 Subject: [PATCH 005/659] Add sinks of servlet dispatcher and filter --- .../CWE/CWE-625/PermissiveDotRegex.ql | 24 +++++- .../security/CWE-625/DotRegexFilter.java | 70 +++++++++++++++++ .../security/CWE-625/DotRegexServlet.java | 43 +++++++++++ .../CWE-625/PermissiveDotRegex.expected | 75 ++++++++++++------- 4 files changed, 184 insertions(+), 28 deletions(-) create mode 100644 java/ql/test/experimental/query-tests/security/CWE-625/DotRegexFilter.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql index 3048c1e4198..d5b59dd7638 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql @@ -33,6 +33,24 @@ private class GetServletUriSource extends SourceModelCsv { } } +/** Sink model of servlet dispatcher. */ +private class UrlDispatchSink extends SinkModelCsv { + override predicate row(string row) { + row = + [ + "javax.servlet;RequestDispatcher;false;forward;;;Argument[-1];url-dispatch;manual", + "javax.servlet;RequestDispatcher;false;include;;;Argument[-1];url-dispatch;manual" + ] + } +} + +/** Sink model of servlet filter. */ +private class UrlFilterSink extends SinkModelCsv { + override predicate row(string row) { + row = ["javax.servlet;FilterChain;true;doFilter;;;Argument[-1];url-filter;manual"] + } +} + /** * `.` without a `\` prefix, which is likely not a character literal in regex */ @@ -119,7 +137,11 @@ class MatchRegexConfiguration extends TaintTracking::Configuration { DataFlow::localExprFlow(ce, guard.(MethodAccess).getQualifier()) or DataFlow::localExprFlow(ce, guard.(MethodAccess).getAnArgument()) ) and - DataFlow::exprNode(se) instanceof UrlRedirectSink and + ( + DataFlow::exprNode(se) instanceof UrlRedirectSink or + sinkNode(DataFlow::exprNode(se), "url-dispatch") or + sinkNode(DataFlow::exprNode(se), "url-filter") + ) and guard.controls(se.getBasicBlock(), true) ) } diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexFilter.java b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexFilter.java new file mode 100644 index 00000000000..6ce97453d8f --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexFilter.java @@ -0,0 +1,70 @@ +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class DotRegexFilter implements Filter { + private static final String PROTECTED_PATTERN = "/protected/.*"; + private static final String CONSTRAINT_PATTERN = "/protected/xyz\\.xml"; + + private ServletContext context; + + public void init(FilterConfig config) throws ServletException { + this.context = config.getServletContext(); + } + + // BAD: A string with line return e.g. `/protected/%0dxyz` can bypass the path check + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + String source = httpRequest.getPathInfo(); + + Pattern p = Pattern.compile(PROTECTED_PATTERN); + Matcher m = p.matcher(source); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + if (!httpRequest.getSession().getAttribute("secAttr").equals("secValue")) { + // Redirect to the login page + httpResponse.sendRedirect("/login.html"); + } else { + // Not protected page - pass the request along the filter chain + chain.doFilter(request, response); + } + } + } + + // GOOD: A string with line return e.g. `/protected/%0dxyz` cannot bypass the path check + public void doFilter2(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + String source = httpRequest.getPathInfo(); + + Pattern p = Pattern.compile(CONSTRAINT_PATTERN); + Matcher m = p.matcher(source); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + if (!httpRequest.getSession().getAttribute("secAttr").equals("secValue")) { + // Redirect to the login page + httpResponse.sendRedirect("/login.html"); + } else { + // Not protected page - pass the request along the filter chain + chain.doFilter(request, response); + } + } + } + + public void destroy() { + // Close resources + } +} \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java index 4db8d45bc18..47d3175afcf 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java +++ b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexServlet.java @@ -5,6 +5,7 @@ import java.util.regex.Pattern; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; public class DotRegexServlet extends HttpServlet { @@ -104,4 +105,46 @@ public class DotRegexServlet extends HttpServlet { } } } + + // BAD: A string with line return e.g. `/protected/%0dxyz` can bypass the path check + protected void doGet6(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String source = request.getPathInfo(); + + Pattern p = Pattern.compile(PROTECTED_PATTERN); + Matcher m = p.matcher(source); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + if (!request.getSession().getAttribute("secAttr").equals("secValue")) { + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/login"); + dispatcher.forward(request, response); + } else { + // Not protected page - render content + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(source); + dispatcher.forward(request, response); + } + } + } + + // GOOD: A string with line return e.g. `/protected/%0dxyz` cannot bypass the path check + protected void doGet7(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String source = request.getPathInfo(); + + Pattern p = Pattern.compile(PROTECTED_PATTERN, Pattern.DOTALL); + Matcher m = p.matcher(source); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + if (!request.getSession().getAttribute("secAttr").equals("secValue")) { + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/login"); + dispatcher.forward(request, response); + } else { + // Not protected page - render content + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(source); + dispatcher.include(request, response); + } + } + } } diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected index 5449a1d96b9..3d7844219b1 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected @@ -1,31 +1,52 @@ edges -| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:20:31:20:47 | PROTECTED_PATTERN | -| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:58:36:58:52 | PROTECTED_PATTERN | -| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:76:37:76:53 | PROTECTED_PATTERN | -| DotRegexServlet.java:11:50:11:64 | "/protected/.*" : String | DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | -| DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | DotRegexServlet.java:21:25:21:30 | source | -| DotRegexServlet.java:37:19:37:39 | getPathInfo(...) : String | DotRegexServlet.java:40:25:40:30 | source | -| DotRegexServlet.java:56:19:56:41 | getRequestURI(...) : String | DotRegexServlet.java:58:21:58:26 | source | -| DotRegexServlet.java:74:19:74:39 | getPathInfo(...) : String | DotRegexServlet.java:76:56:76:61 | source | -| DotRegexServlet.java:92:19:92:39 | getPathInfo(...) : String | DotRegexServlet.java:95:25:95:30 | source | +| DotRegexFilter.java:16:30:16:46 | PROTECTED_PATTERN : String | DotRegexFilter.java:31:31:31:47 | PROTECTED_PATTERN | +| DotRegexFilter.java:16:50:16:64 | "/protected/.*" : String | DotRegexFilter.java:16:30:16:46 | PROTECTED_PATTERN : String | +| DotRegexFilter.java:29:19:29:43 | getPathInfo(...) : String | DotRegexFilter.java:32:25:32:30 | source | +| DotRegexFilter.java:50:19:50:43 | getPathInfo(...) : String | DotRegexFilter.java:53:25:53:30 | source | +| DotRegexServlet.java:12:30:12:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:21:31:21:47 | PROTECTED_PATTERN | +| DotRegexServlet.java:12:30:12:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:59:36:59:52 | PROTECTED_PATTERN | +| DotRegexServlet.java:12:30:12:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:77:37:77:53 | PROTECTED_PATTERN | +| DotRegexServlet.java:12:30:12:46 | PROTECTED_PATTERN : String | DotRegexServlet.java:114:31:114:47 | PROTECTED_PATTERN | +| DotRegexServlet.java:12:50:12:64 | "/protected/.*" : String | DotRegexServlet.java:12:30:12:46 | PROTECTED_PATTERN : String | +| DotRegexServlet.java:19:19:19:39 | getPathInfo(...) : String | DotRegexServlet.java:22:25:22:30 | source | +| DotRegexServlet.java:38:19:38:39 | getPathInfo(...) : String | DotRegexServlet.java:41:25:41:30 | source | +| DotRegexServlet.java:57:19:57:41 | getRequestURI(...) : String | DotRegexServlet.java:59:21:59:26 | source | +| DotRegexServlet.java:75:19:75:39 | getPathInfo(...) : String | DotRegexServlet.java:77:56:77:61 | source | +| DotRegexServlet.java:93:19:93:39 | getPathInfo(...) : String | DotRegexServlet.java:96:25:96:30 | source | +| DotRegexServlet.java:112:19:112:39 | getPathInfo(...) : String | DotRegexServlet.java:115:25:115:30 | source | +| DotRegexServlet.java:133:19:133:39 | getPathInfo(...) : String | DotRegexServlet.java:136:25:136:30 | source | nodes -| DotRegexServlet.java:11:30:11:46 | PROTECTED_PATTERN : String | semmle.label | PROTECTED_PATTERN : String | -| DotRegexServlet.java:11:50:11:64 | "/protected/.*" : String | semmle.label | "/protected/.*" : String | -| DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | -| DotRegexServlet.java:20:31:20:47 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | -| DotRegexServlet.java:21:25:21:30 | source | semmle.label | source | -| DotRegexServlet.java:37:19:37:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | -| DotRegexServlet.java:40:25:40:30 | source | semmle.label | source | -| DotRegexServlet.java:56:19:56:41 | getRequestURI(...) : String | semmle.label | getRequestURI(...) : String | -| DotRegexServlet.java:58:21:58:26 | source | semmle.label | source | -| DotRegexServlet.java:58:36:58:52 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | -| DotRegexServlet.java:74:19:74:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | -| DotRegexServlet.java:76:37:76:53 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | -| DotRegexServlet.java:76:56:76:61 | source | semmle.label | source | -| DotRegexServlet.java:92:19:92:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | -| DotRegexServlet.java:95:25:95:30 | source | semmle.label | source | +| DotRegexFilter.java:16:30:16:46 | PROTECTED_PATTERN : String | semmle.label | PROTECTED_PATTERN : String | +| DotRegexFilter.java:16:50:16:64 | "/protected/.*" : String | semmle.label | "/protected/.*" : String | +| DotRegexFilter.java:29:19:29:43 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexFilter.java:31:31:31:47 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexFilter.java:32:25:32:30 | source | semmle.label | source | +| DotRegexFilter.java:50:19:50:43 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexFilter.java:53:25:53:30 | source | semmle.label | source | +| DotRegexServlet.java:12:30:12:46 | PROTECTED_PATTERN : String | semmle.label | PROTECTED_PATTERN : String | +| DotRegexServlet.java:12:50:12:64 | "/protected/.*" : String | semmle.label | "/protected/.*" : String | +| DotRegexServlet.java:19:19:19:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:21:31:21:47 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:22:25:22:30 | source | semmle.label | source | +| DotRegexServlet.java:38:19:38:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:41:25:41:30 | source | semmle.label | source | +| DotRegexServlet.java:57:19:57:41 | getRequestURI(...) : String | semmle.label | getRequestURI(...) : String | +| DotRegexServlet.java:59:21:59:26 | source | semmle.label | source | +| DotRegexServlet.java:59:36:59:52 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:75:19:75:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:77:37:77:53 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:77:56:77:61 | source | semmle.label | source | +| DotRegexServlet.java:93:19:93:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:96:25:96:30 | source | semmle.label | source | +| DotRegexServlet.java:112:19:112:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:114:31:114:47 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexServlet.java:115:25:115:30 | source | semmle.label | source | +| DotRegexServlet.java:133:19:133:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | +| DotRegexServlet.java:136:25:136:30 | source | semmle.label | source | subpaths #select -| DotRegexServlet.java:21:25:21:30 | source | DotRegexServlet.java:18:19:18:39 | getPathInfo(...) : String | DotRegexServlet.java:21:25:21:30 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:18:19:18:39 | getPathInfo(...) | user-provided value | -| DotRegexServlet.java:58:21:58:26 | source | DotRegexServlet.java:56:19:56:41 | getRequestURI(...) : String | DotRegexServlet.java:58:21:58:26 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:56:19:56:41 | getRequestURI(...) | user-provided value | -| DotRegexServlet.java:76:56:76:61 | source | DotRegexServlet.java:74:19:74:39 | getPathInfo(...) : String | DotRegexServlet.java:76:56:76:61 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:74:19:74:39 | getPathInfo(...) | user-provided value | +| DotRegexFilter.java:32:25:32:30 | source | DotRegexFilter.java:29:19:29:43 | getPathInfo(...) : String | DotRegexFilter.java:32:25:32:30 | source | Potentially authentication bypass due to $@. | DotRegexFilter.java:29:19:29:43 | getPathInfo(...) | user-provided value | +| DotRegexServlet.java:22:25:22:30 | source | DotRegexServlet.java:19:19:19:39 | getPathInfo(...) : String | DotRegexServlet.java:22:25:22:30 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:19:19:19:39 | getPathInfo(...) | user-provided value | +| DotRegexServlet.java:59:21:59:26 | source | DotRegexServlet.java:57:19:57:41 | getRequestURI(...) : String | DotRegexServlet.java:59:21:59:26 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:57:19:57:41 | getRequestURI(...) | user-provided value | +| DotRegexServlet.java:77:56:77:61 | source | DotRegexServlet.java:75:19:75:39 | getPathInfo(...) : String | DotRegexServlet.java:77:56:77:61 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:75:19:75:39 | getPathInfo(...) | user-provided value | +| DotRegexServlet.java:115:25:115:30 | source | DotRegexServlet.java:112:19:112:39 | getPathInfo(...) : String | DotRegexServlet.java:115:25:115:30 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:112:19:112:39 | getPathInfo(...) | user-provided value | From b69eba923831d895971915fe34f9fdbac8ca1783 Mon Sep 17 00:00:00 2001 From: luchua-bc Date: Fri, 29 Jul 2022 01:59:47 +0000 Subject: [PATCH 006/659] Add check for Spring redirect --- .../CWE/CWE-625/PermissiveDotRegex.ql | 33 +++++- .../CWE/CWE-625/SpringUrlRedirect.qll | 109 ++++++++++++++++++ .../security/CWE-625/DotRegexSpring.java | 75 ++++++++++++ .../CWE-625/PermissiveDotRegex.expected | 45 ++++++++ .../query-tests/security/CWE-625/options | 2 +- 5 files changed, 261 insertions(+), 3 deletions(-) create mode 100644 java/ql/src/experimental/Security/CWE/CWE-625/SpringUrlRedirect.qll create mode 100644 java/ql/test/experimental/query-tests/security/CWE-625/DotRegexSpring.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql index d5b59dd7638..693cc77a562 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql @@ -18,6 +18,7 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.UrlRedirect import DataFlow::PathGraph import Regex +import SpringUrlRedirect /** Source model of remote flow source with servlets. */ private class GetServletUriSource extends SourceModelCsv { @@ -51,6 +52,30 @@ private class UrlFilterSink extends SinkModelCsv { } } +/** A Spring framework annotation indicating remote uri user input. */ +class SpringUriInputAnnotation extends Annotation { + SpringUriInputAnnotation() { + exists(AnnotationType a | + a = this.getType() and + a.getPackage().getName() = "org.springframework.web.bind.annotation" + | + ( + a.hasName("PathVariable") or + a.hasName("RequestParam") + ) + ) + } +} + +class SpringUriInputParameterSource extends DataFlow::Node { + SpringUriInputParameterSource() { + this.asParameter() = + any(SpringRequestMappingParameter srmp | + srmp.getAnAnnotation() instanceof SpringUriInputAnnotation + ) + } +} + /** * `.` without a `\` prefix, which is likely not a character literal in regex */ @@ -121,7 +146,10 @@ class PermissiveDotRegexConfig extends DataFlow::Configuration { class MatchRegexConfiguration extends TaintTracking::Configuration { MatchRegexConfiguration() { this = "PermissiveDotRegex::MatchRegexConfiguration" } - override predicate isSource(DataFlow::Node source) { sourceNode(source, "uri-path") } + override predicate isSource(DataFlow::Node source) { + sourceNode(source, "uri-path") or // Servlet uri source + source instanceof SpringUriInputParameterSource // Spring uri source + } override predicate isSink(DataFlow::Node sink) { sink instanceof MatchRegexSink and @@ -140,7 +168,8 @@ class MatchRegexConfiguration extends TaintTracking::Configuration { ( DataFlow::exprNode(se) instanceof UrlRedirectSink or sinkNode(DataFlow::exprNode(se), "url-dispatch") or - sinkNode(DataFlow::exprNode(se), "url-filter") + sinkNode(DataFlow::exprNode(se), "url-filter") or + DataFlow::exprNode(se) instanceof SpringUrlRedirectSink ) and guard.controls(se.getBasicBlock(), true) ) diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/SpringUrlRedirect.qll b/java/ql/src/experimental/Security/CWE/CWE-625/SpringUrlRedirect.qll new file mode 100644 index 00000000000..113afcded5b --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-625/SpringUrlRedirect.qll @@ -0,0 +1,109 @@ +/** Provides methods related to Spring URL redirect from /src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll. */ + +private import java +private import semmle.code.java.dataflow.FlowSources + +/** + * A concatenate expression using the string `redirect:` or `ajaxredirect:` or `forward:` on the left. + * + * E.g: `"redirect:" + redirectUrl` + */ +class RedirectBuilderExpr extends AddExpr { + RedirectBuilderExpr() { + this.getLeftOperand().(CompileTimeConstantExpr).getStringValue() in [ + "redirect:", "ajaxredirect:", "forward:" + ] + } +} + +/** + * A call to `StringBuilder.append` or `StringBuffer.append` method, and the parameter value is + * `"redirect:"` or `"ajaxredirect:"` or `"forward:"`. + * + * E.g: `StringBuilder.append("redirect:")` + */ +class RedirectAppendCall extends MethodAccess { + RedirectAppendCall() { + this.getMethod().hasName("append") and + this.getMethod().getDeclaringType() instanceof StringBuildingType and + this.getArgument(0).(CompileTimeConstantExpr).getStringValue() in [ + "redirect:", "ajaxredirect:", "forward:" + ] + } +} + +/** A URL redirection sink from spring controller method. */ +abstract class SpringUrlRedirectSink extends DataFlow::Node { } + +/** + * A sink for URL Redirection via the Spring View classes. + */ +private class SpringViewUrlRedirectSink extends SpringUrlRedirectSink { + SpringViewUrlRedirectSink() { + // Hardcoded redirect such as "redirect:login" + this.asExpr() + .(CompileTimeConstantExpr) + .getStringValue() + .indexOf(["redirect:", "ajaxredirect:", "forward:"]) = 0 and + any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) + or + exists(RedirectBuilderExpr rbe | + rbe.getRightOperand() = this.asExpr() and + any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) + ) + or + exists(MethodAccess ma, RedirectAppendCall rac | + DataFlow2::localExprFlow(rac.getQualifier(), ma.getQualifier()) and + ma.getMethod().hasName("append") and + ma.getArgument(0) = this.asExpr() and + any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) + ) + or + exists(MethodAccess ma | + ma.getMethod().hasName("setUrl") and + ma.getMethod() + .getDeclaringType() + .hasQualifiedName("org.springframework.web.servlet.view", "AbstractUrlBasedView") and + ma.getArgument(0) = this.asExpr() + ) + or + exists(ClassInstanceExpr cie | + cie.getConstructedType() + .hasQualifiedName("org.springframework.web.servlet.view", "RedirectView") and + cie.getArgument(0) = this.asExpr() + ) + or + exists(ClassInstanceExpr cie | + cie.getConstructedType().hasQualifiedName("org.springframework.web.servlet", "ModelAndView") and + exists(RedirectBuilderExpr rbe | + rbe = cie.getArgument(0) and rbe.getRightOperand() = this.asExpr() + ) + ) + } +} + +/** + * A sink for URL Redirection via the `ResponseEntity` class. + */ +private class SpringResponseEntityUrlRedirectSink extends SpringUrlRedirectSink { + SpringResponseEntityUrlRedirectSink() { + // Find `new ResponseEntity(httpHeaders, ...)` or + // `new ResponseEntity(..., httpHeaders, ...)` sinks + exists(ClassInstanceExpr cie, Argument argument | + cie.getConstructedType() instanceof SpringResponseEntity and + argument.getType() instanceof SpringHttpHeaders and + argument = cie.getArgument([0, 1]) and + this.asExpr() = argument + ) + or + // Find `ResponseEntity.status(...).headers(taintHeaders).build()` or + // `ResponseEntity.status(...).location(URI.create(taintURL)).build()` sinks + exists(MethodAccess ma | + ma.getMethod() + .getDeclaringType() + .hasQualifiedName("org.springframework.http", "ResponseEntity$HeadersBuilder") and + ma.getMethod().getName() in ["headers", "location"] and + this.asExpr() = ma.getArgument(0) + ) + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexSpring.java b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexSpring.java new file mode 100644 index 00000000000..4651508fe19 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-625/DotRegexSpring.java @@ -0,0 +1,75 @@ +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.view.RedirectView; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Controller +public class DotRegexSpring { + private static final String PROTECTED_PATTERN = "/protected/.*"; + private static final String CONSTRAINT_PATTERN = "/protected/xyz\\.xml"; + + @GetMapping("param") + // BAD: A string with line return e.g. `/protected/%0dxyz` can bypass the path check + public String withParam(@RequestParam String path, Model model) throws UnsupportedEncodingException { + Pattern p = Pattern.compile(PROTECTED_PATTERN); + path = decodePath(path); + Matcher m = p.matcher(path); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + if (model.getAttribute("secAttr") == null || !model.getAttribute("secAttr").equals("secValue")) { + return "redirect:login"; + } + } + // Not protected page - render content + return path; + } + + @GetMapping("{path}") + // BAD: A string with line return e.g. `%252Fprotected%252F%250dxyz` can bypass the path check + public RedirectView withPathVariable1(@PathVariable String path, Model model) throws UnsupportedEncodingException { + Pattern p = Pattern.compile(PROTECTED_PATTERN); + path = decodePath(path); + Matcher m = p.matcher(path); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + if (model.getAttribute("secAttr") == null || !model.getAttribute("secAttr").equals("secValue")) { + RedirectView redirectView = new RedirectView("login", true); + return redirectView; + } + } + return null; + } + + @GetMapping("/sp/{path}") + // GOOD: A string with line return e.g. `%252Fprotected%252F%250dxyz` cannot bypass the path check + public String withPathVariable2(@PathVariable String path, Model model) throws UnsupportedEncodingException { + Pattern p = Pattern.compile(CONSTRAINT_PATTERN); + path = decodePath(path); + Matcher m = p.matcher(path); + + if (m.matches()) { + // Protected page - check access token and redirect to login page + if (model.getAttribute("secAttr") == null || !model.getAttribute("secAttr").equals("secValue")) { + return "redirect:login"; + } + } + // Not protected page - render content + return path; + } + + private String decodePath(String path) throws UnsupportedEncodingException { + while (path.indexOf("%") > -1) { + path = URLDecoder.decode(path, "UTF-8"); + } + return path; + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected index 3d7844219b1..48d8bfb72b8 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected @@ -15,6 +15,26 @@ edges | DotRegexServlet.java:93:19:93:39 | getPathInfo(...) : String | DotRegexServlet.java:96:25:96:30 | source | | DotRegexServlet.java:112:19:112:39 | getPathInfo(...) : String | DotRegexServlet.java:115:25:115:30 | source | | DotRegexServlet.java:133:19:133:39 | getPathInfo(...) : String | DotRegexServlet.java:136:25:136:30 | source | +| DotRegexSpring.java:15:30:15:46 | PROTECTED_PATTERN : String | DotRegexSpring.java:21:31:21:47 | PROTECTED_PATTERN | +| DotRegexSpring.java:15:30:15:46 | PROTECTED_PATTERN : String | DotRegexSpring.java:38:31:38:47 | PROTECTED_PATTERN | +| DotRegexSpring.java:15:50:15:64 | "/protected/.*" : String | DotRegexSpring.java:15:30:15:46 | PROTECTED_PATTERN : String | +| DotRegexSpring.java:20:26:20:50 | path : String | DotRegexSpring.java:22:21:22:24 | path : String | +| DotRegexSpring.java:22:10:22:25 | decodePath(...) : String | DotRegexSpring.java:23:25:23:28 | path | +| DotRegexSpring.java:22:21:22:24 | path : String | DotRegexSpring.java:22:10:22:25 | decodePath(...) : String | +| DotRegexSpring.java:22:21:22:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | +| DotRegexSpring.java:37:40:37:64 | path : String | DotRegexSpring.java:39:21:39:24 | path : String | +| DotRegexSpring.java:39:10:39:25 | decodePath(...) : String | DotRegexSpring.java:40:25:40:28 | path | +| DotRegexSpring.java:39:21:39:24 | path : String | DotRegexSpring.java:39:10:39:25 | decodePath(...) : String | +| DotRegexSpring.java:39:21:39:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | +| DotRegexSpring.java:54:34:54:58 | path : String | DotRegexSpring.java:56:21:56:24 | path : String | +| DotRegexSpring.java:56:10:56:25 | decodePath(...) : String | DotRegexSpring.java:57:25:57:28 | path | +| DotRegexSpring.java:56:21:56:24 | path : String | DotRegexSpring.java:56:10:56:25 | decodePath(...) : String | +| DotRegexSpring.java:56:21:56:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | +| DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:71:29:71:32 | path : String | +| DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:73:10:73:13 | path : String | +| DotRegexSpring.java:71:11:71:42 | decode(...) : String | DotRegexSpring.java:71:29:71:32 | path : String | +| DotRegexSpring.java:71:11:71:42 | decode(...) : String | DotRegexSpring.java:73:10:73:13 | path : String | +| DotRegexSpring.java:71:29:71:32 | path : String | DotRegexSpring.java:71:11:71:42 | decode(...) : String | nodes | DotRegexFilter.java:16:30:16:46 | PROTECTED_PATTERN : String | semmle.label | PROTECTED_PATTERN : String | | DotRegexFilter.java:16:50:16:64 | "/protected/.*" : String | semmle.label | "/protected/.*" : String | @@ -43,10 +63,35 @@ nodes | DotRegexServlet.java:115:25:115:30 | source | semmle.label | source | | DotRegexServlet.java:133:19:133:39 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String | | DotRegexServlet.java:136:25:136:30 | source | semmle.label | source | +| DotRegexSpring.java:15:30:15:46 | PROTECTED_PATTERN : String | semmle.label | PROTECTED_PATTERN : String | +| DotRegexSpring.java:15:50:15:64 | "/protected/.*" : String | semmle.label | "/protected/.*" : String | +| DotRegexSpring.java:20:26:20:50 | path : String | semmle.label | path : String | +| DotRegexSpring.java:21:31:21:47 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexSpring.java:22:10:22:25 | decodePath(...) : String | semmle.label | decodePath(...) : String | +| DotRegexSpring.java:22:21:22:24 | path : String | semmle.label | path : String | +| DotRegexSpring.java:23:25:23:28 | path | semmle.label | path | +| DotRegexSpring.java:37:40:37:64 | path : String | semmle.label | path : String | +| DotRegexSpring.java:38:31:38:47 | PROTECTED_PATTERN | semmle.label | PROTECTED_PATTERN | +| DotRegexSpring.java:39:10:39:25 | decodePath(...) : String | semmle.label | decodePath(...) : String | +| DotRegexSpring.java:39:21:39:24 | path : String | semmle.label | path : String | +| DotRegexSpring.java:40:25:40:28 | path | semmle.label | path | +| DotRegexSpring.java:54:34:54:58 | path : String | semmle.label | path : String | +| DotRegexSpring.java:56:10:56:25 | decodePath(...) : String | semmle.label | decodePath(...) : String | +| DotRegexSpring.java:56:21:56:24 | path : String | semmle.label | path : String | +| DotRegexSpring.java:57:25:57:28 | path | semmle.label | path | +| DotRegexSpring.java:69:28:69:38 | path : String | semmle.label | path : String | +| DotRegexSpring.java:71:11:71:42 | decode(...) : String | semmle.label | decode(...) : String | +| DotRegexSpring.java:71:29:71:32 | path : String | semmle.label | path : String | +| DotRegexSpring.java:73:10:73:13 | path : String | semmle.label | path : String | subpaths +| DotRegexSpring.java:22:21:22:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:73:10:73:13 | path : String | DotRegexSpring.java:22:10:22:25 | decodePath(...) : String | +| DotRegexSpring.java:39:21:39:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:73:10:73:13 | path : String | DotRegexSpring.java:39:10:39:25 | decodePath(...) : String | +| DotRegexSpring.java:56:21:56:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:73:10:73:13 | path : String | DotRegexSpring.java:56:10:56:25 | decodePath(...) : String | #select | DotRegexFilter.java:32:25:32:30 | source | DotRegexFilter.java:29:19:29:43 | getPathInfo(...) : String | DotRegexFilter.java:32:25:32:30 | source | Potentially authentication bypass due to $@. | DotRegexFilter.java:29:19:29:43 | getPathInfo(...) | user-provided value | | DotRegexServlet.java:22:25:22:30 | source | DotRegexServlet.java:19:19:19:39 | getPathInfo(...) : String | DotRegexServlet.java:22:25:22:30 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:19:19:19:39 | getPathInfo(...) | user-provided value | | DotRegexServlet.java:59:21:59:26 | source | DotRegexServlet.java:57:19:57:41 | getRequestURI(...) : String | DotRegexServlet.java:59:21:59:26 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:57:19:57:41 | getRequestURI(...) | user-provided value | | DotRegexServlet.java:77:56:77:61 | source | DotRegexServlet.java:75:19:75:39 | getPathInfo(...) : String | DotRegexServlet.java:77:56:77:61 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:75:19:75:39 | getPathInfo(...) | user-provided value | | DotRegexServlet.java:115:25:115:30 | source | DotRegexServlet.java:112:19:112:39 | getPathInfo(...) : String | DotRegexServlet.java:115:25:115:30 | source | Potentially authentication bypass due to $@. | DotRegexServlet.java:112:19:112:39 | getPathInfo(...) | user-provided value | +| DotRegexSpring.java:23:25:23:28 | path | DotRegexSpring.java:20:26:20:50 | path : String | DotRegexSpring.java:23:25:23:28 | path | Potentially authentication bypass due to $@. | DotRegexSpring.java:20:26:20:50 | path | user-provided value | +| DotRegexSpring.java:40:25:40:28 | path | DotRegexSpring.java:37:40:37:64 | path : String | DotRegexSpring.java:40:25:40:28 | path | Potentially authentication bypass due to $@. | DotRegexSpring.java:37:40:37:64 | path | user-provided value | diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/options b/java/ql/test/experimental/query-tests/security/CWE-625/options index 79df30ff8e9..5f11b982510 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-625/options +++ b/java/ql/test/experimental/query-tests/security/CWE-625/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.3.8 From 231178d858e08a26d6e690114f03aaaad058b749 Mon Sep 17 00:00:00 2001 From: Aditya Sharad Date: Wed, 10 Aug 2022 10:49:17 -0700 Subject: [PATCH 007/659] Docs: Add CodeQL standard packs and bundle to CodeQL tools page Include links to changelogs, releases, and source code. --- docs/codeql/codeql-overview/codeql-tools.rst | 34 ++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-overview/codeql-tools.rst b/docs/codeql/codeql-overview/codeql-tools.rst index c51a5286cb0..988ed5d4f0a 100644 --- a/docs/codeql/codeql-overview/codeql-tools.rst +++ b/docs/codeql/codeql-overview/codeql-tools.rst @@ -13,9 +13,39 @@ CodeQL command-line interface The CodeQL command-line interface (CLI) is primarily used to create databases for security research. You can also query CodeQL databases directly from the command line -or using the Visual Studio Code extension. For more information, see -":ref:`CodeQL CLI `." +or using the Visual Studio Code extension. +It can be downloaded from `GitHub releases `__. +For more information, see ":ref:`CodeQL CLI `" and the `CLI changelog `__. +CodeQL packs +----------------------------- + +The standard CodeQL query and library packs +(`source `__) +maintained by GitHub are: +- ``codeql/cpp-queries`` (`changelog `__, `source `__) +- ``codeql/cpp-all`` (`changelog `__, `source `__) +- ``codeql/csharp-queries`` (`changelog `__, `source `__) +- ``codeql/csharp-all`` (`changelog `__, `source `__) +- ``codeql/go-queries`` (`changelog `__, `source `__) +- ``codeql/go-all`` (`changelog `__, `source `__) +- ``codeql/java-queries`` (`changelog `__, `source `__) +- ``codeql/java-all`` (`changelog `__, `source `__) +- ``codeql/javascript-queries`` (`changelog `__, `source `__) +- ``codeql/javascript-all`` (`changelog `__, `source `__) +- ``codeql/python-queries`` (`changelog `__, `source `__) +- ``codeql/python-all`` (`changelog `__, `source `__) +- ``codeql/ruby-queries`` (`changelog `__, `source `__) +- ``codeql/ruby-all`` (`changelog `__, `source `__) + +For more information, see ":ref:`About CodeQL packs `." + +CodeQL bundle +----------------------------- + +The CodeQL bundle consists of the CodeQL CLI together with the standard CodeQL query and library packs +maintained by GitHub. It can be downloaded from `GitHub releases `__. +Use this when running `code scanning with CodeQL `__ on GitHub Actions or in another CI system. CodeQL for Visual Studio Code ----------------------------- From c0da29b2047408c87744d7bd067727ef0ce18f34 Mon Sep 17 00:00:00 2001 From: Aditya Sharad Date: Wed, 10 Aug 2022 11:16:41 -0700 Subject: [PATCH 008/659] Docs: Add spacing to fix list formatting --- docs/codeql/codeql-overview/codeql-tools.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/codeql/codeql-overview/codeql-tools.rst b/docs/codeql/codeql-overview/codeql-tools.rst index 988ed5d4f0a..e7ff532eb45 100644 --- a/docs/codeql/codeql-overview/codeql-tools.rst +++ b/docs/codeql/codeql-overview/codeql-tools.rst @@ -23,6 +23,7 @@ CodeQL packs The standard CodeQL query and library packs (`source `__) maintained by GitHub are: + - ``codeql/cpp-queries`` (`changelog `__, `source `__) - ``codeql/cpp-all`` (`changelog `__, `source `__) - ``codeql/csharp-queries`` (`changelog `__, `source `__) From 94c43c07c72d65c8d8c8084c214061e6d9b164b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= Date: Thu, 11 Aug 2022 12:18:37 +0200 Subject: [PATCH 009/659] Update .gitignore for .vscode/*.log temporaries These keep getting added, by the Makefile extension I believe. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 7b8532b00d2..cfea60b51a1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ .vs/* !.vs/VSWorkspaceSettings.json +# VSCode temporaries +.vscode/*.log + # Byte-compiled python files *.pyc From 76ef779f60b01bf0efe6289c31ea6a89c682cf7e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 28 Jul 2022 13:23:02 +0100 Subject: [PATCH 010/659] C++: Add test and placeholder query. --- cpp/ql/src/Critical/MissingCheckScanf.ql | 14 ++ .../MissingCheckScanf.expected | 0 .../MissingCheckScanf/MissingCheckScanf.qlref | 1 + .../Critical/MissingCheckScanf/test.cpp | 195 ++++++++++++++++++ 4 files changed, 210 insertions(+) create mode 100644 cpp/ql/src/Critical/MissingCheckScanf.ql create mode 100644 cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected create mode 100644 cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.qlref create mode 100644 cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp diff --git a/cpp/ql/src/Critical/MissingCheckScanf.ql b/cpp/ql/src/Critical/MissingCheckScanf.ql new file mode 100644 index 00000000000..3ad7f2b99c0 --- /dev/null +++ b/cpp/ql/src/Critical/MissingCheckScanf.ql @@ -0,0 +1,14 @@ +/** + * @name TODO + * @description TODO + * @kind problem + * @problem.severity TODO + * @security-severity TODO + * @precision TODO + * @id cpp/missing-check-scanf + * @tags TODO + */ + +import cpp + +select "TODO" diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.qlref b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.qlref new file mode 100644 index 00000000000..97e85b5abbe --- /dev/null +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.qlref @@ -0,0 +1 @@ +Critical/MissingCheckScanf.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp new file mode 100644 index 00000000000..2e4abdab545 --- /dev/null +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp @@ -0,0 +1,195 @@ +typedef struct {} FILE; + +int scanf(const char *format, ...); +int fscanf(FILE *stream, const char *format, ...); +int sscanf(const char *s, const char *format, ...); + +void use(int i); + +void set_by_ref(int &i); +void set_by_ptr(int *i); +bool maybe(); + +FILE *get_a_stream(); +const char *get_a_string(); + +int main() +{ + // --- simple cases --- + + { + int i; + + scanf("%d", &i); // BAD: may not have written `i` + use(i); + } + + { + int i; + + if (scanf("%d", &i) == 1) // GOOD: checks return value + { + use(i); + } + } + + { + int i = 0; + + scanf("%d", &i); // GOOD: we assume the initialization of `i` is a reasonable default + use(i); + } + + // --- different scanf functions --- + + { + int i; + + fscanf(get_a_stream(), "%d", &i); // BAD: may not have written `i` + use(i); + } + + { + int i; + + sscanf(get_a_string(), "%d", &i); // BAD: may not have written `i` + use(i); + } + + // --- different ways of checking --- + + { + int i; + + if (scanf("%d", &i) >= 1) // GOOD + { + use(i); + } + } + + { + int i; + + if (scanf("%d", &i) == 1) // GOOD + { + use(i); + } + } + + { + int i; + + if (scanf("%d", &i) != 0) // GOOD (just barely) + { + use(i); + } + } + + { + int i; + + if (scanf("%d", &i) == 0) // BAD: checks return value incorrectly + { + use(i); + } + } + + { + bool b; + int i; + + b = scanf("%d", &i); // GOOD + + if (b >= 1) + { + use(i); + } + } + + { + int i, j; + + if (scanf("%d %d", &i) >= 2) // GOOD + { + use(i); + use(j); + } + } + + { + int i, j; + + if (scanf("%d %d", &i) >= 1) // BAD: checks return value incorrectly + { + use(i); + use(j); + } + } + + // --- different initialization --- + + { + int i; + i = 0; + + scanf("%d", &i); // GOOD + use(i); + } + + { + int i; + + set_by_ref(i); + scanf("%d", &i); // GOOD: we have to assume `i` was initialized + use(i); + } + + { + int i; + + set_by_ptr(&i); + scanf("%d", &i); // GOOD: we have to assume `i` was initialized + use(i); + } + + { + int i; + + if (maybe()) + { + i = 0; + } + + scanf("%d", &i); // BAD: `i` may not have been initialized + use(i); + } + + // --- weird formatting strings --- + + { + int i; + + if (scanf("%n %d", &i) >= 1) // GOOD (`%n` does not consume input) + { + use(i); + } + } + + { + int i; + + if (scanf("%% %d", &i) >= 1) // GOOD (`%%` does not consume input) + { + use(i); + } + } + + { + int i; + + if (scanf("%*d %d", &i) >= 1) // GOOD (`%*d` does not consume input) + { + use(i); + } + } +} From c62ae3b350de68f319f986bc9c1debc689570a13 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 28 Jul 2022 15:37:19 +0100 Subject: [PATCH 011/659] C++: First working. We now prefer flagging the cases where the variable was initialized, as in real world cases we haven't seen it done safely. --- cpp/ql/src/Critical/MissingCheckScanf.ql | 9 +++++-- .../MissingCheckScanf.expected | 9 +++++++ .../Critical/MissingCheckScanf/test.cpp | 24 +++++++++++++------ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/cpp/ql/src/Critical/MissingCheckScanf.ql b/cpp/ql/src/Critical/MissingCheckScanf.ql index 3ad7f2b99c0..80ef5aa596f 100644 --- a/cpp/ql/src/Critical/MissingCheckScanf.ql +++ b/cpp/ql/src/Critical/MissingCheckScanf.ql @@ -2,7 +2,7 @@ * @name TODO * @description TODO * @kind problem - * @problem.severity TODO + * @problem.severity warning * @security-severity TODO * @precision TODO * @id cpp/missing-check-scanf @@ -10,5 +10,10 @@ */ import cpp +import semmle.code.cpp.commons.Scanf -select "TODO" +from ScanfFunction scanf, FunctionCall fc +where + fc.getTarget() = scanf and + fc instanceof ExprInVoidContext +select fc, "This is a call to scanf." diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected index e69de29bb2d..edd1b21a0e0 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected @@ -0,0 +1,9 @@ +| test.cpp:23:3:23:7 | call to scanf | This is a call to scanf. | +| test.cpp:39:3:39:7 | call to scanf | This is a call to scanf. | +| test.cpp:48:3:48:8 | call to fscanf | This is a call to scanf. | +| test.cpp:55:3:55:8 | call to sscanf | This is a call to scanf. | +| test.cpp:135:3:135:7 | call to scanf | This is a call to scanf. | +| test.cpp:143:3:143:7 | call to scanf | This is a call to scanf. | +| test.cpp:151:3:151:7 | call to scanf | This is a call to scanf. | +| test.cpp:163:3:163:7 | call to scanf | This is a call to scanf. | +| test.cpp:173:3:173:7 | call to scanf | This is a call to scanf. | diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp index 2e4abdab545..8d76495b633 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp @@ -36,7 +36,7 @@ int main() { int i = 0; - scanf("%d", &i); // GOOD: we assume the initialization of `i` is a reasonable default + scanf("%d", &i); // BAD use(i); } @@ -79,7 +79,7 @@ int main() { int i; - if (scanf("%d", &i) != 0) // GOOD (just barely) + if (scanf("%d", &i) != 0) // BAD: scanf can return -1 [NOT DETECTED] { use(i); } @@ -88,7 +88,7 @@ int main() { int i; - if (scanf("%d", &i) == 0) // BAD: checks return value incorrectly + if (scanf("%d", &i) == 0) // BAD: checks return value incorrectly [NOT DETECTED] { use(i); } @@ -119,7 +119,7 @@ int main() { int i, j; - if (scanf("%d %d", &i) >= 1) // BAD: checks return value incorrectly + if (scanf("%d %d", &i, &j) >= 1) // BAD: checks return value incorrectly [NOT DETECTED] { use(i); use(j); @@ -132,7 +132,7 @@ int main() int i; i = 0; - scanf("%d", &i); // GOOD + scanf("%d", &i); // BAD use(i); } @@ -140,7 +140,7 @@ int main() int i; set_by_ref(i); - scanf("%d", &i); // GOOD: we have to assume `i` was initialized + scanf("%d", &i); // BAD use(i); } @@ -148,7 +148,7 @@ int main() int i; set_by_ptr(&i); - scanf("%d", &i); // GOOD: we have to assume `i` was initialized + scanf("%d", &i); // BAD use(i); } @@ -164,6 +164,16 @@ int main() use(i); } + // --- different use --- + + { + int i; + int *ptr_i = &i; + + scanf("%d", &i); // BAD: may not have written `i` + use(*ptr_i); + } + // --- weird formatting strings --- { From 4cbfbfe1709009f18a08a813c1cf59b5ca1aae75 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 11 Aug 2022 12:29:50 +0200 Subject: [PATCH 012/659] add call-edge for dynamic dispatch to unknown property from an object literal --- .../javascript/dataflow/internal/CallGraphs.qll | 12 ++++++++++++ .../frameworks/NodeJSLib/tests.expected | 10 ++++++++++ .../Security/CWE-078/CommandInjection.expected | 14 ++++++++++++++ .../UnsafeShellCommandConstruction.expected | 12 ++++++++++++ .../Security/CWE-078/lib/subLib4/index.js | 8 ++++++++ .../Security/CWE-078/lib/subLib4/package.json | 5 +++++ .../Security/CWE-078/lib/subLib4/subsub.js | 5 +++++ 7 files changed, 66 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/index.js create mode 100644 javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/package.json create mode 100644 javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/subsub.js diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll index 94a6532b107..e616772e789 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll @@ -89,6 +89,18 @@ module CallGraph { result = getAFunctionReference(outer, 0, t.continue()).getAnInvocation() and locallyReturnedFunction(outer, function) ) + or + // dynamic dispatch to unknown property of an object + exists(DataFlow::ObjectLiteralNode obj, DataFlow::PropRead read | + getAFunctionReference(function, 0, t.continue()) = obj.getAPropertySource() and + obj.getAPropertyRead() = read and + not exists(read.getPropertyName()) and + result = read and + // there exists only local reads of the object, nothing else. + forex(DataFlow::Node ref | ref = obj.getALocalUse() and exists(ref.asExpr()) | + ref = [obj, any(DataFlow::PropRead r).getBase()] + ) + ) } private predicate locallyReturnedFunction( diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected index 49655c0ffa3..2677e785487 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected @@ -27,6 +27,7 @@ test_RouteHandler_getAResponseHeader | src/http.js:12:19:16:1 | functio ... ar");\\n} | content-type | src/http.js:13:3:13:44 | res.set ... /html') | | src/https.js:4:33:10:1 | functio ... .foo;\\n} | location | src/https.js:7:3:7:42 | res.wri ... rget }) | | src/https.js:12:20:16:1 | functio ... ar");\\n} | content-type | src/https.js:13:3:13:44 | res.set ... /html') | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | test_HeaderDefinition_defines | src/http.js:13:3:13:44 | res.set ... /html') | content-type | text/html | @@ -70,8 +71,11 @@ test_ResponseExpr | src/https.js:15:3:15:5 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} | | src/indirect2.js:9:19:9:21 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:10:47:10:49 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:13:33:13:35 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:13:33:13:35 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | +| src/indirect2.js:14:3:14:5 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:14:3:14:5 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | +| src/indirect2.js:15:3:15:5 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:15:3:15:5 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | | src/indirect.js:16:26:16:28 | res | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:19:38:19:40 | res | src/indirect.js:16:12:20:5 | functio ... ;\\n } | @@ -85,6 +89,7 @@ test_HeaderDefinition | src/http.js:63:3:63:40 | res.set ... , "23") | src/http.js:62:19:65:1 | functio ... r2");\\n} | | src/https.js:7:3:7:42 | res.wri ... rget }) | src/https.js:4:33:10:1 | functio ... .foo;\\n} | | src/https.js:13:3:13:44 | res.set ... /html') | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | test_RouteSetup_getServer | createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:1:2:42 | https.c ... es) {}) | @@ -171,6 +176,9 @@ test_RouteHandler_getAResponseExpr | src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:15:3:15:5 | res | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:19:9:21 | res | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:47:10:49 | res | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:33:13:35 | res | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:14:3:14:5 | res | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:15:3:15:5 | res | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:33:13:35 | res | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:14:3:14:5 | res | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:15:3:15:5 | res | @@ -307,6 +315,7 @@ test_RequestExpr | src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:10:12:10:14 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:10:42:10:44 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:13:28:13:30 | req | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | | src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:17:28:17:30 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | @@ -349,6 +358,7 @@ test_RouteHandler_getARequestExpr | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:12:10:14 | req | | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:42:10:44 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:28:13:30 | req | | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:28:13:30 | req | | src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | | src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:17:28:17:30 | req | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index 3e53d9b79b8..e4661401718 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -134,6 +134,12 @@ nodes | form-parsers.js:59:10:59:33 | "touch ... ilename | | form-parsers.js:59:21:59:24 | part | | form-parsers.js:59:21:59:33 | part.filename | +| lib/subLib4/index.js:6:32:6:35 | name | +| lib/subLib4/index.js:7:18:7:21 | name | +| lib/subLib4/subsub.js:3:28:3:31 | name | +| lib/subLib4/subsub.js:4:10:4:25 | "rm -rf " + name | +| lib/subLib4/subsub.js:4:10:4:25 | "rm -rf " + name | +| lib/subLib4/subsub.js:4:22:4:25 | name | | lib/subLib/index.js:7:32:7:35 | name | | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | @@ -232,6 +238,8 @@ edges | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | | child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | +| child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib4/index.js:6:32:6:35 | name | +| child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib4/index.js:6:32:6:35 | name | | child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib/index.js:7:32:7:35 | name | | child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib/index.js:7:32:7:35 | name | | child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:21:94:35 | ctx.params.host | @@ -306,6 +314,11 @@ edges | form-parsers.js:59:21:59:24 | part | form-parsers.js:59:21:59:33 | part.filename | | form-parsers.js:59:21:59:33 | part.filename | form-parsers.js:59:10:59:33 | "touch ... ilename | | form-parsers.js:59:21:59:33 | part.filename | form-parsers.js:59:10:59:33 | "touch ... ilename | +| lib/subLib4/index.js:6:32:6:35 | name | lib/subLib4/index.js:7:18:7:21 | name | +| lib/subLib4/index.js:7:18:7:21 | name | lib/subLib4/subsub.js:3:28:3:31 | name | +| lib/subLib4/subsub.js:3:28:3:31 | name | lib/subLib4/subsub.js:4:22:4:25 | name | +| lib/subLib4/subsub.js:4:22:4:25 | name | lib/subLib4/subsub.js:4:10:4:25 | "rm -rf " + name | +| lib/subLib4/subsub.js:4:22:4:25 | name | lib/subLib4/subsub.js:4:10:4:25 | "rm -rf " + name | | lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | | lib/subLib/index.js:8:22:8:25 | name | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | | lib/subLib/index.js:8:22:8:25 | name | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | @@ -385,6 +398,7 @@ edges | form-parsers.js:41:10:41:31 | "touch ... ds.name | form-parsers.js:40:26:40:31 | fields | form-parsers.js:41:10:41:31 | "touch ... ds.name | This command depends on $@. | form-parsers.js:40:26:40:31 | fields | a user-provided value | | form-parsers.js:53:10:53:31 | "touch ... ds.name | form-parsers.js:52:34:52:39 | fields | form-parsers.js:53:10:53:31 | "touch ... ds.name | This command depends on $@. | form-parsers.js:52:34:52:39 | fields | a user-provided value | | form-parsers.js:59:10:59:33 | "touch ... ilename | form-parsers.js:58:30:58:33 | part | form-parsers.js:59:10:59:33 | "touch ... ilename | This command depends on $@. | form-parsers.js:58:30:58:33 | part | a user-provided value | +| lib/subLib4/subsub.js:4:10:4:25 | "rm -rf " + name | child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib4/subsub.js:4:10:4:25 | "rm -rf " + name | This command depends on $@. | child_process-test.js:85:37:85:54 | req.query.fileName | a user-provided value | | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | This command depends on $@. | child_process-test.js:85:37:85:54 | req.query.fileName | a user-provided value | | other.js:7:33:7:35 | cmd | other.js:5:25:5:31 | req.url | other.js:7:33:7:35 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value | | other.js:8:28:8:30 | cmd | other.js:5:25:5:31 | req.url | other.js:8:28:8:30 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction.expected index 035eff50202..1206af38368 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction.expected @@ -284,6 +284,12 @@ nodes | lib/subLib3/my-file.ts:3:28:3:31 | name | | lib/subLib3/my-file.ts:4:22:4:25 | name | | lib/subLib3/my-file.ts:4:22:4:25 | name | +| lib/subLib4/index.js:6:32:6:35 | name | +| lib/subLib4/index.js:6:32:6:35 | name | +| lib/subLib4/index.js:7:18:7:21 | name | +| lib/subLib4/subsub.js:3:28:3:31 | name | +| lib/subLib4/subsub.js:4:22:4:25 | name | +| lib/subLib4/subsub.js:4:22:4:25 | name | | lib/subLib/amdSub.js:3:28:3:31 | name | | lib/subLib/amdSub.js:3:28:3:31 | name | | lib/subLib/amdSub.js:4:22:4:25 | name | @@ -640,6 +646,11 @@ edges | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | +| lib/subLib4/index.js:6:32:6:35 | name | lib/subLib4/index.js:7:18:7:21 | name | +| lib/subLib4/index.js:6:32:6:35 | name | lib/subLib4/index.js:7:18:7:21 | name | +| lib/subLib4/index.js:7:18:7:21 | name | lib/subLib4/subsub.js:3:28:3:31 | name | +| lib/subLib4/subsub.js:3:28:3:31 | name | lib/subLib4/subsub.js:4:22:4:25 | name | +| lib/subLib4/subsub.js:3:28:3:31 | name | lib/subLib4/subsub.js:4:22:4:25 | name | | lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | | lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | | lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | @@ -735,6 +746,7 @@ edges | lib/subLib2/compiled-file.ts:4:13:4:28 | "rm -rf " + name | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | $@ based on $@ is later used in $@. | lib/subLib2/compiled-file.ts:4:13:4:28 | "rm -rf " + name | String concatenation | lib/subLib2/compiled-file.ts:3:26:3:29 | name | library input | lib/subLib2/compiled-file.ts:4:5:4:29 | cp.exec ... + name) | shell command | | lib/subLib2/special-file.js:4:10:4:25 | "rm -rf " + name | lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | $@ based on $@ is later used in $@. | lib/subLib2/special-file.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/subLib2/special-file.js:3:28:3:31 | name | library input | lib/subLib2/special-file.js:4:2:4:26 | cp.exec ... + name) | shell command | | lib/subLib3/my-file.ts:4:10:4:25 | "rm -rf " + name | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | $@ based on $@ is later used in $@. | lib/subLib3/my-file.ts:4:10:4:25 | "rm -rf " + name | String concatenation | lib/subLib3/my-file.ts:3:28:3:31 | name | library input | lib/subLib3/my-file.ts:4:2:4:26 | cp.exec ... + name) | shell command | +| lib/subLib4/subsub.js:4:10:4:25 | "rm -rf " + name | lib/subLib4/index.js:6:32:6:35 | name | lib/subLib4/subsub.js:4:22:4:25 | name | $@ based on $@ is later used in $@. | lib/subLib4/subsub.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/subLib4/index.js:6:32:6:35 | name | library input | lib/subLib4/subsub.js:4:2:4:26 | cp.exec ... + name) | shell command | | lib/subLib/amdSub.js:4:10:4:25 | "rm -rf " + name | lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | $@ based on $@ is later used in $@. | lib/subLib/amdSub.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/subLib/amdSub.js:3:28:3:31 | name | library input | lib/subLib/amdSub.js:4:2:4:26 | cp.exec ... + name) | shell command | | lib/subLib/index.js:4:10:4:25 | "rm -rf " + name | lib/subLib/index.js:3:28:3:31 | name | lib/subLib/index.js:4:22:4:25 | name | $@ based on $@ is later used in $@. | lib/subLib/index.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/subLib/index.js:3:28:3:31 | name | library input | lib/subLib/index.js:4:2:4:26 | cp.exec ... + name) | shell command | | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | $@ based on $@ is later used in $@. | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | String concatenation | lib/subLib/index.js:7:32:7:35 | name | library input | lib/subLib/index.js:8:2:8:26 | cp.exec ... + name) | shell command | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/index.js b/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/index.js new file mode 100644 index 00000000000..820349c5c62 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/index.js @@ -0,0 +1,8 @@ +const dispatch = { + GET: require("./bla"), + POST: require("./subsub"), +}; + +module.exports.foo = function (name, type) { + dispatch[type](name); +}; diff --git a/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/package.json b/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/package.json new file mode 100644 index 00000000000..87942f96b4d --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/package.json @@ -0,0 +1,5 @@ +{ + "name": "my-sub-lib", + "version": "0.0.7", + "main": "./index.js" +} diff --git a/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/subsub.js b/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/subsub.js new file mode 100644 index 00000000000..952288a82ce --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-078/lib/subLib4/subsub.js @@ -0,0 +1,5 @@ +const cp = require("child_process") + +module.exports = function (name) { + cp.exec("rm -rf " + name); // NOT OK - functions exported as part of a submodule are also flagged. +}; From c1be060ef8bd99d0f6a7f762449342bcc28cbc30 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 Aug 2022 16:06:10 +0100 Subject: [PATCH 013/659] Swift: Create query + test stubs. --- .../CWE-311/CleartextStorageDatabase.ql | 17 +++++++++++++++++ .../Security/CWE-311/CleartextTransmission.ql | 17 +++++++++++++++++ .../CWE-311/CleartextStorageDatabase.expected | 1 + .../CWE-311/CleartextStorageDatabase.qlref | 1 + .../CWE-311/CleartextTransmission.expected | 1 + .../CWE-311/CleartextTransmission.qlref | 1 + .../query-tests/Security/CWE-311/test.swift | 4 ++++ 7 files changed, 42 insertions(+) create mode 100644 swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql create mode 100644 swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql create mode 100644 swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected create mode 100644 swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.qlref create mode 100644 swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected create mode 100644 swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.qlref create mode 100644 swift/ql/test/query-tests/Security/CWE-311/test.swift diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql new file mode 100644 index 00000000000..b2b24fdf9d2 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql @@ -0,0 +1,17 @@ +/** + * @name Cleartext storage of sensitive information in a local database + * @description TODO + * @kind path-problem + * @problem.severity TODO + * @security-severity TODO + * @precision TODO + * @id swift/TODO + * @tags security + * external/cwe/cwe-312 + */ + +import swift +import codeql.swift.dataflow.DataFlow +import DataFlow::PathGraph + +select "TODO" diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql new file mode 100644 index 00000000000..3fa3ee3f4e7 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql @@ -0,0 +1,17 @@ +/** + * @name Cleartext transmission of sensitive information + * @description TODO + * @kind path-problem + * @problem.severity TODO + * @security-severity TODO + * @precision TODO + * @id swift/TODO + * @tags security + * external/cwe/cwe-319 + */ + +import swift +import codeql.swift.dataflow.DataFlow +import DataFlow::PathGraph + +select "TODO" diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected new file mode 100644 index 00000000000..1333ed77b7e --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -0,0 +1 @@ +TODO diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.qlref b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.qlref new file mode 100644 index 00000000000..d73f4fc4bc2 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.qlref @@ -0,0 +1 @@ +queries/Security/CWE-311/CleartextStorageDatabase.ql \ No newline at end of file diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected new file mode 100644 index 00000000000..1333ed77b7e --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -0,0 +1 @@ +TODO diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.qlref b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.qlref new file mode 100644 index 00000000000..f4c5a561e61 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.qlref @@ -0,0 +1 @@ +queries/Security/CWE-311/CleartextTransmission.ql \ No newline at end of file diff --git a/swift/ql/test/query-tests/Security/CWE-311/test.swift b/swift/ql/test/query-tests/Security/CWE-311/test.swift new file mode 100644 index 00000000000..986e3bc8ea3 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/test.swift @@ -0,0 +1,4 @@ + +// --- stubs --- + +// --- tests --- From 60e0f095867a817c399cf290129ea14f56f4e9e5 Mon Sep 17 00:00:00 2001 From: Daniel Santos Date: Fri, 17 Sep 2021 19:01:00 -0500 Subject: [PATCH 014/659] Additional hardcoded credentials candidates 3rd-party api calls --- .../src/Security/CWE/CWE-798/SensitiveApi.qll | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-798/SensitiveApi.qll b/java/ql/src/Security/CWE/CWE-798/SensitiveApi.qll index 86ecd73f289..64b19aa13b0 100644 --- a/java/ql/src/Security/CWE/CWE-798/SensitiveApi.qll +++ b/java/ql/src/Security/CWE/CWE-798/SensitiveApi.qll @@ -438,6 +438,49 @@ private predicate otherApiCallableCredentialParam(string s) { "com.azure.identity.UsernamePasswordCredentialBuilder;username(String);0", "com.azure.identity.UsernamePasswordCredentialBuilder;password(String);0", "com.azure.identity.ClientSecretCredentialBuilder;clientSecret(String);0", - "org.apache.shiro.mgt.AbstractRememberMeManager;setCipherKey(byte[]);0" + "org.apache.shiro.mgt.AbstractRememberMeManager;setCipherKey(byte[]);0", + "com.jcraft.jsch.JSch;getSession(String, String, int);0", + "com.jcraft.jsch.JSch;getSession(String, String);0", + "ch.ethz.ssh2.Connection;authenticateWithPassword(String, String);0", + "org.apache.sshd.client.SshClient;connect(String, String, int);0", + "org.apache.sshd.client.SshClient;connect(String, SocketAddress);0", + "net.schmizz.sshj.SSHClient;authPassword(String, char[]);0", + "net.schmizz.sshj.SSHClient;authPassword(String, String);0", + "com.sshtools.j2ssh.authentication.SshAuthenticationClient;setUsername(String);0", + "com.sshtools.j2ssh.authentication.PasswordAuthenticationClient;setUsername(String);0", + "com.trilead.ssh2.Connection;authenticateWithPassword(String, String);0", + "com.trilead.ssh2.Connection;authenticateWithDSA(String, String, String);0", + "com.trilead.ssh2.Connection;authenticateWithNone(String);0", + "com.trilead.ssh2.Connection;getRemainingAuthMethods(String);0", + "com.trilead.ssh2.Connection;isAuthMethodAvailable(String, String);0", + "com.trilead.ssh2.Connection;authenticateWithPublicKey(String, char[], String);0", + "com.trilead.ssh2.Connection;authenticateWithPublicKey(String, File, String);0", + "com.jcraft.jsch.Session;setPassword(byte[]);0", + "com.jcraft.jsch.Session;setPassword(String);0", + "ch.ethz.ssh2.Connection;authenticateWithPassword(String, String);1", + "org.apache.sshd.client.session.AbstractClientSession;addPasswordIdentity(String);0", + "net.schmizz.sshj.SSHClient;authPassword(String, char[]);1", + "net.schmizz.sshj.SSHClient;authPassword(String, String);1", + "com.sshtools.j2ssh.authentication.PasswordAuthenticationClient;setPassword(String);0", + "com.trilead.ssh2.Connection;authenticateWithPassword(String, String);1", + "com.trilead.ssh2.Connection;authenticateWithDSA(String, String, String);2", + "com.trilead.ssh2.Connection;authenticateWithPublicKey(String, char[], String);2", + "com.trilead.ssh2.Connection;authenticateWithPublicKey(String, File, String);2", + "com.trilead.ssh2.Connection;authenticateWithDSA(String, String, String);1", + "com.trilead.ssh2.Connection;authenticateWithPublicKey(String, char[], String);1", + "org.apache.commons.net.ftp.FTPClient;login(String, String);0", + "org.apache.commons.net.ftp.FTPClient;login(String, String, String);0", + "org.apache.commons.net.ftp.FTPClient;login(String, String);1", + "org.apache.commons.net.ftp.FTPClient;login(String, String, String);1", + "com.mongodb.MongoCredential;createCredential(String, String, char[]);0", + "com.mongodb.MongoCredential;createMongoCRCredential(String, String, char[]);0", + "com.mongodb.MongoCredential;createPlainCredential(String, String, char[]);0", + "com.mongodb.MongoCredential;createScramSha1Credential(String, String, char[]);0", + "com.mongodb.MongoCredential;createGSSAPICredential(String);0", + "com.mongodb.MongoCredential;createMongoX509Credential(String);0", + "com.mongodb.MongoCredential;createCredential(String, String, char[]);2", + "com.mongodb.MongoCredential;createMongoCRCredential(String, String, char[]);2", + "com.mongodb.MongoCredential;createPlainCredential(String, String, char[]);2", + "com.mongodb.MongoCredential;createScramSha1Credential(String, String, char[]);2" ] } From 0a6ccbca453e7c5bf0f3852f0a62d5749dd861b9 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 30 May 2022 20:41:17 +0100 Subject: [PATCH 015/659] Add stubs and tests for new hardcoded-credential sinks --- .../tests/HardcodedApacheFtpCredentials.java | 13 ++ .../tests/HardcodedApacheSshdCredentials.java | 12 + .../HardcodedCredentialsApiCall.expected | 96 ++++++++ .../HardcodedCredentialsSourceCall.expected | 64 ++++++ .../HardcodedGanymedSsh2Credentials.java | 11 + .../tests/HardcodedJ2sshCredentials.java | 11 + .../tests/HardcodedJschCredentials.java | 16 ++ .../tests/HardcodedMongoCredentials.java | 12 + .../tests/HardcodedSshjCredentials.java | 13 ++ .../tests/HardcodedTrileadSshCredentials.java | 19 ++ .../security/CWE-798/semmle/tests/options | 2 +- .../org/apache/commons/net/SocketClient.java | 22 ++ .../apache/commons/net/ftp/Configurable.java | 22 ++ .../org/apache/commons/net/ftp/FTP.java | 24 ++ .../org/apache/commons/net/ftp/FTPClient.java | 33 +++ .../org/apache/sshd/agent/SshAgent.java | 21 ++ .../apache/sshd/agent/SshAgentFactory.java | 18 ++ .../sshd/agent/SshAgentKeyConstraint.java | 14 ++ .../org/apache/sshd/agent/SshAgentServer.java | 10 + .../agent/common/AgentForwardSupport.java | 10 + .../client/ClientAuthenticationManager.java | 43 ++++ .../sshd/client/ClientFactoryManager.java | 17 ++ .../org/apache/sshd/client/SshClient.java | 108 +++++++++ .../AuthenticationIdentitiesProvider.java | 18 ++ .../org/apache/sshd/client/auth/UserAuth.java | 19 ++ .../sshd/client/auth/UserAuthFactory.java | 13 ++ .../HostBasedAuthenticationReporter.java | 15 ++ .../client/auth/keyboard/UserInteraction.java | 26 +++ .../PasswordAuthenticationReporter.java | 14 ++ .../password/PasswordIdentityProvider.java | 21 ++ .../PublicKeyAuthenticationReporter.java | 16 ++ .../client/channel/AbstractClientChannel.java | 78 +++++++ .../client/channel/ChannelDirectTcpip.java | 18 ++ .../sshd/client/channel/ChannelExec.java | 16 ++ .../sshd/client/channel/ChannelSession.java | 21 ++ .../sshd/client/channel/ChannelShell.java | 16 ++ .../sshd/client/channel/ChannelSubsystem.java | 17 ++ .../sshd/client/channel/ClientChannel.java | 39 ++++ .../client/channel/ClientChannelEvent.java | 12 + .../channel/PtyCapableChannelSession.java | 37 +++ .../client/config/hosts/HostConfigEntry.java | 113 +++++++++ .../config/hosts/HostConfigEntryResolver.java | 13 ++ .../client/config/hosts/HostPatternValue.java | 19 ++ .../config/hosts/HostPatternsHolder.java | 35 +++ .../config/keys/ClientIdentityLoader.java | 18 ++ .../keys/ClientIdentityLoaderHolder.java | 11 + .../keys/ClientIdentityLoaderManager.java | 11 + .../apache/sshd/client/future/AuthFuture.java | 17 ++ .../sshd/client/future/ConnectFuture.java | 21 ++ .../apache/sshd/client/future/OpenFuture.java | 16 ++ .../client/keyverifier/ServerKeyVerifier.java | 12 + .../client/session/AbstractClientSession.java | 104 +++++++++ .../client/session/ClientProxyConnector.java | 10 + .../session/ClientProxyConnectorHolder.java | 11 + .../sshd/client/session/ClientSession.java | 69 ++++++ .../client/session/ClientSessionCreator.java | 27 +++ .../client/session/ClientSessionHolder.java | 10 + .../client/session/ClientSessionImpl.java | 36 +++ .../client/session/ClientUserAuthService.java | 41 ++++ .../sshd/client/session/SessionFactory.java | 18 ++ .../forward/DynamicPortForwardingTracker.java | 14 ++ .../ExplicitPortForwardingTracker.java | 18 ++ .../forward/PortForwardingTracker.java | 24 ++ .../sshd/client/simple/SimpleClient.java | 11 + .../simple/SimpleClientConfigurator.java | 15 ++ .../client/simple/SimpleSessionClient.java | 26 +++ .../sshd/common/AlgorithmNameProvider.java | 9 + .../sshd/common/AttributeRepository.java | 20 ++ .../apache/sshd/common/AttributeStore.java | 14 ++ .../org/apache/sshd/common/Closeable.java | 23 ++ .../org/apache/sshd/common/Factory.java | 11 + .../apache/sshd/common/FactoryManager.java | 53 +++++ .../sshd/common/FactoryManagerHolder.java | 10 + .../org/apache/sshd/common/NamedFactory.java | 17 ++ .../org/apache/sshd/common/NamedResource.java | 22 ++ .../apache/sshd/common/OptionalFeature.java | 15 ++ .../apache/sshd/common/PropertyResolver.java | 25 ++ .../org/apache/sshd/common/Service.java | 16 ++ .../apache/sshd/common/ServiceFactory.java | 14 ++ .../sshd/common/auth/MutableUserHolder.java | 10 + .../common/auth/UserAuthFactoriesManager.java | 20 ++ .../sshd/common/auth/UserAuthInstance.java | 11 + .../common/auth/UserAuthMethodFactory.java | 20 ++ .../sshd/common/auth/UsernameHolder.java | 9 + .../sshd/common/channel/AbstractChannel.java | 120 ++++++++++ .../apache/sshd/common/channel/Channel.java | 55 +++++ .../channel/ChannelAsyncInputStream.java | 24 ++ .../channel/ChannelAsyncOutputStream.java | 31 +++ .../sshd/common/channel/ChannelFactory.java | 14 ++ .../sshd/common/channel/ChannelHolder.java | 10 + .../sshd/common/channel/ChannelListener.java | 17 ++ .../channel/ChannelListenerManager.java | 12 + .../common/channel/IoWriteFutureImpl.java | 13 ++ .../PtyChannelConfigurationHolder.java | 23 ++ .../PtyChannelConfigurationMutator.java | 19 ++ .../apache/sshd/common/channel/PtyMode.java | 35 +++ .../sshd/common/channel/RequestHandler.java | 18 ++ .../sshd/common/channel/StreamingChannel.java | 15 ++ .../apache/sshd/common/channel/Window.java | 38 ++++ .../channel/throttle/ChannelStreamWriter.java | 12 + .../throttle/ChannelStreamWriterResolver.java | 12 + .../ChannelStreamWriterResolverManager.java | 15 ++ .../org/apache/sshd/common/cipher/Cipher.java | 21 ++ .../sshd/common/cipher/CipherInformation.java | 15 ++ .../sshd/common/compression/Compression.java | 18 ++ .../compression/CompressionInformation.java | 11 + .../config/keys/FilePasswordProvider.java | 21 ++ .../keys/FilePasswordProviderHolder.java | 11 + .../keys/FilePasswordProviderManager.java | 11 + .../config/keys/OpenSshCertificate.java | 51 +++++ .../org/apache/sshd/common/digest/Digest.java | 13 ++ .../sshd/common/digest/DigestInformation.java | 10 + .../sshd/common/file/FileSystemFactory.java | 13 ++ .../apache/sshd/common/forward/Forwarder.java | 16 ++ .../sshd/common/forward/ForwarderFactory.java | 11 + .../forward/PortForwardingEventListener.java | 21 ++ .../PortForwardingEventListenerManager.java | 12 + ...tForwardingEventListenerManagerHolder.java | 13 ++ .../PortForwardingInformationProvider.java | 20 ++ .../common/forward/PortForwardingManager.java | 17 ++ .../sshd/common/future/AbstractSshFuture.java | 25 ++ .../sshd/common/future/CloseFuture.java | 11 + .../common/future/DefaultCloseFuture.java | 15 ++ .../future/DefaultKeyExchangeFuture.java | 15 ++ .../sshd/common/future/DefaultSshFuture.java | 24 ++ .../future/DefaultVerifiableSshFuture.java | 13 ++ .../sshd/common/future/KeyExchangeFuture.java | 11 + .../apache/sshd/common/future/SshFuture.java | 12 + .../sshd/common/future/SshFutureListener.java | 11 + .../sshd/common/future/VerifiableFuture.java | 14 ++ .../sshd/common/future/WaitableFuture.java | 20 ++ .../helpers/AbstractFactoryManager.java | 122 ++++++++++ .../sshd/common/io/AbstractIoWriteFuture.java | 16 ++ .../org/apache/sshd/common/io/IoAcceptor.java | 18 ++ .../sshd/common/io/IoConnectFuture.java | 17 ++ .../apache/sshd/common/io/IoConnector.java | 13 ++ .../org/apache/sshd/common/io/IoHandler.java | 14 ++ .../apache/sshd/common/io/IoInputStream.java | 12 + .../apache/sshd/common/io/IoOutputStream.java | 12 + .../apache/sshd/common/io/IoReadFuture.java | 14 ++ .../org/apache/sshd/common/io/IoService.java | 14 ++ .../common/io/IoServiceEventListener.java | 17 ++ .../io/IoServiceEventListenerManager.java | 11 + .../sshd/common/io/IoServiceFactory.java | 15 ++ .../common/io/IoServiceFactoryFactory.java | 14 ++ .../org/apache/sshd/common/io/IoSession.java | 27 +++ .../apache/sshd/common/io/IoWriteFuture.java | 12 + .../common/kex/AbstractKexFactoryManager.java | 36 +++ .../sshd/common/kex/KexFactoryManager.java | 40 ++++ .../sshd/common/kex/KexProposalOption.java | 25 ++ .../org/apache/sshd/common/kex/KexState.java | 12 + .../apache/sshd/common/kex/KeyExchange.java | 25 ++ .../sshd/common/kex/KeyExchangeFactory.java | 12 + .../kex/extension/KexExtensionHandler.java | 31 +++ .../extension/KexExtensionHandlerManager.java | 11 + .../keyprovider/KeyIdentityProvider.java | 22 ++ .../KeyIdentityProviderHolder.java | 11 + .../common/keyprovider/KeySizeIndicator.java | 9 + .../org/apache/sshd/common/mac/Mac.java | 17 ++ .../sshd/common/mac/MacInformation.java | 12 + .../org/apache/sshd/common/random/Random.java | 12 + .../common/session/ConnectionService.java | 24 ++ .../ReservedSessionMessagesHandler.java | 22 ++ .../ReservedSessionMessagesManager.java | 11 + .../apache/sshd/common/session/Session.java | 63 ++++++ .../sshd/common/session/SessionContext.java | 38 ++++ .../common/session/SessionContextHolder.java | 10 + .../session/SessionDisconnectHandler.java | 20 ++ .../SessionDisconnectHandlerManager.java | 11 + .../session/SessionHeartbeatController.java | 24 ++ .../sshd/common/session/SessionHolder.java | 13 ++ .../sshd/common/session/SessionListener.java | 31 +++ .../session/SessionListenerManager.java | 12 + .../common/session/SessionWorkBuffer.java | 17 ++ .../UnknownChannelReferenceHandler.java | 12 + ...UnknownChannelReferenceHandlerManager.java | 12 + .../session/helpers/AbstractSession.java | 214 ++++++++++++++++++ .../helpers/AbstractSessionFactory.java | 18 ++ .../helpers/AbstractSessionIoHandler.java | 19 ++ .../session/helpers/PendingWriteFuture.java | 19 ++ .../common/session/helpers/SessionHelper.java | 140 ++++++++++++ .../helpers/SessionTimeoutListener.java | 19 ++ .../session/helpers/TimeoutIndicator.java | 22 ++ .../sshd/common/signature/Signature.java | 19 ++ .../signature/SignatureFactoriesHolder.java | 14 ++ .../signature/SignatureFactoriesManager.java | 19 ++ .../sshd/common/util/EventNotifier.java | 9 + .../sshd/common/util/ObjectBuilder.java | 11 + .../org/apache/sshd/common/util/Readable.java | 12 + .../sshd/common/util/SshdEventListener.java | 10 + .../sshd/common/util/buffer/Buffer.java | 120 ++++++++++ .../common/util/buffer/ByteArrayBuffer.java | 45 ++++ .../buffer/keys/BufferPublicKeyParser.java | 16 ++ .../util/closeable/AbstractCloseable.java | 34 +++ .../closeable/AbstractInnerCloseable.java | 16 ++ .../sshd/common/util/closeable/Builder.java | 23 ++ .../util/closeable/IoBaseCloseable.java | 12 + .../sshd/common/util/io/functors/Invoker.java | 15 ++ .../util/logging/AbstractLoggingBean.java | 35 +++ .../common/util/logging/SimplifiedLog.java | 34 +++ .../net/ConnectionEndpointsIndicator.java | 11 + .../common/util/net/SshdSocketAddress.java | 68 ++++++ .../threads/CloseableExecutorService.java | 12 + .../util/threads/ExecutorServiceCarrier.java | 10 + .../server/forward/AgentForwardingFilter.java | 12 + .../sshd/server/forward/ForwardingFilter.java | 12 + .../server/forward/TcpForwardingFilter.java | 24 ++ .../server/forward/X11ForwardingFilter.java | 12 + .../sshd/server/x11/X11ForwardSupport.java | 13 ++ .../org/slf4j/Logger.java | 71 ++++++ .../org/slf4j/Marker.java | 22 ++ .../ch/ethz/ssh2/Connection.java | 15 ++ .../PasswordAuthenticationClient.java | 6 + .../SshAuthenticationClient.java | 5 + .../jsch-0.1.55/com/jcraft/jsch/Channel.java | 0 .../com/jcraft/jsch/ChannelExec.java | 0 .../com/jcraft/jsch/ChannelSession.java | 0 .../jsch-0.1.55/com/jcraft/jsch/JSch.java | 10 +- .../com/jcraft/jsch/JSchException.java | 29 +++ .../jsch-0.1.55/com/jcraft/jsch/Session.java | 9 +- .../com/mongodb/MongoCredential.java | 58 +++++ .../com/mongodb/annotations/Immutable.java | 37 +++ .../com/mongodb/lang/Nullable.java | 42 ++++ .../sshj/common/RemoteAddressProvider.java | 18 ++ .../net/schmizz/sshj/SSHClient.java | 40 ++++ .../net/schmizz/sshj/SocketClient.java | 18 ++ .../net/schmizz/sshj/common/SSHException.java | 22 ++ .../channel/direct/SessionFactory.java | 20 ++ .../sshj/transport/TransportException.java | 20 ++ .../sshj/userauth/UserAuthException.java | 22 ++ .../com/trilead/ssh2/Connection.java | 46 ++++ 231 files changed, 5520 insertions(+), 7 deletions(-) create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheFtpCredentials.java create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheSshdCredentials.java create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedGanymedSsh2Credentials.java create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJ2sshCredentials.java create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJschCredentials.java create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedMongoCredentials.java create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedSshjCredentials.java create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedTrileadSshCredentials.java create mode 100644 java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/SocketClient.java create mode 100644 java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/Configurable.java create mode 100644 java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/FTP.java create mode 100644 java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/FTPClient.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgent.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentKeyConstraint.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentServer.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/common/AgentForwardSupport.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/ClientAuthenticationManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/ClientFactoryManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/SshClient.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/AuthenticationIdentitiesProvider.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/UserAuth.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/UserAuthFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/hostbased/HostBasedAuthenticationReporter.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/keyboard/UserInteraction.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/password/PasswordAuthenticationReporter.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/pubkey/PublicKeyAuthenticationReporter.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/AbstractClientChannel.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelDirectTcpip.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelExec.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelSession.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelShell.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelSubsystem.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ClientChannel.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ClientChannelEvent.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/PtyCapableChannelSession.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostConfigEntry.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostConfigEntryResolver.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostPatternValue.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostPatternsHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoader.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoaderManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/AuthFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/ConnectFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/OpenFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/keyverifier/ServerKeyVerifier.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/AbstractClientSession.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientProxyConnector.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientProxyConnectorHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSession.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionCreator.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionImpl.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientUserAuthService.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/SessionFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/DynamicPortForwardingTracker.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/ExplicitPortForwardingTracker.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/PortForwardingTracker.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleClient.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleClientConfigurator.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleSessionClient.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AlgorithmNameProvider.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AttributeRepository.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AttributeStore.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Closeable.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Factory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/FactoryManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/FactoryManagerHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/NamedFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/NamedResource.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/OptionalFeature.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/PropertyResolver.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Service.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/ServiceFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/MutableUserHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthFactoriesManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthInstance.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthMethodFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UsernameHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/AbstractChannel.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/Channel.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelAsyncInputStream.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelAsyncOutputStream.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelListener.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelListenerManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/IoWriteFutureImpl.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyChannelConfigurationHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyChannelConfigurationMutator.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyMode.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/RequestHandler.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/StreamingChannel.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/Window.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriter.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriterResolver.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriterResolverManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/cipher/Cipher.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/cipher/CipherInformation.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/compression/Compression.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/compression/CompressionInformation.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProvider.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/OpenSshCertificate.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/digest/Digest.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/digest/DigestInformation.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/file/FileSystemFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/Forwarder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/ForwarderFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListener.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListenerManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListenerManagerHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingInformationProvider.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/AbstractSshFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/CloseFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultCloseFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultKeyExchangeFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultSshFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultVerifiableSshFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/KeyExchangeFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/SshFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/SshFutureListener.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/VerifiableFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/WaitableFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/helpers/AbstractFactoryManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/AbstractIoWriteFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoAcceptor.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoConnectFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoConnector.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoHandler.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoInputStream.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoOutputStream.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoReadFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoService.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceEventListener.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceEventListenerManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceFactoryFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoSession.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoWriteFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/AbstractKexFactoryManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexFactoryManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexProposalOption.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexState.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KeyExchange.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KeyExchangeFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/extension/KexExtensionHandler.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/extension/KexExtensionHandlerManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeyIdentityProviderHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeySizeIndicator.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/mac/Mac.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/mac/MacInformation.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/random/Random.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ConnectionService.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ReservedSessionMessagesManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/Session.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionContext.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionContextHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionDisconnectHandler.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionDisconnectHandlerManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionHeartbeatController.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionListener.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionListenerManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionWorkBuffer.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/UnknownChannelReferenceHandler.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/UnknownChannelReferenceHandlerManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSession.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSessionFactory.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSessionIoHandler.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/PendingWriteFuture.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/SessionHelper.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/SessionTimeoutListener.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/TimeoutIndicator.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/Signature.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/SignatureFactoriesHolder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/SignatureFactoriesManager.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/EventNotifier.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/ObjectBuilder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/Readable.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/SshdEventListener.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/Buffer.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/AbstractCloseable.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/AbstractInnerCloseable.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/Builder.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/IoBaseCloseable.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/io/functors/Invoker.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/logging/AbstractLoggingBean.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/logging/SimplifiedLog.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/net/ConnectionEndpointsIndicator.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/net/SshdSocketAddress.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/threads/CloseableExecutorService.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/threads/ExecutorServiceCarrier.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/AgentForwardingFilter.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/ForwardingFilter.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/TcpForwardingFilter.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/X11ForwardingFilter.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/x11/X11ForwardSupport.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/slf4j/Logger.java create mode 100644 java/ql/test/stubs/apache-mina-sshd-2.8.0/org/slf4j/Marker.java create mode 100644 java/ql/test/stubs/ganymed-ssh-2-260/ch/ethz/ssh2/Connection.java create mode 100644 java/ql/test/stubs/j2ssh-1.5.5/com/sshtools/j2ssh/authentication/PasswordAuthenticationClient.java create mode 100644 java/ql/test/stubs/j2ssh-1.5.5/com/sshtools/j2ssh/authentication/SshAuthenticationClient.java rename java/ql/test/{experimental => }/stubs/jsch-0.1.55/com/jcraft/jsch/Channel.java (100%) rename java/ql/test/{experimental => }/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelExec.java (100%) rename java/ql/test/{experimental => }/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelSession.java (100%) rename java/ql/test/{experimental => }/stubs/jsch-0.1.55/com/jcraft/jsch/JSch.java (91%) create mode 100644 java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/JSchException.java rename java/ql/test/{experimental => }/stubs/jsch-0.1.55/com/jcraft/jsch/Session.java (96%) create mode 100644 java/ql/test/stubs/mongodbClient/com/mongodb/MongoCredential.java create mode 100644 java/ql/test/stubs/mongodbClient/com/mongodb/annotations/Immutable.java create mode 100644 java/ql/test/stubs/mongodbClient/com/mongodb/lang/Nullable.java create mode 100644 java/ql/test/stubs/sshj-0.33.0/com/hierynomus/sshj/common/RemoteAddressProvider.java create mode 100644 java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/SSHClient.java create mode 100644 java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/SocketClient.java create mode 100644 java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/common/SSHException.java create mode 100644 java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/connection/channel/direct/SessionFactory.java create mode 100644 java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/transport/TransportException.java create mode 100644 java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/userauth/UserAuthException.java create mode 100644 java/ql/test/stubs/trilead-ssh2-212/com/trilead/ssh2/Connection.java diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheFtpCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheFtpCredentials.java new file mode 100644 index 00000000000..b62cd2f3d66 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheFtpCredentials.java @@ -0,0 +1,13 @@ +import org.apache.commons.net.ftp.FTPClient; + +import java.io.IOException; + +public class HardcodedApacheFtpCredentials { + public static void main(FTPClient client) { + // BAD: Hardcoded credentials used for the session username and/or password. + try { + client.login("username", "password"); + client.login("username", "password", "blah"); + } catch(IOException e) { } + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheSshdCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheSshdCredentials.java new file mode 100644 index 00000000000..756c74945b3 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheSshdCredentials.java @@ -0,0 +1,12 @@ +import org.apache.sshd.client.SshClient; +import org.apache.sshd.client.session.AbstractClientSession; +import java.io.IOException; + +public class HardcodedApacheSshdCredentials { + public static void main(SshClient client, AbstractClientSession session) { + // BAD: Hardcoded credentials used for the session username and/or password. + client.connect("Username", "hostname", 22); + client.connect("Username", null); + session.addPasswordIdentity("password"); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected index 96cdab78eb8..1b304a9fffb 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected @@ -27,9 +27,16 @@ edges | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | | HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | +| HardcodedJschCredentials.java:13:28:13:37 | "password" : String | HardcodedJschCredentials.java:13:28:13:48 | getBytes(...) | +| HardcodedMongoCredentials.java:5:58:5:67 | "password" : String | HardcodedMongoCredentials.java:5:58:5:81 | toCharArray(...) | +| HardcodedMongoCredentials.java:6:65:6:74 | "password" : String | HardcodedMongoCredentials.java:6:65:6:88 | toCharArray(...) | +| HardcodedMongoCredentials.java:7:63:7:72 | "password" : String | HardcodedMongoCredentials.java:7:63:7:86 | toCharArray(...) | +| HardcodedMongoCredentials.java:8:67:8:76 | "password" : String | HardcodedMongoCredentials.java:8:67:8:90 | toCharArray(...) | | HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | | HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | HardcodedShiroKey.java:18:46:18:87 | decode(...) | | HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | HardcodedShiroKey.java:26:46:26:109 | decode(...) | +| HardcodedSshjCredentials.java:9:39:9:48 | "password" : String | HardcodedSshjCredentials.java:9:39:9:62 | toCharArray(...) | +| HardcodedTrileadSshCredentials.java:15:50:15:54 | "key" : String | HardcodedTrileadSshCredentials.java:15:50:15:68 | toCharArray(...) | | Test.java:9:16:9:22 | "admin" : String | Test.java:12:13:12:15 | usr : String | | Test.java:9:16:9:22 | "admin" : String | Test.java:15:36:15:38 | usr | | Test.java:9:16:9:22 | "admin" : String | Test.java:17:39:17:41 | usr | @@ -63,6 +70,11 @@ nodes | FileCredentialTest.java:23:36:23:36 | v | semmle.label | v | | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | semmle.label | "ACCESS_KEY" | | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | semmle.label | "SECRET_KEY" | +| HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | semmle.label | "username" | +| HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | semmle.label | "password" | +| HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | semmle.label | "username" | +| HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | semmle.label | "password" | +| HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | semmle.label | "password" | | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | semmle.label | this <.method> [post update] [clientSecret] : String | | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | semmle.label | this <.method> [post update] [username] : String | | HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | semmle.label | this <.field> [post update] [username] : String | @@ -81,12 +93,55 @@ nodes | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | semmle.label | new HardcodedAzureCredentials(...) [username] : String | | HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | +| HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | semmle.label | "username" | +| HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | semmle.label | "password" | +| HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | semmle.label | "Username" | +| HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | semmle.label | "Username" | +| HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | semmle.label | "password" | +| HardcodedJschCredentials.java:10:41:10:50 | "Username" | semmle.label | "Username" | +| HardcodedJschCredentials.java:11:42:11:51 | "Username" | semmle.label | "Username" | +| HardcodedJschCredentials.java:12:27:12:36 | "password" | semmle.label | "password" | +| HardcodedJschCredentials.java:13:28:13:37 | "password" : String | semmle.label | "password" : String | +| HardcodedJschCredentials.java:13:28:13:48 | getBytes(...) | semmle.label | getBytes(...) | +| HardcodedMongoCredentials.java:5:38:5:47 | "Username" | semmle.label | "Username" | +| HardcodedMongoCredentials.java:5:58:5:67 | "password" : String | semmle.label | "password" : String | +| HardcodedMongoCredentials.java:5:58:5:81 | toCharArray(...) | semmle.label | toCharArray(...) | +| HardcodedMongoCredentials.java:6:45:6:54 | "Username" | semmle.label | "Username" | +| HardcodedMongoCredentials.java:6:65:6:74 | "password" : String | semmle.label | "password" : String | +| HardcodedMongoCredentials.java:6:65:6:88 | toCharArray(...) | semmle.label | toCharArray(...) | +| HardcodedMongoCredentials.java:7:43:7:52 | "Username" | semmle.label | "Username" | +| HardcodedMongoCredentials.java:7:63:7:72 | "password" : String | semmle.label | "password" : String | +| HardcodedMongoCredentials.java:7:63:7:86 | toCharArray(...) | semmle.label | toCharArray(...) | +| HardcodedMongoCredentials.java:8:47:8:56 | "Username" | semmle.label | "Username" | +| HardcodedMongoCredentials.java:8:67:8:76 | "password" : String | semmle.label | "password" : String | +| HardcodedMongoCredentials.java:8:67:8:90 | toCharArray(...) | semmle.label | toCharArray(...) | +| HardcodedMongoCredentials.java:9:44:9:48 | "key" | semmle.label | "key" | +| HardcodedMongoCredentials.java:10:47:10:51 | "key" | semmle.label | "key" | | HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | semmle.label | "TEST123" : String | | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | semmle.label | getBytes(...) | | HardcodedShiroKey.java:18:46:18:87 | decode(...) | semmle.label | decode(...) | | HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | semmle.label | "4AvVhmFLUs0KTA3Kprsdag==" : String | | HardcodedShiroKey.java:26:46:26:109 | decode(...) | semmle.label | decode(...) | | HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | semmle.label | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | +| HardcodedSshjCredentials.java:8:25:8:34 | "Username" | semmle.label | "Username" | +| HardcodedSshjCredentials.java:8:37:8:46 | "password" | semmle.label | "password" | +| HardcodedSshjCredentials.java:9:27:9:36 | "Username" | semmle.label | "Username" | +| HardcodedSshjCredentials.java:9:39:9:48 | "password" : String | semmle.label | "password" : String | +| HardcodedSshjCredentials.java:9:39:9:62 | toCharArray(...) | semmle.label | toCharArray(...) | +| HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | semmle.label | "password" | +| HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | semmle.label | "password" | +| HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | semmle.label | "key" | +| HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:15:50:15:54 | "key" : String | semmle.label | "key" : String | +| HardcodedTrileadSshCredentials.java:15:50:15:68 | toCharArray(...) | semmle.label | toCharArray(...) | +| HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | semmle.label | "password" | +| HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | semmle.label | "password" | | Test.java:9:16:9:22 | "admin" : String | semmle.label | "admin" : String | | Test.java:10:17:10:24 | "123456" : String | semmle.label | "123456" : String | | Test.java:12:13:12:15 | usr : String | semmle.label | usr : String | @@ -118,12 +173,53 @@ subpaths | FileCredentialTest.java:18:35:18:41 | "admin" | FileCredentialTest.java:18:35:18:41 | "admin" | FileCredentialTest.java:18:35:18:41 | "admin" | Hard-coded value flows to $@. | FileCredentialTest.java:18:35:18:41 | "admin" | sensitive API call | | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | Hard-coded value flows to $@. | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | sensitive API call | | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | Hard-coded value flows to $@. | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | sensitive API call | +| HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | sensitive API call | +| HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | sensitive API call | +| HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | sensitive API call | +| HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | sensitive API call | +| HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | Hard-coded value flows to $@. | HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | sensitive API call | | HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" | HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:18:13:18:20 | username | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:18:13:18:20 | username | sensitive API call | | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | sensitive API call | | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | sensitive API call | +| HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | Hard-coded value flows to $@. | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | sensitive API call | +| HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | Hard-coded value flows to $@. | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | sensitive API call | +| HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | sensitive API call | +| HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | sensitive API call | +| HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | sensitive API call | +| HardcodedJschCredentials.java:10:41:10:50 | "Username" | HardcodedJschCredentials.java:10:41:10:50 | "Username" | HardcodedJschCredentials.java:10:41:10:50 | "Username" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:10:41:10:50 | "Username" | sensitive API call | +| HardcodedJschCredentials.java:11:42:11:51 | "Username" | HardcodedJschCredentials.java:11:42:11:51 | "Username" | HardcodedJschCredentials.java:11:42:11:51 | "Username" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:11:42:11:51 | "Username" | sensitive API call | +| HardcodedJschCredentials.java:12:27:12:36 | "password" | HardcodedJschCredentials.java:12:27:12:36 | "password" | HardcodedJschCredentials.java:12:27:12:36 | "password" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:12:27:12:36 | "password" | sensitive API call | +| HardcodedJschCredentials.java:13:28:13:37 | "password" | HardcodedJschCredentials.java:13:28:13:37 | "password" : String | HardcodedJschCredentials.java:13:28:13:48 | getBytes(...) | Hard-coded value flows to $@. | HardcodedJschCredentials.java:13:28:13:48 | getBytes(...) | sensitive API call | +| HardcodedMongoCredentials.java:5:38:5:47 | "Username" | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | sensitive API call | +| HardcodedMongoCredentials.java:5:58:5:67 | "password" | HardcodedMongoCredentials.java:5:58:5:67 | "password" : String | HardcodedMongoCredentials.java:5:58:5:81 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:5:58:5:81 | toCharArray(...) | sensitive API call | +| HardcodedMongoCredentials.java:6:45:6:54 | "Username" | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | sensitive API call | +| HardcodedMongoCredentials.java:6:65:6:74 | "password" | HardcodedMongoCredentials.java:6:65:6:74 | "password" : String | HardcodedMongoCredentials.java:6:65:6:88 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:6:65:6:88 | toCharArray(...) | sensitive API call | +| HardcodedMongoCredentials.java:7:43:7:52 | "Username" | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | sensitive API call | +| HardcodedMongoCredentials.java:7:63:7:72 | "password" | HardcodedMongoCredentials.java:7:63:7:72 | "password" : String | HardcodedMongoCredentials.java:7:63:7:86 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:7:63:7:86 | toCharArray(...) | sensitive API call | +| HardcodedMongoCredentials.java:8:47:8:56 | "Username" | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | sensitive API call | +| HardcodedMongoCredentials.java:8:67:8:76 | "password" | HardcodedMongoCredentials.java:8:67:8:76 | "password" : String | HardcodedMongoCredentials.java:8:67:8:90 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:8:67:8:90 | toCharArray(...) | sensitive API call | +| HardcodedMongoCredentials.java:9:44:9:48 | "key" | HardcodedMongoCredentials.java:9:44:9:48 | "key" | HardcodedMongoCredentials.java:9:44:9:48 | "key" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:9:44:9:48 | "key" | sensitive API call | +| HardcodedMongoCredentials.java:10:47:10:51 | "key" | HardcodedMongoCredentials.java:10:47:10:51 | "key" | HardcodedMongoCredentials.java:10:47:10:51 | "key" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:10:47:10:51 | "key" | sensitive API call | | HardcodedShiroKey.java:9:46:9:54 | "TEST123" | HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | sensitive API call | | HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" | HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | HardcodedShiroKey.java:18:46:18:87 | decode(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:18:46:18:87 | decode(...) | sensitive API call | | HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" | HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | HardcodedShiroKey.java:26:46:26:109 | decode(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:26:46:26:109 | decode(...) | sensitive API call | +| HardcodedSshjCredentials.java:8:25:8:34 | "Username" | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | sensitive API call | +| HardcodedSshjCredentials.java:8:37:8:46 | "password" | HardcodedSshjCredentials.java:8:37:8:46 | "password" | HardcodedSshjCredentials.java:8:37:8:46 | "password" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:8:37:8:46 | "password" | sensitive API call | +| HardcodedSshjCredentials.java:9:27:9:36 | "Username" | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | sensitive API call | +| HardcodedSshjCredentials.java:9:39:9:48 | "password" | HardcodedSshjCredentials.java:9:39:9:48 | "password" : String | HardcodedSshjCredentials.java:9:39:9:62 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:9:39:9:62 | toCharArray(...) | sensitive API call | +| HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | sensitive API call | +| HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | sensitive API call | +| HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | sensitive API call | +| HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | sensitive API call | +| HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | sensitive API call | +| HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | sensitive API call | +| HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | sensitive API call | +| HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | sensitive API call | +| HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | sensitive API call | +| HardcodedTrileadSshCredentials.java:15:50:15:54 | "key" | HardcodedTrileadSshCredentials.java:15:50:15:54 | "key" : String | HardcodedTrileadSshCredentials.java:15:50:15:68 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:50:15:68 | toCharArray(...) | sensitive API call | +| HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | sensitive API call | +| HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | sensitive API call | +| HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | sensitive API call | | Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:15:36:15:38 | usr | Hard-coded value flows to $@. | Test.java:15:36:15:38 | usr | sensitive API call | | Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:17:39:17:41 | usr | Hard-coded value flows to $@. | Test.java:17:39:17:41 | usr | sensitive API call | | Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:18:39:18:41 | usr | Hard-coded value flows to $@. | Test.java:18:39:18:41 | usr | sensitive API call | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected index bf73fdaa93d..0b87b0c69c8 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected @@ -15,6 +15,10 @@ edges | User.java:2:30:2:39 | DEFAULT_PW : String | User.java:5:15:5:24 | DEFAULT_PW | | User.java:2:43:2:50 | "123456" : String | User.java:2:30:2:39 | DEFAULT_PW : String | nodes +| HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | semmle.label | "username" | +| HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | semmle.label | "password" | +| HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | semmle.label | "username" | +| HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | semmle.label | "password" | | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | semmle.label | this <.method> [post update] [clientSecret] : String | | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | semmle.label | this <.method> [post update] [username] : String | | HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | semmle.label | this <.field> [post update] [username] : String | @@ -29,6 +33,34 @@ nodes | HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String | | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | semmle.label | new HardcodedAzureCredentials(...) [username] : String | +| HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | semmle.label | "username" | +| HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | semmle.label | "password" | +| HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | semmle.label | "Username" | +| HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | semmle.label | "Username" | +| HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | semmle.label | "password" | +| HardcodedJschCredentials.java:10:41:10:50 | "Username" | semmle.label | "Username" | +| HardcodedJschCredentials.java:11:42:11:51 | "Username" | semmle.label | "Username" | +| HardcodedJschCredentials.java:12:27:12:36 | "password" | semmle.label | "password" | +| HardcodedMongoCredentials.java:5:38:5:47 | "Username" | semmle.label | "Username" | +| HardcodedMongoCredentials.java:6:45:6:54 | "Username" | semmle.label | "Username" | +| HardcodedMongoCredentials.java:7:43:7:52 | "Username" | semmle.label | "Username" | +| HardcodedMongoCredentials.java:8:47:8:56 | "Username" | semmle.label | "Username" | +| HardcodedMongoCredentials.java:9:44:9:48 | "key" | semmle.label | "key" | +| HardcodedMongoCredentials.java:10:47:10:51 | "key" | semmle.label | "key" | +| HardcodedSshjCredentials.java:8:25:8:34 | "Username" | semmle.label | "Username" | +| HardcodedSshjCredentials.java:8:37:8:46 | "password" | semmle.label | "password" | +| HardcodedSshjCredentials.java:9:27:9:36 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | semmle.label | "password" | +| HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | semmle.label | "key" | +| HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | semmle.label | "password" | +| HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | semmle.label | "Username" | +| HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | semmle.label | "password" | | Test.java:10:17:10:24 | "123456" : String | semmle.label | "123456" : String | | Test.java:26:17:26:20 | pass | semmle.label | pass | | User.java:2:30:2:39 | DEFAULT_PW : String | semmle.label | DEFAULT_PW : String | @@ -36,7 +68,39 @@ nodes | User.java:5:15:5:24 | DEFAULT_PW | semmle.label | DEFAULT_PW | subpaths #select +| HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | sensitive call | +| HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | sensitive call | +| HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | sensitive call | +| HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | sensitive call | | HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" | HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:18:13:18:20 | username | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:18:13:18:20 | username | sensitive call | | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | sensitive call | +| HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | Hard-coded value flows to $@. | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | sensitive call | +| HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | Hard-coded value flows to $@. | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | sensitive call | +| HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | sensitive call | +| HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | sensitive call | +| HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | sensitive call | +| HardcodedJschCredentials.java:10:41:10:50 | "Username" | HardcodedJschCredentials.java:10:41:10:50 | "Username" | HardcodedJschCredentials.java:10:41:10:50 | "Username" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:10:41:10:50 | "Username" | sensitive call | +| HardcodedJschCredentials.java:11:42:11:51 | "Username" | HardcodedJschCredentials.java:11:42:11:51 | "Username" | HardcodedJschCredentials.java:11:42:11:51 | "Username" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:11:42:11:51 | "Username" | sensitive call | +| HardcodedJschCredentials.java:12:27:12:36 | "password" | HardcodedJschCredentials.java:12:27:12:36 | "password" | HardcodedJschCredentials.java:12:27:12:36 | "password" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:12:27:12:36 | "password" | sensitive call | +| HardcodedMongoCredentials.java:5:38:5:47 | "Username" | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | sensitive call | +| HardcodedMongoCredentials.java:6:45:6:54 | "Username" | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | sensitive call | +| HardcodedMongoCredentials.java:7:43:7:52 | "Username" | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | sensitive call | +| HardcodedMongoCredentials.java:8:47:8:56 | "Username" | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | sensitive call | +| HardcodedMongoCredentials.java:9:44:9:48 | "key" | HardcodedMongoCredentials.java:9:44:9:48 | "key" | HardcodedMongoCredentials.java:9:44:9:48 | "key" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:9:44:9:48 | "key" | sensitive call | +| HardcodedMongoCredentials.java:10:47:10:51 | "key" | HardcodedMongoCredentials.java:10:47:10:51 | "key" | HardcodedMongoCredentials.java:10:47:10:51 | "key" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:10:47:10:51 | "key" | sensitive call | +| HardcodedSshjCredentials.java:8:25:8:34 | "Username" | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | sensitive call | +| HardcodedSshjCredentials.java:8:37:8:46 | "password" | HardcodedSshjCredentials.java:8:37:8:46 | "password" | HardcodedSshjCredentials.java:8:37:8:46 | "password" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:8:37:8:46 | "password" | sensitive call | +| HardcodedSshjCredentials.java:9:27:9:36 | "Username" | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | sensitive call | +| HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | sensitive call | +| HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | sensitive call | +| HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | sensitive call | +| HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | sensitive call | +| HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | sensitive call | +| HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | sensitive call | +| HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | sensitive call | +| HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | sensitive call | +| HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | sensitive call | +| HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | sensitive call | +| HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | sensitive call | | Test.java:10:17:10:24 | "123456" | Test.java:10:17:10:24 | "123456" : String | Test.java:26:17:26:20 | pass | Hard-coded value flows to $@. | Test.java:26:17:26:20 | pass | sensitive call | | User.java:2:43:2:50 | "123456" | User.java:2:43:2:50 | "123456" : String | User.java:5:15:5:24 | DEFAULT_PW | Hard-coded value flows to $@. | User.java:5:15:5:24 | DEFAULT_PW | sensitive call | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedGanymedSsh2Credentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedGanymedSsh2Credentials.java new file mode 100644 index 00000000000..b093a8b5f89 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedGanymedSsh2Credentials.java @@ -0,0 +1,11 @@ +import ch.ethz.ssh2.Connection; +import java.io.IOException; + +public class HardcodedGanymedSsh2Credentials { + public static void main(Connection conn) { + // BAD: Hardcoded credentials used for the session username and/or password. + try { + conn.authenticateWithPassword("username", "password"); + } catch(IOException e) { } + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJ2sshCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJ2sshCredentials.java new file mode 100644 index 00000000000..38831107966 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJ2sshCredentials.java @@ -0,0 +1,11 @@ +import com.sshtools.j2ssh.authentication.SshAuthenticationClient; +import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient; + +public class HardcodedJ2sshCredentials { + public static void main(SshAuthenticationClient client1, PasswordAuthenticationClient client2) { + // BAD: Hardcoded credentials used for the session username and/or password. + client1.setUsername("Username"); + client2.setUsername("Username"); + client2.setPassword("password"); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJschCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJschCredentials.java new file mode 100644 index 00000000000..b2b50d1d452 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJschCredentials.java @@ -0,0 +1,16 @@ +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import java.io.IOException; + +public class HardcodedJschCredentials { + public static void main(JSch jsch) { + // BAD: Hardcoded credentials used for the session username and/or password. + try { + Session session = jsch.getSession("Username", "hostname"); + Session session2 = jsch.getSession("Username", "hostname", 22); + session.setPassword("password"); + session2.setPassword("password".getBytes()); + } catch(JSchException e) { } + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedMongoCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedMongoCredentials.java new file mode 100644 index 00000000000..e08c96db945 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedMongoCredentials.java @@ -0,0 +1,12 @@ +import com.mongodb.MongoCredential; + +public class HardcodedMongoCredentials { + public static void test() { + MongoCredential.createCredential("Username", "blah", "password".toCharArray()); + MongoCredential.createMongoCRCredential("Username", "blah", "password".toCharArray()); + MongoCredential.createPlainCredential("Username", "blah", "password".toCharArray()); + MongoCredential.createScramSha1Credential("Username", "blah", "password".toCharArray()); + MongoCredential.createGSSAPICredential("key"); + MongoCredential.createMongoX509Credential("key"); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedSshjCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedSshjCredentials.java new file mode 100644 index 00000000000..d2222248053 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedSshjCredentials.java @@ -0,0 +1,13 @@ +import net.schmizz.sshj.SSHClient; +import java.io.IOException; + +public class HardcodedSshjCredentials { + public static void main(SSHClient client) { + // BAD: Hardcoded credentials used for the session username and/or password. + try { + client.authPassword("Username", "password"); + client.authPassword("Username", "password".toCharArray()); + } + catch(IOException e) { } + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedTrileadSshCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedTrileadSshCredentials.java new file mode 100644 index 00000000000..38279e49121 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedTrileadSshCredentials.java @@ -0,0 +1,19 @@ +import com.trilead.ssh2.Connection; + +import java.io.IOException; +import java.io.File; + +public class HardcodedTrileadSshCredentials { + public static void main(Connection conn) { + // BAD: Hardcoded credentials used for the session username and/or password. + try { + conn.authenticateWithPassword("Username", "password"); + conn.authenticateWithDSA("Username", "password", "key"); + conn.authenticateWithNone("Username"); + conn.getRemainingAuthMethods("Username"); + conn.isAuthMethodAvailable("Username", "method"); + conn.authenticateWithPublicKey("Username", "key".toCharArray(), "password"); + conn.authenticateWithPublicKey("Username", (File)null, "password"); + } catch(IOException e) { } + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/options b/java/ql/test/query-tests/security/CWE-798/semmle/tests/options index 2d21958e299..1009a2fc6e8 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/options +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/options @@ -1 +1 @@ -// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/amazon-aws-sdk-1.11.700:${testdir}/../../../../../stubs/azure-sdk-for-java:${testdir}/../../../../../stubs/shiro-core-1.4.0 +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/amazon-aws-sdk-1.11.700:${testdir}/../../../../../stubs/azure-sdk-for-java:${testdir}/../../../../../stubs/shiro-core-1.4.0:${testdir}/../../../../../stubs/jsch-0.1.55:${testdir}/../../../../../stubs/ganymed-ssh-2-260:${testdir}/../../../../../stubs/apache-mina-sshd-2.8.0:${testdir}/../../../../../stubs/sshj-0.33.0:${testdir}/../../../../../stubs/j2ssh-1.5.5:${testdir}/../../../../../stubs/trilead-ssh2-212:${testdir}/../../../../../stubs/apache-commons-net-3.8.0:${testdir}/../../../../../stubs/mongodbClient diff --git a/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/SocketClient.java b/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/SocketClient.java new file mode 100644 index 00000000000..91988ea1c9d --- /dev/null +++ b/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/SocketClient.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.net; + +public abstract class SocketClient +{ +} diff --git a/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/Configurable.java b/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/Configurable.java new file mode 100644 index 00000000000..28b4b07b1b7 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/Configurable.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.net.ftp; + +public interface Configurable { + +} diff --git a/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/FTP.java b/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/FTP.java new file mode 100644 index 00000000000..caaf9c6d1f8 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/FTP.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.net.ftp; + +import org.apache.commons.net.SocketClient; + +public class FTP extends SocketClient +{ +} diff --git a/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/FTPClient.java b/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/FTPClient.java new file mode 100644 index 00000000000..17d92709f88 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-net-3.8.0/org/apache/commons/net/ftp/FTPClient.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.net.ftp; + +import java.io.IOException; + +public class FTPClient extends FTP implements Configurable { + + public boolean login(final String username, final String password) throws IOException + { + return true; + } + + public boolean login(final String username, final String password, final String account) throws IOException + { + return true; + } + +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgent.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgent.java new file mode 100644 index 00000000000..9b5a4a5cda6 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgent.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.sshd.agent.SshAgent for testing purposes + +package org.apache.sshd.agent; + +import java.nio.channels.Channel; +import java.security.KeyPair; +import java.security.PublicKey; +import java.util.Map; +import org.apache.sshd.agent.SshAgentKeyConstraint; +import org.apache.sshd.common.session.SessionContext; + +public interface SshAgent extends Channel +{ + Iterable> getIdentities(); + Map.Entry sign(SessionContext p0, PublicKey p1, String p2, byte[] p3); + default KeyPair resolveLocalIdentity(PublicKey p0){ return null; } + static String SSH_AUTHSOCKET_ENV_NAME = null; + void addIdentity(KeyPair p0, String p1, SshAgentKeyConstraint... p2); + void removeAllIdentities(); + void removeIdentity(PublicKey p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentFactory.java new file mode 100644 index 00000000000..e41f65e0c2a --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentFactory.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.agent.SshAgentFactory for testing purposes + +package org.apache.sshd.agent; + +import java.util.List; +import org.apache.sshd.agent.SshAgent; +import org.apache.sshd.agent.SshAgentServer; +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.channel.ChannelFactory; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.session.Session; + +public interface SshAgentFactory +{ + List getChannelForwardingFactories(FactoryManager p0); + SshAgent createClient(Session p0, FactoryManager p1); + SshAgentServer createServer(ConnectionService p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentKeyConstraint.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentKeyConstraint.java new file mode 100644 index 00000000000..2a030d56b33 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentKeyConstraint.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.agent.SshAgentKeyConstraint for testing purposes + +package org.apache.sshd.agent; + +import org.apache.sshd.common.util.buffer.Buffer; + +abstract public class SshAgentKeyConstraint +{ + protected SshAgentKeyConstraint() {} + protected SshAgentKeyConstraint(byte p0){} + public byte getId(){ return 0; } + public static SshAgentKeyConstraint CONFIRM = null; + public void put(Buffer p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentServer.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentServer.java new file mode 100644 index 00000000000..0bdb01f3f2e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/SshAgentServer.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.agent.SshAgentServer for testing purposes + +package org.apache.sshd.agent; + +import java.nio.channels.Channel; + +public interface SshAgentServer extends Channel +{ + String getId(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/common/AgentForwardSupport.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/common/AgentForwardSupport.java new file mode 100644 index 00000000000..62b16f0d0d5 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/agent/common/AgentForwardSupport.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.agent.common.AgentForwardSupport for testing purposes + +package org.apache.sshd.agent.common; + +import org.apache.sshd.common.Closeable; + +public interface AgentForwardSupport extends Closeable +{ + String initialize(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/ClientAuthenticationManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/ClientAuthenticationManager.java new file mode 100644 index 00000000000..ac77d662f7e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/ClientAuthenticationManager.java @@ -0,0 +1,43 @@ +// Generated automatically from org.apache.sshd.client.ClientAuthenticationManager for testing purposes + +package org.apache.sshd.client; + +import java.security.KeyPair; +import java.util.Collection; +import org.apache.sshd.client.auth.AuthenticationIdentitiesProvider; +import org.apache.sshd.client.auth.UserAuth; +import org.apache.sshd.client.auth.UserAuthFactory; +import org.apache.sshd.client.auth.hostbased.HostBasedAuthenticationReporter; +import org.apache.sshd.client.auth.keyboard.UserInteraction; +import org.apache.sshd.client.auth.password.PasswordAuthenticationReporter; +import org.apache.sshd.client.auth.password.PasswordIdentityProvider; +import org.apache.sshd.client.auth.pubkey.PublicKeyAuthenticationReporter; +import org.apache.sshd.client.keyverifier.ServerKeyVerifier; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.common.auth.UserAuthFactoriesManager; +import org.apache.sshd.common.auth.UserAuthInstance; +import org.apache.sshd.common.auth.UserAuthMethodFactory; +import org.apache.sshd.common.keyprovider.KeyIdentityProviderHolder; +import org.apache.sshd.common.session.SessionContext; + +public interface ClientAuthenticationManager extends KeyIdentityProviderHolder, UserAuthFactoriesManager +{ + AuthenticationIdentitiesProvider getRegisteredIdentities(); + HostBasedAuthenticationReporter getHostBasedAuthenticationReporter(); + KeyPair removePublicKeyIdentity(KeyPair p0); + PasswordAuthenticationReporter getPasswordAuthenticationReporter(); + PasswordIdentityProvider getPasswordIdentityProvider(); + PublicKeyAuthenticationReporter getPublicKeyAuthenticationReporter(); + ServerKeyVerifier getServerKeyVerifier(); + String removePasswordIdentity(String p0); + UserInteraction getUserInteraction(); + default void setUserAuthFactoriesNames(Collection p0){} + void addPasswordIdentity(String p0); + void addPublicKeyIdentity(KeyPair p0); + void setHostBasedAuthenticationReporter(HostBasedAuthenticationReporter p0); + void setPasswordAuthenticationReporter(PasswordAuthenticationReporter p0); + void setPasswordIdentityProvider(PasswordIdentityProvider p0); + void setPublicKeyAuthenticationReporter(PublicKeyAuthenticationReporter p0); + void setServerKeyVerifier(ServerKeyVerifier p0); + void setUserInteraction(UserInteraction p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/ClientFactoryManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/ClientFactoryManager.java new file mode 100644 index 00000000000..9cedaf33c52 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/ClientFactoryManager.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.client.ClientFactoryManager for testing purposes + +package org.apache.sshd.client; + +import org.apache.sshd.client.ClientAuthenticationManager; +import org.apache.sshd.client.config.hosts.HostConfigEntryResolver; +import org.apache.sshd.client.config.keys.ClientIdentityLoaderManager; +import org.apache.sshd.client.session.ClientProxyConnectorHolder; +import org.apache.sshd.client.session.ClientSessionCreator; +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.config.keys.FilePasswordProviderManager; + +public interface ClientFactoryManager extends ClientAuthenticationManager, ClientIdentityLoaderManager, ClientProxyConnectorHolder, ClientSessionCreator, FactoryManager, FilePasswordProviderManager +{ + HostConfigEntryResolver getHostConfigEntryResolver(); + void setHostConfigEntryResolver(HostConfigEntryResolver p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/SshClient.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/SshClient.java new file mode 100644 index 00000000000..037e87fdc0e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/SshClient.java @@ -0,0 +1,108 @@ +// Generated automatically from org.apache.sshd.client.SshClient for testing purposes + +package org.apache.sshd.client; + +import java.net.SocketAddress; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.security.KeyPair; +import java.util.Collection; +import java.util.List; +import org.apache.sshd.client.ClientFactoryManager; +import org.apache.sshd.client.auth.AuthenticationIdentitiesProvider; +import org.apache.sshd.client.auth.UserAuthFactory; +import org.apache.sshd.client.auth.hostbased.HostBasedAuthenticationReporter; +import org.apache.sshd.client.auth.keyboard.UserInteraction; +import org.apache.sshd.client.auth.password.PasswordAuthenticationReporter; +import org.apache.sshd.client.auth.password.PasswordIdentityProvider; +import org.apache.sshd.client.auth.pubkey.PublicKeyAuthenticationReporter; +import org.apache.sshd.client.config.hosts.HostConfigEntry; +import org.apache.sshd.client.config.hosts.HostConfigEntryResolver; +import org.apache.sshd.client.config.keys.ClientIdentityLoader; +import org.apache.sshd.client.future.ConnectFuture; +import org.apache.sshd.client.keyverifier.ServerKeyVerifier; +import org.apache.sshd.client.session.ClientProxyConnector; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.SessionFactory; +import org.apache.sshd.client.simple.SimpleClient; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.Factory; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.ServiceFactory; +import org.apache.sshd.common.config.keys.FilePasswordProvider; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.SshFutureListener; +import org.apache.sshd.common.helpers.AbstractFactoryManager; +import org.apache.sshd.common.io.IoConnectFuture; +import org.apache.sshd.common.io.IoConnector; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; + +public class SshClient extends AbstractFactoryManager implements ClientFactoryManager, Closeable +{ + protected Closeable getInnerCloseable(){ return null; } + protected ConnectFuture doConnect(HostConfigEntry p0, List p1, AttributeRepository p2, SocketAddress p3){ return null; } + protected ConnectFuture doConnect(String p0, SocketAddress p1, AttributeRepository p2, SocketAddress p3, KeyIdentityProvider p4, HostConfigEntry p5){ return null; } + protected HostConfigEntry resolveHost(String p0, String p1, int p2, AttributeRepository p3, SocketAddress p4){ return null; } + protected IoConnector connector = null; + protected IoConnector createConnector(){ return null; } + protected KeyIdentityProvider preloadClientIdentities(Collection p0){ return null; } + protected List parseProxyJumps(String p0, AttributeRepository p1){ return null; } + protected List userAuthFactories = null; + protected SessionFactory createSessionFactory(){ return null; } + protected SessionFactory sessionFactory = null; + protected SshFutureListener createConnectCompletionListener(ConnectFuture p0, String p1, SocketAddress p2, KeyIdentityProvider p3, HostConfigEntry p4){ return null; } + protected void checkConfig(){} + protected void onConnectOperationComplete(IoSession p0, ConnectFuture p1, String p2, SocketAddress p3, KeyIdentityProvider p4, HostConfigEntry p5){} + protected void setupDefaultSessionIdentities(ClientSession p0, KeyIdentityProvider p1){} + public AuthenticationIdentitiesProvider getRegisteredIdentities(){ return null; } + public ClientIdentityLoader getClientIdentityLoader(){ return null; } + public ClientProxyConnector getClientProxyConnector(){ return null; } + public ConnectFuture connect(HostConfigEntry p0, AttributeRepository p1, SocketAddress p2){ return null; } + public ConnectFuture connect(String p0){ return null; } + public ConnectFuture connect(String p0, SocketAddress p1, AttributeRepository p2, SocketAddress p3){ return null; } + public ConnectFuture connect(String p0, String p1, int p2, AttributeRepository p3, SocketAddress p4){ return null; } + public FilePasswordProvider getFilePasswordProvider(){ return null; } + public HostBasedAuthenticationReporter getHostBasedAuthenticationReporter(){ return null; } + public HostConfigEntryResolver getHostConfigEntryResolver(){ return null; } + public KeyIdentityProvider getKeyIdentityProvider(){ return null; } + public KeyPair removePublicKeyIdentity(KeyPair p0){ return null; } + public List getUserAuthFactories(){ return null; } + public PasswordAuthenticationReporter getPasswordAuthenticationReporter(){ return null; } + public PasswordIdentityProvider getPasswordIdentityProvider(){ return null; } + public PublicKeyAuthenticationReporter getPublicKeyAuthenticationReporter(){ return null; } + public ServerKeyVerifier getServerKeyVerifier(){ return null; } + public SessionFactory getSessionFactory(){ return null; } + public SshClient(){} + public String removePasswordIdentity(String p0){ return null; } + public String toString(){ return null; } + public UserInteraction getUserInteraction(){ return null; } + public boolean isStarted(){ return false; } + public static C setKeyPairProvider(C p0, Path p1, boolean p2, boolean p3, FilePasswordProvider p4, LinkOption... p5){ return null; } + public static C setKeyPairProvider(C p0, boolean p1, boolean p2, FilePasswordProvider p3, LinkOption... p4){ return null; } + public static Factory DEFAULT_SSH_CLIENT_FACTORY = null; + public static List DEFAULT_SERVICE_FACTORIES = null; + public static List DEFAULT_USER_AUTH_FACTORIES = null; + public static SimpleClient setUpDefaultSimpleClient(){ return null; } + public static SimpleClient wrapAsSimpleClient(SshClient p0){ return null; } + public static SshClient setUpDefaultClient(){ return null; } + public void addPasswordIdentity(String p0){} + public void addPublicKeyIdentity(KeyPair p0){} + public void open(){} + public void setClientIdentityLoader(ClientIdentityLoader p0){} + public void setClientProxyConnector(ClientProxyConnector p0){} + public void setFilePasswordProvider(FilePasswordProvider p0){} + public void setHostBasedAuthenticationReporter(HostBasedAuthenticationReporter p0){} + public void setHostConfigEntryResolver(HostConfigEntryResolver p0){} + public void setKeyIdentityProvider(KeyIdentityProvider p0){} + public void setPasswordAuthenticationReporter(PasswordAuthenticationReporter p0){} + public void setPasswordIdentityProvider(PasswordIdentityProvider p0){} + public void setPublicKeyAuthenticationReporter(PublicKeyAuthenticationReporter p0){} + public void setServerKeyVerifier(ServerKeyVerifier p0){} + public void setSessionFactory(SessionFactory p0){} + public void setUserAuthFactories(List p0){} + public void setUserInteraction(UserInteraction p0){} + public void start(){} + public void stop(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/AuthenticationIdentitiesProvider.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/AuthenticationIdentitiesProvider.java new file mode 100644 index 00000000000..394aa7bccd4 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/AuthenticationIdentitiesProvider.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.client.auth.AuthenticationIdentitiesProvider for testing purposes + +package org.apache.sshd.client.auth; + +import java.util.Comparator; +import java.util.List; +import org.apache.sshd.client.auth.password.PasswordIdentityProvider; +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; +import org.apache.sshd.common.session.SessionContext; + +public interface AuthenticationIdentitiesProvider extends KeyIdentityProvider, PasswordIdentityProvider +{ + Iterable loadIdentities(SessionContext p0); + static AuthenticationIdentitiesProvider wrapIdentities(Iterable p0){ return null; } + static Comparator KEYPAIR_IDENTITY_COMPARATOR = null; + static Comparator PASSWORD_IDENTITY_COMPARATOR = null; + static int findIdentityIndex(List p0, Comparator p1, Object p2){ return 0; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/UserAuth.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/UserAuth.java new file mode 100644 index 00000000000..471fb2ea214 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/UserAuth.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.sshd.client.auth.UserAuth for testing purposes + +package org.apache.sshd.client.auth; + +import java.util.List; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.ClientSessionHolder; +import org.apache.sshd.common.auth.UserAuthInstance; +import org.apache.sshd.common.session.SessionContext; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface UserAuth extends ClientSessionHolder, UserAuthInstance +{ + boolean process(Buffer p0); + default void signalAuthMethodFailure(ClientSession p0, String p1, boolean p2, List p3, Buffer p4){} + default void signalAuthMethodSuccess(ClientSession p0, String p1, Buffer p2){} + void destroy(); + void init(ClientSession p0, String p1); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/UserAuthFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/UserAuthFactory.java new file mode 100644 index 00000000000..268ebb63afb --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/UserAuthFactory.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.client.auth.UserAuthFactory for testing purposes + +package org.apache.sshd.client.auth; + +import org.apache.sshd.client.auth.UserAuth; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.common.auth.UserAuthInstance; +import org.apache.sshd.common.auth.UserAuthMethodFactory; +import org.apache.sshd.common.session.SessionContext; + +public interface UserAuthFactory extends UserAuthMethodFactory +{ +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/hostbased/HostBasedAuthenticationReporter.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/hostbased/HostBasedAuthenticationReporter.java new file mode 100644 index 00000000000..0e56d4bcfb1 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/hostbased/HostBasedAuthenticationReporter.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.client.auth.hostbased.HostBasedAuthenticationReporter for testing purposes + +package org.apache.sshd.client.auth.hostbased; + +import java.security.KeyPair; +import java.util.List; +import org.apache.sshd.client.session.ClientSession; + +public interface HostBasedAuthenticationReporter +{ + default void signalAuthenticationAttempt(ClientSession p0, String p1, KeyPair p2, String p3, String p4, byte[] p5){} + default void signalAuthenticationExhausted(ClientSession p0, String p1, String p2, String p3){} + default void signalAuthenticationFailure(ClientSession p0, String p1, KeyPair p2, String p3, String p4, boolean p5, List p6){} + default void signalAuthenticationSuccess(ClientSession p0, String p1, KeyPair p2, String p3, String p4){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/keyboard/UserInteraction.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/keyboard/UserInteraction.java new file mode 100644 index 00000000000..43a0b3b2d4d --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/keyboard/UserInteraction.java @@ -0,0 +1,26 @@ +// Generated automatically from org.apache.sshd.client.auth.keyboard.UserInteraction for testing purposes + +package org.apache.sshd.client.auth.keyboard; + +import java.security.KeyPair; +import java.util.List; +import org.apache.sshd.client.session.ClientSession; + +public interface UserInteraction +{ + String getUpdatedPassword(ClientSession p0, String p1, String p2); + String[] interactive(ClientSession p0, String p1, String p2, String p3, String[] p4, boolean[] p5); + default KeyPair resolveAuthPublicKeyIdentityAttempt(ClientSession p0){ return null; } + default String resolveAuthPasswordAttempt(ClientSession p0){ return null; } + default boolean isInteractionAllowed(ClientSession p0){ return false; } + default void serverVersionInfo(ClientSession p0, List p1){} + default void welcome(ClientSession p0, String p1, String p2){} + static String AUTO_DETECT_PASSWORD_PROMPT = null; + static String CHECK_INTERACTIVE_PASSWORD_DELIM = null; + static String DEFAULT_CHECK_INTERACTIVE_PASSWORD_DELIM = null; + static String DEFAULT_INTERACTIVE_PASSWORD_PROMPT = null; + static String INTERACTIVE_PASSWORD_PROMPT = null; + static UserInteraction NONE = null; + static boolean DEFAULT_AUTO_DETECT_PASSWORD_PROMPT = false; + static int findPromptComponentLastPosition(String p0, String p1){ return 0; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/password/PasswordAuthenticationReporter.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/password/PasswordAuthenticationReporter.java new file mode 100644 index 00000000000..5b96b94daac --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/password/PasswordAuthenticationReporter.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.client.auth.password.PasswordAuthenticationReporter for testing purposes + +package org.apache.sshd.client.auth.password; + +import java.util.List; +import org.apache.sshd.client.session.ClientSession; + +public interface PasswordAuthenticationReporter +{ + default void signalAuthenticationAttempt(ClientSession p0, String p1, String p2, boolean p3, String p4){} + default void signalAuthenticationExhausted(ClientSession p0, String p1){} + default void signalAuthenticationFailure(ClientSession p0, String p1, String p2, boolean p3, List p4){} + default void signalAuthenticationSuccess(ClientSession p0, String p1, String p2){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java new file mode 100644 index 00000000000..7da0b2b5f0e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.sshd.client.auth.password.PasswordIdentityProvider for testing purposes + +package org.apache.sshd.client.auth.password; + +import java.util.Collection; +import java.util.Iterator; +import org.apache.sshd.common.session.SessionContext; + +public interface PasswordIdentityProvider +{ + Iterable loadPasswords(SessionContext p0); + static Iterable iterableOf(SessionContext p0, Collection p1){ return null; } + static Iterator iteratorOf(SessionContext p0, PasswordIdentityProvider p1){ return null; } + static Iterator iteratorOf(SessionContext p0, PasswordIdentityProvider p1, PasswordIdentityProvider p2){ return null; } + static PasswordIdentityProvider EMPTY_PASSWORDS_PROVIDER = null; + static PasswordIdentityProvider multiProvider(SessionContext p0, Collection p1){ return null; } + static PasswordIdentityProvider multiProvider(SessionContext p0, PasswordIdentityProvider... p1){ return null; } + static PasswordIdentityProvider resolvePasswordIdentityProvider(SessionContext p0, PasswordIdentityProvider p1, PasswordIdentityProvider p2){ return null; } + static PasswordIdentityProvider wrapPasswords(Iterable p0){ return null; } + static PasswordIdentityProvider wrapPasswords(String... p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/pubkey/PublicKeyAuthenticationReporter.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/pubkey/PublicKeyAuthenticationReporter.java new file mode 100644 index 00000000000..51b61cd10d3 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/auth/pubkey/PublicKeyAuthenticationReporter.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.client.auth.pubkey.PublicKeyAuthenticationReporter for testing purposes + +package org.apache.sshd.client.auth.pubkey; + +import java.security.KeyPair; +import java.util.List; +import org.apache.sshd.client.session.ClientSession; + +public interface PublicKeyAuthenticationReporter +{ + default void signalAuthenticationAttempt(ClientSession p0, String p1, KeyPair p2, String p3){} + default void signalAuthenticationExhausted(ClientSession p0, String p1){} + default void signalAuthenticationFailure(ClientSession p0, String p1, KeyPair p2, boolean p3, List p4){} + default void signalAuthenticationSuccess(ClientSession p0, String p1, KeyPair p2){} + default void signalSignatureAttempt(ClientSession p0, String p1, KeyPair p2, String p3, byte[] p4){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/AbstractClientChannel.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/AbstractClientChannel.java new file mode 100644 index 00000000000..fd74e0627b8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/AbstractClientChannel.java @@ -0,0 +1,78 @@ +// Generated automatically from org.apache.sshd.client.channel.AbstractClientChannel for testing purposes + +package org.apache.sshd.client.channel; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collection; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import org.apache.sshd.client.channel.ClientChannel; +import org.apache.sshd.client.channel.ClientChannelEvent; +import org.apache.sshd.client.future.OpenFuture; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.channel.AbstractChannel; +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.channel.ChannelAsyncInputStream; +import org.apache.sshd.common.channel.ChannelAsyncOutputStream; +import org.apache.sshd.common.channel.RequestHandler; +import org.apache.sshd.common.channel.StreamingChannel; +import org.apache.sshd.common.io.IoInputStream; +import org.apache.sshd.common.io.IoOutputStream; +import org.apache.sshd.common.util.EventNotifier; +import org.apache.sshd.common.util.buffer.Buffer; + +abstract public class AbstractClientChannel extends AbstractChannel implements ClientChannel +{ + protected AbstractClientChannel() {} + protected > C updateCurrentChannelState(C p0){ return null; } + protected AbstractClientChannel(String p0){} + protected AbstractClientChannel(String p0, Collection> p1){} + protected ChannelAsyncInputStream asyncErr = null; + protected ChannelAsyncInputStream asyncOut = null; + protected ChannelAsyncOutputStream asyncIn = null; + protected Closeable getInnerCloseable(){ return null; } + protected InputStream in = null; + protected InputStream invertedErr = null; + protected InputStream invertedOut = null; + protected OpenFuture openFuture = null; + protected OutputStream err = null; + protected OutputStream invertedIn = null; + protected OutputStream out = null; + protected StreamingChannel.Streaming streaming = null; + protected String openFailureLang = null; + protected String openFailureMsg = null; + protected abstract void doOpen(); + protected final AtomicBoolean opened = null; + protected final AtomicReference exitStatusHolder = null; + protected final AtomicReference exitSignalHolder = null; + protected int openFailureReason = 0; + protected void addChannelSignalRequestHandlers(EventNotifier p0){} + protected void doWriteData(byte[] p0, int p1, long p2){} + protected void doWriteExtendedData(byte[] p0, int p1, long p2){} + public InputStream getIn(){ return null; } + public InputStream getInvertedErr(){ return null; } + public InputStream getInvertedOut(){ return null; } + public Integer getExitStatus(){ return null; } + public IoInputStream getAsyncErr(){ return null; } + public IoInputStream getAsyncOut(){ return null; } + public IoOutputStream getAsyncIn(){ return null; } + public OpenFuture open(){ return null; } + public OpenFuture open(int p0, long p1, long p2, Buffer p3){ return null; } + public OutputStream getErr(){ return null; } + public OutputStream getInvertedIn(){ return null; } + public OutputStream getOut(){ return null; } + public Set getChannelState(){ return null; } + public Set waitFor(Collection p0, long p1){ return null; } + public StreamingChannel.Streaming getStreaming(){ return null; } + public String getChannelType(){ return null; } + public String getExitSignal(){ return null; } + public void handleOpenFailure(Buffer p0){} + public void handleOpenSuccess(int p0, long p1, long p2, Buffer p3){} + public void handleWindowAdjust(Buffer p0){} + public void setErr(OutputStream p0){} + public void setIn(InputStream p0){} + public void setOut(OutputStream p0){} + public void setStreaming(StreamingChannel.Streaming p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelDirectTcpip.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelDirectTcpip.java new file mode 100644 index 00000000000..f943a8630f4 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelDirectTcpip.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.client.channel.ChannelDirectTcpip for testing purposes + +package org.apache.sshd.client.channel; + +import org.apache.sshd.client.channel.AbstractClientChannel; +import org.apache.sshd.client.future.OpenFuture; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public class ChannelDirectTcpip extends AbstractClientChannel +{ + protected ChannelDirectTcpip() {} + protected void doOpen(){} + protected void doWriteData(byte[] p0, int p1, long p2){} + public ChannelDirectTcpip(SshdSocketAddress p0, SshdSocketAddress p1){} + public OpenFuture open(){ return null; } + public SshdSocketAddress getLocalSocketAddress(){ return null; } + public SshdSocketAddress getRemoteSocketAddress(){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelExec.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelExec.java new file mode 100644 index 00000000000..79d2623abac --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelExec.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.client.channel.ChannelExec for testing purposes + +package org.apache.sshd.client.channel; + +import java.util.Map; +import org.apache.sshd.client.channel.PtyCapableChannelSession; +import org.apache.sshd.common.channel.PtyChannelConfigurationHolder; + +public class ChannelExec extends PtyCapableChannelSession +{ + protected ChannelExec() {} + protected void doOpen(){} + public ChannelExec(String p0, PtyChannelConfigurationHolder p1, Map p2){} + public void handleFailure(){} + public void handleSuccess(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelSession.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelSession.java new file mode 100644 index 00000000000..e795b315b28 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelSession.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.sshd.client.channel.ChannelSession for testing purposes + +package org.apache.sshd.client.channel; + +import java.io.InputStream; +import org.apache.sshd.client.channel.AbstractClientChannel; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.channel.RequestHandler; +import org.apache.sshd.common.util.buffer.Buffer; + +public class ChannelSession extends AbstractClientChannel +{ + protected Closeable getInnerCloseable(){ return null; } + protected RequestHandler.Result handleInternalRequest(String p0, boolean p1, Buffer p2){ return null; } + protected RequestHandler.Result handleXonXoff(Buffer p0, boolean p1){ return null; } + protected int securedRead(InputStream p0, int p1, byte[] p2, int p3, int p4){ return 0; } + protected void closeImmediately0(){} + protected void doOpen(){} + protected void pumpInputStream(){} + public ChannelSession(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelShell.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelShell.java new file mode 100644 index 00000000000..5cc71848754 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelShell.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.client.channel.ChannelShell for testing purposes + +package org.apache.sshd.client.channel; + +import java.util.Map; +import org.apache.sshd.client.channel.PtyCapableChannelSession; +import org.apache.sshd.common.channel.PtyChannelConfigurationHolder; + +public class ChannelShell extends PtyCapableChannelSession +{ + protected ChannelShell() {} + protected void doOpen(){} + public ChannelShell(PtyChannelConfigurationHolder p0, Map p1){} + public void handleFailure(){} + public void handleSuccess(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelSubsystem.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelSubsystem.java new file mode 100644 index 00000000000..d993167cbac --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ChannelSubsystem.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.client.channel.ChannelSubsystem for testing purposes + +package org.apache.sshd.client.channel; + +import org.apache.sshd.client.channel.ChannelSession; + +public class ChannelSubsystem extends ChannelSession +{ + protected ChannelSubsystem() {} + protected void doOpen(){} + public ChannelSubsystem(String p0){} + public String toString(){ return null; } + public final String getSubsystem(){ return null; } + public void handleFailure(){} + public void handleSuccess(){} + public void onClose(Runnable p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ClientChannel.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ClientChannel.java new file mode 100644 index 00000000000..192598fcd4c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ClientChannel.java @@ -0,0 +1,39 @@ +// Generated automatically from org.apache.sshd.client.channel.ClientChannel for testing purposes + +package org.apache.sshd.client.channel; + +import java.io.InputStream; +import java.io.OutputStream; +import java.time.Duration; +import java.util.Collection; +import java.util.Set; +import org.apache.sshd.client.channel.ClientChannelEvent; +import org.apache.sshd.client.future.OpenFuture; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.ClientSessionHolder; +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.channel.StreamingChannel; +import org.apache.sshd.common.io.IoInputStream; +import org.apache.sshd.common.io.IoOutputStream; + +public interface ClientChannel extends Channel, ClientSessionHolder, StreamingChannel +{ + InputStream getInvertedErr(); + InputStream getInvertedOut(); + Integer getExitStatus(); + IoInputStream getAsyncErr(); + IoInputStream getAsyncOut(); + IoOutputStream getAsyncIn(); + OpenFuture open(); + OutputStream getInvertedIn(); + Set getChannelState(); + Set waitFor(Collection p0, long p1); + String getChannelType(); + String getExitSignal(); + default ClientSession getClientSession(){ return null; } + default Set waitFor(Collection p0, Duration p1){ return null; } + static void validateCommandExitStatusCode(String p0, Integer p1){} + void setErr(OutputStream p0); + void setIn(InputStream p0); + void setOut(OutputStream p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ClientChannelEvent.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ClientChannelEvent.java new file mode 100644 index 00000000000..a1025438748 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/ClientChannelEvent.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.client.channel.ClientChannelEvent for testing purposes + +package org.apache.sshd.client.channel; + +import java.util.Set; + +public enum ClientChannelEvent +{ + CLOSED, EOF, EXIT_SIGNAL, EXIT_STATUS, OPENED, STDERR_DATA, STDOUT_DATA, TIMEOUT; + private ClientChannelEvent() {} + public static Set VALUES = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/PtyCapableChannelSession.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/PtyCapableChannelSession.java new file mode 100644 index 00000000000..a2d501d3968 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/channel/PtyCapableChannelSession.java @@ -0,0 +1,37 @@ +// Generated automatically from org.apache.sshd.client.channel.PtyCapableChannelSession for testing purposes + +package org.apache.sshd.client.channel; + +import java.util.Map; +import org.apache.sshd.client.channel.ChannelSession; +import org.apache.sshd.common.channel.PtyChannelConfigurationHolder; +import org.apache.sshd.common.channel.PtyChannelConfigurationMutator; +import org.apache.sshd.common.channel.PtyMode; + +public class PtyCapableChannelSession extends ChannelSession implements PtyChannelConfigurationMutator +{ + protected PtyCapableChannelSession() {} + protected String resolvePtyType(PtyChannelConfigurationHolder p0){ return null; } + protected void doOpenPty(){} + public Map getPtyModes(){ return null; } + public Object setEnv(String p0, Object p1){ return null; } + public PtyCapableChannelSession(boolean p0, PtyChannelConfigurationHolder p1, Map p2){} + public String getPtyType(){ return null; } + public boolean isAgentForwarding(){ return false; } + public boolean isUsePty(){ return false; } + public int getPtyColumns(){ return 0; } + public int getPtyHeight(){ return 0; } + public int getPtyLines(){ return 0; } + public int getPtyWidth(){ return 0; } + public void sendWindowChange(int p0, int p1){} + public void sendWindowChange(int p0, int p1, int p2, int p3){} + public void setAgentForwarding(boolean p0){} + public void setPtyColumns(int p0){} + public void setPtyHeight(int p0){} + public void setPtyLines(int p0){} + public void setPtyModes(Map p0){} + public void setPtyType(String p0){} + public void setPtyWidth(int p0){} + public void setUsePty(boolean p0){} + public void setupSensibleDefaultPty(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostConfigEntry.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostConfigEntry.java new file mode 100644 index 00000000000..417d06c1329 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostConfigEntry.java @@ -0,0 +1,113 @@ +// Generated automatically from org.apache.sshd.client.config.hosts.HostConfigEntry for testing purposes + +package org.apache.sshd.client.config.hosts; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.net.URL; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NavigableSet; +import org.apache.sshd.client.config.hosts.HostConfigEntryResolver; +import org.apache.sshd.client.config.hosts.HostPatternsHolder; +import org.apache.sshd.common.auth.MutableUserHolder; + +public class HostConfigEntry extends HostPatternsHolder implements MutableUserHolder +{ + public A append(A p0){ return null; } + public Collection getIdentities(){ return null; } + public HostConfigEntry(){} + public HostConfigEntry(String p0, String p1, int p2, String p3){} + public HostConfigEntry(String p0, String p1, int p2, String p3, String p4){} + public Map getProperties(){ return null; } + public Map updateGlobalProperties(Map p0){ return null; } + public String appendPropertyValue(String p0, String p1){ return null; } + public String getHost(){ return null; } + public String getHostName(){ return null; } + public String getProperty(String p0){ return null; } + public String getProperty(String p0, String p1){ return null; } + public String getProxyJump(){ return null; } + public String getUsername(){ return null; } + public String removeProperty(String p0){ return null; } + public String resolveHostName(String p0){ return null; } + public String resolveProxyJump(String p0){ return null; } + public String resolveUsername(String p0){ return null; } + public String setProperty(String p0, String p1){ return null; } + public String toString(){ return null; } + public boolean isIdentitiesOnly(){ return false; } + public boolean processGlobalValues(HostConfigEntry p0){ return false; } + public boolean updateGlobalHostName(String p0){ return false; } + public boolean updateGlobalIdentities(Collection p0){ return false; } + public boolean updateGlobalIdentityOnly(boolean p0){ return false; } + public boolean updateGlobalPort(int p0){ return false; } + public boolean updateGlobalUserName(String p0){ return false; } + public int getPort(){ return 0; } + public int resolvePort(int p0){ return 0; } + public static A appendHostConfigEntries(A p0, Collection p1){ return null; } + public static A appendNonEmptyPort(A p0, String p1, int p2){ return null; } + public static A appendNonEmptyProperties(A p0, Map p1){ return null; } + public static A appendNonEmptyProperty(A p0, String p1, Object p2){ return null; } + public static A appendNonEmptyValues(A p0, String p1, Collection p2){ return null; } + public static A appendNonEmptyValues(A p0, String p1, Object... p2){ return null; } + public static HostConfigEntry findBestMatch(Collection p0){ return null; } + public static HostConfigEntry findBestMatch(Iterable p0){ return null; } + public static HostConfigEntry findBestMatch(Iterator p0){ return null; } + public static HostConfigEntry normalizeEntry(HostConfigEntry p0, String p1, int p2, String p3, String p4){ return null; } + public static HostConfigEntryResolver toHostConfigEntryResolver(Collection p0){ return null; } + public static List readHostConfigEntries(BufferedReader p0){ return null; } + public static List readHostConfigEntries(InputStream p0, boolean p1){ return null; } + public static List readHostConfigEntries(Path p0, OpenOption... p1){ return null; } + public static List readHostConfigEntries(Reader p0, boolean p1){ return null; } + public static List readHostConfigEntries(URL p0){ return null; } + public static List updateEntriesList(List p0, HostConfigEntry p1){ return null; } + public static List parseConfigValue(String p0){ return null; } + public static NavigableSet EXPLICIT_PROPERTIES = null; + public static Path getDefaultHostConfigFile(){ return null; } + public static String EXCLUSIVE_IDENTITIES_CONFIG_PROP = null; + public static String HOST_CONFIG_PROP = null; + public static String HOST_NAME_CONFIG_PROP = null; + public static String IDENTITY_AGENT = null; + public static String IDENTITY_FILE_CONFIG_PROP = null; + public static String MULTI_VALUE_SEPARATORS = null; + public static String PORT_CONFIG_PROP = null; + public static String PROXY_JUMP_CONFIG_PROP = null; + public static String STD_CONFIG_FILENAME = null; + public static String USER_CONFIG_PROP = null; + public static String resolveHostName(String p0, String p1){ return null; } + public static String resolveIdentityFilePath(String p0, String p1, int p2, String p3){ return null; } + public static String resolveProxyJump(String p0, String p1){ return null; } + public static String resolveUsername(String p0, String p1){ return null; } + public static StringBuilder appendUserHome(StringBuilder p0){ return null; } + public static StringBuilder appendUserHome(StringBuilder p0, Path p1){ return null; } + public static StringBuilder appendUserHome(StringBuilder p0, String p1){ return null; } + public static boolean DEFAULT_EXCLUSIVE_IDENTITIES = false; + public static char HOME_TILDE_CHAR = '0'; + public static char LOCAL_HOME_MACRO = '0'; + public static char LOCAL_HOST_MACRO = '0'; + public static char LOCAL_USER_MACRO = '0'; + public static char PATH_MACRO_CHAR = '0'; + public static char REMOTE_HOST_MACRO = '0'; + public static char REMOTE_PORT_MACRO = '0'; + public static char REMOTE_USER_MACRO = '0'; + public static int resolvePort(int p0, int p1){ return 0; } + public static void writeHostConfigEntries(OutputStream p0, boolean p1, Collection p2){} + public static void writeHostConfigEntries(Path p0, Collection p1, OpenOption... p2){} + public void addIdentity(Path p0){} + public void addIdentity(String p0){} + public void processProperty(String p0, Collection p1, boolean p2){} + public void setHost(Collection p0){} + public void setHost(String p0){} + public void setHostName(String p0){} + public void setIdentities(Collection p0){} + public void setIdentitiesOnly(boolean p0){} + public void setPort(int p0){} + public void setProperties(Map p0){} + public void setProxyJump(String p0){} + public void setUsername(String p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostConfigEntryResolver.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostConfigEntryResolver.java new file mode 100644 index 00000000000..45a8cda6d4e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostConfigEntryResolver.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.client.config.hosts.HostConfigEntryResolver for testing purposes + +package org.apache.sshd.client.config.hosts; + +import java.net.SocketAddress; +import org.apache.sshd.client.config.hosts.HostConfigEntry; +import org.apache.sshd.common.AttributeRepository; + +public interface HostConfigEntryResolver +{ + HostConfigEntry resolveEffectiveHost(String p0, int p1, SocketAddress p2, String p3, String p4, AttributeRepository p5); + static HostConfigEntryResolver EMPTY = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostPatternValue.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostPatternValue.java new file mode 100644 index 00000000000..2ead5870745 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostPatternValue.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.sshd.client.config.hosts.HostPatternValue for testing purposes + +package org.apache.sshd.client.config.hosts; + +import java.util.regex.Pattern; + +public class HostPatternValue +{ + public HostPatternValue(){} + public HostPatternValue(Pattern p0, boolean p1){} + public HostPatternValue(Pattern p0, int p1, boolean p2){} + public Pattern getPattern(){ return null; } + public String toString(){ return null; } + public boolean isNegated(){ return false; } + public int getPort(){ return 0; } + public void setNegated(boolean p0){} + public void setPattern(Pattern p0){} + public void setPort(int p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostPatternsHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostPatternsHolder.java new file mode 100644 index 00000000000..3ab2a41e7cb --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/hosts/HostPatternsHolder.java @@ -0,0 +1,35 @@ +// Generated automatically from org.apache.sshd.client.config.hosts.HostPatternsHolder for testing purposes + +package org.apache.sshd.client.config.hosts; + +import java.util.Collection; +import java.util.List; +import java.util.regex.Pattern; +import org.apache.sshd.client.config.hosts.HostConfigEntry; +import org.apache.sshd.client.config.hosts.HostPatternValue; + +abstract public class HostPatternsHolder +{ + protected HostPatternsHolder(){} + public Collection getPatterns(){ return null; } + public boolean isHostMatch(String p0, int p1){ return false; } + public static HostPatternValue toPattern(CharSequence p0){ return null; } + public static List findMatchingEntries(String p0, Collection p1){ return null; } + public static List findMatchingEntries(String p0, HostConfigEntry... p1){ return null; } + public static List parsePatterns(CharSequence... p0){ return null; } + public static List parsePatterns(Collection p0){ return null; } + public static String ALL_HOSTS_PATTERN = null; + public static String PATTERN_CHARS = null; + public static boolean isHostMatch(String p0, Pattern p1){ return false; } + public static boolean isHostMatch(String p0, int p1, Collection p2){ return false; } + public static boolean isPortMatch(int p0, int p1){ return false; } + public static boolean isSpecificHostPattern(String p0){ return false; } + public static boolean isValidPatternChar(char p0){ return false; } + public static char NEGATION_CHAR_PATTERN = '0'; + public static char NON_STANDARD_PORT_PATTERN_ENCLOSURE_END_DELIM = '0'; + public static char NON_STANDARD_PORT_PATTERN_ENCLOSURE_START_DELIM = '0'; + public static char PORT_VALUE_DELIMITER = '0'; + public static char SINGLE_CHAR_PATTERN = '0'; + public static char WILDCARD_PATTERN = '0'; + public void setPatterns(Collection p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoader.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoader.java new file mode 100644 index 00000000000..d751cadea2b --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoader.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.client.config.keys.ClientIdentityLoader for testing purposes + +package org.apache.sshd.client.config.keys; + +import java.security.KeyPair; +import java.util.Collection; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.config.keys.FilePasswordProvider; +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; +import org.apache.sshd.common.session.SessionContext; + +public interface ClientIdentityLoader +{ + Iterable loadClientIdentities(SessionContext p0, NamedResource p1, FilePasswordProvider p2); + boolean isValidLocation(NamedResource p0); + static ClientIdentityLoader DEFAULT = null; + static KeyIdentityProvider asKeyIdentityProvider(ClientIdentityLoader p0, Collection p1, FilePasswordProvider p2, boolean p3){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java new file mode 100644 index 00000000000..d5258ecd24f --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.client.config.keys.ClientIdentityLoaderHolder for testing purposes + +package org.apache.sshd.client.config.keys; + +import org.apache.sshd.client.config.keys.ClientIdentityLoader; + +public interface ClientIdentityLoaderHolder +{ + ClientIdentityLoader getClientIdentityLoader(); + static ClientIdentityLoaderHolder loaderHolderOf(ClientIdentityLoader p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoaderManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoaderManager.java new file mode 100644 index 00000000000..9cacb82c6d2 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/config/keys/ClientIdentityLoaderManager.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.client.config.keys.ClientIdentityLoaderManager for testing purposes + +package org.apache.sshd.client.config.keys; + +import org.apache.sshd.client.config.keys.ClientIdentityLoader; +import org.apache.sshd.client.config.keys.ClientIdentityLoaderHolder; + +public interface ClientIdentityLoaderManager extends ClientIdentityLoaderHolder +{ + void setClientIdentityLoader(ClientIdentityLoader p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/AuthFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/AuthFuture.java new file mode 100644 index 00000000000..9cbf8a40fdc --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/AuthFuture.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.client.future.AuthFuture for testing purposes + +package org.apache.sshd.client.future; + +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.VerifiableFuture; + +public interface AuthFuture extends SshFuture, VerifiableFuture +{ + Throwable getException(); + boolean isCanceled(); + boolean isFailure(); + boolean isSuccess(); + void cancel(); + void setAuthed(boolean p0); + void setException(Throwable p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/ConnectFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/ConnectFuture.java new file mode 100644 index 00000000000..75042645933 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/ConnectFuture.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.sshd.client.future.ConnectFuture for testing purposes + +package org.apache.sshd.client.future; + +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.ClientSessionHolder; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.VerifiableFuture; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionHolder; + +public interface ConnectFuture extends ClientSessionHolder, SessionHolder, SshFuture, VerifiableFuture +{ + Throwable getException(); + boolean isCanceled(); + boolean isConnected(); + default ClientSession getClientSession(){ return null; } + void cancel(); + void setException(Throwable p0); + void setSession(ClientSession p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/OpenFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/OpenFuture.java new file mode 100644 index 00000000000..3651767c72e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/future/OpenFuture.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.client.future.OpenFuture for testing purposes + +package org.apache.sshd.client.future; + +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.VerifiableFuture; + +public interface OpenFuture extends SshFuture, VerifiableFuture +{ + Throwable getException(); + boolean isCanceled(); + boolean isOpened(); + void cancel(); + void setException(Throwable p0); + void setOpened(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/keyverifier/ServerKeyVerifier.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/keyverifier/ServerKeyVerifier.java new file mode 100644 index 00000000000..cd863e885e8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/keyverifier/ServerKeyVerifier.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.client.keyverifier.ServerKeyVerifier for testing purposes + +package org.apache.sshd.client.keyverifier; + +import java.net.SocketAddress; +import java.security.PublicKey; +import org.apache.sshd.client.session.ClientSession; + +public interface ServerKeyVerifier +{ + boolean verifyServerKey(ClientSession p0, SocketAddress p1, PublicKey p2); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/AbstractClientSession.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/AbstractClientSession.java new file mode 100644 index 00000000000..a94b2449f34 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/AbstractClientSession.java @@ -0,0 +1,104 @@ +// Generated automatically from org.apache.sshd.client.session.AbstractClientSession for testing purposes + +package org.apache.sshd.client.session; + +import java.net.SocketAddress; +import java.security.KeyPair; +import java.security.PublicKey; +import java.util.List; +import java.util.Map; +import org.apache.sshd.client.ClientFactoryManager; +import org.apache.sshd.client.auth.AuthenticationIdentitiesProvider; +import org.apache.sshd.client.auth.UserAuthFactory; +import org.apache.sshd.client.auth.hostbased.HostBasedAuthenticationReporter; +import org.apache.sshd.client.auth.keyboard.UserInteraction; +import org.apache.sshd.client.auth.password.PasswordAuthenticationReporter; +import org.apache.sshd.client.auth.password.PasswordIdentityProvider; +import org.apache.sshd.client.auth.pubkey.PublicKeyAuthenticationReporter; +import org.apache.sshd.client.channel.ChannelDirectTcpip; +import org.apache.sshd.client.channel.ChannelExec; +import org.apache.sshd.client.channel.ChannelShell; +import org.apache.sshd.client.channel.ChannelSubsystem; +import org.apache.sshd.client.channel.ClientChannel; +import org.apache.sshd.client.keyverifier.ServerKeyVerifier; +import org.apache.sshd.client.session.ClientProxyConnector; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.ClientUserAuthService; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.channel.PtyChannelConfigurationHolder; +import org.apache.sshd.common.forward.Forwarder; +import org.apache.sshd.common.future.KeyExchangeFuture; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.session.helpers.AbstractSession; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +abstract public class AbstractClientSession extends AbstractSession implements ClientSession +{ + protected AbstractClientSession() {} + protected AbstractClientSession(ClientFactoryManager p0, IoSession p1){} + protected ClientUserAuthService getUserAuthService(){ return null; } + protected ConnectionService getConnectionService(){ return null; } + protected Forwarder getForwarder(){ return null; } + protected IoWriteFuture sendClientIdentification(){ return null; } + protected String resolveAvailableSignaturesProposal(FactoryManager p0){ return null; } + protected boolean readIdentification(Buffer p0){ return false; } + protected byte[] receiveKexInit(Buffer p0){ return null; } + protected byte[] sendKexInit(Map p0){ return null; } + protected final boolean sendImmediateClientIdentification = false; + protected final boolean sendImmediateKexInit = false; + protected void checkKeys(){} + protected void initializeKeyExchangePhase(){} + protected void initializeProxyConnector(){} + protected void receiveKexInit(Map p0, byte[] p1){} + protected void setKexSeed(byte... p0){} + protected void signalExtraServerVersionInfo(String p0, List p1){} + public AttributeRepository getConnectionContext(){ return null; } + public AuthenticationIdentitiesProvider getRegisteredIdentities(){ return null; } + public ChannelDirectTcpip createDirectTcpipChannel(SshdSocketAddress p0, SshdSocketAddress p1){ return null; } + public ChannelExec createExecChannel(String p0, PtyChannelConfigurationHolder p1, Map p2){ return null; } + public ChannelShell createShellChannel(PtyChannelConfigurationHolder p0, Map p1){ return null; } + public ChannelSubsystem createSubsystemChannel(String p0){ return null; } + public ClientChannel createChannel(String p0){ return null; } + public ClientChannel createChannel(String p0, String p1){ return null; } + public ClientFactoryManager getFactoryManager(){ return null; } + public ClientProxyConnector getClientProxyConnector(){ return null; } + public HostBasedAuthenticationReporter getHostBasedAuthenticationReporter(){ return null; } + public KeyExchangeFuture switchToNoneCipher(){ return null; } + public KeyIdentityProvider getKeyIdentityProvider(){ return null; } + public KeyPair removePublicKeyIdentity(KeyPair p0){ return null; } + public List getUserAuthFactories(){ return null; } + public PasswordAuthenticationReporter getPasswordAuthenticationReporter(){ return null; } + public PasswordIdentityProvider getPasswordIdentityProvider(){ return null; } + public PublicKey getServerKey(){ return null; } + public PublicKeyAuthenticationReporter getPublicKeyAuthenticationReporter(){ return null; } + public ServerKeyVerifier getServerKeyVerifier(){ return null; } + public SocketAddress getConnectAddress(){ return null; } + public SshdSocketAddress startDynamicPortForwarding(SshdSocketAddress p0){ return null; } + public SshdSocketAddress startLocalPortForwarding(SshdSocketAddress p0, SshdSocketAddress p1){ return null; } + public SshdSocketAddress startRemotePortForwarding(SshdSocketAddress p0, SshdSocketAddress p1){ return null; } + public String removePasswordIdentity(String p0){ return null; } + public UserInteraction getUserInteraction(){ return null; } + public void addPasswordIdentity(String p0){} + public void addPublicKeyIdentity(KeyPair p0){} + public void setClientProxyConnector(ClientProxyConnector p0){} + public void setConnectAddress(SocketAddress p0){} + public void setHostBasedAuthenticationReporter(HostBasedAuthenticationReporter p0){} + public void setKeyIdentityProvider(KeyIdentityProvider p0){} + public void setPasswordAuthenticationReporter(PasswordAuthenticationReporter p0){} + public void setPasswordIdentityProvider(PasswordIdentityProvider p0){} + public void setPublicKeyAuthenticationReporter(PublicKeyAuthenticationReporter p0){} + public void setServerKey(PublicKey p0){} + public void setServerKeyVerifier(ServerKeyVerifier p0){} + public void setUserAuthFactories(List p0){} + public void setUserInteraction(UserInteraction p0){} + public void startService(String p0, Buffer p1){} + public void stopDynamicPortForwarding(SshdSocketAddress p0){} + public void stopLocalPortForwarding(SshdSocketAddress p0){} + public void stopRemotePortForwarding(SshdSocketAddress p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientProxyConnector.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientProxyConnector.java new file mode 100644 index 00000000000..30ff68af885 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientProxyConnector.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.client.session.ClientProxyConnector for testing purposes + +package org.apache.sshd.client.session; + +import org.apache.sshd.client.session.ClientSession; + +public interface ClientProxyConnector +{ + void sendClientProxyMetadata(ClientSession p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientProxyConnectorHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientProxyConnectorHolder.java new file mode 100644 index 00000000000..855f40df899 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientProxyConnectorHolder.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.client.session.ClientProxyConnectorHolder for testing purposes + +package org.apache.sshd.client.session; + +import org.apache.sshd.client.session.ClientProxyConnector; + +public interface ClientProxyConnectorHolder +{ + ClientProxyConnector getClientProxyConnector(); + void setClientProxyConnector(ClientProxyConnector p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSession.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSession.java new file mode 100644 index 00000000000..d9a649dca9e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSession.java @@ -0,0 +1,69 @@ +// Generated automatically from org.apache.sshd.client.session.ClientSession for testing purposes + +package org.apache.sshd.client.session; + +import java.io.OutputStream; +import java.net.SocketAddress; +import java.nio.charset.Charset; +import java.security.PublicKey; +import java.time.Duration; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import org.apache.sshd.client.ClientAuthenticationManager; +import org.apache.sshd.client.ClientFactoryManager; +import org.apache.sshd.client.channel.ChannelDirectTcpip; +import org.apache.sshd.client.channel.ChannelExec; +import org.apache.sshd.client.channel.ChannelShell; +import org.apache.sshd.client.channel.ChannelSubsystem; +import org.apache.sshd.client.channel.ClientChannel; +import org.apache.sshd.client.channel.ClientChannelEvent; +import org.apache.sshd.client.future.AuthFuture; +import org.apache.sshd.client.session.ClientProxyConnectorHolder; +import org.apache.sshd.client.session.forward.DynamicPortForwardingTracker; +import org.apache.sshd.client.session.forward.ExplicitPortForwardingTracker; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.channel.PtyChannelConfigurationHolder; +import org.apache.sshd.common.forward.PortForwardingManager; +import org.apache.sshd.common.future.KeyExchangeFuture; +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public interface ClientSession extends ClientAuthenticationManager, ClientProxyConnectorHolder, PortForwardingManager, Session +{ + AttributeRepository getConnectionContext(); + AuthFuture auth(); + ChannelDirectTcpip createDirectTcpipChannel(SshdSocketAddress p0, SshdSocketAddress p1); + ChannelExec createExecChannel(String p0, PtyChannelConfigurationHolder p1, Map p2); + ChannelShell createShellChannel(PtyChannelConfigurationHolder p0, Map p1); + ChannelSubsystem createSubsystemChannel(String p0); + ClientChannel createChannel(String p0); + ClientChannel createChannel(String p0, String p1); + ClientFactoryManager getFactoryManager(); + KeyExchangeFuture switchToNoneCipher(); + Map getMetadataMap(); + PublicKey getServerKey(); + Set getSessionState(); + Set waitFor(Collection p0, long p1); + SocketAddress getConnectAddress(); + default ChannelExec createExecChannel(String p0){ return null; } + default ChannelShell createShellChannel(){ return null; } + default DynamicPortForwardingTracker createDynamicPortForwardingTracker(SshdSocketAddress p0){ return null; } + default ExplicitPortForwardingTracker createLocalPortForwardingTracker(SshdSocketAddress p0, SshdSocketAddress p1){ return null; } + default ExplicitPortForwardingTracker createLocalPortForwardingTracker(int p0, SshdSocketAddress p1){ return null; } + default ExplicitPortForwardingTracker createRemotePortForwardingTracker(SshdSocketAddress p0, SshdSocketAddress p1){ return null; } + default Set waitFor(Collection p0, Duration p1){ return null; } + default String executeRemoteCommand(String p0){ return null; } + default String executeRemoteCommand(String p0, OutputStream p1, Charset p2){ return null; } + default void executeRemoteCommand(String p0, OutputStream p1, OutputStream p2, Charset p3){} + static Iterator passwordIteratorOf(ClientSession p0){ return null; } + static KeyIdentityProvider providerOf(ClientSession p0){ return null; } + static Set REMOTE_COMMAND_WAIT_EVENTS = null; + static public enum ClientSessionEvent + { + AUTHED, CLOSED, TIMEOUT, WAIT_AUTH; + private ClientSessionEvent() {} + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionCreator.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionCreator.java new file mode 100644 index 00000000000..cddb9567125 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionCreator.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.sshd.client.session.ClientSessionCreator for testing purposes + +package org.apache.sshd.client.session; + +import java.net.SocketAddress; +import org.apache.sshd.client.config.hosts.HostConfigEntry; +import org.apache.sshd.client.future.ConnectFuture; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public interface ClientSessionCreator +{ + ConnectFuture connect(HostConfigEntry p0, AttributeRepository p1, SocketAddress p2); + ConnectFuture connect(String p0); + ConnectFuture connect(String p0, SocketAddress p1, AttributeRepository p2, SocketAddress p3); + ConnectFuture connect(String p0, String p1, int p2, AttributeRepository p3, SocketAddress p4); + default ConnectFuture connect(HostConfigEntry p0){ return null; } + default ConnectFuture connect(HostConfigEntry p0, AttributeRepository p1){ return null; } + default ConnectFuture connect(HostConfigEntry p0, SocketAddress p1){ return null; } + default ConnectFuture connect(String p0, SocketAddress p1){ return null; } + default ConnectFuture connect(String p0, SocketAddress p1, AttributeRepository p2){ return null; } + default ConnectFuture connect(String p0, SocketAddress p1, SocketAddress p2){ return null; } + default ConnectFuture connect(String p0, String p1, int p2){ return null; } + default ConnectFuture connect(String p0, String p1, int p2, AttributeRepository p3){ return null; } + default ConnectFuture connect(String p0, String p1, int p2, SocketAddress p3){ return null; } + static AttributeRepository.AttributeKey TARGET_SERVER = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionHolder.java new file mode 100644 index 00000000000..1a01efe33b7 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionHolder.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.client.session.ClientSessionHolder for testing purposes + +package org.apache.sshd.client.session; + +import org.apache.sshd.client.session.ClientSession; + +public interface ClientSessionHolder +{ + ClientSession getClientSession(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionImpl.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionImpl.java new file mode 100644 index 00000000000..193d1fe538c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientSessionImpl.java @@ -0,0 +1,36 @@ +// Generated automatically from org.apache.sshd.client.session.ClientSessionImpl for testing purposes + +package org.apache.sshd.client.session; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.sshd.client.ClientFactoryManager; +import org.apache.sshd.client.future.AuthFuture; +import org.apache.sshd.client.session.AbstractClientSession; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.common.Service; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.session.SessionListener; +import org.apache.sshd.common.util.buffer.Buffer; + +public class ClientSessionImpl extends AbstractClientSession +{ + protected ClientSessionImpl() {} + protected > C updateCurrentSessionState(C p0){ return null; } + protected List getServices(){ return null; } + protected String nextServiceName(){ return null; } + protected void handleDisconnect(int p0, String p1, String p2, Buffer p3){} + protected void preClose(){} + protected void sendInitialServiceRequest(){} + protected void signalAuthFailure(Throwable p0){} + protected void signalSessionEvent(SessionListener.Event p0){} + public AuthFuture auth(){ return null; } + public ClientSessionImpl(ClientFactoryManager p0, IoSession p1){} + public Map getMetadataMap(){ return null; } + public Set getSessionState(){ return null; } + public Set waitFor(Collection p0, long p1){ return null; } + public void exceptionCaught(Throwable p0){} + public void switchToNextService(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientUserAuthService.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientUserAuthService.java new file mode 100644 index 00000000000..4e68ac975f7 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/ClientUserAuthService.java @@ -0,0 +1,41 @@ +// Generated automatically from org.apache.sshd.client.session.ClientUserAuthService for testing purposes + +package org.apache.sshd.client.session; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import org.apache.sshd.client.auth.UserAuthFactory; +import org.apache.sshd.client.future.AuthFuture; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.ClientSessionHolder; +import org.apache.sshd.client.session.ClientSessionImpl; +import org.apache.sshd.common.Service; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.closeable.AbstractCloseable; + +public class ClientUserAuthService extends AbstractCloseable implements ClientSessionHolder, Service +{ + protected ClientUserAuthService() {} + protected AuthFuture createAuthFuture(ClientSession p0, String p1){ return null; } + protected AuthFuture updateCurrentAuthFuture(ClientSession p0, String p1){ return null; } + protected IoWriteFuture sendInitialAuthRequest(ClientSession p0, String p1){ return null; } + protected List serverMethods = null; + protected final AtomicReference authFutureHolder = null; + protected final ClientSessionImpl clientSession = null; + protected final List clientMethods = null; + protected final List authFactories = null; + protected void preClose(){} + protected void processUserAuth(Buffer p0){} + protected void tryNext(int p0){} + public AuthFuture auth(String p0){ return null; } + public ClientSession getClientSession(){ return null; } + public ClientSession getSession(){ return null; } + public ClientUserAuthService(Session p0){} + public Map getProperties(){ return null; } + public String getCurrentServiceName(){ return null; } + public void process(int p0, Buffer p1){} + public void start(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/SessionFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/SessionFactory.java new file mode 100644 index 00000000000..7f0a2434d74 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/SessionFactory.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.client.session.SessionFactory for testing purposes + +package org.apache.sshd.client.session; + +import org.apache.sshd.client.ClientFactoryManager; +import org.apache.sshd.client.session.ClientSessionImpl; +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.session.helpers.AbstractSession; +import org.apache.sshd.common.session.helpers.AbstractSessionFactory; + +public class SessionFactory extends AbstractSessionFactory +{ + protected SessionFactory() {} + protected ClientSessionImpl doCreateSession(IoSession p0){ return null; } + public SessionFactory(ClientFactoryManager p0){} + public final ClientFactoryManager getClient(){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/DynamicPortForwardingTracker.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/DynamicPortForwardingTracker.java new file mode 100644 index 00000000000..617090b3c9b --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/DynamicPortForwardingTracker.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.client.session.forward.DynamicPortForwardingTracker for testing purposes + +package org.apache.sshd.client.session.forward; + +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.forward.PortForwardingTracker; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public class DynamicPortForwardingTracker extends PortForwardingTracker +{ + protected DynamicPortForwardingTracker() {} + public DynamicPortForwardingTracker(ClientSession p0, SshdSocketAddress p1, SshdSocketAddress p2){} + public void close(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/ExplicitPortForwardingTracker.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/ExplicitPortForwardingTracker.java new file mode 100644 index 00000000000..f17787724c7 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/ExplicitPortForwardingTracker.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.client.session.forward.ExplicitPortForwardingTracker for testing purposes + +package org.apache.sshd.client.session.forward; + +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.forward.PortForwardingTracker; +import org.apache.sshd.common.util.net.ConnectionEndpointsIndicator; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public class ExplicitPortForwardingTracker extends PortForwardingTracker implements ConnectionEndpointsIndicator +{ + protected ExplicitPortForwardingTracker() {} + public ExplicitPortForwardingTracker(ClientSession p0, boolean p1, SshdSocketAddress p2, SshdSocketAddress p3, SshdSocketAddress p4){} + public SshdSocketAddress getRemoteAddress(){ return null; } + public String toString(){ return null; } + public boolean isLocalForwarding(){ return false; } + public void close(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/PortForwardingTracker.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/PortForwardingTracker.java new file mode 100644 index 00000000000..942af45832e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/session/forward/PortForwardingTracker.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.sshd.client.session.forward.PortForwardingTracker for testing purposes + +package org.apache.sshd.client.session.forward; + +import java.nio.channels.Channel; +import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.session.ClientSessionHolder; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionHolder; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +abstract public class PortForwardingTracker implements Channel, ClientSessionHolder, SessionHolder +{ + protected PortForwardingTracker() {} + protected PortForwardingTracker(ClientSession p0, SshdSocketAddress p1, SshdSocketAddress p2){} + protected final AtomicBoolean open = null; + public ClientSession getClientSession(){ return null; } + public ClientSession getSession(){ return null; } + public SshdSocketAddress getBoundAddress(){ return null; } + public SshdSocketAddress getLocalAddress(){ return null; } + public String toString(){ return null; } + public boolean isOpen(){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleClient.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleClient.java new file mode 100644 index 00000000000..95595f2f070 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleClient.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.client.simple.SimpleClient for testing purposes + +package org.apache.sshd.client.simple; + +import java.nio.channels.Channel; +import org.apache.sshd.client.simple.SimpleClientConfigurator; +import org.apache.sshd.client.simple.SimpleSessionClient; + +public interface SimpleClient extends Channel, SimpleClientConfigurator, SimpleSessionClient +{ +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleClientConfigurator.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleClientConfigurator.java new file mode 100644 index 00000000000..cfd993af2f6 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleClientConfigurator.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.client.simple.SimpleClientConfigurator for testing purposes + +package org.apache.sshd.client.simple; + + +public interface SimpleClientConfigurator +{ + long getAuthenticationTimeout(); + long getConnectTimeout(); + static int DEFAULT_PORT = 0; + static long DEFAULT_AUTHENTICATION_TIMEOUT = 0; + static long DEFAULT_CONNECT_TIMEOUT = 0; + void setAuthenticationTimeout(long p0); + void setConnectTimeout(long p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleSessionClient.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleSessionClient.java new file mode 100644 index 00000000000..975031a5b92 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/client/simple/SimpleSessionClient.java @@ -0,0 +1,26 @@ +// Generated automatically from org.apache.sshd.client.simple.SimpleSessionClient for testing purposes + +package org.apache.sshd.client.simple; + +import java.net.InetAddress; +import java.net.SocketAddress; +import java.nio.channels.Channel; +import java.security.KeyPair; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.simple.SimpleClientConfigurator; + +public interface SimpleSessionClient extends Channel, SimpleClientConfigurator +{ + ClientSession sessionLogin(SocketAddress p0, String p1, KeyPair p2); + ClientSession sessionLogin(SocketAddress p0, String p1, String p2); + ClientSession sessionLogin(String p0, KeyPair p1); + ClientSession sessionLogin(String p0, String p1); + default ClientSession sessionLogin(InetAddress p0, String p1, KeyPair p2){ return null; } + default ClientSession sessionLogin(InetAddress p0, String p1, String p2){ return null; } + default ClientSession sessionLogin(InetAddress p0, int p1, String p2, KeyPair p3){ return null; } + default ClientSession sessionLogin(InetAddress p0, int p1, String p2, String p3){ return null; } + default ClientSession sessionLogin(String p0, String p1, KeyPair p2){ return null; } + default ClientSession sessionLogin(String p0, String p1, String p2){ return null; } + default ClientSession sessionLogin(String p0, int p1, String p2, KeyPair p3){ return null; } + default ClientSession sessionLogin(String p0, int p1, String p2, String p3){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AlgorithmNameProvider.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AlgorithmNameProvider.java new file mode 100644 index 00000000000..7399eb75a82 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AlgorithmNameProvider.java @@ -0,0 +1,9 @@ +// Generated automatically from org.apache.sshd.common.AlgorithmNameProvider for testing purposes + +package org.apache.sshd.common; + + +public interface AlgorithmNameProvider +{ + String getAlgorithm(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AttributeRepository.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AttributeRepository.java new file mode 100644 index 00000000000..a797c900468 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AttributeRepository.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.sshd.common.AttributeRepository for testing purposes + +package org.apache.sshd.common; + +import java.util.Collection; +import java.util.Map; + +public interface AttributeRepository +{ + T getAttribute(AttributeRepository.AttributeKey p0); + Collection> attributeKeys(); + default T resolveAttribute(AttributeRepository.AttributeKey p0){ return null; } + int getAttributesCount(); + static AttributeRepository ofKeyValuePair(AttributeRepository.AttributeKey p0, A p1){ return null; } + static AttributeRepository ofAttributesMap(Map, ? extends Object> p0){ return null; } + static public class AttributeKey + { + public AttributeKey(){} + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AttributeStore.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AttributeStore.java new file mode 100644 index 00000000000..d784d042cca --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/AttributeStore.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.AttributeStore for testing purposes + +package org.apache.sshd.common; + +import java.util.function.Function; +import org.apache.sshd.common.AttributeRepository; + +public interface AttributeStore extends AttributeRepository +{ + T removeAttribute(AttributeRepository.AttributeKey p0); + T setAttribute(AttributeRepository.AttributeKey p0, T p1); + default T computeAttributeIfAbsent(AttributeRepository.AttributeKey p0, Function, ? extends T> p1){ return null; } + void clearAttributes(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Closeable.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Closeable.java new file mode 100644 index 00000000000..ef7b0c0db89 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Closeable.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.sshd.common.Closeable for testing purposes + +package org.apache.sshd.common; + +import java.nio.channels.Channel; +import java.time.Duration; +import org.apache.sshd.common.PropertyResolver; +import org.apache.sshd.common.future.CloseFuture; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.SshFutureListener; + +public interface Closeable extends Channel +{ + CloseFuture close(boolean p0); + boolean isClosed(); + boolean isClosing(); + default boolean isOpen(){ return false; } + default void close(){} + static Duration getMaxCloseWaitTime(PropertyResolver p0){ return null; } + static void close(Closeable p0){} + void addCloseFutureListener(SshFutureListener p0); + void removeCloseFutureListener(SshFutureListener p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Factory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Factory.java new file mode 100644 index 00000000000..93a7ac6f8f6 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Factory.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.Factory for testing purposes + +package org.apache.sshd.common; + +import java.util.function.Supplier; + +public interface Factory extends Supplier +{ + T create(); + default T get(){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/FactoryManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/FactoryManager.java new file mode 100644 index 00000000000..1b2093c0bda --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/FactoryManager.java @@ -0,0 +1,53 @@ +// Generated automatically from org.apache.sshd.common.FactoryManager for testing purposes + +package org.apache.sshd.common; + +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import org.apache.sshd.agent.SshAgentFactory; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.AttributeStore; +import org.apache.sshd.common.Factory; +import org.apache.sshd.common.ServiceFactory; +import org.apache.sshd.common.channel.ChannelFactory; +import org.apache.sshd.common.channel.ChannelListenerManager; +import org.apache.sshd.common.channel.RequestHandler; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolverManager; +import org.apache.sshd.common.file.FileSystemFactory; +import org.apache.sshd.common.forward.ForwarderFactory; +import org.apache.sshd.common.forward.PortForwardingEventListenerManager; +import org.apache.sshd.common.io.IoServiceEventListenerManager; +import org.apache.sshd.common.io.IoServiceFactory; +import org.apache.sshd.common.kex.KexFactoryManager; +import org.apache.sshd.common.random.Random; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.session.ReservedSessionMessagesManager; +import org.apache.sshd.common.session.SessionDisconnectHandlerManager; +import org.apache.sshd.common.session.SessionHeartbeatController; +import org.apache.sshd.common.session.SessionListenerManager; +import org.apache.sshd.common.session.UnknownChannelReferenceHandlerManager; +import org.apache.sshd.server.forward.AgentForwardingFilter; +import org.apache.sshd.server.forward.ForwardingFilter; +import org.apache.sshd.server.forward.TcpForwardingFilter; +import org.apache.sshd.server.forward.X11ForwardingFilter; + +public interface FactoryManager extends AttributeStore, ChannelListenerManager, ChannelStreamWriterResolverManager, IoServiceEventListenerManager, KexFactoryManager, PortForwardingEventListenerManager, ReservedSessionMessagesManager, SessionDisconnectHandlerManager, SessionHeartbeatController, SessionListenerManager, UnknownChannelReferenceHandlerManager +{ + Factory getRandomFactory(); + FileSystemFactory getFileSystemFactory(); + ForwarderFactory getForwarderFactory(); + ForwardingFilter getForwardingFilter(); + IoServiceFactory getIoServiceFactory(); + List getChannelFactories(); + List getServiceFactories(); + List> getGlobalRequestHandlers(); + ScheduledExecutorService getScheduledExecutorService(); + SshAgentFactory getAgentFactory(); + String getVersion(); + default T resolveAttribute(AttributeRepository.AttributeKey p0){ return null; } + default AgentForwardingFilter getAgentForwardingFilter(){ return null; } + default TcpForwardingFilter getTcpForwardingFilter(){ return null; } + default X11ForwardingFilter getX11ForwardingFilter(){ return null; } + static T resolveAttribute(FactoryManager p0, AttributeRepository.AttributeKey p1){ return null; } + static String DEFAULT_VERSION = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/FactoryManagerHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/FactoryManagerHolder.java new file mode 100644 index 00000000000..49a2f7dddff --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/FactoryManagerHolder.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.common.FactoryManagerHolder for testing purposes + +package org.apache.sshd.common; + +import org.apache.sshd.common.FactoryManager; + +public interface FactoryManagerHolder +{ + FactoryManager getFactoryManager(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/NamedFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/NamedFactory.java new file mode 100644 index 00000000000..9dfcbd22c46 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/NamedFactory.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.common.NamedFactory for testing purposes + +package org.apache.sshd.common; + +import java.util.Collection; +import java.util.List; +import java.util.function.Function; +import org.apache.sshd.common.Factory; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.OptionalFeature; + +public interface NamedFactory extends Factory, NamedResource +{ + static List setUpBuiltinFactories(boolean p0, Collection p1){ return null; } + static List setUpTransformedFactories(boolean p0, Collection p1, Function p2){ return null; } + static T create(Collection> p0, String p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/NamedResource.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/NamedResource.java new file mode 100644 index 00000000000..2e38914fb9a --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/NamedResource.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.sshd.common.NamedResource for testing purposes + +package org.apache.sshd.common; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.function.Function; + +public interface NamedResource +{ + String getName(); + static R findByName(String p0, Comparator p1, Collection p2){ return null; } + static R findFirstMatchByName(Collection p0, Comparator p1, Collection p2){ return null; } + static R removeByName(String p0, Comparator p1, Collection p2){ return null; } + static Comparator BY_NAME_COMPARATOR = null; + static Function NAME_EXTRACTOR = null; + static List getNameList(Collection p0){ return null; } + static NamedResource ofName(String p0){ return null; } + static String getNames(Collection p0){ return null; } + static int safeCompareByName(NamedResource p0, NamedResource p1, boolean p2){ return 0; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/OptionalFeature.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/OptionalFeature.java new file mode 100644 index 00000000000..f1a7a279eaa --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/OptionalFeature.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.common.OptionalFeature for testing purposes + +package org.apache.sshd.common; + +import java.util.Collection; + +public interface OptionalFeature +{ + boolean isSupported(); + static OptionalFeature FALSE = null; + static OptionalFeature TRUE = null; + static OptionalFeature all(Collection p0){ return null; } + static OptionalFeature any(Collection p0){ return null; } + static OptionalFeature of(boolean p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/PropertyResolver.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/PropertyResolver.java new file mode 100644 index 00000000000..28e9b088299 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/PropertyResolver.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.sshd.common.PropertyResolver for testing purposes + +package org.apache.sshd.common; + +import java.nio.charset.Charset; +import java.util.Map; + +public interface PropertyResolver +{ + Map getProperties(); + PropertyResolver getParentPropertyResolver(); + default Boolean getBoolean(String p0){ return null; } + default Charset getCharset(String p0, Charset p1){ return null; } + default Integer getInteger(String p0){ return null; } + default Long getLong(String p0){ return null; } + default Object getObject(String p0){ return null; } + default String getString(String p0){ return null; } + default String getStringProperty(String p0, String p1){ return null; } + default boolean getBooleanProperty(String p0, boolean p1){ return false; } + default boolean isEmpty(){ return false; } + default int getIntProperty(String p0, int p1){ return 0; } + default long getLongProperty(String p0, long p1){ return 0; } + static PropertyResolver EMPTY = null; + static boolean isEmpty(PropertyResolver p0){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Service.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Service.java new file mode 100644 index 00000000000..2582614f33d --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/Service.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.common.Service for testing purposes + +package org.apache.sshd.common; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.PropertyResolver; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionHolder; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface Service extends Closeable, PropertyResolver, SessionHolder +{ + default PropertyResolver getParentPropertyResolver(){ return null; } + void process(int p0, Buffer p1); + void start(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/ServiceFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/ServiceFactory.java new file mode 100644 index 00000000000..a71d2ae8fad --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/ServiceFactory.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.ServiceFactory for testing purposes + +package org.apache.sshd.common; + +import java.util.Collection; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.Service; +import org.apache.sshd.common.session.Session; + +public interface ServiceFactory extends NamedResource +{ + Service create(Session p0); + static Service create(Collection p0, String p1, Session p2){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/MutableUserHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/MutableUserHolder.java new file mode 100644 index 00000000000..68f2d4b2716 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/MutableUserHolder.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.common.auth.MutableUserHolder for testing purposes + +package org.apache.sshd.common.auth; + +import org.apache.sshd.common.auth.UsernameHolder; + +public interface MutableUserHolder extends UsernameHolder +{ + void setUsername(String p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthFactoriesManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthFactoriesManager.java new file mode 100644 index 00000000000..d53bf67fc32 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthFactoriesManager.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.sshd.common.auth.UserAuthFactoriesManager for testing purposes + +package org.apache.sshd.common.auth; + +import java.util.Collection; +import java.util.List; +import org.apache.sshd.common.auth.UserAuthInstance; +import org.apache.sshd.common.auth.UserAuthMethodFactory; +import org.apache.sshd.common.session.SessionContext; + +public interface UserAuthFactoriesManager, F extends UserAuthMethodFactory> +{ + List getUserAuthFactories(); + default List getUserAuthFactoriesNames(){ return null; } + default String getUserAuthFactoriesNameList(){ return null; } + default void setUserAuthFactoriesNameList(String p0){} + default void setUserAuthFactoriesNames(String... p0){} + void setUserAuthFactories(List p0); + void setUserAuthFactoriesNames(Collection p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthInstance.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthInstance.java new file mode 100644 index 00000000000..ba0132f878f --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthInstance.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.auth.UserAuthInstance for testing purposes + +package org.apache.sshd.common.auth; + +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.session.SessionContext; + +public interface UserAuthInstance extends NamedResource +{ + S getSession(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthMethodFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthMethodFactory.java new file mode 100644 index 00000000000..ec454d3554b --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UserAuthMethodFactory.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.sshd.common.auth.UserAuthMethodFactory for testing purposes + +package org.apache.sshd.common.auth; + +import java.util.Collection; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.auth.UserAuthInstance; +import org.apache.sshd.common.session.SessionContext; + +public interface UserAuthMethodFactory> extends NamedResource +{ + M createUserAuth(S p0); + static > M createUserAuth(S p0, Collection> p1, String p2){ return null; } + static String HOST_BASED = null; + static String KB_INTERACTIVE = null; + static String PASSWORD = null; + static String PUBLIC_KEY = null; + static boolean isDataIntegrityAuthenticationTransport(SessionContext p0){ return false; } + static boolean isSecureAuthenticationTransport(SessionContext p0){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UsernameHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UsernameHolder.java new file mode 100644 index 00000000000..5bc47141a89 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/auth/UsernameHolder.java @@ -0,0 +1,9 @@ +// Generated automatically from org.apache.sshd.common.auth.UsernameHolder for testing purposes + +package org.apache.sshd.common.auth; + + +public interface UsernameHolder +{ + String getUsername(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/AbstractChannel.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/AbstractChannel.java new file mode 100644 index 00000000000..fc3c94ff65a --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/AbstractChannel.java @@ -0,0 +1,120 @@ +// Generated automatically from org.apache.sshd.common.channel.AbstractChannel for testing purposes + +package org.apache.sshd.common.channel; + +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; +import java.util.function.IntUnaryOperator; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.PropertyResolver; +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.channel.ChannelListener; +import org.apache.sshd.common.channel.RequestHandler; +import org.apache.sshd.common.channel.Window; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolver; +import org.apache.sshd.common.future.DefaultCloseFuture; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.closeable.AbstractInnerCloseable; +import org.apache.sshd.common.util.io.functors.Invoker; +import org.apache.sshd.common.util.threads.CloseableExecutorService; +import org.apache.sshd.common.util.threads.ExecutorServiceCarrier; + +abstract public class AbstractChannel extends AbstractInnerCloseable implements Channel, ExecutorServiceCarrier +{ + protected AbstractChannel() {} + protected AbstractChannel(String p0, boolean p1){} + protected AbstractChannel(String p0, boolean p1, Collection> p2, CloseableExecutorService p3){} + protected AbstractChannel(boolean p0){} + protected AbstractChannel(boolean p0, Collection> p1){} + protected AtomicReference gracefulState = null; + protected Closeable getInnerCloseable(){ return null; } + protected ConnectionService service = null; + protected Date addPendingRequest(String p0, boolean p1){ return null; } + protected Date removePendingRequest(String p0){ return null; } + protected IoWriteFuture sendEof(){ return null; } + protected IoWriteFuture sendResponse(Buffer p0, String p1, RequestHandler.Result p2, boolean p3){ return null; } + protected RequestHandler.Result handleInternalRequest(String p0, boolean p1, Buffer p2){ return null; } + protected abstract void doWriteData(byte[] p0, int p1, long p2); + protected abstract void doWriteExtendedData(byte[] p0, int p1, long p2); + protected final AtomicBoolean closeSignaled = null; + protected final AtomicBoolean eofReceived = null; + protected final AtomicBoolean eofSent = null; + protected final AtomicBoolean initialized = null; + protected final AtomicBoolean unregisterSignaled = null; + protected final ChannelListener channelListenerProxy = null; + protected final Collection channelListeners = null; + protected final DefaultCloseFuture gracefulFuture = null; + protected long validateIncomingDataSize(int p0, long p1){ return 0; } + protected void configureWindow(){} + protected void handleChannelRequest(String p0, boolean p1, Buffer p2){} + protected void handleUnknownChannelRequest(String p0, boolean p1, Buffer p2){} + protected void invokeChannelSignaller(Invoker p0){} + protected void notifyStateChanged(ChannelListener p0, String p1){} + protected void notifyStateChanged(String p0){} + protected void preClose(){} + protected void sendWindowAdjust(long p0){} + protected void setRecipient(int p0){} + protected void signalChannelClosed(ChannelListener p0, Throwable p1){} + protected void signalChannelInitialized(){} + protected void signalChannelInitialized(ChannelListener p0){} + protected void signalChannelOpenFailure(ChannelListener p0, Throwable p1){} + protected void signalChannelOpenFailure(Throwable p0){} + protected void signalChannelOpenSuccess(){} + protected void signalChannelOpenSuccess(ChannelListener p0){} + public T computeAttributeIfAbsent(AttributeRepository.AttributeKey p0, Function, ? extends T> p1){ return null; } + public T getAttribute(AttributeRepository.AttributeKey p0){ return null; } + public T removeAttribute(AttributeRepository.AttributeKey p0){ return null; } + public T setAttribute(AttributeRepository.AttributeKey p0, T p1){ return null; } + public ChannelListener getChannelListenerProxy(){ return null; } + public ChannelStreamWriterResolver getChannelStreamWriterResolver(){ return null; } + public ChannelStreamWriterResolver resolveChannelStreamWriterResolver(){ return null; } + public CloseableExecutorService getExecutorService(){ return null; } + public Collection> attributeKeys(){ return null; } + public IoWriteFuture writePacket(Buffer p0){ return null; } + public List> getRequestHandlers(){ return null; } + public Map getProperties(){ return null; } + public PropertyResolver getParentPropertyResolver(){ return null; } + public Session getSession(){ return null; } + public String toString(){ return null; } + public Window getLocalWindow(){ return null; } + public Window getRemoteWindow(){ return null; } + public boolean isEofSent(){ return false; } + public boolean isEofSignalled(){ return false; } + public boolean isInitialized(){ return false; } + public int getAttributesCount(){ return 0; } + public int getId(){ return 0; } + public int getRecipient(){ return 0; } + public static IntUnaryOperator RESPONSE_BUFFER_GROWTH_FACTOR = null; + public void addChannelListener(ChannelListener p0){} + public void addRequestHandler(RequestHandler p0){} + public void clearAttributes(){} + public void handleChannelRegistrationResult(ConnectionService p0, Session p1, int p2, boolean p3){} + public void handleChannelUnregistration(ConnectionService p0){} + public void handleClose(){} + public void handleData(Buffer p0){} + public void handleEof(){} + public void handleExtendedData(Buffer p0){} + public void handleFailure(){} + public void handleRequest(Buffer p0){} + public void handleSuccess(){} + public void handleWindowAdjust(Buffer p0){} + public void init(ConnectionService p0, Session p1, int p2){} + public void removeChannelListener(ChannelListener p0){} + public void removeRequestHandler(RequestHandler p0){} + public void setChannelStreamWriterResolver(ChannelStreamWriterResolver p0){} + public void signalChannelClosed(Throwable p0){} + static enum GracefulState + { + CloseReceived, CloseSent, Closed, Opened; + private GracefulState() {} + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/Channel.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/Channel.java new file mode 100644 index 00000000000..d0aa35f7dba --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/Channel.java @@ -0,0 +1,55 @@ +// Generated automatically from org.apache.sshd.common.channel.Channel for testing purposes + +package org.apache.sshd.common.channel; + +import java.util.Collection; +import java.util.List; +import org.apache.sshd.client.future.OpenFuture; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.AttributeStore; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.PropertyResolver; +import org.apache.sshd.common.channel.ChannelListenerManager; +import org.apache.sshd.common.channel.RequestHandler; +import org.apache.sshd.common.channel.Window; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolverManager; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionHolder; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface Channel extends AttributeStore, ChannelListenerManager, ChannelStreamWriterResolverManager, Closeable, PropertyResolver, SessionHolder +{ + IoWriteFuture writePacket(Buffer p0); + List> getRequestHandlers(); + OpenFuture open(int p0, long p1, long p2, Buffer p3); + Window getLocalWindow(); + Window getRemoteWindow(); + boolean isEofSignalled(); + boolean isInitialized(); + default T resolveAttribute(AttributeRepository.AttributeKey p0){ return null; } + default void addRequestHandlers(Collection> p0){} + default void removeRequestHandlers(Collection> p0){} + int getId(); + int getRecipient(); + static T resolveAttribute(Channel p0, AttributeRepository.AttributeKey p1){ return null; } + static String CHANNEL_EXEC = null; + static String CHANNEL_SHELL = null; + static String CHANNEL_SUBSYSTEM = null; + void addRequestHandler(RequestHandler p0); + void handleChannelRegistrationResult(ConnectionService p0, Session p1, int p2, boolean p3); + void handleChannelUnregistration(ConnectionService p0); + void handleClose(); + void handleData(Buffer p0); + void handleEof(); + void handleExtendedData(Buffer p0); + void handleFailure(); + void handleOpenFailure(Buffer p0); + void handleOpenSuccess(int p0, long p1, long p2, Buffer p3); + void handleRequest(Buffer p0); + void handleSuccess(); + void handleWindowAdjust(Buffer p0); + void init(ConnectionService p0, Session p1, int p2); + void removeRequestHandler(RequestHandler p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelAsyncInputStream.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelAsyncInputStream.java new file mode 100644 index 00000000000..e9f12348902 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelAsyncInputStream.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.sshd.common.channel.ChannelAsyncInputStream for testing purposes + +package org.apache.sshd.common.channel; + +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.channel.ChannelHolder; +import org.apache.sshd.common.future.CloseFuture; +import org.apache.sshd.common.io.IoInputStream; +import org.apache.sshd.common.io.IoReadFuture; +import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.closeable.AbstractCloseable; + +public class ChannelAsyncInputStream extends AbstractCloseable implements ChannelHolder, IoInputStream +{ + protected ChannelAsyncInputStream() {} + protected CloseFuture doCloseGracefully(){ return null; } + protected void preClose(){} + public Channel getChannel(){ return null; } + public ChannelAsyncInputStream(Channel p0){} + public IoReadFuture read(Buffer p0){ return null; } + public String toString(){ return null; } + public void write(Readable p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelAsyncOutputStream.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelAsyncOutputStream.java new file mode 100644 index 00000000000..b082117a3e8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelAsyncOutputStream.java @@ -0,0 +1,31 @@ +// Generated automatically from org.apache.sshd.common.channel.ChannelAsyncOutputStream for testing purposes + +package org.apache.sshd.common.channel; + +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.channel.ChannelHolder; +import org.apache.sshd.common.channel.IoWriteFutureImpl; +import org.apache.sshd.common.future.CloseFuture; +import org.apache.sshd.common.io.IoOutputStream; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.closeable.AbstractCloseable; + +public class ChannelAsyncOutputStream extends AbstractCloseable implements ChannelHolder, IoOutputStream +{ + protected ChannelAsyncOutputStream() {} + protected Buffer createSendBuffer(Buffer p0, Channel p1, long p2){ return null; } + protected CloseFuture doCloseGracefully(){ return null; } + protected void doWriteIfPossible(boolean p0){} + protected void onWritten(IoWriteFutureImpl p0, int p1, long p2, IoWriteFuture p3){} + protected void preClose(){} + public Channel getChannel(){ return null; } + public ChannelAsyncOutputStream(Channel p0, byte p1){} + public ChannelAsyncOutputStream(Channel p0, byte p1, boolean p2){} + public IoWriteFuture writeBuffer(Buffer p0){ return null; } + public String toString(){ return null; } + public boolean isSendChunkIfRemoteWindowIsSmallerThanPacketSize(){ return false; } + public byte getCommandType(){ return 0; } + public void onWindowExpanded(){} + public void setSendChunkIfRemoteWindowIsSmallerThanPacketSize(boolean p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelFactory.java new file mode 100644 index 00000000000..7d74417f911 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelFactory.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.channel.ChannelFactory for testing purposes + +package org.apache.sshd.common.channel; + +import java.util.Collection; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.session.Session; + +public interface ChannelFactory extends NamedResource +{ + Channel createChannel(Session p0); + static Channel createChannel(Session p0, Collection p1, String p2){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelHolder.java new file mode 100644 index 00000000000..a80c4bdb3b2 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelHolder.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.common.channel.ChannelHolder for testing purposes + +package org.apache.sshd.common.channel; + +import org.apache.sshd.common.channel.Channel; + +public interface ChannelHolder +{ + Channel getChannel(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelListener.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelListener.java new file mode 100644 index 00000000000..4e8b16d88df --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelListener.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.common.channel.ChannelListener for testing purposes + +package org.apache.sshd.common.channel; + +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.util.SshdEventListener; + +public interface ChannelListener extends SshdEventListener +{ + default void channelClosed(Channel p0, Throwable p1){} + default void channelInitialized(Channel p0){} + default void channelOpenFailure(Channel p0, Throwable p1){} + default void channelOpenSuccess(Channel p0){} + default void channelStateChanged(Channel p0, String p1){} + static L validateListener(L p0){ return null; } + static ChannelListener EMPTY = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelListenerManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelListenerManager.java new file mode 100644 index 00000000000..899d9142dfb --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/ChannelListenerManager.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.channel.ChannelListenerManager for testing purposes + +package org.apache.sshd.common.channel; + +import org.apache.sshd.common.channel.ChannelListener; + +public interface ChannelListenerManager +{ + ChannelListener getChannelListenerProxy(); + void addChannelListener(ChannelListener p0); + void removeChannelListener(ChannelListener p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/IoWriteFutureImpl.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/IoWriteFutureImpl.java new file mode 100644 index 00000000000..c2382565d09 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/IoWriteFutureImpl.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.common.channel.IoWriteFutureImpl for testing purposes + +package org.apache.sshd.common.channel; + +import org.apache.sshd.common.io.AbstractIoWriteFuture; +import org.apache.sshd.common.util.buffer.Buffer; + +public class IoWriteFutureImpl extends AbstractIoWriteFuture +{ + protected IoWriteFutureImpl() {} + public Buffer getBuffer(){ return null; } + public IoWriteFutureImpl(Object p0, Buffer p1){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyChannelConfigurationHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyChannelConfigurationHolder.java new file mode 100644 index 00000000000..4225ef615ba --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyChannelConfigurationHolder.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.sshd.common.channel.PtyChannelConfigurationHolder for testing purposes + +package org.apache.sshd.common.channel; + +import java.util.Map; +import org.apache.sshd.common.channel.PtyMode; + +public interface PtyChannelConfigurationHolder +{ + Map getPtyModes(); + String getPtyType(); + int getPtyColumns(); + int getPtyHeight(); + int getPtyLines(); + int getPtyWidth(); + static Map DEFAULT_PTY_MODES = null; + static String DUMMY_PTY_TYPE = null; + static String WINDOWS_PTY_TYPE = null; + static int DEFAULT_COLUMNS_COUNT = 0; + static int DEFAULT_HEIGHT = 0; + static int DEFAULT_ROWS_COUNT = 0; + static int DEFAULT_WIDTH = 0; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyChannelConfigurationMutator.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyChannelConfigurationMutator.java new file mode 100644 index 00000000000..8182418a684 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyChannelConfigurationMutator.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.sshd.common.channel.PtyChannelConfigurationMutator for testing purposes + +package org.apache.sshd.common.channel; + +import java.util.Map; +import org.apache.sshd.common.channel.PtyChannelConfigurationHolder; +import org.apache.sshd.common.channel.PtyMode; + +public interface PtyChannelConfigurationMutator extends PtyChannelConfigurationHolder +{ + static M copyConfiguration(PtyChannelConfigurationHolder p0, M p1){ return null; } + static M setupSensitiveDefaultPtyConfiguration(M p0){ return null; } + void setPtyColumns(int p0); + void setPtyHeight(int p0); + void setPtyLines(int p0); + void setPtyModes(Map p0); + void setPtyType(String p0); + void setPtyWidth(int p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyMode.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyMode.java new file mode 100644 index 00000000000..ae950c08e76 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/PtyMode.java @@ -0,0 +1,35 @@ +// Generated automatically from org.apache.sshd.common.channel.PtyMode for testing purposes + +package org.apache.sshd.common.channel; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.NavigableMap; +import java.util.Set; +import java.util.function.ToIntFunction; + +public enum PtyMode +{ + CS7, CS8, ECHO, ECHOCTL, ECHOE, ECHOK, ECHOKE, ECHONL, ICANON, ICRNL, IEXTEN, IGNCR, IGNPAR, IMAXBEL, INLCR, INPCK, ISIG, ISTRIP, IUCLC, IUTF8, IXANY, IXOFF, IXON, NOFLSH, OCRNL, OLCUC, ONLCR, ONLRET, ONOCR, OPOST, PARENB, PARMRK, PARODD, PENDIN, TOSTOP, TTY_OP_ISPEED, TTY_OP_OSPEED, VDISCARD, VDSUSP, VEOF, VEOL, VEOL2, VERASE, VFLUSH, VINTR, VKILL, VLNEXT, VQUIT, VREPRINT, VSTART, VSTATUS, VSTOP, VSUSP, VSWTCH, VWERASE, XCASE; + private PtyMode() {} + public int toInt(){ return 0; } + public static Comparator BY_OPCODE = null; + public static Integer FALSE_SETTING = null; + public static Integer TRUE_SETTING = null; + public static Map createEnabledOptions(Collection p0){ return null; } + public static Map createEnabledOptions(PtyMode... p0){ return null; } + public static NavigableMap COMMANDS = null; + public static PtyMode fromInt(int p0){ return null; } + public static PtyMode fromName(String p0){ return null; } + public static Set MODES = null; + public static Set resolveEnabledOptions(Map p0, Collection p1){ return null; } + public static Set resolveEnabledOptions(Map p0, PtyMode... p1){ return null; } + public static ToIntFunction OPCODE_EXTRACTOR = null; + public static boolean getBooleanSettingValue(Map p0, Collection p1, boolean p2){ return false; } + public static boolean getBooleanSettingValue(Map p0, PtyMode p1){ return false; } + public static boolean getBooleanSettingValue(Object p0){ return false; } + public static boolean getBooleanSettingValue(int p0){ return false; } + public static boolean isCharSetting(PtyMode p0){ return false; } + public static byte TTY_OP_END = 0; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/RequestHandler.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/RequestHandler.java new file mode 100644 index 00000000000..6ffc36e1037 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/RequestHandler.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.common.channel.RequestHandler for testing purposes + +package org.apache.sshd.common.channel; + +import java.util.Set; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface RequestHandler +{ + RequestHandler.Result process(T p0, String p1, boolean p2, Buffer p3); + static public enum Result + { + Replied, ReplyFailure, ReplySuccess, Unsupported; + private Result() {} + public static RequestHandler.Result fromName(String p0){ return null; } + public static Set VALUES = null; + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/StreamingChannel.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/StreamingChannel.java new file mode 100644 index 00000000000..13cb612af40 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/StreamingChannel.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.common.channel.StreamingChannel for testing purposes + +package org.apache.sshd.common.channel; + + +public interface StreamingChannel +{ + StreamingChannel.Streaming getStreaming(); + static public enum Streaming + { + Async, Sync; + private Streaming() {} + } + void setStreaming(StreamingChannel.Streaming p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/Window.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/Window.java new file mode 100644 index 00000000000..f970fa84228 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/Window.java @@ -0,0 +1,38 @@ +// Generated automatically from org.apache.sshd.common.channel.Window for testing purposes + +package org.apache.sshd.common.channel; + +import java.nio.channels.Channel; +import java.time.Duration; +import java.util.function.Predicate; +import org.apache.sshd.common.PropertyResolver; +import org.apache.sshd.common.channel.AbstractChannel; +import org.apache.sshd.common.channel.ChannelHolder; +import org.apache.sshd.common.util.logging.AbstractLoggingBean; + +public class Window extends AbstractLoggingBean implements Channel, ChannelHolder +{ + protected Window() {} + protected void checkInitialized(String p0){} + protected void updateSize(long p0){} + protected void waitForCondition(Predicate p0, Duration p1){} + public AbstractChannel getChannel(){ return null; } + public String toString(){ return null; } + public Window(AbstractChannel p0, Object p1, boolean p2, boolean p3){} + public boolean isOpen(){ return false; } + public long getMaxSize(){ return 0; } + public long getPacketSize(){ return 0; } + public long getSize(){ return 0; } + public long waitForSpace(Duration p0){ return 0; } + public long waitForSpace(long p0){ return 0; } + public static Predicate SPACE_AVAILABLE_PREDICATE = null; + public void check(long p0){} + public void close(){} + public void consume(long p0){} + public void consumeAndCheck(long p0){} + public void expand(int p0){} + public void init(PropertyResolver p0){} + public void init(long p0, long p1, PropertyResolver p2){} + public void waitAndConsume(long p0, Duration p1){} + public void waitAndConsume(long p0, long p1){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriter.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriter.java new file mode 100644 index 00000000000..8324652c2c4 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriter.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.channel.throttle.ChannelStreamWriter for testing purposes + +package org.apache.sshd.common.channel.throttle; + +import java.nio.channels.Channel; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface ChannelStreamWriter extends Channel +{ + IoWriteFuture writeData(Buffer p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriterResolver.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriterResolver.java new file mode 100644 index 00000000000..68e7124f9d0 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriterResolver.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolver for testing purposes + +package org.apache.sshd.common.channel.throttle; + +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriter; + +public interface ChannelStreamWriterResolver +{ + ChannelStreamWriter resolveChannelStreamWriter(Channel p0, byte p1); + static ChannelStreamWriterResolver NONE = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriterResolverManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriterResolverManager.java new file mode 100644 index 00000000000..f7a86aa657b --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/channel/throttle/ChannelStreamWriterResolverManager.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolverManager for testing purposes + +package org.apache.sshd.common.channel.throttle; + +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriter; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolver; + +public interface ChannelStreamWriterResolverManager extends ChannelStreamWriterResolver +{ + ChannelStreamWriterResolver getChannelStreamWriterResolver(); + default ChannelStreamWriter resolveChannelStreamWriter(Channel p0, byte p1){ return null; } + default ChannelStreamWriterResolver resolveChannelStreamWriterResolver(){ return null; } + void setChannelStreamWriterResolver(ChannelStreamWriterResolver p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/cipher/Cipher.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/cipher/Cipher.java new file mode 100644 index 00000000000..3053d596919 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/cipher/Cipher.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.sshd.common.cipher.Cipher for testing purposes + +package org.apache.sshd.common.cipher; + +import org.apache.sshd.common.cipher.CipherInformation; + +public interface Cipher extends CipherInformation +{ + default void update(byte[] p0){} + default void updateAAD(byte[] p0){} + default void updateWithAAD(byte[] p0, int p1, int p2, int p3){} + static boolean checkSupported(String p0, int p1){ return false; } + static public enum Mode + { + Decrypt, Encrypt; + private Mode() {} + } + void init(Cipher.Mode p0, byte[] p1, byte[] p2); + void update(byte[] p0, int p1, int p2); + void updateAAD(byte[] p0, int p1, int p2); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/cipher/CipherInformation.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/cipher/CipherInformation.java new file mode 100644 index 00000000000..40f0cc0d38a --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/cipher/CipherInformation.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.common.cipher.CipherInformation for testing purposes + +package org.apache.sshd.common.cipher; + +import org.apache.sshd.common.AlgorithmNameProvider; +import org.apache.sshd.common.keyprovider.KeySizeIndicator; + +public interface CipherInformation extends AlgorithmNameProvider, KeySizeIndicator +{ + String getTransformation(); + int getAuthenticationTagSize(); + int getCipherBlockSize(); + int getIVSize(); + int getKdfSize(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/compression/Compression.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/compression/Compression.java new file mode 100644 index 00000000000..62df98c4ba3 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/compression/Compression.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.common.compression.Compression for testing purposes + +package org.apache.sshd.common.compression; + +import org.apache.sshd.common.compression.CompressionInformation; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface Compression extends CompressionInformation +{ + static public enum Type + { + Deflater, Inflater; + private Type() {} + } + void compress(Buffer p0); + void init(Compression.Type p0, int p1); + void uncompress(Buffer p0, Buffer p1); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/compression/CompressionInformation.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/compression/CompressionInformation.java new file mode 100644 index 00000000000..0a3b199f3cc --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/compression/CompressionInformation.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.compression.CompressionInformation for testing purposes + +package org.apache.sshd.common.compression; + +import org.apache.sshd.common.NamedResource; + +public interface CompressionInformation extends NamedResource +{ + boolean isCompressionExecuted(); + boolean isDelayed(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProvider.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProvider.java new file mode 100644 index 00000000000..0c43620daad --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProvider.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.sshd.common.config.keys.FilePasswordProvider for testing purposes + +package org.apache.sshd.common.config.keys; + +import java.util.Set; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.session.SessionContext; + +public interface FilePasswordProvider +{ + String getPassword(SessionContext p0, NamedResource p1, int p2); + default FilePasswordProvider.ResourceDecodeResult handleDecodeAttemptResult(SessionContext p0, NamedResource p1, int p2, String p3, Exception p4){ return null; } + static FilePasswordProvider EMPTY = null; + static FilePasswordProvider of(String p0){ return null; } + static public enum ResourceDecodeResult + { + IGNORE, RETRY, TERMINATE; + private ResourceDecodeResult() {} + public static Set VALUES = null; + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java new file mode 100644 index 00000000000..725548fd116 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.config.keys.FilePasswordProviderHolder for testing purposes + +package org.apache.sshd.common.config.keys; + +import org.apache.sshd.common.config.keys.FilePasswordProvider; + +public interface FilePasswordProviderHolder +{ + FilePasswordProvider getFilePasswordProvider(); + static FilePasswordProviderHolder providerHolderOf(FilePasswordProvider p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java new file mode 100644 index 00000000000..785b38286b8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.config.keys.FilePasswordProviderManager for testing purposes + +package org.apache.sshd.common.config.keys; + +import org.apache.sshd.common.config.keys.FilePasswordProvider; +import org.apache.sshd.common.config.keys.FilePasswordProviderHolder; + +public interface FilePasswordProviderManager extends FilePasswordProviderHolder +{ + void setFilePasswordProvider(FilePasswordProvider p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/OpenSshCertificate.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/OpenSshCertificate.java new file mode 100644 index 00000000000..9551bc0266c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/config/keys/OpenSshCertificate.java @@ -0,0 +1,51 @@ +// Generated automatically from org.apache.sshd.common.config.keys.OpenSshCertificate for testing purposes + +package org.apache.sshd.common.config.keys; + +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.Collection; +import java.util.List; + +public interface OpenSshCertificate extends PrivateKey, PublicKey +{ + Collection getPrincipals(); + List getCriticalOptions(); + List getExtensions(); + OpenSshCertificate.Type getType(); + PublicKey getCaPubKey(); + PublicKey getCertPubKey(); + String getId(); + String getKeyType(); + String getRawKeyType(); + String getReserved(); + String getSignatureAlgorithm(); + byte[] getMessage(); + byte[] getNonce(); + byte[] getRawSignature(); + byte[] getSignature(); + long getSerial(); + long getValidAfter(); + long getValidBefore(); + static boolean isValidNow(OpenSshCertificate p0){ return false; } + static long INFINITY = 0; + static long MIN_EPOCH = 0; + static public class CertificateOption + { + protected CertificateOption() {} + public CertificateOption(String p0){} + public CertificateOption(String p0, String p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final String getData(){ return null; } + public final String getName(){ return null; } + public int hashCode(){ return 0; } + } + static public enum Type + { + HOST, USER; + private Type() {} + public int getCode(){ return 0; } + public static OpenSshCertificate.Type fromCode(int p0){ return null; } + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/digest/Digest.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/digest/Digest.java new file mode 100644 index 00000000000..def526b3a12 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/digest/Digest.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.common.digest.Digest for testing purposes + +package org.apache.sshd.common.digest; + +import org.apache.sshd.common.digest.DigestInformation; + +public interface Digest extends Comparable, DigestInformation +{ + byte[] digest(); + void init(); + void update(byte[] p0); + void update(byte[] p0, int p1, int p2); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/digest/DigestInformation.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/digest/DigestInformation.java new file mode 100644 index 00000000000..01cf40ef25a --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/digest/DigestInformation.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.common.digest.DigestInformation for testing purposes + +package org.apache.sshd.common.digest; + +import org.apache.sshd.common.AlgorithmNameProvider; + +public interface DigestInformation extends AlgorithmNameProvider +{ + int getBlockSize(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/file/FileSystemFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/file/FileSystemFactory.java new file mode 100644 index 00000000000..c6fa0c57ac1 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/file/FileSystemFactory.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.common.file.FileSystemFactory for testing purposes + +package org.apache.sshd.common.file; + +import java.nio.file.FileSystem; +import java.nio.file.Path; +import org.apache.sshd.common.session.SessionContext; + +public interface FileSystemFactory +{ + FileSystem createFileSystem(SessionContext p0); + Path getUserHomeDir(SessionContext p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/Forwarder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/Forwarder.java new file mode 100644 index 00000000000..6fcb349ee2f --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/Forwarder.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.common.forward.Forwarder for testing purposes + +package org.apache.sshd.common.forward; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.forward.PortForwardingEventListenerManager; +import org.apache.sshd.common.forward.PortForwardingEventListenerManagerHolder; +import org.apache.sshd.common.forward.PortForwardingManager; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public interface Forwarder extends Closeable, PortForwardingEventListenerManager, PortForwardingEventListenerManagerHolder, PortForwardingManager +{ + SshdSocketAddress getForwardedPort(int p0); + SshdSocketAddress localPortForwardingRequested(SshdSocketAddress p0); + void localPortForwardingCancelled(SshdSocketAddress p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/ForwarderFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/ForwarderFactory.java new file mode 100644 index 00000000000..a8fd59303b7 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/ForwarderFactory.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.forward.ForwarderFactory for testing purposes + +package org.apache.sshd.common.forward; + +import org.apache.sshd.common.forward.Forwarder; +import org.apache.sshd.common.session.ConnectionService; + +public interface ForwarderFactory +{ + Forwarder create(ConnectionService p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListener.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListener.java new file mode 100644 index 00000000000..c6892ca3b2f --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListener.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.sshd.common.forward.PortForwardingEventListener for testing purposes + +package org.apache.sshd.common.forward; + +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.SshdEventListener; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public interface PortForwardingEventListener extends SshdEventListener +{ + default void establishedDynamicTunnel(Session p0, SshdSocketAddress p1, SshdSocketAddress p2, Throwable p3){} + default void establishedExplicitTunnel(Session p0, SshdSocketAddress p1, SshdSocketAddress p2, boolean p3, SshdSocketAddress p4, Throwable p5){} + default void establishingDynamicTunnel(Session p0, SshdSocketAddress p1){} + default void establishingExplicitTunnel(Session p0, SshdSocketAddress p1, SshdSocketAddress p2, boolean p3){} + default void tearingDownDynamicTunnel(Session p0, SshdSocketAddress p1){} + default void tearingDownExplicitTunnel(Session p0, SshdSocketAddress p1, boolean p2, SshdSocketAddress p3){} + default void tornDownDynamicTunnel(Session p0, SshdSocketAddress p1, Throwable p2){} + default void tornDownExplicitTunnel(Session p0, SshdSocketAddress p1, boolean p2, SshdSocketAddress p3, Throwable p4){} + static L validateListener(L p0){ return null; } + static PortForwardingEventListener EMPTY = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListenerManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListenerManager.java new file mode 100644 index 00000000000..05f818c275a --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListenerManager.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.forward.PortForwardingEventListenerManager for testing purposes + +package org.apache.sshd.common.forward; + +import org.apache.sshd.common.forward.PortForwardingEventListener; + +public interface PortForwardingEventListenerManager +{ + PortForwardingEventListener getPortForwardingEventListenerProxy(); + void addPortForwardingEventListener(PortForwardingEventListener p0); + void removePortForwardingEventListener(PortForwardingEventListener p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListenerManagerHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListenerManagerHolder.java new file mode 100644 index 00000000000..fec2688f59c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingEventListenerManagerHolder.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.common.forward.PortForwardingEventListenerManagerHolder for testing purposes + +package org.apache.sshd.common.forward; + +import java.util.Collection; +import org.apache.sshd.common.forward.PortForwardingEventListenerManager; + +public interface PortForwardingEventListenerManagerHolder +{ + Collection getRegisteredManagers(); + boolean addPortForwardingEventListenerManager(PortForwardingEventListenerManager p0); + boolean removePortForwardingEventListenerManager(PortForwardingEventListenerManager p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingInformationProvider.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingInformationProvider.java new file mode 100644 index 00000000000..3b347f044d3 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingInformationProvider.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.sshd.common.forward.PortForwardingInformationProvider for testing purposes + +package org.apache.sshd.common.forward; + +import java.util.List; +import java.util.Map; +import java.util.NavigableSet; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public interface PortForwardingInformationProvider +{ + List> getRemoteForwardsBindings(); + List> getLocalForwardsBindings(); + List getBoundLocalPortForwards(int p0); + List getStartedLocalPortForwards(); + NavigableSet getStartedRemotePortForwards(); + SshdSocketAddress getBoundRemotePortForward(int p0); + default boolean isLocalPortForwardingStartedForPort(int p0){ return false; } + default boolean isRemotePortForwardingStartedForPort(int p0){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingManager.java new file mode 100644 index 00000000000..ff7621a9739 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/forward/PortForwardingManager.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.common.forward.PortForwardingManager for testing purposes + +package org.apache.sshd.common.forward; + +import org.apache.sshd.common.forward.PortForwardingInformationProvider; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public interface PortForwardingManager extends PortForwardingInformationProvider +{ + SshdSocketAddress startDynamicPortForwarding(SshdSocketAddress p0); + SshdSocketAddress startLocalPortForwarding(SshdSocketAddress p0, SshdSocketAddress p1); + SshdSocketAddress startRemotePortForwarding(SshdSocketAddress p0, SshdSocketAddress p1); + default SshdSocketAddress startLocalPortForwarding(int p0, SshdSocketAddress p1){ return null; } + void stopDynamicPortForwarding(SshdSocketAddress p0); + void stopLocalPortForwarding(SshdSocketAddress p0); + void stopRemotePortForwarding(SshdSocketAddress p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/AbstractSshFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/AbstractSshFuture.java new file mode 100644 index 00000000000..907a762f1c0 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/AbstractSshFuture.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.sshd.common.future.AbstractSshFuture for testing purposes + +package org.apache.sshd.common.future; + +import java.util.function.Function; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.SshFutureListener; +import org.apache.sshd.common.util.logging.AbstractLoggingBean; + +abstract public class AbstractSshFuture extends AbstractLoggingBean implements SshFuture +{ + protected AbstractSshFuture() {} + protected E formatExceptionMessage(Function p0, String p1, Object... p2){ return null; } + protected R verifyResult(Class p0, long p1){ return null; } + protected AbstractSshFuture(Object p0){} + protected SshFutureListener asListener(Object p0){ return null; } + protected T asT(){ return null; } + protected abstract Object await0(long p0, boolean p1); + protected static Object CANCELED = null; + protected void notifyListener(SshFutureListener p0){} + public Object getId(){ return null; } + public String toString(){ return null; } + public boolean await(long p0){ return false; } + public boolean awaitUninterruptibly(long p0){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/CloseFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/CloseFuture.java new file mode 100644 index 00000000000..eea259d3fb1 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/CloseFuture.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.future.CloseFuture for testing purposes + +package org.apache.sshd.common.future; + +import org.apache.sshd.common.future.SshFuture; + +public interface CloseFuture extends SshFuture +{ + boolean isClosed(); + void setClosed(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultCloseFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultCloseFuture.java new file mode 100644 index 00000000000..bfb5f2584a1 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultCloseFuture.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.common.future.DefaultCloseFuture for testing purposes + +package org.apache.sshd.common.future; + +import org.apache.sshd.common.future.CloseFuture; +import org.apache.sshd.common.future.DefaultSshFuture; +import org.apache.sshd.common.future.SshFuture; + +public class DefaultCloseFuture extends DefaultSshFuture implements CloseFuture +{ + protected DefaultCloseFuture() {} + public DefaultCloseFuture(Object p0, Object p1){} + public boolean isClosed(){ return false; } + public void setClosed(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultKeyExchangeFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultKeyExchangeFuture.java new file mode 100644 index 00000000000..fbb021f6202 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultKeyExchangeFuture.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.common.future.DefaultKeyExchangeFuture for testing purposes + +package org.apache.sshd.common.future; + +import org.apache.sshd.common.future.DefaultVerifiableSshFuture; +import org.apache.sshd.common.future.KeyExchangeFuture; +import org.apache.sshd.common.future.SshFuture; + +public class DefaultKeyExchangeFuture extends DefaultVerifiableSshFuture implements KeyExchangeFuture +{ + protected DefaultKeyExchangeFuture() {} + public DefaultKeyExchangeFuture(Object p0, Object p1){} + public KeyExchangeFuture verify(long p0){ return null; } + public Throwable getException(){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultSshFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultSshFuture.java new file mode 100644 index 00000000000..65cac56fadd --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultSshFuture.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.sshd.common.future.DefaultSshFuture for testing purposes + +package org.apache.sshd.common.future; + +import org.apache.sshd.common.future.AbstractSshFuture; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.SshFutureListener; + +public class DefaultSshFuture extends AbstractSshFuture +{ + protected DefaultSshFuture() {} + protected Object await0(long p0, boolean p1){ return null; } + protected void notifyListeners(){} + public DefaultSshFuture(Object p0, Object p1){} + public Object getValue(){ return null; } + public String toString(){ return null; } + public T addListener(SshFutureListener p0){ return null; } + public T removeListener(SshFutureListener p0){ return null; } + public boolean isCanceled(){ return false; } + public boolean isDone(){ return false; } + public int getNumRegisteredListeners(){ return 0; } + public void cancel(){} + public void setValue(Object p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultVerifiableSshFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultVerifiableSshFuture.java new file mode 100644 index 00000000000..b359cd8df5c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/DefaultVerifiableSshFuture.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.common.future.DefaultVerifiableSshFuture for testing purposes + +package org.apache.sshd.common.future; + +import org.apache.sshd.common.future.DefaultSshFuture; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.VerifiableFuture; + +abstract public class DefaultVerifiableSshFuture extends DefaultSshFuture implements VerifiableFuture +{ + protected DefaultVerifiableSshFuture() {} + protected DefaultVerifiableSshFuture(Object p0, Object p1){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/KeyExchangeFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/KeyExchangeFuture.java new file mode 100644 index 00000000000..508c015a54e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/KeyExchangeFuture.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.future.KeyExchangeFuture for testing purposes + +package org.apache.sshd.common.future; + +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.VerifiableFuture; + +public interface KeyExchangeFuture extends SshFuture, VerifiableFuture +{ + Throwable getException(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/SshFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/SshFuture.java new file mode 100644 index 00000000000..9eddd441d14 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/SshFuture.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.future.SshFuture for testing purposes + +package org.apache.sshd.common.future; + +import org.apache.sshd.common.future.SshFutureListener; +import org.apache.sshd.common.future.WaitableFuture; + +public interface SshFuture extends WaitableFuture +{ + T addListener(SshFutureListener p0); + T removeListener(SshFutureListener p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/SshFutureListener.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/SshFutureListener.java new file mode 100644 index 00000000000..bb35db3b1c2 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/SshFutureListener.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.future.SshFutureListener for testing purposes + +package org.apache.sshd.common.future; + +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.util.SshdEventListener; + +public interface SshFutureListener extends SshdEventListener +{ + void operationComplete(T p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/VerifiableFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/VerifiableFuture.java new file mode 100644 index 00000000000..297598bf313 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/VerifiableFuture.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.future.VerifiableFuture for testing purposes + +package org.apache.sshd.common.future; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +public interface VerifiableFuture +{ + T verify(long p0); + default T verify(){ return null; } + default T verify(Duration p0){ return null; } + default T verify(long p0, TimeUnit p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/WaitableFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/WaitableFuture.java new file mode 100644 index 00000000000..88d5feda3fe --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/future/WaitableFuture.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.sshd.common.future.WaitableFuture for testing purposes + +package org.apache.sshd.common.future; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +public interface WaitableFuture +{ + Object getId(); + boolean await(long p0); + boolean awaitUninterruptibly(long p0); + boolean isDone(); + default boolean await(){ return false; } + default boolean await(Duration p0){ return false; } + default boolean await(long p0, TimeUnit p1){ return false; } + default boolean awaitUninterruptibly(){ return false; } + default boolean awaitUninterruptibly(Duration p0){ return false; } + default boolean awaitUninterruptibly(long p0, TimeUnit p1){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/helpers/AbstractFactoryManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/helpers/AbstractFactoryManager.java new file mode 100644 index 00000000000..19d178c8de4 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/helpers/AbstractFactoryManager.java @@ -0,0 +1,122 @@ +// Generated automatically from org.apache.sshd.common.helpers.AbstractFactoryManager for testing purposes + +package org.apache.sshd.common.helpers; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.function.Function; +import org.apache.sshd.agent.SshAgentFactory; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.Factory; +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.PropertyResolver; +import org.apache.sshd.common.ServiceFactory; +import org.apache.sshd.common.channel.ChannelFactory; +import org.apache.sshd.common.channel.ChannelListener; +import org.apache.sshd.common.channel.RequestHandler; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolver; +import org.apache.sshd.common.file.FileSystemFactory; +import org.apache.sshd.common.forward.ForwarderFactory; +import org.apache.sshd.common.forward.PortForwardingEventListener; +import org.apache.sshd.common.io.IoServiceEventListener; +import org.apache.sshd.common.io.IoServiceFactory; +import org.apache.sshd.common.io.IoServiceFactoryFactory; +import org.apache.sshd.common.kex.AbstractKexFactoryManager; +import org.apache.sshd.common.random.Random; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.session.ReservedSessionMessagesHandler; +import org.apache.sshd.common.session.SessionDisconnectHandler; +import org.apache.sshd.common.session.SessionListener; +import org.apache.sshd.common.session.UnknownChannelReferenceHandler; +import org.apache.sshd.common.session.helpers.AbstractSession; +import org.apache.sshd.common.session.helpers.AbstractSessionFactory; +import org.apache.sshd.common.session.helpers.SessionTimeoutListener; +import org.apache.sshd.server.forward.ForwardingFilter; + +abstract public class AbstractFactoryManager extends AbstractKexFactoryManager implements FactoryManager +{ + protected AbstractFactoryManager(){} + protected Factory randomFactory = null; + protected FileSystemFactory fileSystemFactory = null; + protected ForwarderFactory forwarderFactory = null; + protected ForwardingFilter forwardingFilter = null; + protected IoServiceFactory ioServiceFactory = null; + protected IoServiceFactoryFactory ioServiceFactoryFactory = null; + protected List channelFactories = null; + protected List serviceFactories = null; + protected List> globalRequestHandlers = null; + protected ScheduledExecutorService executor = null; + protected ScheduledFuture timeoutListenerFuture = null; + protected SessionTimeoutListener createSessionTimeoutListener(){ return null; } + protected SessionTimeoutListener sessionTimeoutListener = null; + protected SshAgentFactory agentFactory = null; + protected boolean shutdownExecutor = false; + protected final ChannelListener channelListenerProxy = null; + protected final Collection channelListeners = null; + protected final Collection tunnelListeners = null; + protected final Collection sessionListeners = null; + protected final PortForwardingEventListener tunnelListenerProxy = null; + protected final SessionListener sessionListenerProxy = null; + protected void checkConfig(){} + protected void removeSessionTimeout(AbstractSessionFactory p0){} + protected void setupSessionTimeout(AbstractSessionFactory p0){} + protected void stopSessionTimeoutListener(AbstractSessionFactory p0){} + public T computeAttributeIfAbsent(AttributeRepository.AttributeKey p0, Function, ? extends T> p1){ return null; } + public T getAttribute(AttributeRepository.AttributeKey p0){ return null; } + public T removeAttribute(AttributeRepository.AttributeKey p0){ return null; } + public T setAttribute(AttributeRepository.AttributeKey p0, T p1){ return null; } + public ChannelListener getChannelListenerProxy(){ return null; } + public ChannelStreamWriterResolver getChannelStreamWriterResolver(){ return null; } + public Collection> attributeKeys(){ return null; } + public Factory getRandomFactory(){ return null; } + public FileSystemFactory getFileSystemFactory(){ return null; } + public ForwarderFactory getForwarderFactory(){ return null; } + public ForwardingFilter getForwardingFilter(){ return null; } + public IoServiceEventListener getIoServiceEventListener(){ return null; } + public IoServiceFactory getIoServiceFactory(){ return null; } + public IoServiceFactoryFactory getIoServiceFactoryFactory(){ return null; } + public List getChannelFactories(){ return null; } + public List getServiceFactories(){ return null; } + public List> getGlobalRequestHandlers(){ return null; } + public Map getProperties(){ return null; } + public PortForwardingEventListener getPortForwardingEventListenerProxy(){ return null; } + public PropertyResolver getParentPropertyResolver(){ return null; } + public ReservedSessionMessagesHandler getReservedSessionMessagesHandler(){ return null; } + public ScheduledExecutorService getScheduledExecutorService(){ return null; } + public SessionDisconnectHandler getSessionDisconnectHandler(){ return null; } + public SessionListener getSessionListenerProxy(){ return null; } + public SshAgentFactory getAgentFactory(){ return null; } + public String getVersion(){ return null; } + public UnknownChannelReferenceHandler getUnknownChannelReferenceHandler(){ return null; } + public UnknownChannelReferenceHandler resolveUnknownChannelReferenceHandler(){ return null; } + public int getAttributesCount(){ return 0; } + public int getNioWorkers(){ return 0; } + public void addChannelListener(ChannelListener p0){} + public void addPortForwardingEventListener(PortForwardingEventListener p0){} + public void addSessionListener(SessionListener p0){} + public void clearAttributes(){} + public void removeChannelListener(ChannelListener p0){} + public void removePortForwardingEventListener(PortForwardingEventListener p0){} + public void removeSessionListener(SessionListener p0){} + public void setAgentFactory(SshAgentFactory p0){} + public void setChannelFactories(List p0){} + public void setChannelStreamWriterResolver(ChannelStreamWriterResolver p0){} + public void setFileSystemFactory(FileSystemFactory p0){} + public void setForwarderFactory(ForwarderFactory p0){} + public void setForwardingFilter(ForwardingFilter p0){} + public void setGlobalRequestHandlers(List> p0){} + public void setIoServiceEventListener(IoServiceEventListener p0){} + public void setIoServiceFactoryFactory(IoServiceFactoryFactory p0){} + public void setNioWorkers(int p0){} + public void setParentPropertyResolver(PropertyResolver p0){} + public void setRandomFactory(Factory p0){} + public void setReservedSessionMessagesHandler(ReservedSessionMessagesHandler p0){} + public void setScheduledExecutorService(ScheduledExecutorService p0){} + public void setScheduledExecutorService(ScheduledExecutorService p0, boolean p1){} + public void setServiceFactories(List p0){} + public void setSessionDisconnectHandler(SessionDisconnectHandler p0){} + public void setUnknownChannelReferenceHandler(UnknownChannelReferenceHandler p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/AbstractIoWriteFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/AbstractIoWriteFuture.java new file mode 100644 index 00000000000..34dddabbb74 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/AbstractIoWriteFuture.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.common.io.AbstractIoWriteFuture for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.future.DefaultVerifiableSshFuture; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.io.IoWriteFuture; + +abstract public class AbstractIoWriteFuture extends DefaultVerifiableSshFuture implements IoWriteFuture +{ + protected AbstractIoWriteFuture() {} + protected AbstractIoWriteFuture(Object p0, Object p1){} + public IoWriteFuture verify(long p0){ return null; } + public Throwable getException(){ return null; } + public boolean isWritten(){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoAcceptor.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoAcceptor.java new file mode 100644 index 00000000000..1c0182a3d7d --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoAcceptor.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.common.io.IoAcceptor for testing purposes + +package org.apache.sshd.common.io; + +import java.net.SocketAddress; +import java.util.Collection; +import java.util.Set; +import org.apache.sshd.common.io.IoService; + +public interface IoAcceptor extends IoService +{ + Set getBoundAddresses(); + void bind(Collection p0); + void bind(SocketAddress p0); + void unbind(); + void unbind(Collection p0); + void unbind(SocketAddress p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoConnectFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoConnectFuture.java new file mode 100644 index 00000000000..bf3d746d7ef --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoConnectFuture.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.common.io.IoConnectFuture for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.io.IoSession; + +public interface IoConnectFuture extends SshFuture +{ + IoSession getSession(); + Throwable getException(); + boolean isCanceled(); + boolean isConnected(); + void cancel(); + void setException(Throwable p0); + void setSession(IoSession p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoConnector.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoConnector.java new file mode 100644 index 00000000000..b5c6a7a8d5d --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoConnector.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.common.io.IoConnector for testing purposes + +package org.apache.sshd.common.io; + +import java.net.SocketAddress; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.io.IoConnectFuture; +import org.apache.sshd.common.io.IoService; + +public interface IoConnector extends IoService +{ + IoConnectFuture connect(SocketAddress p0, AttributeRepository p1, SocketAddress p2); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoHandler.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoHandler.java new file mode 100644 index 00000000000..2e84ccd48b8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoHandler.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.io.IoHandler for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.util.Readable; + +public interface IoHandler +{ + void exceptionCaught(IoSession p0, Throwable p1); + void messageReceived(IoSession p0, Readable p1); + void sessionClosed(IoSession p0); + void sessionCreated(IoSession p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoInputStream.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoInputStream.java new file mode 100644 index 00000000000..824d01b4a26 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoInputStream.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.io.IoInputStream for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.io.IoReadFuture; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface IoInputStream extends Closeable +{ + IoReadFuture read(Buffer p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoOutputStream.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoOutputStream.java new file mode 100644 index 00000000000..a17060c976a --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoOutputStream.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.io.IoOutputStream for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface IoOutputStream extends Closeable +{ + IoWriteFuture writeBuffer(Buffer p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoReadFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoReadFuture.java new file mode 100644 index 00000000000..afbd30600fc --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoReadFuture.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.io.IoReadFuture for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.VerifiableFuture; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface IoReadFuture extends SshFuture, VerifiableFuture +{ + Buffer getBuffer(); + Throwable getException(); + int getRead(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoService.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoService.java new file mode 100644 index 00000000000..d2504007ff3 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoService.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.io.IoService for testing purposes + +package org.apache.sshd.common.io; + +import java.util.Map; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.io.IoServiceEventListenerManager; +import org.apache.sshd.common.io.IoSession; + +public interface IoService extends Closeable, IoServiceEventListenerManager +{ + Map getManagedSessions(); + static boolean DEFAULT_REUSE_ADDRESS = false; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceEventListener.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceEventListener.java new file mode 100644 index 00000000000..c6aac5c062f --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceEventListener.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.common.io.IoServiceEventListener for testing purposes + +package org.apache.sshd.common.io; + +import java.net.SocketAddress; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.io.IoAcceptor; +import org.apache.sshd.common.io.IoConnector; +import org.apache.sshd.common.util.SshdEventListener; + +public interface IoServiceEventListener extends SshdEventListener +{ + default void abortAcceptedConnection(IoAcceptor p0, SocketAddress p1, SocketAddress p2, SocketAddress p3, Throwable p4){} + default void abortEstablishedConnection(IoConnector p0, SocketAddress p1, AttributeRepository p2, SocketAddress p3, Throwable p4){} + default void connectionAccepted(IoAcceptor p0, SocketAddress p1, SocketAddress p2, SocketAddress p3){} + default void connectionEstablished(IoConnector p0, SocketAddress p1, AttributeRepository p2, SocketAddress p3){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceEventListenerManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceEventListenerManager.java new file mode 100644 index 00000000000..fde63a4f4fc --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceEventListenerManager.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.io.IoServiceEventListenerManager for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.io.IoServiceEventListener; + +public interface IoServiceEventListenerManager +{ + IoServiceEventListener getIoServiceEventListener(); + void setIoServiceEventListener(IoServiceEventListener p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceFactory.java new file mode 100644 index 00000000000..1cc4cc2cb7e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceFactory.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.common.io.IoServiceFactory for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.io.IoAcceptor; +import org.apache.sshd.common.io.IoConnector; +import org.apache.sshd.common.io.IoHandler; +import org.apache.sshd.common.io.IoServiceEventListenerManager; + +public interface IoServiceFactory extends Closeable, IoServiceEventListenerManager +{ + IoAcceptor createAcceptor(IoHandler p0); + IoConnector createConnector(IoHandler p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceFactoryFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceFactoryFactory.java new file mode 100644 index 00000000000..9e647c68fe6 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoServiceFactoryFactory.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.io.IoServiceFactoryFactory for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.Factory; +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.io.IoServiceFactory; +import org.apache.sshd.common.util.threads.CloseableExecutorService; + +public interface IoServiceFactoryFactory +{ + IoServiceFactory create(FactoryManager p0); + void setExecutorServiceFactory(Factory p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoSession.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoSession.java new file mode 100644 index 00000000000..29724eff76e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoSession.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.sshd.common.io.IoSession for testing purposes + +package org.apache.sshd.common.io; + +import java.net.SocketAddress; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.future.CloseFuture; +import org.apache.sshd.common.io.IoService; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.net.ConnectionEndpointsIndicator; + +public interface IoSession extends Closeable, ConnectionEndpointsIndicator +{ + CloseFuture close(boolean p0); + IoService getService(); + IoWriteFuture writeBuffer(Buffer p0); + Object getAttribute(Object p0); + Object removeAttribute(Object p0); + Object setAttribute(Object p0, Object p1); + Object setAttributeIfAbsent(Object p0, Object p1); + SocketAddress getAcceptanceAddress(); + default void resumeRead(){} + default void suspendRead(){} + long getId(); + void shutdownOutputStream(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoWriteFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoWriteFuture.java new file mode 100644 index 00000000000..3c5936364fc --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/io/IoWriteFuture.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.io.IoWriteFuture for testing purposes + +package org.apache.sshd.common.io; + +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.VerifiableFuture; + +public interface IoWriteFuture extends SshFuture, VerifiableFuture +{ + Throwable getException(); + boolean isWritten(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/AbstractKexFactoryManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/AbstractKexFactoryManager.java new file mode 100644 index 00000000000..5230d07536d --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/AbstractKexFactoryManager.java @@ -0,0 +1,36 @@ +// Generated automatically from org.apache.sshd.common.kex.AbstractKexFactoryManager for testing purposes + +package org.apache.sshd.common.kex; + +import java.util.Collection; +import java.util.List; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.cipher.Cipher; +import org.apache.sshd.common.compression.Compression; +import org.apache.sshd.common.kex.KexFactoryManager; +import org.apache.sshd.common.kex.KeyExchangeFactory; +import org.apache.sshd.common.kex.extension.KexExtensionHandler; +import org.apache.sshd.common.mac.Mac; +import org.apache.sshd.common.signature.Signature; +import org.apache.sshd.common.util.closeable.AbstractInnerCloseable; + +abstract public class AbstractKexFactoryManager extends AbstractInnerCloseable implements KexFactoryManager +{ + protected > C resolveEffectiveFactories(C p0, C p1){ return null; } + protected V resolveEffectiveProvider(Class p0, V p1, V p2){ return null; } + protected AbstractKexFactoryManager(){} + protected AbstractKexFactoryManager(KexFactoryManager p0){} + protected KexFactoryManager getDelegate(){ return null; } + public KexExtensionHandler getKexExtensionHandler(){ return null; } + public List getKeyExchangeFactories(){ return null; } + public List> getCipherFactories(){ return null; } + public List> getCompressionFactories(){ return null; } + public List> getMacFactories(){ return null; } + public List> getSignatureFactories(){ return null; } + public void setCipherFactories(List> p0){} + public void setCompressionFactories(List> p0){} + public void setKexExtensionHandler(KexExtensionHandler p0){} + public void setKeyExchangeFactories(List p0){} + public void setMacFactories(List> p0){} + public void setSignatureFactories(List> p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexFactoryManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexFactoryManager.java new file mode 100644 index 00000000000..747b9bf3453 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexFactoryManager.java @@ -0,0 +1,40 @@ +// Generated automatically from org.apache.sshd.common.kex.KexFactoryManager for testing purposes + +package org.apache.sshd.common.kex; + +import java.util.Collection; +import java.util.List; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.cipher.Cipher; +import org.apache.sshd.common.compression.Compression; +import org.apache.sshd.common.kex.KeyExchangeFactory; +import org.apache.sshd.common.kex.extension.KexExtensionHandlerManager; +import org.apache.sshd.common.mac.Mac; +import org.apache.sshd.common.signature.SignatureFactoriesManager; + +public interface KexFactoryManager extends KexExtensionHandlerManager, SignatureFactoriesManager +{ + List getKeyExchangeFactories(); + List> getCipherFactories(); + List> getCompressionFactories(); + List> getMacFactories(); + default List getCipherFactoriesNames(){ return null; } + default List getCompressionFactoriesNames(){ return null; } + default List getMacFactoriesNames(){ return null; } + default String getCipherFactoriesNameList(){ return null; } + default String getCompressionFactoriesNameList(){ return null; } + default String getMacFactoriesNameList(){ return null; } + default void setCipherFactoriesNameList(String p0){} + default void setCipherFactoriesNames(Collection p0){} + default void setCipherFactoriesNames(String... p0){} + default void setCompressionFactoriesNameList(String p0){} + default void setCompressionFactoriesNames(Collection p0){} + default void setCompressionFactoriesNames(String... p0){} + default void setMacFactoriesNameList(String p0){} + default void setMacFactoriesNames(Collection p0){} + default void setMacFactoriesNames(String... p0){} + void setCipherFactories(List> p0); + void setCompressionFactories(List> p0); + void setKeyExchangeFactories(List p0); + void setMacFactories(List> p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexProposalOption.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexProposalOption.java new file mode 100644 index 00000000000..83bf1cf8c32 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexProposalOption.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.sshd.common.kex.KexProposalOption for testing purposes + +package org.apache.sshd.common.kex; + +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +public enum KexProposalOption +{ + ALGORITHMS, C2SCOMP, C2SENC, C2SLANG, C2SMAC, S2CCOMP, S2CENC, S2CLANG, S2CMAC, SERVERKEYS; + private KexProposalOption() {} + public final String getDescription(){ return null; } + public final int getProposalIndex(){ return 0; } + public static Comparator BY_PROPOSAL_INDEX = null; + public static KexProposalOption fromName(String p0){ return null; } + public static KexProposalOption fromProposalIndex(int p0){ return null; } + public static List VALUES = null; + public static Set CIPHER_PROPOSALS = null; + public static Set COMPRESSION_PROPOSALS = null; + public static Set FIRST_KEX_PACKET_GUESS_MATCHES = null; + public static Set LANGUAGE_PROPOSALS = null; + public static Set MAC_PROPOSALS = null; + public static int PROPOSAL_MAX = 0; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexState.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexState.java new file mode 100644 index 00000000000..1b3f107a9b3 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KexState.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.kex.KexState for testing purposes + +package org.apache.sshd.common.kex; + +import java.util.Set; + +public enum KexState +{ + DONE, INIT, KEYS, RUN, UNKNOWN; + private KexState() {} + public static Set VALUES = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KeyExchange.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KeyExchange.java new file mode 100644 index 00000000000..1ac831d012c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KeyExchange.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.sshd.common.kex.KeyExchange for testing purposes + +package org.apache.sshd.common.kex; + +import java.math.BigInteger; +import java.util.NavigableMap; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.digest.Digest; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionHolder; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface KeyExchange extends NamedResource, SessionHolder +{ + Digest getHash(); + boolean next(int p0, Buffer p1); + byte[] getH(); + byte[] getK(); + static NavigableMap GROUP_KEX_OPCODES_MAP = null; + static NavigableMap SIMPLE_KEX_OPCODES_MAP = null; + static String getGroupKexOpcodeName(int p0){ return null; } + static String getSimpleKexOpcodeName(int p0){ return null; } + static boolean isValidDHValue(BigInteger p0, BigInteger p1){ return false; } + void init(byte[] p0, byte[] p1, byte[] p2, byte[] p3); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KeyExchangeFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KeyExchangeFactory.java new file mode 100644 index 00000000000..eb57b900dae --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/KeyExchangeFactory.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.kex.KeyExchangeFactory for testing purposes + +package org.apache.sshd.common.kex; + +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.kex.KeyExchange; +import org.apache.sshd.common.session.Session; + +public interface KeyExchangeFactory extends NamedResource +{ + KeyExchange createKeyExchange(Session p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/extension/KexExtensionHandler.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/extension/KexExtensionHandler.java new file mode 100644 index 00000000000..39f436c8a31 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/extension/KexExtensionHandler.java @@ -0,0 +1,31 @@ +// Generated automatically from org.apache.sshd.common.kex.extension.KexExtensionHandler for testing purposes + +package org.apache.sshd.common.kex.extension; + +import java.util.Map; +import java.util.Set; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface KexExtensionHandler +{ + default boolean handleKexCompressionMessage(Session p0, Buffer p1){ return false; } + default boolean handleKexExtensionRequest(Session p0, int p1, int p2, String p3, byte[] p4){ return false; } + default boolean handleKexExtensionsMessage(Session p0, Buffer p1){ return false; } + default boolean isKexExtensionsAvailable(Session p0, KexExtensionHandler.AvailabilityPhase p1){ return false; } + default void handleKexExtensionNegotiation(Session p0, KexProposalOption p1, String p2, Map p3, String p4, Map p5, String p6){} + default void handleKexInitProposal(Session p0, boolean p1, Map p2){} + default void sendKexExtensions(Session p0, KexExtensionHandler.KexPhase p1){} + static public enum AvailabilityPhase + { + AUTHOK, NEWKEYS, PREKEX, PROPOSAL; + private AvailabilityPhase() {} + } + static public enum KexPhase + { + AUTHOK, NEWKEYS; + private KexPhase() {} + public static Set VALUES = null; + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/extension/KexExtensionHandlerManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/extension/KexExtensionHandlerManager.java new file mode 100644 index 00000000000..ebfb4574f0c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/kex/extension/KexExtensionHandlerManager.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.kex.extension.KexExtensionHandlerManager for testing purposes + +package org.apache.sshd.common.kex.extension; + +import org.apache.sshd.common.kex.extension.KexExtensionHandler; + +public interface KexExtensionHandlerManager +{ + KexExtensionHandler getKexExtensionHandler(); + void setKexExtensionHandler(KexExtensionHandler p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java new file mode 100644 index 00000000000..07d8923a859 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.sshd.common.keyprovider.KeyIdentityProvider for testing purposes + +package org.apache.sshd.common.keyprovider; + +import java.security.KeyPair; +import java.util.Collection; +import java.util.Iterator; +import org.apache.sshd.common.session.SessionContext; + +public interface KeyIdentityProvider +{ + Iterable loadKeys(SessionContext p0); + static Iterable iterableOf(SessionContext p0, Collection p1){ return null; } + static KeyIdentityProvider EMPTY_KEYS_PROVIDER = null; + static KeyIdentityProvider multiProvider(Collection p0){ return null; } + static KeyIdentityProvider multiProvider(KeyIdentityProvider... p0){ return null; } + static KeyIdentityProvider resolveKeyIdentityProvider(KeyIdentityProvider p0, KeyIdentityProvider p1){ return null; } + static KeyIdentityProvider wrapKeyPairs(Iterable p0){ return null; } + static KeyIdentityProvider wrapKeyPairs(KeyPair... p0){ return null; } + static KeyPair exhaustCurrentIdentities(Iterator p0){ return null; } + static boolean isEmpty(KeyIdentityProvider p0){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeyIdentityProviderHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeyIdentityProviderHolder.java new file mode 100644 index 00000000000..2eae757e3f9 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeyIdentityProviderHolder.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.keyprovider.KeyIdentityProviderHolder for testing purposes + +package org.apache.sshd.common.keyprovider; + +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; + +public interface KeyIdentityProviderHolder +{ + KeyIdentityProvider getKeyIdentityProvider(); + void setKeyIdentityProvider(KeyIdentityProvider p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeySizeIndicator.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeySizeIndicator.java new file mode 100644 index 00000000000..32fb9a6adf2 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/keyprovider/KeySizeIndicator.java @@ -0,0 +1,9 @@ +// Generated automatically from org.apache.sshd.common.keyprovider.KeySizeIndicator for testing purposes + +package org.apache.sshd.common.keyprovider; + + +public interface KeySizeIndicator +{ + int getKeySize(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/mac/Mac.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/mac/Mac.java new file mode 100644 index 00000000000..24568df76d6 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/mac/Mac.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.common.mac.Mac for testing purposes + +package org.apache.sshd.common.mac; + +import org.apache.sshd.common.mac.MacInformation; + +public interface Mac extends MacInformation +{ + default byte[] doFinal(){ return null; } + default void doFinal(byte[] p0){} + default void update(byte[] p0){} + static boolean equals(byte[] p0, int p1, byte[] p2, int p3, int p4){ return false; } + void doFinal(byte[] p0, int p1); + void init(byte[] p0); + void update(byte[] p0, int p1, int p2); + void updateUInt(long p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/mac/MacInformation.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/mac/MacInformation.java new file mode 100644 index 00000000000..a88e71ad722 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/mac/MacInformation.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.mac.MacInformation for testing purposes + +package org.apache.sshd.common.mac; + +import org.apache.sshd.common.AlgorithmNameProvider; + +public interface MacInformation extends AlgorithmNameProvider +{ + default boolean isEncryptThenMac(){ return false; } + int getBlockSize(); + int getDefaultBlockSize(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/random/Random.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/random/Random.java new file mode 100644 index 00000000000..874ad8e22cf --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/random/Random.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.random.Random for testing purposes + +package org.apache.sshd.common.random; + +import org.apache.sshd.common.NamedResource; + +public interface Random extends NamedResource +{ + default void fill(byte[] p0){} + int random(int p0); + void fill(byte[] p0, int p1, int p2); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ConnectionService.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ConnectionService.java new file mode 100644 index 00000000000..092315bddc9 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ConnectionService.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.sshd.common.session.ConnectionService for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.agent.common.AgentForwardSupport; +import org.apache.sshd.common.Service; +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.forward.Forwarder; +import org.apache.sshd.common.forward.PortForwardingEventListenerManager; +import org.apache.sshd.common.forward.PortForwardingEventListenerManagerHolder; +import org.apache.sshd.common.session.SessionHeartbeatController; +import org.apache.sshd.common.session.UnknownChannelReferenceHandlerManager; +import org.apache.sshd.server.x11.X11ForwardSupport; + +public interface ConnectionService extends PortForwardingEventListenerManager, PortForwardingEventListenerManagerHolder, Service, SessionHeartbeatController, UnknownChannelReferenceHandlerManager +{ + AgentForwardSupport getAgentForwardSupport(); + Forwarder getForwarder(); + X11ForwardSupport getX11ForwardSupport(); + boolean isAllowMoreSessions(); + int registerChannel(Channel p0); + void setAllowMoreSessions(boolean p0); + void unregisterChannel(Channel p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java new file mode 100644 index 00000000000..5f770fe3fcb --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.sshd.common.session.ReservedSessionMessagesHandler for testing purposes + +package org.apache.sshd.common.session; + +import java.util.List; +import java.util.Map; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.SshdEventListener; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface ReservedSessionMessagesHandler extends SshdEventListener +{ + default IoWriteFuture sendIdentification(Session p0, String p1, List p2){ return null; } + default IoWriteFuture sendKexInitRequest(Session p0, Map p1, Buffer p2){ return null; } + default boolean handleUnimplementedMessage(Session p0, int p1, Buffer p2){ return false; } + default boolean sendReservedHeartbeat(ConnectionService p0){ return false; } + default void handleDebugMessage(Session p0, Buffer p1){} + default void handleIgnoreMessage(Session p0, Buffer p1){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ReservedSessionMessagesManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ReservedSessionMessagesManager.java new file mode 100644 index 00000000000..4f0aa5f4268 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/ReservedSessionMessagesManager.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.session.ReservedSessionMessagesManager for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.common.session.ReservedSessionMessagesHandler; + +public interface ReservedSessionMessagesManager +{ + ReservedSessionMessagesHandler getReservedSessionMessagesHandler(); + void setReservedSessionMessagesHandler(ReservedSessionMessagesHandler p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/Session.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/Session.java new file mode 100644 index 00000000000..50495d9b981 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/Session.java @@ -0,0 +1,63 @@ +// Generated automatically from org.apache.sshd.common.session.Session for testing purposes + +package org.apache.sshd.common.session; + +import java.net.SocketAddress; +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.TimeUnit; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.FactoryManagerHolder; +import org.apache.sshd.common.Service; +import org.apache.sshd.common.auth.MutableUserHolder; +import org.apache.sshd.common.channel.ChannelListenerManager; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolverManager; +import org.apache.sshd.common.forward.PortForwardingEventListenerManager; +import org.apache.sshd.common.forward.PortForwardingInformationProvider; +import org.apache.sshd.common.future.KeyExchangeFuture; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.kex.KexFactoryManager; +import org.apache.sshd.common.kex.KeyExchange; +import org.apache.sshd.common.session.ReservedSessionMessagesManager; +import org.apache.sshd.common.session.SessionContext; +import org.apache.sshd.common.session.SessionDisconnectHandlerManager; +import org.apache.sshd.common.session.SessionListenerManager; +import org.apache.sshd.common.session.UnknownChannelReferenceHandlerManager; +import org.apache.sshd.common.session.helpers.TimeoutIndicator; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface Session extends ChannelListenerManager, ChannelStreamWriterResolverManager, FactoryManagerHolder, KexFactoryManager, MutableUserHolder, PortForwardingEventListenerManager, PortForwardingInformationProvider, ReservedSessionMessagesManager, SessionContext, SessionDisconnectHandlerManager, SessionListenerManager, UnknownChannelReferenceHandlerManager +{ + T getService(Class p0); + Buffer createBuffer(byte p0, int p1); + Buffer prepareBuffer(byte p0, Buffer p1); + Buffer request(String p0, Buffer p1, long p2); + Duration getAuthTimeout(); + Duration getIdleTimeout(); + Instant getAuthTimeoutStart(); + Instant getIdleTimeoutStart(); + Instant resetAuthTimeout(); + Instant resetIdleTimeout(); + IoSession getIoSession(); + IoWriteFuture sendDebugMessage(boolean p0, Object p1, String p2); + IoWriteFuture sendIgnoreMessage(byte... p0); + IoWriteFuture writePacket(Buffer p0); + IoWriteFuture writePacket(Buffer p0, long p1, TimeUnit p2); + KeyExchange getKex(); + KeyExchangeFuture reExchangeKeys(); + TimeoutIndicator getTimeoutStatus(); + default T resolveAttribute(AttributeRepository.AttributeKey p0){ return null; } + default Buffer createBuffer(byte p0){ return null; } + default Buffer request(String p0, Buffer p1, Duration p2){ return null; } + default Buffer request(String p0, Buffer p1, long p2, TimeUnit p3){ return null; } + default IoWriteFuture writePacket(Buffer p0, Duration p1){ return null; } + default IoWriteFuture writePacket(Buffer p0, long p1){ return null; } + default SocketAddress getLocalAddress(){ return null; } + default SocketAddress getRemoteAddress(){ return null; } + static T resolveAttribute(Session p0, AttributeRepository.AttributeKey p1){ return null; } + void disconnect(int p0, String p1); + void exceptionCaught(Throwable p0); + void setAuthenticated(); + void startService(String p0, Buffer p1); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionContext.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionContext.java new file mode 100644 index 00000000000..9e7c9d60642 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionContext.java @@ -0,0 +1,38 @@ +// Generated automatically from org.apache.sshd.common.session.SessionContext for testing purposes + +package org.apache.sshd.common.session; + +import java.util.Map; +import org.apache.sshd.common.AttributeStore; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.auth.UsernameHolder; +import org.apache.sshd.common.cipher.CipherInformation; +import org.apache.sshd.common.compression.CompressionInformation; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.kex.KexState; +import org.apache.sshd.common.mac.MacInformation; +import org.apache.sshd.common.session.SessionHeartbeatController; +import org.apache.sshd.common.util.net.ConnectionEndpointsIndicator; + +public interface SessionContext extends AttributeStore, Closeable, ConnectionEndpointsIndicator, SessionHeartbeatController, UsernameHolder +{ + CipherInformation getCipherInformation(boolean p0); + CompressionInformation getCompressionInformation(boolean p0); + KexState getKexState(); + MacInformation getMacInformation(boolean p0); + Map getClientKexProposals(); + Map getKexNegotiationResult(); + Map getServerKexProposals(); + String getClientVersion(); + String getNegotiatedKexParameter(KexProposalOption p0); + String getServerVersion(); + boolean isAuthenticated(); + boolean isServerSession(); + byte[] getSessionId(); + static String DEFAULT_SSH_VERSION_PREFIX = null; + static String FALLBACK_SSH_VERSION_PREFIX = null; + static boolean isDataIntegrityTransport(SessionContext p0){ return false; } + static boolean isSecureSessionTransport(SessionContext p0){ return false; } + static boolean isValidVersionPrefix(String p0){ return false; } + static int MAX_VERSION_LINE_LENGTH = 0; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionContextHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionContextHolder.java new file mode 100644 index 00000000000..83a3d48b57c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionContextHolder.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.common.session.SessionContextHolder for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.common.session.SessionContext; + +public interface SessionContextHolder +{ + SessionContext getSessionContext(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionDisconnectHandler.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionDisconnectHandler.java new file mode 100644 index 00000000000..80c04914300 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionDisconnectHandler.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.sshd.common.session.SessionDisconnectHandler for testing purposes + +package org.apache.sshd.common.session; + +import java.util.Map; +import org.apache.sshd.common.Service; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.helpers.TimeoutIndicator; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface SessionDisconnectHandler +{ + default boolean handleAuthCountDisconnectReason(Session p0, Service p1, String p2, String p3, String p4, int p5, int p6){ return false; } + default boolean handleAuthParamsDisconnectReason(Session p0, Service p1, String p2, String p3, String p4, String p5){ return false; } + default boolean handleKexDisconnectReason(Session p0, Map p1, Map p2, Map p3, KexProposalOption p4){ return false; } + default boolean handleSessionsCountDisconnectReason(Session p0, Service p1, String p2, int p3, int p4){ return false; } + default boolean handleTimeoutDisconnectReason(Session p0, TimeoutIndicator p1){ return false; } + default boolean handleUnsupportedServiceDisconnectReason(Session p0, int p1, String p2, Buffer p3){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionDisconnectHandlerManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionDisconnectHandlerManager.java new file mode 100644 index 00000000000..a9b71bceb61 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionDisconnectHandlerManager.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.session.SessionDisconnectHandlerManager for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.common.session.SessionDisconnectHandler; + +public interface SessionDisconnectHandlerManager +{ + SessionDisconnectHandler getSessionDisconnectHandler(); + void setSessionDisconnectHandler(SessionDisconnectHandler p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionHeartbeatController.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionHeartbeatController.java new file mode 100644 index 00000000000..212bb1c4ade --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionHeartbeatController.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.sshd.common.session.SessionHeartbeatController for testing purposes + +package org.apache.sshd.common.session; + +import java.time.Duration; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import org.apache.sshd.common.PropertyResolver; + +public interface SessionHeartbeatController extends PropertyResolver +{ + default Duration getSessionHeartbeatInterval(){ return null; } + default SessionHeartbeatController.HeartbeatType getSessionHeartbeatType(){ return null; } + default void disableSessionHeartbeat(){} + default void setSessionHeartbeat(SessionHeartbeatController.HeartbeatType p0, Duration p1){} + default void setSessionHeartbeat(SessionHeartbeatController.HeartbeatType p0, TimeUnit p1, long p2){} + static public enum HeartbeatType + { + IGNORE, NONE, RESERVED; + private HeartbeatType() {} + public static SessionHeartbeatController.HeartbeatType fromName(String p0){ return null; } + public static Set VALUES = null; + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionHolder.java new file mode 100644 index 00000000000..940b50a176b --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionHolder.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.common.session.SessionHolder for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionContext; +import org.apache.sshd.common.session.SessionContextHolder; + +public interface SessionHolder extends SessionContextHolder +{ + S getSession(); + default SessionContext getSessionContext(){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionListener.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionListener.java new file mode 100644 index 00000000000..bf635a48e9b --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionListener.java @@ -0,0 +1,31 @@ +// Generated automatically from org.apache.sshd.common.session.SessionListener for testing purposes + +package org.apache.sshd.common.session; + +import java.util.List; +import java.util.Map; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.SshdEventListener; + +public interface SessionListener extends SshdEventListener +{ + default void sessionClosed(Session p0){} + default void sessionCreated(Session p0){} + default void sessionDisconnect(Session p0, int p1, String p2, String p3, boolean p4){} + default void sessionEstablished(Session p0){} + default void sessionEvent(Session p0, SessionListener.Event p1){} + default void sessionException(Session p0, Throwable p1){} + default void sessionNegotiationEnd(Session p0, Map p1, Map p2, Map p3, Throwable p4){} + default void sessionNegotiationOptionsCreated(Session p0, Map p1){} + default void sessionNegotiationStart(Session p0, Map p1, Map p2){} + default void sessionPeerIdentificationLine(Session p0, String p1, List p2){} + default void sessionPeerIdentificationReceived(Session p0, String p1, List p2){} + default void sessionPeerIdentificationSend(Session p0, String p1, List p2){} + static L validateListener(L p0){ return null; } + static public enum Event + { + Authenticated, KexCompleted, KeyEstablished; + private Event() {} + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionListenerManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionListenerManager.java new file mode 100644 index 00000000000..ed60ea0423b --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionListenerManager.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.session.SessionListenerManager for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.common.session.SessionListener; + +public interface SessionListenerManager +{ + SessionListener getSessionListenerProxy(); + void addSessionListener(SessionListener p0); + void removeSessionListener(SessionListener p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionWorkBuffer.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionWorkBuffer.java new file mode 100644 index 00000000000..a0f5510b630 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/SessionWorkBuffer.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.sshd.common.session.SessionWorkBuffer for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionHolder; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; + +public class SessionWorkBuffer extends ByteArrayBuffer implements SessionHolder +{ + protected SessionWorkBuffer() {} + public Buffer clear(boolean p0){ return null; } + public Session getSession(){ return null; } + public SessionWorkBuffer(Session p0){} + public void forceClear(boolean p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/UnknownChannelReferenceHandler.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/UnknownChannelReferenceHandler.java new file mode 100644 index 00000000000..da0ea9c1f6e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/UnknownChannelReferenceHandler.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.session.UnknownChannelReferenceHandler for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.common.channel.Channel; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface UnknownChannelReferenceHandler +{ + Channel handleUnknownChannelCommand(ConnectionService p0, byte p1, int p2, Buffer p3); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/UnknownChannelReferenceHandlerManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/UnknownChannelReferenceHandlerManager.java new file mode 100644 index 00000000000..ba5ac96da35 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/UnknownChannelReferenceHandlerManager.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.session.UnknownChannelReferenceHandlerManager for testing purposes + +package org.apache.sshd.common.session; + +import org.apache.sshd.common.session.UnknownChannelReferenceHandler; + +public interface UnknownChannelReferenceHandlerManager +{ + UnknownChannelReferenceHandler getUnknownChannelReferenceHandler(); + UnknownChannelReferenceHandler resolveUnknownChannelReferenceHandler(); + void setUnknownChannelReferenceHandler(UnknownChannelReferenceHandler p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSession.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSession.java new file mode 100644 index 00000000000..9b93f46e56f --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSession.java @@ -0,0 +1,214 @@ +// Generated automatically from org.apache.sshd.common.session.helpers.AbstractSession for testing purposes + +package org.apache.sshd.common.session.helpers; + +import java.time.Duration; +import java.time.Instant; +import java.util.AbstractMap; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.Service; +import org.apache.sshd.common.channel.ChannelListener; +import org.apache.sshd.common.cipher.Cipher; +import org.apache.sshd.common.cipher.CipherInformation; +import org.apache.sshd.common.compression.Compression; +import org.apache.sshd.common.compression.CompressionInformation; +import org.apache.sshd.common.forward.PortForwardingEventListener; +import org.apache.sshd.common.future.DefaultKeyExchangeFuture; +import org.apache.sshd.common.future.KeyExchangeFuture; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.kex.KexState; +import org.apache.sshd.common.kex.KeyExchange; +import org.apache.sshd.common.mac.Mac; +import org.apache.sshd.common.mac.MacInformation; +import org.apache.sshd.common.random.Random; +import org.apache.sshd.common.session.SessionListener; +import org.apache.sshd.common.session.SessionWorkBuffer; +import org.apache.sshd.common.session.helpers.PendingWriteFuture; +import org.apache.sshd.common.session.helpers.SessionHelper; +import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.Buffer; + +abstract public class AbstractSession extends SessionHelper +{ + protected AbstractSession() {} + protected B validateTargetBuffer(int p0, B p1){ return null; } + protected AbstractSession(boolean p0, FactoryManager p1, IoSession p2){} + protected AbstractSession.MessageCodingSettings inSettings = null; + protected AbstractSession.MessageCodingSettings outSettings = null; + protected Boolean firstKexPacketFollows = null; + protected Buffer encode(Buffer p0){ return null; } + protected Buffer preProcessEncodeBuffer(int p0, Buffer p1){ return null; } + protected Buffer resolveOutputPacket(Buffer p0){ return null; } + protected Cipher inCipher = null; + protected Cipher outCipher = null; + protected Closeable getInnerCloseable(){ return null; } + protected Compression inCompression = null; + protected Compression outCompression = null; + protected DefaultKeyExchangeFuture kexInitializedFuture = null; + protected Duration maxRekeyInterval = null; + protected IoWriteFuture doWritePacket(Buffer p0){ return null; } + protected IoWriteFuture notImplemented(int p0, Buffer p1){ return null; } + protected IoWriteFuture sendNewKeys(){ return null; } + protected KeyExchange kex = null; + protected KeyExchangeFuture checkRekey(){ return null; } + protected KeyExchangeFuture requestNewKeysExchange(){ return null; } + protected List> sendPendingPackets(Queue p0){ return null; } + protected List getServices(){ return null; } + protected Mac inMac = null; + protected Mac outMac = null; + protected Map.Entry comparePreferredKexProposalOption(KexProposalOption p0){ return null; } + protected Map negotiate(){ return null; } + protected Map setNegotiationResult(Map p0){ return null; } + protected PendingWriteFuture enqueuePendingPacket(Buffer p0){ return null; } + protected Service currentService = null; + protected SessionWorkBuffer uncompressBuffer = null; + protected String clientVersion = null; + protected String resolveAvailableSignaturesProposal(){ return null; } + protected String resolveSessionKexProposal(String p0){ return null; } + protected String serverVersion = null; + protected abstract String resolveAvailableSignaturesProposal(FactoryManager p0); + protected abstract boolean readIdentification(Buffer p0); + protected abstract void checkKeys(); + protected abstract void receiveKexInit(Map p0, byte[] p1); + protected abstract void setKexSeed(byte... p0); + protected boolean doInvokeUnimplementedMessageHandler(int p0, Buffer p1){ return false; } + protected boolean handleFirstKexPacketFollows(int p0, Buffer p1, boolean p2){ return false; } + protected boolean handleServiceRequest(String p0, Buffer p1){ return false; } + protected boolean isRekeyBlocksCountExceeded(){ return false; } + protected boolean isRekeyDataSizeExceeded(){ return false; } + protected boolean isRekeyPacketCountsExceeded(){ return false; } + protected boolean isRekeyRequired(){ return false; } + protected boolean isRekeyTimeIntervalExceeded(){ return false; } + protected byte[] getClientKexData(){ return null; } + protected byte[] getServerKexData(){ return null; } + protected byte[] inMacResult = null; + protected byte[] receiveKexInit(Buffer p0){ return null; } + protected byte[] receiveKexInit(Buffer p0, Map p1){ return null; } + protected byte[] sendKexInit(){ return null; } + protected byte[] sendKexInit(Map p0){ return null; } + protected byte[] sessionId = null; + protected final AtomicLong globalRequestSeqo = null; + protected final AtomicLong ignorePacketsCount = null; + protected final AtomicLong inBlocksCount = null; + protected final AtomicLong inBytesCount = null; + protected final AtomicLong inPacketsCount = null; + protected final AtomicLong maxRekeyBlocks = null; + protected final AtomicLong outBlocksCount = null; + protected final AtomicLong outBytesCount = null; + protected final AtomicLong outPacketsCount = null; + protected final AtomicReference kexFutureHolder = null; + protected final AtomicReference lastKeyTimeValue = null; + protected final AtomicReference kexState = null; + protected final AtomicReference pendingGlobalRequest = null; + protected final ChannelListener channelListenerProxy = null; + protected final Collection channelListeners = null; + protected final Collection tunnelListeners = null; + protected final Collection sessionListeners = null; + protected final Map clientProposal = null; + protected final Map negotiationResult = null; + protected final Map serverProposal = null; + protected final Map unmodClientProposal = null; + protected final Map unmodNegotiationResult = null; + protected final Map unmodServerProposal = null; + protected final Object decodeLock = null; + protected final Object encodeLock = null; + protected final Object kexLock = null; + protected final Object requestLock = null; + protected final PortForwardingEventListener tunnelListenerProxy = null; + protected final Queue pendingPackets = null; + protected final Random random = null; + protected final SessionListener sessionListenerProxy = null; + protected final SessionWorkBuffer decoderBuffer = null; + protected int decoderLength = 0; + protected int decoderState = 0; + protected int ignorePacketDataLength = 0; + protected int ignorePacketsVariance = 0; + protected int inCipherSize = 0; + protected int inMacSize = 0; + protected int outCipherSize = 0; + protected int outMacSize = 0; + protected int resolveIgnoreBufferDataLength(){ return 0; } + protected long determineRekeyBlockLimit(int p0, int p1){ return 0; } + protected long ignorePacketsFrequency = 0; + protected long maxRekeyBytes = 0; + protected long maxRekyPackets = 0; + protected long seqi = 0; + protected long seqo = 0; + protected void aeadOutgoingBuffer(Buffer p0, int p1, int p2){} + protected void appendOutgoingMac(Buffer p0, int p1, int p2){} + protected void decode(){} + protected void doHandleMessage(Buffer p0){} + protected void doKexNegotiation(){} + protected void encryptOutgoingBuffer(Buffer p0, int p1, int p2){} + protected void handleKexExtension(int p0, Buffer p1){} + protected void handleKexInit(Buffer p0){} + protected void handleKexMessage(int p0, Buffer p1){} + protected void handleMessage(Buffer p0){} + protected void handleNewCompression(int p0, Buffer p1){} + protected void handleNewKeys(int p0, Buffer p1){} + protected void handleServiceAccept(Buffer p0){} + protected void handleServiceAccept(String p0, Buffer p1){} + protected void handleServiceRequest(Buffer p0){} + protected void preClose(){} + protected void prepareNewKeys(){} + protected void refreshConfiguration(){} + protected void requestFailure(Buffer p0){} + protected void requestSuccess(Buffer p0){} + protected void setClientKexData(byte[] p0){} + protected void setInputEncoding(){} + protected void setOutputEncoding(){} + protected void setServerKexData(byte[] p0){} + protected void signalRequestFailure(){} + protected void validateIncomingMac(byte[] p0, int p1, int p2){} + protected void validateKexState(int p0, KexState p1){} + public T getService(Class p0){ return null; } + public Buffer createBuffer(byte p0, int p1){ return null; } + public Buffer prepareBuffer(byte p0, Buffer p1){ return null; } + public Buffer request(String p0, Buffer p1, long p2){ return null; } + public ChannelListener getChannelListenerProxy(){ return null; } + public CipherInformation getCipherInformation(boolean p0){ return null; } + public CompressionInformation getCompressionInformation(boolean p0){ return null; } + public IoWriteFuture writePacket(Buffer p0){ return null; } + public KexState getKexState(){ return null; } + public KeyExchange getKex(){ return null; } + public KeyExchangeFuture reExchangeKeys(){ return null; } + public MacInformation getMacInformation(boolean p0){ return null; } + public Map getClientKexProposals(){ return null; } + public Map getKexNegotiationResult(){ return null; } + public Map getServerKexProposals(){ return null; } + public PortForwardingEventListener getPortForwardingEventListenerProxy(){ return null; } + public SessionListener getSessionListenerProxy(){ return null; } + public String getClientVersion(){ return null; } + public String getNegotiatedKexParameter(KexProposalOption p0){ return null; } + public String getServerVersion(){ return null; } + public byte[] getSessionId(){ return null; } + public static AbstractSession getSession(IoSession p0){ return null; } + public static AbstractSession getSession(IoSession p0, boolean p1){ return null; } + public static String SESSION = null; + public static int calculatePadLength(int p0, int p1, boolean p2){ return 0; } + public static void attachSession(IoSession p0, AbstractSession p1){} + public void addChannelListener(ChannelListener p0){} + public void addPortForwardingEventListener(PortForwardingEventListener p0){} + public void addSessionListener(SessionListener p0){} + public void messageReceived(Readable p0){} + public void removeChannelListener(ChannelListener p0){} + public void removePortForwardingEventListener(PortForwardingEventListener p0){} + public void removeSessionListener(SessionListener p0){} + static class MessageCodingSettings + { + protected MessageCodingSettings() {} + public Cipher getCipher(long p0){ return null; } + public Compression getCompression(){ return null; } + public Mac getMac(){ return null; } + public MessageCodingSettings(Cipher p0, Mac p1, Compression p2, Cipher.Mode p3, byte[] p4, byte[] p5){} + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSessionFactory.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSessionFactory.java new file mode 100644 index 00000000000..fae9b1fbeda --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSessionFactory.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.sshd.common.session.helpers.AbstractSessionFactory for testing purposes + +package org.apache.sshd.common.session.helpers; + +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.session.helpers.AbstractSession; +import org.apache.sshd.common.session.helpers.AbstractSessionIoHandler; + +abstract public class AbstractSessionFactory extends AbstractSessionIoHandler +{ + protected AbstractSessionFactory() {} + protected AbstractSessionFactory(M p0){} + protected S createSession(IoSession p0){ return null; } + protected S setupSession(S p0){ return null; } + protected abstract S doCreateSession(IoSession p0); + public M getFactoryManager(){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSessionIoHandler.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSessionIoHandler.java new file mode 100644 index 00000000000..886dd17f018 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/AbstractSessionIoHandler.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.sshd.common.session.helpers.AbstractSessionIoHandler for testing purposes + +package org.apache.sshd.common.session.helpers; + +import org.apache.sshd.common.io.IoHandler; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.session.helpers.AbstractSession; +import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.logging.AbstractLoggingBean; + +abstract public class AbstractSessionIoHandler extends AbstractLoggingBean implements IoHandler +{ + protected AbstractSessionIoHandler(){} + protected abstract AbstractSession createSession(IoSession p0); + public void exceptionCaught(IoSession p0, Throwable p1){} + public void messageReceived(IoSession p0, Readable p1){} + public void sessionClosed(IoSession p0){} + public void sessionCreated(IoSession p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/PendingWriteFuture.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/PendingWriteFuture.java new file mode 100644 index 00000000000..b1a0ed961c3 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/PendingWriteFuture.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.sshd.common.session.helpers.PendingWriteFuture for testing purposes + +package org.apache.sshd.common.session.helpers; + +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.SshFutureListener; +import org.apache.sshd.common.io.AbstractIoWriteFuture; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.util.buffer.Buffer; + +public class PendingWriteFuture extends AbstractIoWriteFuture implements SshFutureListener +{ + protected PendingWriteFuture() {} + public Buffer getBuffer(){ return null; } + public PendingWriteFuture(Object p0, Buffer p1){} + public void operationComplete(IoWriteFuture p0){} + public void setException(Throwable p0){} + public void setWritten(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/SessionHelper.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/SessionHelper.java new file mode 100644 index 00000000000..8efdf4b8cca --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/SessionHelper.java @@ -0,0 +1,140 @@ +// Generated automatically from org.apache.sshd.common.session.helpers.SessionHelper for testing purposes + +package org.apache.sshd.common.session.helpers; + +import java.net.SocketAddress; +import java.time.Duration; +import java.time.Instant; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.NavigableSet; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import org.apache.sshd.common.AttributeRepository; +import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.PropertyResolver; +import org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolver; +import org.apache.sshd.common.digest.Digest; +import org.apache.sshd.common.forward.Forwarder; +import org.apache.sshd.common.io.IoSession; +import org.apache.sshd.common.io.IoWriteFuture; +import org.apache.sshd.common.kex.AbstractKexFactoryManager; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.random.Random; +import org.apache.sshd.common.session.ConnectionService; +import org.apache.sshd.common.session.ReservedSessionMessagesHandler; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionDisconnectHandler; +import org.apache.sshd.common.session.SessionListener; +import org.apache.sshd.common.session.UnknownChannelReferenceHandler; +import org.apache.sshd.common.session.helpers.TimeoutIndicator; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.io.functors.Invoker; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +abstract public class SessionHelper extends AbstractKexFactoryManager implements Session +{ + protected SessionHelper() {} + protected Buffer preProcessEncodeBuffer(int p0, Buffer p1){ return null; } + protected Forwarder getForwarder(){ return null; } + protected Instant authStart = null; + protected Instant idleStart = null; + protected IoWriteFuture sendIdentification(String p0, List p1){ return null; } + protected IoWriteFuture sendNotImplemented(long p0){ return null; } + protected List doReadIdentification(Buffer p0, boolean p1){ return null; } + protected Map createProposal(String p0){ return null; } + protected Map mergeProposals(Map p0, Map p1){ return null; } + protected ReservedSessionMessagesHandler resolveReservedSessionMessagesHandler(){ return null; } + protected SessionHelper(boolean p0, FactoryManager p1, IoSession p2){} + protected SocketAddress resolvePeerAddress(SocketAddress p0){ return null; } + protected String resolveIdentificationString(String p0){ return null; } + protected String resolveSessionKexProposal(String p0){ return null; } + protected TimeoutIndicator checkAuthenticationTimeout(Instant p0, Duration p1){ return null; } + protected TimeoutIndicator checkForTimeouts(){ return null; } + protected TimeoutIndicator checkIdleTimeout(Instant p0, Duration p1){ return null; } + protected abstract ConnectionService getConnectionService(); + protected boolean doInvokeUnimplementedMessageHandler(int p0, Buffer p1){ return false; } + protected byte[] resizeKey(byte[] p0, int p1, Digest p2, byte[] p3, byte[] p4){ return null; } + protected final Object sessionLock = null; + protected long calculateNextIgnorePacketCount(Random p0, long p1, int p2){ return 0; } + protected void doInvokeDebugMessageHandler(Buffer p0){} + protected void doInvokeIgnoreMessageHandler(Buffer p0){} + protected void handleDebug(Buffer p0){} + protected void handleDisconnect(Buffer p0){} + protected void handleDisconnect(int p0, String p1, String p2, Buffer p3){} + protected void handleIgnore(Buffer p0){} + protected void handleUnimplemented(Buffer p0){} + protected void invokeSessionSignaller(Invoker p0){} + protected void signalDisconnect(SessionListener p0, int p1, String p2, String p3, boolean p4){} + protected void signalDisconnect(int p0, String p1, String p2, boolean p3){} + protected void signalExceptionCaught(SessionListener p0, Throwable p1){} + protected void signalExceptionCaught(Throwable p0){} + protected void signalNegotiationEnd(Map p0, Map p1, Map p2, Throwable p3){} + protected void signalNegotiationEnd(SessionListener p0, Map p1, Map p2, Map p3, Throwable p4){} + protected void signalNegotiationOptionsCreated(Map p0){} + protected void signalNegotiationOptionsCreated(SessionListener p0, Map p1){} + protected void signalNegotiationStart(Map p0, Map p1){} + protected void signalNegotiationStart(SessionListener p0, Map p1, Map p2){} + protected void signalPeerIdentificationReceived(SessionListener p0, String p1, List p2){} + protected void signalPeerIdentificationReceived(String p0, List p1){} + protected void signalReadPeerIdentificationLine(SessionListener p0, String p1, List p2){} + protected void signalReadPeerIdentificationLine(String p0, List p1){} + protected void signalSendIdentification(SessionListener p0, String p1, List p2){} + protected void signalSendIdentification(String p0, List p1){} + protected void signalSessionClosed(){} + protected void signalSessionClosed(SessionListener p0){} + protected void signalSessionCreated(IoSession p0){} + protected void signalSessionCreated(SessionListener p0){} + protected void signalSessionEstablished(IoSession p0){} + protected void signalSessionEstablished(SessionListener p0){} + protected void signalSessionEvent(SessionListener p0, SessionListener.Event p1){} + protected void signalSessionEvent(SessionListener.Event p0){} + public T computeAttributeIfAbsent(AttributeRepository.AttributeKey p0, Function, ? extends T> p1){ return null; } + public T getAttribute(AttributeRepository.AttributeKey p0){ return null; } + public T removeAttribute(AttributeRepository.AttributeKey p0){ return null; } + public T setAttribute(AttributeRepository.AttributeKey p0, T p1){ return null; } + public ChannelStreamWriterResolver getChannelStreamWriterResolver(){ return null; } + public ChannelStreamWriterResolver resolveChannelStreamWriterResolver(){ return null; } + public Collection> attributeKeys(){ return null; } + public Duration getAuthTimeout(){ return null; } + public Duration getIdleTimeout(){ return null; } + public FactoryManager getFactoryManager(){ return null; } + public Instant getAuthTimeoutStart(){ return null; } + public Instant getIdleTimeoutStart(){ return null; } + public Instant resetAuthTimeout(){ return null; } + public Instant resetIdleTimeout(){ return null; } + public IoSession getIoSession(){ return null; } + public IoWriteFuture sendDebugMessage(boolean p0, Object p1, String p2){ return null; } + public IoWriteFuture sendIgnoreMessage(byte... p0){ return null; } + public IoWriteFuture writePacket(Buffer p0, long p1, TimeUnit p2){ return null; } + public List> getRemoteForwardsBindings(){ return null; } + public List> getLocalForwardsBindings(){ return null; } + public List getBoundLocalPortForwards(int p0){ return null; } + public List getStartedLocalPortForwards(){ return null; } + public Map getProperties(){ return null; } + public NavigableSet getStartedRemotePortForwards(){ return null; } + public PropertyResolver getParentPropertyResolver(){ return null; } + public ReservedSessionMessagesHandler getReservedSessionMessagesHandler(){ return null; } + public SessionDisconnectHandler getSessionDisconnectHandler(){ return null; } + public SshdSocketAddress getBoundRemotePortForward(int p0){ return null; } + public String getUsername(){ return null; } + public String toString(){ return null; } + public TimeoutIndicator getTimeoutStatus(){ return null; } + public UnknownChannelReferenceHandler getUnknownChannelReferenceHandler(){ return null; } + public UnknownChannelReferenceHandler resolveUnknownChannelReferenceHandler(){ return null; } + public boolean isAuthenticated(){ return false; } + public boolean isLocalPortForwardingStartedForPort(int p0){ return false; } + public boolean isRemotePortForwardingStartedForPort(int p0){ return false; } + public boolean isServerSession(){ return false; } + public int getAttributesCount(){ return 0; } + public void clearAttributes(){} + public void disconnect(int p0, String p1){} + public void exceptionCaught(Throwable p0){} + public void setAuthenticated(){} + public void setChannelStreamWriterResolver(ChannelStreamWriterResolver p0){} + public void setReservedSessionMessagesHandler(ReservedSessionMessagesHandler p0){} + public void setSessionDisconnectHandler(SessionDisconnectHandler p0){} + public void setUnknownChannelReferenceHandler(UnknownChannelReferenceHandler p0){} + public void setUsername(String p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/SessionTimeoutListener.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/SessionTimeoutListener.java new file mode 100644 index 00000000000..b170cad8ab0 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/SessionTimeoutListener.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.sshd.common.session.helpers.SessionTimeoutListener for testing purposes + +package org.apache.sshd.common.session.helpers; + +import java.util.Set; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.session.SessionListener; +import org.apache.sshd.common.session.helpers.SessionHelper; +import org.apache.sshd.common.util.logging.AbstractLoggingBean; + +public class SessionTimeoutListener extends AbstractLoggingBean implements Runnable, SessionListener +{ + protected final Set sessions = null; + public SessionTimeoutListener(){} + public void run(){} + public void sessionClosed(Session p0){} + public void sessionCreated(Session p0){} + public void sessionException(Session p0, Throwable p1){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/TimeoutIndicator.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/TimeoutIndicator.java new file mode 100644 index 00000000000..0b87c69f4e8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/session/helpers/TimeoutIndicator.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.sshd.common.session.helpers.TimeoutIndicator for testing purposes + +package org.apache.sshd.common.session.helpers; + +import java.time.Duration; + +public class TimeoutIndicator +{ + protected TimeoutIndicator() {} + public Duration getExpiredValue(){ return null; } + public Duration getThresholdValue(){ return null; } + public String toString(){ return null; } + public TimeoutIndicator(TimeoutIndicator.TimeoutStatus p0, Duration p1, Duration p2){} + public TimeoutIndicator.TimeoutStatus getStatus(){ return null; } + public static String toDisplayDurationValue(Duration p0){ return null; } + public static TimeoutIndicator NONE = null; + static public enum TimeoutStatus + { + AuthTimeout, IdleTimeout, NoTimeout; + private TimeoutStatus() {} + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/Signature.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/Signature.java new file mode 100644 index 00000000000..0135c9bf791 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/Signature.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.sshd.common.signature.Signature for testing purposes + +package org.apache.sshd.common.signature; + +import java.security.PrivateKey; +import java.security.PublicKey; +import org.apache.sshd.common.AlgorithmNameProvider; +import org.apache.sshd.common.session.SessionContext; + +public interface Signature extends AlgorithmNameProvider +{ + boolean verify(SessionContext p0, byte[] p1); + byte[] sign(SessionContext p0); + default String getSshAlgorithmName(String p0){ return null; } + default void update(SessionContext p0, byte[] p1){} + void initSigner(SessionContext p0, PrivateKey p1); + void initVerifier(SessionContext p0, PublicKey p1); + void update(SessionContext p0, byte[] p1, int p2, int p3); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/SignatureFactoriesHolder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/SignatureFactoriesHolder.java new file mode 100644 index 00000000000..d39a50b45e8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/SignatureFactoriesHolder.java @@ -0,0 +1,14 @@ +// Generated automatically from org.apache.sshd.common.signature.SignatureFactoriesHolder for testing purposes + +package org.apache.sshd.common.signature; + +import java.util.List; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.signature.Signature; + +public interface SignatureFactoriesHolder +{ + List> getSignatureFactories(); + default List getSignatureFactoriesNames(){ return null; } + default String getSignatureFactoriesNameList(){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/SignatureFactoriesManager.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/SignatureFactoriesManager.java new file mode 100644 index 00000000000..e618ecaf893 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/signature/SignatureFactoriesManager.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.sshd.common.signature.SignatureFactoriesManager for testing purposes + +package org.apache.sshd.common.signature; + +import java.util.Collection; +import java.util.List; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.signature.Signature; +import org.apache.sshd.common.signature.SignatureFactoriesHolder; + +public interface SignatureFactoriesManager extends SignatureFactoriesHolder +{ + default void setSignatureFactoriesNameList(String p0){} + default void setSignatureFactoriesNames(Collection p0){} + default void setSignatureFactoriesNames(String... p0){} + static List> getSignatureFactories(SignatureFactoriesManager p0){ return null; } + static List> resolveSignatureFactories(SignatureFactoriesManager p0, SignatureFactoriesManager p1){ return null; } + void setSignatureFactories(List> p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/EventNotifier.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/EventNotifier.java new file mode 100644 index 00000000000..c9aff18d6e0 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/EventNotifier.java @@ -0,0 +1,9 @@ +// Generated automatically from org.apache.sshd.common.util.EventNotifier for testing purposes + +package org.apache.sshd.common.util; + + +public interface EventNotifier +{ + void notifyEvent(E p0); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/ObjectBuilder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/ObjectBuilder.java new file mode 100644 index 00000000000..006f36916be --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/ObjectBuilder.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.util.ObjectBuilder for testing purposes + +package org.apache.sshd.common.util; + +import java.util.function.Supplier; + +public interface ObjectBuilder extends Supplier +{ + T build(); + default T get(){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/Readable.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/Readable.java new file mode 100644 index 00000000000..3ade0a65a15 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/Readable.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.util.Readable for testing purposes + +package org.apache.sshd.common.util; + +import java.nio.ByteBuffer; + +public interface Readable +{ + int available(); + static Readable readable(ByteBuffer p0){ return null; } + void getRawBytes(byte[] p0, int p1, int p2); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/SshdEventListener.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/SshdEventListener.java new file mode 100644 index 00000000000..4bc7d4f7daf --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/SshdEventListener.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.common.util.SshdEventListener for testing purposes + +package org.apache.sshd.common.util; + +import java.util.EventListener; + +public interface SshdEventListener extends EventListener +{ + static L validateListener(L p0, String p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/Buffer.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/Buffer.java new file mode 100644 index 00000000000..ee6ab0b8ad7 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/Buffer.java @@ -0,0 +1,120 @@ +// Generated automatically from org.apache.sshd.common.util.buffer.Buffer for testing purposes + +package org.apache.sshd.common.util.buffer; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.security.KeyPair; +import java.security.PublicKey; +import java.security.spec.ECParameterSpec; +import java.util.Collection; +import java.util.List; +import java.util.function.IntUnaryOperator; +import java.util.logging.Level; +import org.apache.sshd.common.PropertyResolver; +import org.apache.sshd.common.config.keys.OpenSshCertificate; +import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser; +import org.apache.sshd.common.util.logging.SimplifiedLog; + +abstract public class Buffer implements Readable +{ + protected Buffer(){} + protected KeyPair extractEC(String p0, ECParameterSpec p1){ return null; } + protected abstract int size(); + protected abstract void copyRawBytes(int p0, byte[] p1, int p2, int p3); + protected final byte[] workBuf = null; + public BigInteger getMPInt(){ return null; } + public Buffer clear(){ return null; } + public Buffer ensureCapacity(int p0){ return null; } + public Collection getAvailableStrings(){ return null; } + public Collection getAvailableStrings(Charset p0){ return null; } + public Collection getStringList(boolean p0){ return null; } + public Collection getStringList(boolean p0, Charset p1){ return null; } + public KeyPair getKeyPair(){ return null; } + public List getCertificateOptions(){ return null; } + public List getCertificateOptions(Charset p0){ return null; } + public List getNameList(){ return null; } + public List getNameList(Charset p0){ return null; } + public List getNameList(Charset p0, char p1){ return null; } + public List getNameList(char p0){ return null; } + public List getStringList(int p0){ return null; } + public List getStringList(int p0, Charset p1){ return null; } + public PublicKey getPublicKey(){ return null; } + public PublicKey getPublicKey(BufferPublicKeyParser p0){ return null; } + public PublicKey getRawPublicKey(){ return null; } + public PublicKey getRawPublicKey(BufferPublicKeyParser p0){ return null; } + public String getString(){ return null; } + public String toHex(){ return null; } + public String toString(){ return null; } + public abstract Buffer clear(boolean p0); + public abstract Buffer ensureCapacity(int p0, IntUnaryOperator p1); + public abstract String getString(Charset p0); + public abstract byte[] array(); + public abstract byte[] getBytesConsumed(); + public abstract int capacity(); + public abstract int putBuffer(Readable p0, boolean p1); + public abstract int rpos(); + public abstract int wpos(); + public abstract void compact(); + public abstract void putBuffer(ByteBuffer p0); + public abstract void putRawBytes(byte[] p0, int p1, int p2); + public abstract void rpos(int p0); + public abstract void wpos(int p0); + public boolean getBoolean(){ return false; } + public boolean isValidMessageStructure(Class... p0){ return false; } + public boolean isValidMessageStructure(Collection> p0){ return false; } + public byte getByte(){ return 0; } + public byte rawByte(int p0){ return 0; } + public byte[] getBytes(){ return null; } + public byte[] getCompactData(){ return null; } + public byte[] getMPIntAsBytes(){ return null; } + public int ensureAvailable(int p0){ return 0; } + public int getInt(){ return 0; } + public int getUByte(){ return 0; } + public long getLong(){ return 0; } + public long getUInt(){ return 0; } + public long rawUInt(int p0){ return 0; } + public short getShort(){ return 0; } + public void dumpHex(SimplifiedLog p0, Level p1, String p2, PropertyResolver p3){} + public void dumpHex(SimplifiedLog p0, String p1, PropertyResolver p2){} + public void getRawBytes(byte[] p0){} + public void putAndWipeBytes(byte[] p0){} + public void putAndWipeBytes(byte[] p0, int p1, int p2){} + public void putAndWipeChars(char[] p0){} + public void putAndWipeChars(char[] p0, Charset p1){} + public void putAndWipeChars(char[] p0, int p1, int p2){} + public void putAndWipeChars(char[] p0, int p1, int p2, Charset p3){} + public void putBoolean(boolean p0){} + public void putBuffer(Readable p0){} + public void putBufferedData(Object p0){} + public void putByte(byte p0){} + public void putBytes(byte[] p0){} + public void putBytes(byte[] p0, int p1, int p2){} + public void putCertificateOptions(List p0){} + public void putCertificateOptions(List p0, Charset p1){} + public void putChars(char[] p0){} + public void putChars(char[] p0, Charset p1){} + public void putChars(char[] p0, int p1, int p2){} + public void putChars(char[] p0, int p1, int p2, Charset p3){} + public void putInt(long p0){} + public void putKeyPair(KeyPair p0){} + public void putLong(long p0){} + public void putMPInt(BigInteger p0){} + public void putMPInt(byte[] p0){} + public void putNameList(Collection p0){} + public void putNameList(Collection p0, Charset p1){} + public void putNameList(Collection p0, Charset p1, char p2){} + public void putNameList(Collection p0, char p1){} + public void putOptionalBufferedData(Object p0){} + public void putPublicKey(PublicKey p0){} + public void putRawBytes(byte[] p0){} + public void putRawPublicKey(PublicKey p0){} + public void putRawPublicKeyBytes(PublicKey p0){} + public void putShort(int p0){} + public void putString(String p0){} + public void putString(String p0, Charset p1){} + public void putStringList(Collection p0, Charset p1, boolean p2){} + public void putStringList(Collection p0, boolean p1){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java new file mode 100644 index 00000000000..a0d3babd05d --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java @@ -0,0 +1,45 @@ +// Generated automatically from org.apache.sshd.common.util.buffer.ByteArrayBuffer for testing purposes + +package org.apache.sshd.common.util.buffer; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.function.IntUnaryOperator; +import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.Buffer; + +public class ByteArrayBuffer extends Buffer +{ + protected int size(){ return 0; } + protected void copyRawBytes(int p0, byte[] p1, int p2, int p3){} + public Buffer clear(boolean p0){ return null; } + public Buffer ensureCapacity(int p0, IntUnaryOperator p1){ return null; } + public ByteArrayBuffer(){} + public ByteArrayBuffer(byte[] p0){} + public ByteArrayBuffer(byte[] p0, boolean p1){} + public ByteArrayBuffer(byte[] p0, int p1, int p2){} + public ByteArrayBuffer(byte[] p0, int p1, int p2, boolean p3){} + public ByteArrayBuffer(int p0){} + public ByteArrayBuffer(int p0, boolean p1){} + public String getString(Charset p0){ return null; } + public byte getByte(){ return 0; } + public byte rawByte(int p0){ return 0; } + public byte[] array(){ return null; } + public byte[] getBytesConsumed(){ return null; } + public int available(){ return 0; } + public int capacity(){ return 0; } + public int putBuffer(Readable p0, boolean p1){ return 0; } + public int rpos(){ return 0; } + public int wpos(){ return 0; } + public long rawUInt(int p0){ return 0; } + public static ByteArrayBuffer getCompactClone(byte[] p0){ return null; } + public static ByteArrayBuffer getCompactClone(byte[] p0, int p1, int p2){ return null; } + public static int DEFAULT_SIZE = 0; + public void compact(){} + public void getRawBytes(byte[] p0, int p1, int p2){} + public void putBuffer(ByteBuffer p0){} + public void putByte(byte p0){} + public void putRawBytes(byte[] p0, int p1, int p2){} + public void rpos(int p0){} + public void wpos(int p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java new file mode 100644 index 00000000000..20e7aaf8f91 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser for testing purposes + +package org.apache.sshd.common.util.buffer.keys; + +import java.security.PublicKey; +import java.util.Collection; +import org.apache.sshd.common.util.buffer.Buffer; + +public interface BufferPublicKeyParser +{ + PUB getRawPublicKey(String p0, Buffer p1); + boolean isKeyTypeSupported(String p0); + static BufferPublicKeyParser DEFAULT = null; + static BufferPublicKeyParser EMPTY = null; + static BufferPublicKeyParser aggregate(Collection> p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/AbstractCloseable.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/AbstractCloseable.java new file mode 100644 index 00000000000..37c2341d9d9 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/AbstractCloseable.java @@ -0,0 +1,34 @@ +// Generated automatically from org.apache.sshd.common.util.closeable.AbstractCloseable for testing purposes + +package org.apache.sshd.common.util.closeable; + +import java.util.concurrent.atomic.AtomicReference; +import org.apache.sshd.common.future.CloseFuture; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.future.SshFutureListener; +import org.apache.sshd.common.util.closeable.Builder; +import org.apache.sshd.common.util.closeable.IoBaseCloseable; + +abstract public class AbstractCloseable extends IoBaseCloseable +{ + protected AbstractCloseable(){} + protected AbstractCloseable(String p0){} + protected Builder builder(){ return null; } + protected CloseFuture doCloseGracefully(){ return null; } + protected final AtomicReference state = null; + protected final CloseFuture closeFuture = null; + protected final Object futureLock = null; + protected void doCloseImmediately(){} + protected void preClose(){} + public Object getFutureLock(){ return null; } + public final CloseFuture close(boolean p0){ return null; } + public final boolean isClosed(){ return false; } + public final boolean isClosing(){ return false; } + public void addCloseFutureListener(SshFutureListener p0){} + public void removeCloseFutureListener(SshFutureListener p0){} + static public enum State + { + Closed, Graceful, Immediate, Opened; + private State() {} + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/AbstractInnerCloseable.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/AbstractInnerCloseable.java new file mode 100644 index 00000000000..be823f7eef9 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/AbstractInnerCloseable.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.sshd.common.util.closeable.AbstractInnerCloseable for testing purposes + +package org.apache.sshd.common.util.closeable; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.future.CloseFuture; +import org.apache.sshd.common.util.closeable.AbstractCloseable; + +abstract public class AbstractInnerCloseable extends AbstractCloseable +{ + protected AbstractInnerCloseable(){} + protected AbstractInnerCloseable(String p0){} + protected abstract Closeable getInnerCloseable(); + protected final CloseFuture doCloseGracefully(){ return null; } + protected final void doCloseImmediately(){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/Builder.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/Builder.java new file mode 100644 index 00000000000..9711c7c202a --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/Builder.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.sshd.common.util.closeable.Builder for testing purposes + +package org.apache.sshd.common.util.closeable; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.future.SshFuture; +import org.apache.sshd.common.util.ObjectBuilder; + +public class Builder implements ObjectBuilder +{ + protected Builder() {} + public Builder when(Object p0, Iterable> p1){ return null; } + public Builder when(SshFuture p0){ return null; } + public Builder close(Closeable p0){ return null; } + public Builder parallel(Closeable... p0){ return null; } + public Builder parallel(Object p0, Iterable p1){ return null; } + public Builder run(Object p0, Runnable p1){ return null; } + public Builder sequential(Closeable... p0){ return null; } + public Builder sequential(Object p0, Iterable p1){ return null; } + public Builder(Object p0){} + public Closeable build(){ return null; } + public final Builder when(SshFuture... p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/IoBaseCloseable.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/IoBaseCloseable.java new file mode 100644 index 00000000000..6c6581c6bdd --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/closeable/IoBaseCloseable.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.util.closeable.IoBaseCloseable for testing purposes + +package org.apache.sshd.common.util.closeable; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.util.logging.AbstractLoggingBean; + +abstract public class IoBaseCloseable extends AbstractLoggingBean implements Closeable +{ + protected IoBaseCloseable(){} + protected IoBaseCloseable(String p0){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/io/functors/Invoker.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/io/functors/Invoker.java new file mode 100644 index 00000000000..c3bcff48324 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/io/functors/Invoker.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.sshd.common.util.io.functors.Invoker for testing purposes + +package org.apache.sshd.common.util.io.functors; + +import java.util.AbstractMap; +import java.util.Collection; + +public interface Invoker +{ + RET invoke(ARG p0); + static AbstractMap.SimpleImmutableEntry, Throwable> invokeTillFirstFailure(ARG p0, Collection> p1){ return null; } + static Invoker wrapAll(Collection> p0){ return null; } + static Invoker wrapFirst(Collection> p0){ return null; } + static void invokeAll(ARG p0, Collection> p1){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/logging/AbstractLoggingBean.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/logging/AbstractLoggingBean.java new file mode 100644 index 00000000000..76b36f39ec8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/logging/AbstractLoggingBean.java @@ -0,0 +1,35 @@ +// Generated automatically from org.apache.sshd.common.util.logging.AbstractLoggingBean for testing purposes + +package org.apache.sshd.common.util.logging; + +import org.apache.sshd.common.util.logging.SimplifiedLog; +import org.slf4j.Logger; + +abstract public class AbstractLoggingBean +{ + protected AbstractLoggingBean(){} + protected AbstractLoggingBean(Logger p0){} + protected AbstractLoggingBean(String p0){} + protected SimplifiedLog getSimplifiedLogger(){ return null; } + protected final Logger log = null; + protected void debug(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Throwable p7){} + protected void debug(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Throwable p6){} + protected void debug(String p0, Object p1, Object p2, Object p3, Object p4, Throwable p5){} + protected void debug(String p0, Object p1, Object p2, Object p3, Throwable p4){} + protected void debug(String p0, Object p1, Object p2, Throwable p3){} + protected void error(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Throwable p7){} + protected void error(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Throwable p6){} + protected void error(String p0, Object p1, Object p2, Object p3, Object p4, Throwable p5){} + protected void error(String p0, Object p1, Object p2, Object p3, Throwable p4){} + protected void error(String p0, Object p1, Object p2, Throwable p3){} + protected void info(String p0, Object p1, Object p2, Object p3, Throwable p4){} + protected void info(String p0, Object p1, Object p2, Throwable p3){} + protected void warn(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9, Throwable p10){} + protected void warn(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Throwable p9){} + protected void warn(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Throwable p8){} + protected void warn(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Throwable p7){} + protected void warn(String p0, Object p1, Object p2, Object p3, Object p4, Object p5, Throwable p6){} + protected void warn(String p0, Object p1, Object p2, Object p3, Object p4, Throwable p5){} + protected void warn(String p0, Object p1, Object p2, Object p3, Throwable p4){} + protected void warn(String p0, Object p1, Object p2, Throwable p3){} +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/logging/SimplifiedLog.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/logging/SimplifiedLog.java new file mode 100644 index 00000000000..0ff1d91cd26 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/logging/SimplifiedLog.java @@ -0,0 +1,34 @@ +// Generated automatically from org.apache.sshd.common.util.logging.SimplifiedLog for testing purposes + +package org.apache.sshd.common.util.logging; + +import java.util.logging.Level; + +public interface SimplifiedLog +{ + boolean isEnabledLevel(Level p0); + default boolean isDebugEnabled(){ return false; } + default boolean isErrorEnabled(){ return false; } + default boolean isInfoEnabled(){ return false; } + default boolean isTraceEnabled(){ return false; } + default boolean isWarnEnabled(){ return false; } + default void debug(String p0){} + default void debug(String p0, Throwable p1){} + default void error(String p0){} + default void error(String p0, Throwable p1){} + default void info(String p0){} + default void info(String p0, Throwable p1){} + default void log(Level p0, Object p1){} + default void trace(String p0){} + default void trace(String p0, Throwable p1){} + default void warn(String p0){} + default void warn(String p0, Throwable p1){} + static SimplifiedLog EMPTY = null; + static boolean isDebugEnabled(Level p0){ return false; } + static boolean isErrorEnabled(Level p0){ return false; } + static boolean isInfoEnabled(Level p0){ return false; } + static boolean isLoggable(Level p0, Level p1){ return false; } + static boolean isTraceEnabled(Level p0){ return false; } + static boolean isWarnEnabled(Level p0){ return false; } + void log(Level p0, Object p1, Throwable p2); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/net/ConnectionEndpointsIndicator.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/net/ConnectionEndpointsIndicator.java new file mode 100644 index 00000000000..975a94c288e --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/net/ConnectionEndpointsIndicator.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.sshd.common.util.net.ConnectionEndpointsIndicator for testing purposes + +package org.apache.sshd.common.util.net; + +import java.net.SocketAddress; + +public interface ConnectionEndpointsIndicator +{ + SocketAddress getLocalAddress(); + SocketAddress getRemoteAddress(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/net/SshdSocketAddress.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/net/SshdSocketAddress.java new file mode 100644 index 00000000000..cf34b75923c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/net/SshdSocketAddress.java @@ -0,0 +1,68 @@ +// Generated automatically from org.apache.sshd.common.util.net.SshdSocketAddress for testing purposes + +package org.apache.sshd.common.util.net; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class SshdSocketAddress extends SocketAddress +{ + protected SshdSocketAddress() {} + protected boolean isEquivalent(SshdSocketAddress p0){ return false; } + public InetSocketAddress toInetSocketAddress(){ return null; } + public SshdSocketAddress(InetSocketAddress p0){} + public SshdSocketAddress(String p0, int p1){} + public SshdSocketAddress(int p0){} + public String getHostName(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int getPort(){ return 0; } + public int hashCode(){ return 0; } + public static Map.Entry findMatchingOptionalWildcardEntry(Map p0, SshdSocketAddress p1){ return null; } + public static V findByOptionalWildcardAddress(Map p0, SshdSocketAddress p1){ return null; } + public static V removeByOptionalWildcardAddress(Map p0, SshdSocketAddress p1){ return null; } + public static Comparator BY_HOST_ADDRESS = null; + public static Comparator BY_HOST_AND_PORT = null; + public static InetAddress getFirstExternalNetwork4Address(){ return null; } + public static InetSocketAddress toInetSocketAddress(SocketAddress p0){ return null; } + public static List getExternalNetwork4Addresses(){ return null; } + public static Set WELL_KNOWN_IPV4_ADDRESSES = null; + public static Set WELL_KNOWN_IPV6_ADDRESSES = null; + public static SshdSocketAddress LOCALHOST_ADDRESS = null; + public static SshdSocketAddress toSshdSocketAddress(SocketAddress p0){ return null; } + public static String BROADCAST_ADDRESS = null; + public static String CARRIER_GRADE_NAT_PREFIX = null; + public static String IPV4_ANYADDR = null; + public static String IPV6_LONG_ANY_ADDRESS = null; + public static String IPV6_LONG_LOCALHOST = null; + public static String IPV6_SHORT_ANY_ADDRESS = null; + public static String IPV6_SHORT_LOCALHOST = null; + public static String LOCALHOST_IPV4 = null; + public static String LOCALHOST_NAME = null; + public static String PRIVATE_CLASS_A_PREFIX = null; + public static String PRIVATE_CLASS_B_PREFIX = null; + public static String PRIVATE_CLASS_C_PREFIX = null; + public static String toAddressString(InetAddress p0){ return null; } + public static String toAddressString(SocketAddress p0){ return null; } + public static boolean isCarrierGradeNatIPv4Address(String p0){ return false; } + public static boolean isEquivalentHostName(String p0, String p1, boolean p2){ return false; } + public static boolean isIPv4Address(String p0){ return false; } + public static boolean isIPv4LoopbackAddress(String p0){ return false; } + public static boolean isIPv6Address(String p0){ return false; } + public static boolean isIPv6LoopbackAddress(String p0){ return false; } + public static boolean isLoopback(InetAddress p0){ return false; } + public static boolean isLoopback(String p0){ return false; } + public static boolean isLoopbackAlias(String p0, String p1){ return false; } + public static boolean isPrivateIPv4Address(String p0){ return false; } + public static boolean isValidHostAddress(InetAddress p0){ return false; } + public static boolean isValidIPv4AddressComponent(CharSequence p0){ return false; } + public static boolean isWildcardAddress(String p0){ return false; } + public static int IPV6_MAX_HEX_DIGITS_PER_GROUP = 0; + public static int IPV6_MAX_HEX_GROUPS = 0; + public static int toAddressPort(SocketAddress p0){ return 0; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/threads/CloseableExecutorService.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/threads/CloseableExecutorService.java new file mode 100644 index 00000000000..ac65788f3c8 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/threads/CloseableExecutorService.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.common.util.threads.CloseableExecutorService for testing purposes + +package org.apache.sshd.common.util.threads; + +import java.time.Duration; +import java.util.concurrent.ExecutorService; +import org.apache.sshd.common.Closeable; + +public interface CloseableExecutorService extends Closeable, ExecutorService +{ + default boolean awaitTermination(Duration p0){ return false; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/threads/ExecutorServiceCarrier.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/threads/ExecutorServiceCarrier.java new file mode 100644 index 00000000000..69e20a1a3a2 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/common/util/threads/ExecutorServiceCarrier.java @@ -0,0 +1,10 @@ +// Generated automatically from org.apache.sshd.common.util.threads.ExecutorServiceCarrier for testing purposes + +package org.apache.sshd.common.util.threads; + +import org.apache.sshd.common.util.threads.CloseableExecutorService; + +public interface ExecutorServiceCarrier +{ + CloseableExecutorService getExecutorService(); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/AgentForwardingFilter.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/AgentForwardingFilter.java new file mode 100644 index 00000000000..1c38922baae --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/AgentForwardingFilter.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.server.forward.AgentForwardingFilter for testing purposes + +package org.apache.sshd.server.forward; + +import org.apache.sshd.common.session.Session; + +public interface AgentForwardingFilter +{ + boolean canForwardAgent(Session p0, String p1); + static AgentForwardingFilter DEFAULT = null; + static AgentForwardingFilter of(boolean p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/ForwardingFilter.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/ForwardingFilter.java new file mode 100644 index 00000000000..8576bc9d09d --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/ForwardingFilter.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.server.forward.ForwardingFilter for testing purposes + +package org.apache.sshd.server.forward; + +import org.apache.sshd.server.forward.AgentForwardingFilter; +import org.apache.sshd.server.forward.TcpForwardingFilter; +import org.apache.sshd.server.forward.X11ForwardingFilter; + +public interface ForwardingFilter extends AgentForwardingFilter, TcpForwardingFilter, X11ForwardingFilter +{ + static ForwardingFilter asForwardingFilter(AgentForwardingFilter p0, X11ForwardingFilter p1, TcpForwardingFilter p2){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/TcpForwardingFilter.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/TcpForwardingFilter.java new file mode 100644 index 00000000000..668a65f4d04 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/TcpForwardingFilter.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.sshd.server.forward.TcpForwardingFilter for testing purposes + +package org.apache.sshd.server.forward; + +import java.util.Set; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.net.SshdSocketAddress; + +public interface TcpForwardingFilter +{ + boolean canConnect(TcpForwardingFilter.Type p0, SshdSocketAddress p1, Session p2); + boolean canListen(SshdSocketAddress p0, Session p1); + static TcpForwardingFilter DEFAULT = null; + static public enum Type + { + Direct, Forwarded; + private Type() {} + public final String getName(){ return null; } + public static Set VALUES = null; + public static TcpForwardingFilter.Type fromEnumName(String p0){ return null; } + public static TcpForwardingFilter.Type fromName(String p0){ return null; } + public static TcpForwardingFilter.Type fromString(String p0){ return null; } + } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/X11ForwardingFilter.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/X11ForwardingFilter.java new file mode 100644 index 00000000000..93e3e119eef --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/forward/X11ForwardingFilter.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.sshd.server.forward.X11ForwardingFilter for testing purposes + +package org.apache.sshd.server.forward; + +import org.apache.sshd.common.session.Session; + +public interface X11ForwardingFilter +{ + boolean canForwardX11(Session p0, String p1); + static X11ForwardingFilter DEFAULT = null; + static X11ForwardingFilter of(boolean p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/x11/X11ForwardSupport.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/x11/X11ForwardSupport.java new file mode 100644 index 00000000000..55c2ecd7052 --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/apache/sshd/server/x11/X11ForwardSupport.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.sshd.server.x11.X11ForwardSupport for testing purposes + +package org.apache.sshd.server.x11; + +import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.io.IoHandler; + +public interface X11ForwardSupport extends Closeable, IoHandler +{ + String createDisplay(boolean p0, String p1, String p2, int p3); + static String ENV_DISPLAY = null; + static String XAUTH_COMMAND = null; +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/slf4j/Logger.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/slf4j/Logger.java new file mode 100644 index 00000000000..6b2d3033e0c --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/slf4j/Logger.java @@ -0,0 +1,71 @@ +// Generated automatically from org.slf4j.Logger for testing purposes + +package org.slf4j; + +import org.slf4j.Marker; + +public interface Logger +{ + String getName(); + boolean isDebugEnabled(); + boolean isDebugEnabled(Marker p0); + boolean isErrorEnabled(); + boolean isErrorEnabled(Marker p0); + boolean isInfoEnabled(); + boolean isInfoEnabled(Marker p0); + boolean isTraceEnabled(); + boolean isTraceEnabled(Marker p0); + boolean isWarnEnabled(); + boolean isWarnEnabled(Marker p0); + static String ROOT_LOGGER_NAME = null; + void debug(Marker p0, String p1); + void debug(Marker p0, String p1, Object p2); + void debug(Marker p0, String p1, Object p2, Object p3); + void debug(Marker p0, String p1, Object... p2); + void debug(Marker p0, String p1, Throwable p2); + void debug(String p0); + void debug(String p0, Object p1); + void debug(String p0, Object p1, Object p2); + void debug(String p0, Object... p1); + void debug(String p0, Throwable p1); + void error(Marker p0, String p1); + void error(Marker p0, String p1, Object p2); + void error(Marker p0, String p1, Object p2, Object p3); + void error(Marker p0, String p1, Object... p2); + void error(Marker p0, String p1, Throwable p2); + void error(String p0); + void error(String p0, Object p1); + void error(String p0, Object p1, Object p2); + void error(String p0, Object... p1); + void error(String p0, Throwable p1); + void info(Marker p0, String p1); + void info(Marker p0, String p1, Object p2); + void info(Marker p0, String p1, Object p2, Object p3); + void info(Marker p0, String p1, Object... p2); + void info(Marker p0, String p1, Throwable p2); + void info(String p0); + void info(String p0, Object p1); + void info(String p0, Object p1, Object p2); + void info(String p0, Object... p1); + void info(String p0, Throwable p1); + void trace(Marker p0, String p1); + void trace(Marker p0, String p1, Object p2); + void trace(Marker p0, String p1, Object p2, Object p3); + void trace(Marker p0, String p1, Object... p2); + void trace(Marker p0, String p1, Throwable p2); + void trace(String p0); + void trace(String p0, Object p1); + void trace(String p0, Object p1, Object p2); + void trace(String p0, Object... p1); + void trace(String p0, Throwable p1); + void warn(Marker p0, String p1); + void warn(Marker p0, String p1, Object p2); + void warn(Marker p0, String p1, Object p2, Object p3); + void warn(Marker p0, String p1, Object... p2); + void warn(Marker p0, String p1, Throwable p2); + void warn(String p0); + void warn(String p0, Object p1); + void warn(String p0, Object p1, Object p2); + void warn(String p0, Object... p1); + void warn(String p0, Throwable p1); +} diff --git a/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/slf4j/Marker.java b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/slf4j/Marker.java new file mode 100644 index 00000000000..bf8ac78dc7f --- /dev/null +++ b/java/ql/test/stubs/apache-mina-sshd-2.8.0/org/slf4j/Marker.java @@ -0,0 +1,22 @@ +// Generated automatically from org.slf4j.Marker for testing purposes + +package org.slf4j; + +import java.io.Serializable; +import java.util.Iterator; + +public interface Marker extends Serializable +{ + Iterator iterator(); + String getName(); + boolean contains(Marker p0); + boolean contains(String p0); + boolean equals(Object p0); + boolean hasChildren(); + boolean hasReferences(); + boolean remove(Marker p0); + int hashCode(); + static String ANY_MARKER = null; + static String ANY_NON_NULL_MARKER = null; + void add(Marker p0); +} diff --git a/java/ql/test/stubs/ganymed-ssh-2-260/ch/ethz/ssh2/Connection.java b/java/ql/test/stubs/ganymed-ssh-2-260/ch/ethz/ssh2/Connection.java new file mode 100644 index 00000000000..b57e4208e27 --- /dev/null +++ b/java/ql/test/stubs/ganymed-ssh-2-260/ch/ethz/ssh2/Connection.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2006-2011 Christian Plattner. All rights reserved. + * Please refer to the LICENSE.txt for licensing details. + */ +package ch.ethz.ssh2; + +import java.io.IOException; + +public class Connection +{ + public synchronized boolean authenticateWithPassword(String user, String password) throws IOException + { + return true; + } +} diff --git a/java/ql/test/stubs/j2ssh-1.5.5/com/sshtools/j2ssh/authentication/PasswordAuthenticationClient.java b/java/ql/test/stubs/j2ssh-1.5.5/com/sshtools/j2ssh/authentication/PasswordAuthenticationClient.java new file mode 100644 index 00000000000..d11b5294096 --- /dev/null +++ b/java/ql/test/stubs/j2ssh-1.5.5/com/sshtools/j2ssh/authentication/PasswordAuthenticationClient.java @@ -0,0 +1,6 @@ +package com.sshtools.j2ssh.authentication; + +public class PasswordAuthenticationClient { + public void setUsername(String username) { } + public void setPassword(String password) { } +} diff --git a/java/ql/test/stubs/j2ssh-1.5.5/com/sshtools/j2ssh/authentication/SshAuthenticationClient.java b/java/ql/test/stubs/j2ssh-1.5.5/com/sshtools/j2ssh/authentication/SshAuthenticationClient.java new file mode 100644 index 00000000000..4351eed3430 --- /dev/null +++ b/java/ql/test/stubs/j2ssh-1.5.5/com/sshtools/j2ssh/authentication/SshAuthenticationClient.java @@ -0,0 +1,5 @@ +package com.sshtools.j2ssh.authentication; + +public class SshAuthenticationClient { + public void setUsername(String username) { } +} diff --git a/java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/Channel.java b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/Channel.java similarity index 100% rename from java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/Channel.java rename to java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/Channel.java diff --git a/java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelExec.java b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelExec.java similarity index 100% rename from java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelExec.java rename to java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelExec.java diff --git a/java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelSession.java b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelSession.java similarity index 100% rename from java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelSession.java rename to java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/ChannelSession.java diff --git a/java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/JSch.java b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/JSch.java similarity index 91% rename from java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/JSch.java rename to java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/JSch.java index b8ce91b9715..422d96423bc 100644 --- a/java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/JSch.java +++ b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/JSch.java @@ -8,8 +8,8 @@ modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products @@ -33,7 +33,11 @@ public class JSch { public JSch() {} - public Session getSession(String username, String host, int port) { + public Session getSession(String username, String host) throws JSchException { + return null; + } + + public Session getSession(String username, String host, int port) throws JSchException { return null; } diff --git a/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/JSchException.java b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/JSchException.java new file mode 100644 index 00000000000..415c19c7eed --- /dev/null +++ b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/JSchException.java @@ -0,0 +1,29 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package com.jcraft.jsch; + +public class JSchException extends Exception { + +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/Session.java b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/Session.java similarity index 96% rename from java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/Session.java rename to java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/Session.java index 4cf2015fceb..241442a4a1d 100644 --- a/java/ql/test/experimental/stubs/jsch-0.1.55/com/jcraft/jsch/Session.java +++ b/java/ql/test/stubs/jsch-0.1.55/com/jcraft/jsch/Session.java @@ -8,8 +8,8 @@ modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products @@ -34,10 +34,13 @@ public class Session implements Runnable { public Channel openChannel(String type) { if ("exec".equals(type)) return new ChannelExec(); - + return null; } + public void setPassword(byte[] password) { + } + public void setPassword(String password) { } diff --git a/java/ql/test/stubs/mongodbClient/com/mongodb/MongoCredential.java b/java/ql/test/stubs/mongodbClient/com/mongodb/MongoCredential.java new file mode 100644 index 00000000000..38e24b29bce --- /dev/null +++ b/java/ql/test/stubs/mongodbClient/com/mongodb/MongoCredential.java @@ -0,0 +1,58 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb; + +import com.mongodb.annotations.Immutable; +import com.mongodb.lang.Nullable; + +@Immutable +public final class MongoCredential { + + public static MongoCredential createCredential(final String userName, final String database, final char[] password) { + return null; + } + + public static MongoCredential createScramSha1Credential(final String userName, final String source, final char[] password) { + return null; + } + + public static MongoCredential createScramSha256Credential(final String userName, final String source, final char[] password) { + return null; + } + + public static MongoCredential createMongoX509Credential(final String userName) { + return null; + } + + public static MongoCredential createPlainCredential(final String userName, final String source, final char[] password) { + return null; + } + + public static MongoCredential createGSSAPICredential(final String userName) { + return null; + } + + public static MongoCredential createAwsCredential(@Nullable final String userName, @Nullable final char[] password) { + return null; + } + + public static MongoCredential createMongoCRCredential​(String userName, String database, char[] password) { + // Deprecated function removed in most recent releases of the Mongo driver. + return null; + } + +} diff --git a/java/ql/test/stubs/mongodbClient/com/mongodb/annotations/Immutable.java b/java/ql/test/stubs/mongodbClient/com/mongodb/annotations/Immutable.java new file mode 100644 index 00000000000..9c5e634db86 --- /dev/null +++ b/java/ql/test/stubs/mongodbClient/com/mongodb/annotations/Immutable.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2005 Brian Goetz and Tim Peierls + * Released under the Creative Commons Attribution License + * (http://creativecommons.org/licenses/by/2.5) + * Official home: http://www.jcip.net + * + * Any republication or derived work distributed in source code form + * must include this copyright and license notice. + */ + +package com.mongodb.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *

    The class to which this annotation is applied is immutable. This means that its state cannot be seen to change by callers, which + * implies that

    + *
      + *
    • all public fields are final,
    • + *
    • all public final reference fields refer to other immutable objects, and
    • + *
    • constructors and methods do not publish references to any internal state which is potentially mutable by the + * implementation.
    • + *
    + *

    Immutable objects may still have internal mutable state for purposes of performance optimization; some state + * variables may be lazily computed, so long as they are computed from immutable state and that callers cannot tell the difference.

    + * + *

    Immutable objects are inherently thread-safe; they may be passed between threads or published without synchronization.

    + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Immutable { +} \ No newline at end of file diff --git a/java/ql/test/stubs/mongodbClient/com/mongodb/lang/Nullable.java b/java/ql/test/stubs/mongodbClient/com/mongodb/lang/Nullable.java new file mode 100644 index 00000000000..43af2ce109f --- /dev/null +++ b/java/ql/test/stubs/mongodbClient/com/mongodb/lang/Nullable.java @@ -0,0 +1,42 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.lang; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * A common annotation to declare that annotated elements can be {@code null} under some circumstance. Leverages JSR 305 meta-annotations to + * indicate nullability in Java to common tools with JSR 305 support and used by Kotlin to infer nullability of Spring API. + * + *

    Should be used at parameter, return value, and field level. Methods override should repeat parent {@code @Nullable} annotations + * unless they behave differently.

    + * + *

    Can be used in association with {@code NonNullApi} to override the default non-nullable semantic to nullable.

    + * + * @see NonNullApi + * @see NonNull + * @since 3.7 + */ +@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Nullable { +} \ No newline at end of file diff --git a/java/ql/test/stubs/sshj-0.33.0/com/hierynomus/sshj/common/RemoteAddressProvider.java b/java/ql/test/stubs/sshj-0.33.0/com/hierynomus/sshj/common/RemoteAddressProvider.java new file mode 100644 index 00000000000..0323a997c46 --- /dev/null +++ b/java/ql/test/stubs/sshj-0.33.0/com/hierynomus/sshj/common/RemoteAddressProvider.java @@ -0,0 +1,18 @@ +/* + * Copyright (C)2009 - SSHJ Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.hierynomus.sshj.common; + +public interface RemoteAddressProvider { } diff --git a/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/SSHClient.java b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/SSHClient.java new file mode 100644 index 00000000000..dc0307d90c1 --- /dev/null +++ b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/SSHClient.java @@ -0,0 +1,40 @@ +/* + * Copyright (C)2009 - SSHJ Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.schmizz.sshj; + +import net.schmizz.sshj.connection.channel.direct.SessionFactory; +import net.schmizz.sshj.userauth.UserAuthException; +import net.schmizz.sshj.transport.TransportException; + +import java.io.Closeable; + +public class SSHClient + extends SocketClient + implements Closeable, SessionFactory { + + public void authPassword(String username, String password) + throws UserAuthException, TransportException { + + } + + public void authPassword(final String username, final char[] password) + throws UserAuthException, TransportException { + + } + + public void close() { } + +} diff --git a/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/SocketClient.java b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/SocketClient.java new file mode 100644 index 00000000000..63a69f387b3 --- /dev/null +++ b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/SocketClient.java @@ -0,0 +1,18 @@ +/* + * Copyright (C)2009 - SSHJ Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.schmizz.sshj; + +public abstract class SocketClient { } diff --git a/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/common/SSHException.java b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/common/SSHException.java new file mode 100644 index 00000000000..96243a5d326 --- /dev/null +++ b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/common/SSHException.java @@ -0,0 +1,22 @@ +/* + * Copyright (C)2009 - SSHJ Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.schmizz.sshj.common; + +import java.io.IOException; + +public class SSHException extends IOException { + +} diff --git a/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/connection/channel/direct/SessionFactory.java b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/connection/channel/direct/SessionFactory.java new file mode 100644 index 00000000000..a5fa96e5ecb --- /dev/null +++ b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/connection/channel/direct/SessionFactory.java @@ -0,0 +1,20 @@ +/* + * Copyright (C)2009 - SSHJ Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.schmizz.sshj.connection.channel.direct; + +import com.hierynomus.sshj.common.RemoteAddressProvider; + +public interface SessionFactory extends RemoteAddressProvider { } diff --git a/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/transport/TransportException.java b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/transport/TransportException.java new file mode 100644 index 00000000000..5091f021cc9 --- /dev/null +++ b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/transport/TransportException.java @@ -0,0 +1,20 @@ +/* + * Copyright (C)2009 - SSHJ Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.schmizz.sshj.transport; + +import net.schmizz.sshj.common.SSHException; + +public class TransportException extends SSHException { } \ No newline at end of file diff --git a/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/userauth/UserAuthException.java b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/userauth/UserAuthException.java new file mode 100644 index 00000000000..558cfb22989 --- /dev/null +++ b/java/ql/test/stubs/sshj-0.33.0/net/schmizz/sshj/userauth/UserAuthException.java @@ -0,0 +1,22 @@ +/* + * Copyright (C)2009 - SSHJ Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.schmizz.sshj.userauth; + +import net.schmizz.sshj.common.SSHException; + +public class UserAuthException extends SSHException { + +} \ No newline at end of file diff --git a/java/ql/test/stubs/trilead-ssh2-212/com/trilead/ssh2/Connection.java b/java/ql/test/stubs/trilead-ssh2-212/com/trilead/ssh2/Connection.java new file mode 100644 index 00000000000..68145189e32 --- /dev/null +++ b/java/ql/test/stubs/trilead-ssh2-212/com/trilead/ssh2/Connection.java @@ -0,0 +1,46 @@ +package com.trilead.ssh2; + +import java.io.File; +import java.io.IOException; + +public class Connection +{ + + public synchronized boolean authenticateWithDSA(String user, String pem, String password) throws IOException + { + return true; + } + + public synchronized boolean authenticateWithPassword(String user, String password) throws IOException + { + return true; + } + + public synchronized boolean authenticateWithNone(String user) throws IOException + { + return true; + } + + public synchronized boolean authenticateWithPublicKey(String user, char[] pemPrivateKey, String password) + throws IOException + { + return true; + } + + public synchronized boolean authenticateWithPublicKey(String user, File pemFile, String password) + throws IOException + { + return true; + } + + public synchronized String[] getRemainingAuthMethods(String user) throws IOException + { + return null; + } + + public synchronized boolean isAuthMethodAvailable(String user, String method) throws IOException + { + return true; + } + +} From ddb0846e066d776609a87da8d7eea1ecc43f48c5 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 30 May 2022 21:06:45 +0100 Subject: [PATCH 016/659] Split up hardcoded creds queries, ready for conversion to inline expectations --- .../java/security}/HardcodedCredentials.qll | 0 .../HardcodedCredentialsApiCallQuery.qll | 54 +++++++++++++++++++ .../HardcodedCredentialsComparison.qll | 25 +++++++++ .../HardcodedCredentialsSourceCall.qll | 51 ++++++++++++++++++ .../java/security/HardcodedPasswordField.qll | 14 +++++ .../code/java/security}/SensitiveApi.qll | 0 .../CWE-798/HardcodedCredentialsApiCall.ql | 48 +---------------- .../CWE-798/HardcodedCredentialsComparison.ql | 13 +---- .../CWE-798/HardcodedCredentialsSourceCall.ql | 34 +----------- .../CWE/CWE-798/HardcodedPasswordField.ql | 7 +-- 10 files changed, 150 insertions(+), 96 deletions(-) rename java/ql/{src/Security/CWE/CWE-798 => lib/semmle/code/java/security}/HardcodedCredentials.qll (100%) create mode 100644 java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll create mode 100644 java/ql/lib/semmle/code/java/security/HardcodedCredentialsComparison.qll create mode 100644 java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCall.qll create mode 100644 java/ql/lib/semmle/code/java/security/HardcodedPasswordField.qll rename java/ql/{src/Security/CWE/CWE-798 => lib/semmle/code/java/security}/SensitiveApi.qll (100%) diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentials.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentials.qll similarity index 100% rename from java/ql/src/Security/CWE/CWE-798/HardcodedCredentials.qll rename to java/ql/lib/semmle/code/java/security/HardcodedCredentials.qll diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll new file mode 100644 index 00000000000..2fdec983b31 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll @@ -0,0 +1,54 @@ +/** + * Provides a data-flow configuration for tracking a hard-coded credential in a call to a sensitive Java API which may compromise security. + */ + +import java +import semmle.code.java.dataflow.DataFlow +import HardcodedCredentials + +/** + * Tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security. + */ +class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { + HardcodedCredentialApiCallConfiguration() { this = "HardcodedCredentialApiCallConfiguration" } + + override predicate isSource(DataFlow::Node n) { + n.asExpr() instanceof HardcodedExpr and + not n.asExpr().getEnclosingCallable() instanceof ToStringMethod + } + + override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsApiSink } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + node1.asExpr().getType() instanceof TypeString and + ( + exists(MethodAccess ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) | + node2.asExpr() = ma and + ma.getQualifier() = node1.asExpr() + ) + or + // These base64 routines are usually taint propagators, and this is not a general + // TaintTracking::Configuration, so we must specifically include them here + // as a common transform applied to a constant before passing to a remote API. + exists(MethodAccess ma | + ma.getMethod() + .hasQualifiedName([ + "java.util", "cn.hutool.core.codec", "org.apache.shiro.codec", + "apache.commons.codec.binary", "org.springframework.util" + ], ["Base64$Encoder", "Base64$Decoder", "Base64", "Base64Utils"], + [ + "encode", "encodeToString", "decode", "decodeBase64", "encodeBase64", + "encodeBase64Chunked", "encodeBase64String", "encodeBase64URLSafe", + "encodeBase64URLSafeString" + ]) + | + node1.asExpr() = ma.getArgument(0) and + node2.asExpr() = ma + ) + ) + } + + override predicate isBarrier(DataFlow::Node n) { + n.asExpr().(MethodAccess).getMethod() instanceof MethodSystemGetenv + } +} diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsComparison.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsComparison.qll new file mode 100644 index 00000000000..7f668b90bc1 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsComparison.qll @@ -0,0 +1,25 @@ +/** + * Provides classes and predicates to detect comparing a parameter to a hard-coded credential. + */ + +import HardcodedCredentials + +/** + * A call to a method that is or overrides `java.lang.Object.equals`. + */ +class EqualsAccess extends MethodAccess { + EqualsAccess() { getMethod() instanceof EqualsMethod } +} + +/** + * Holds if `sink` compares password `p` against a hardcoded expression `source`. + */ +predicate isHardcodedCredentialsComparison( + EqualsAccess sink, HardcodedExpr source, PasswordVariable p +) { + source = sink.getQualifier() and + p.getAnAccess() = sink.getArgument(0) + or + source = sink.getArgument(0) and + p.getAnAccess() = sink.getQualifier() +} diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCall.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCall.qll new file mode 100644 index 00000000000..7125ffda088 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCall.qll @@ -0,0 +1,51 @@ +/** + * Provides classes to detect using a hard-coded credential in a sensitive call. + */ + +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.DataFlow2 +import HardcodedCredentials + +/** + * A data-flow configuration that tracks hardcoded expressions flowing to a parameter whose name suggests + * it may be a credential, excluding those which flow on to other such insecure usage sites. + */ +class HardcodedCredentialSourceCallConfiguration extends DataFlow::Configuration { + HardcodedCredentialSourceCallConfiguration() { + this = "HardcodedCredentialSourceCallConfiguration" + } + + override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof HardcodedExpr } + + override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof FinalCredentialsSourceSink } +} + +/** + * A data-flow configuration that tracks flow from an argument whose corresponding parameter name suggests + * a credential, to an argument to a sensitive call. + */ +class HardcodedCredentialSourceCallConfiguration2 extends DataFlow2::Configuration { + HardcodedCredentialSourceCallConfiguration2() { + this = "HardcodedCredentialSourceCallConfiguration2" + } + + override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof CredentialsSourceSink } + + override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsSink } +} + +/** + * An argument to a call, where the parameter name corresponding + * to the argument indicates that it may contain credentials, and + * where this expression does not flow on to another `CredentialsSink`. + */ +class FinalCredentialsSourceSink extends CredentialsSourceSink { + FinalCredentialsSourceSink() { + not exists(HardcodedCredentialSourceCallConfiguration2 conf, CredentialsSink other | + this != other + | + conf.hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(other)) + ) + } +} diff --git a/java/ql/lib/semmle/code/java/security/HardcodedPasswordField.qll b/java/ql/lib/semmle/code/java/security/HardcodedPasswordField.qll new file mode 100644 index 00000000000..4127718af0b --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/HardcodedPasswordField.qll @@ -0,0 +1,14 @@ +/** + * Provides a predicate identifying assignments of harcoded values to password fields. + */ + +import HardcodedCredentials + +/** + * Holds if non-empty constant value `e` is assigned to password field `f`. + */ +predicate passwordFieldAssignedHardcodedValue(PasswordVariable f, CompileTimeConstantExpr e) { + f instanceof Field and + f.getAnAssignedValue() = e and + not e.(StringLiteral).getValue() = "" +} diff --git a/java/ql/src/Security/CWE/CWE-798/SensitiveApi.qll b/java/ql/lib/semmle/code/java/security/SensitiveApi.qll similarity index 100% rename from java/ql/src/Security/CWE/CWE-798/SensitiveApi.qll rename to java/ql/lib/semmle/code/java/security/SensitiveApi.qll diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql index a787d2ddfd3..2b84f4b8065 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql @@ -10,55 +10,9 @@ * external/cwe/cwe-798 */ -import java -import semmle.code.java.dataflow.DataFlow -import HardcodedCredentials +import semmle.code.java.security.HardcodedCredentialsApiCallQuery import DataFlow::PathGraph -class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { - HardcodedCredentialApiCallConfiguration() { this = "HardcodedCredentialApiCallConfiguration" } - - override predicate isSource(DataFlow::Node n) { - n.asExpr() instanceof HardcodedExpr and - not n.asExpr().getEnclosingCallable() instanceof ToStringMethod - } - - override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsApiSink } - - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - node1.asExpr().getType() instanceof TypeString and - ( - exists(MethodAccess ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) | - node2.asExpr() = ma and - ma.getQualifier() = node1.asExpr() - ) - or - // These base64 routines are usually taint propagators, and this is not a general - // TaintTracking::Configuration, so we must specifically include them here - // as a common transform applied to a constant before passing to a remote API. - exists(MethodAccess ma | - ma.getMethod() - .hasQualifiedName([ - "java.util", "cn.hutool.core.codec", "org.apache.shiro.codec", - "apache.commons.codec.binary", "org.springframework.util" - ], ["Base64$Encoder", "Base64$Decoder", "Base64", "Base64Utils"], - [ - "encode", "encodeToString", "decode", "decodeBase64", "encodeBase64", - "encodeBase64Chunked", "encodeBase64String", "encodeBase64URLSafe", - "encodeBase64URLSafeString" - ]) - | - node1.asExpr() = ma.getArgument(0) and - node2.asExpr() = ma - ) - ) - } - - override predicate isBarrier(DataFlow::Node n) { - n.asExpr().(MethodAccess).getMethod() instanceof MethodSystemGetenv - } -} - from DataFlow::PathNode source, DataFlow::PathNode sink, HardcodedCredentialApiCallConfiguration conf where conf.hasFlowPath(source, sink) diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql index d43530f7d69..4a21fcc5e92 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql @@ -11,17 +11,8 @@ */ import java -import HardcodedCredentials - -class EqualsAccess extends MethodAccess { - EqualsAccess() { getMethod() instanceof EqualsMethod } -} +import semmle.code.java.security.HardcodedCredentialsComparison from EqualsAccess sink, HardcodedExpr source, PasswordVariable p -where - source = sink.getQualifier() and - p.getAnAccess() = sink.getArgument(0) - or - source = sink.getArgument(0) and - p.getAnAccess() = sink.getQualifier() +where isHardcodedCredentialsComparison(sink, source, p) select source, "Hard-coded value is $@ with password variable $@.", sink, "compared", p, p.getName() diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql index e14188905fa..6b5c78c1f05 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql @@ -11,41 +11,9 @@ */ import java -import semmle.code.java.dataflow.DataFlow -import semmle.code.java.dataflow.DataFlow2 -import HardcodedCredentials +import semmle.code.java.security.HardcodedCredentialsSourceCall import DataFlow::PathGraph -class HardcodedCredentialSourceCallConfiguration extends DataFlow::Configuration { - HardcodedCredentialSourceCallConfiguration() { - this = "HardcodedCredentialSourceCallConfiguration" - } - - override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof HardcodedExpr } - - override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof FinalCredentialsSourceSink } -} - -class HardcodedCredentialSourceCallConfiguration2 extends DataFlow2::Configuration { - HardcodedCredentialSourceCallConfiguration2() { - this = "HardcodedCredentialSourceCallConfiguration2" - } - - override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof CredentialsSourceSink } - - override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsSink } -} - -class FinalCredentialsSourceSink extends CredentialsSourceSink { - FinalCredentialsSourceSink() { - not exists(HardcodedCredentialSourceCallConfiguration2 conf, CredentialsSink other | - this != other - | - conf.hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(other)) - ) - } -} - from DataFlow::PathNode source, DataFlow::PathNode sink, HardcodedCredentialSourceCallConfiguration conf diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql index 0a98c000300..d148b8d605d 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql @@ -11,11 +11,8 @@ */ import java -import HardcodedCredentials +import semmle.code.java.security.HardcodedPasswordField from PasswordVariable f, CompileTimeConstantExpr e -where - f instanceof Field and - f.getAnAssignedValue() = e and - not e.(StringLiteral).getValue() = "" +where passwordFieldAssignedHardcodedValue(f, e) select f, "Sensitive field is assigned a hard-coded $@.", e, "value" From b62e9dc92c246a075f4e3a63ecfe07984d8c0d5d Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sat, 13 Aug 2022 14:02:05 +0100 Subject: [PATCH 017/659] Convert tests to inline expectations and fix one bug revealed doing so Specifically Apache sshd defines its sensitive api calls on an inherited interface, and they need to be described that way for us to pick them up. --- ...> HardcodedCredentialsSourceCallQuery.qll} | 0 .../code/java/security/SensitiveApi.qll | 4 +- .../CWE-798/HardcodedCredentialsSourceCall.ql | 2 +- .../CWE-798/semmle/tests/CredentialsTest.java | 4 +- .../semmle/tests/FileCredentialTest.java | 4 +- .../semmle/tests/HardcodedAWSCredentials.java | 4 +- .../tests/HardcodedApacheFtpCredentials.java | 4 +- .../tests/HardcodedApacheSshdCredentials.java | 6 +- .../tests/HardcodedAzureCredentials.java | 6 +- .../HardcodedCredentialsApiCall.expected | 234 ------------------ .../tests/HardcodedCredentialsApiCall.ql | 20 ++ .../tests/HardcodedCredentialsApiCall.qlref | 1 - .../HardcodedCredentialsComparison.expected | 1 - .../tests/HardcodedCredentialsComparison.ql | 18 ++ .../HardcodedCredentialsComparison.qlref | 1 - .../HardcodedCredentialsSourceCall.expected | 106 -------- .../tests/HardcodedCredentialsSourceCall.ql | 20 ++ .../HardcodedCredentialsSourceCall.qlref | 1 - .../HardcodedGanymedSsh2Credentials.java | 2 +- .../tests/HardcodedJ2sshCredentials.java | 6 +- .../tests/HardcodedJschCredentials.java | 8 +- .../tests/HardcodedMongoCredentials.java | 12 +- .../tests/HardcodedPasswordField.expected | 1 - .../semmle/tests/HardcodedPasswordField.ql | 18 ++ .../semmle/tests/HardcodedPasswordField.qlref | 1 - .../semmle/tests/HardcodedShiroKey.java | 8 +- .../tests/HardcodedSshjCredentials.java | 4 +- .../tests/HardcodedTrileadSshCredentials.java | 14 +- .../security/CWE-798/semmle/tests/Test.java | 20 +- .../security/CWE-798/semmle/tests/User.java | 2 +- 30 files changed, 131 insertions(+), 401 deletions(-) rename java/ql/lib/semmle/code/java/security/{HardcodedCredentialsSourceCall.qll => HardcodedCredentialsSourceCallQuery.qll} (100%) create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql delete mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.qlref create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.ql delete mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.qlref create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.ql delete mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.qlref create mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.ql delete mode 100644 java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.qlref diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCall.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll similarity index 100% rename from java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCall.qll rename to java/ql/lib/semmle/code/java/security/HardcodedCredentialsSourceCallQuery.qll diff --git a/java/ql/lib/semmle/code/java/security/SensitiveApi.qll b/java/ql/lib/semmle/code/java/security/SensitiveApi.qll index 64b19aa13b0..80b14a4ac1d 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveApi.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveApi.qll @@ -442,8 +442,8 @@ private predicate otherApiCallableCredentialParam(string s) { "com.jcraft.jsch.JSch;getSession(String, String, int);0", "com.jcraft.jsch.JSch;getSession(String, String);0", "ch.ethz.ssh2.Connection;authenticateWithPassword(String, String);0", - "org.apache.sshd.client.SshClient;connect(String, String, int);0", - "org.apache.sshd.client.SshClient;connect(String, SocketAddress);0", + "org.apache.sshd.client.session.ClientSessionCreator;connect(String, String, int);0", + "org.apache.sshd.client.session.ClientSessionCreator;connect(String, SocketAddress);0", "net.schmizz.sshj.SSHClient;authPassword(String, char[]);0", "net.schmizz.sshj.SSHClient;authPassword(String, String);0", "com.sshtools.j2ssh.authentication.SshAuthenticationClient;setUsername(String);0", diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql index 6b5c78c1f05..33acad610ff 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql @@ -11,7 +11,7 @@ */ import java -import semmle.code.java.security.HardcodedCredentialsSourceCall +import semmle.code.java.security.HardcodedCredentialsSourceCallQuery import DataFlow::PathGraph from diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/CredentialsTest.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/CredentialsTest.java index 643aed69042..71d122ab0ad 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/CredentialsTest.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/CredentialsTest.java @@ -10,11 +10,11 @@ public class CredentialsTest { String url = "jdbc:mysql://localhost/test"; String u = "admin"; // hard-coded credential (flow source) - DriverManager.getConnection(url, u, p); // sensitive call (flow target) + DriverManager.getConnection(url, u, p); // $ HardcodedCredentialsApiCall test(url, u, p); } public static void test(String url, String v, String q) throws SQLException { - DriverManager.getConnection(url, v, q); // sensitive call (flow target) + DriverManager.getConnection(url, v, q); // $ HardcodedCredentialsApiCall } } diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/FileCredentialTest.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/FileCredentialTest.java index 47dd451fa30..593295ebf3c 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/FileCredentialTest.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/FileCredentialTest.java @@ -15,12 +15,12 @@ public class FileCredentialTest { String p = readText(new File(file)); - DriverManager.getConnection("", "admin", p); // sensitive call (flow target) + DriverManager.getConnection("", "admin", p); // $ HardcodedCredentialsApiCall test(url, u, p); } public static void test(String url, String v, String q) throws SQLException { - DriverManager.getConnection(url, v, q); // sensitive call (flow target) + DriverManager.getConnection(url, v, q); // $ HardcodedCredentialsApiCall } public static String readText(File f) throws IOException diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAWSCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAWSCredentials.java index 4a853250618..b34ab8c0539 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAWSCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAWSCredentials.java @@ -4,7 +4,7 @@ import com.amazonaws.auth.BasicAWSCredentials; public class HardcodedAWSCredentials { public static void main(String[] args) { //BAD: Hardcoded credentials for connecting to AWS services - //To fix the problem, use other approaches including AWS credentials file, environment variables, or instance/container credentials instead - AWSCredentials creds = new BasicAWSCredentials("ACCESS_KEY", "SECRET_KEY"); + //To fix the problem, use other approaches including AWS credentials file, environment variables, or instance/container credentials instead + AWSCredentials creds = new BasicAWSCredentials("ACCESS_KEY", "SECRET_KEY"); // $ HardcodedCredentialsApiCall } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheFtpCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheFtpCredentials.java index b62cd2f3d66..102e8192503 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheFtpCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheFtpCredentials.java @@ -6,8 +6,8 @@ public class HardcodedApacheFtpCredentials { public static void main(FTPClient client) { // BAD: Hardcoded credentials used for the session username and/or password. try { - client.login("username", "password"); - client.login("username", "password", "blah"); + client.login("username", "password"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + client.login("username", "password", "blah"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall } catch(IOException e) { } } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheSshdCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheSshdCredentials.java index 756c74945b3..ac1538e7e2f 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheSshdCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedApacheSshdCredentials.java @@ -5,8 +5,8 @@ import java.io.IOException; public class HardcodedApacheSshdCredentials { public static void main(SshClient client, AbstractClientSession session) { // BAD: Hardcoded credentials used for the session username and/or password. - client.connect("Username", "hostname", 22); - client.connect("Username", null); - session.addPasswordIdentity("password"); + client.connect("Username", "hostname", 22); // $ HardcodedCredentialsApiCall + client.connect("Username", null); // $ HardcodedCredentialsApiCall + session.addPasswordIdentity("password"); // $ HardcodedCredentialsApiCall } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAzureCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAzureCredentials.java index d243e18d608..712d28e1af8 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAzureCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAzureCredentials.java @@ -15,8 +15,8 @@ public class HardcodedAzureCredentials { public void testHardcodedUsernamePassword(String input) { UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredentialBuilder() .clientId(clientId) - .username(username) - .password(clientSecret) + .username(username) // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + .password(clientSecret) // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall .build(); SecretClient client = new SecretClientBuilder() @@ -43,7 +43,7 @@ public class HardcodedAzureCredentials { public void testHardcodedClientSecret(String input) { ClientSecretCredential defaultCredential = new ClientSecretCredentialBuilder() .clientId(clientId) - .clientSecret(clientSecret) + .clientSecret(clientSecret) // $ HardcodedCredentialsApiCall .tenantId(tenantId) .build(); } diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected index 1b304a9fffb..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected @@ -1,234 +0,0 @@ -edges -| CredentialsTest.java:7:30:7:30 | p : String | CredentialsTest.java:13:39:13:39 | p | -| CredentialsTest.java:7:30:7:30 | p : String | CredentialsTest.java:14:16:14:16 | p : String | -| CredentialsTest.java:7:34:7:41 | "123456" : String | CredentialsTest.java:7:30:7:30 | p : String | -| CredentialsTest.java:11:14:11:20 | "admin" : String | CredentialsTest.java:13:36:13:36 | u | -| CredentialsTest.java:11:14:11:20 | "admin" : String | CredentialsTest.java:14:13:14:13 | u : String | -| CredentialsTest.java:14:13:14:13 | u : String | CredentialsTest.java:17:38:17:45 | v : String | -| CredentialsTest.java:14:16:14:16 | p : String | CredentialsTest.java:17:48:17:55 | q : String | -| CredentialsTest.java:17:38:17:45 | v : String | CredentialsTest.java:18:36:18:36 | v | -| CredentialsTest.java:17:48:17:55 | q : String | CredentialsTest.java:18:39:18:39 | q | -| FileCredentialTest.java:13:14:13:20 | "admin" : String | FileCredentialTest.java:19:13:19:13 | u : String | -| FileCredentialTest.java:19:13:19:13 | u : String | FileCredentialTest.java:22:38:22:45 | v : String | -| FileCredentialTest.java:22:38:22:45 | v : String | FileCredentialTest.java:23:36:23:36 | v | -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | -| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | -| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | -| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | -| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | -| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | -| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | -| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | username | -| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | -| HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String | -| HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | -| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | -| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | -| HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | -| HardcodedJschCredentials.java:13:28:13:37 | "password" : String | HardcodedJschCredentials.java:13:28:13:48 | getBytes(...) | -| HardcodedMongoCredentials.java:5:58:5:67 | "password" : String | HardcodedMongoCredentials.java:5:58:5:81 | toCharArray(...) | -| HardcodedMongoCredentials.java:6:65:6:74 | "password" : String | HardcodedMongoCredentials.java:6:65:6:88 | toCharArray(...) | -| HardcodedMongoCredentials.java:7:63:7:72 | "password" : String | HardcodedMongoCredentials.java:7:63:7:86 | toCharArray(...) | -| HardcodedMongoCredentials.java:8:67:8:76 | "password" : String | HardcodedMongoCredentials.java:8:67:8:90 | toCharArray(...) | -| HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | -| HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | HardcodedShiroKey.java:18:46:18:87 | decode(...) | -| HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | HardcodedShiroKey.java:26:46:26:109 | decode(...) | -| HardcodedSshjCredentials.java:9:39:9:48 | "password" : String | HardcodedSshjCredentials.java:9:39:9:62 | toCharArray(...) | -| HardcodedTrileadSshCredentials.java:15:50:15:54 | "key" : String | HardcodedTrileadSshCredentials.java:15:50:15:68 | toCharArray(...) | -| Test.java:9:16:9:22 | "admin" : String | Test.java:12:13:12:15 | usr : String | -| Test.java:9:16:9:22 | "admin" : String | Test.java:15:36:15:38 | usr | -| Test.java:9:16:9:22 | "admin" : String | Test.java:17:39:17:41 | usr | -| Test.java:9:16:9:22 | "admin" : String | Test.java:18:39:18:41 | usr | -| Test.java:10:17:10:24 | "123456" : String | Test.java:12:18:12:21 | pass : String | -| Test.java:10:17:10:24 | "123456" : String | Test.java:15:41:15:44 | pass | -| Test.java:10:17:10:24 | "123456" : String | Test.java:18:44:18:61 | toCharArray(...) | -| Test.java:12:13:12:15 | usr : String | Test.java:29:38:29:48 | user : String | -| Test.java:12:18:12:21 | pass : String | Test.java:29:51:29:65 | password : String | -| Test.java:17:44:17:51 | "123456" : String | Test.java:17:44:17:65 | toCharArray(...) | -| Test.java:20:16:20:39 | new byte[] : byte[] | Test.java:21:78:21:80 | key | -| Test.java:23:17:23:26 | "abcdefgh" : String | Test.java:24:79:24:82 | key2 | -| Test.java:29:38:29:48 | user : String | Test.java:30:36:30:39 | user | -| Test.java:29:51:29:65 | password : String | Test.java:30:42:30:49 | password | -nodes -| CredentialsTest.java:7:30:7:30 | p : String | semmle.label | p : String | -| CredentialsTest.java:7:34:7:41 | "123456" : String | semmle.label | "123456" : String | -| CredentialsTest.java:11:14:11:20 | "admin" : String | semmle.label | "admin" : String | -| CredentialsTest.java:13:36:13:36 | u | semmle.label | u | -| CredentialsTest.java:13:39:13:39 | p | semmle.label | p | -| CredentialsTest.java:14:13:14:13 | u : String | semmle.label | u : String | -| CredentialsTest.java:14:16:14:16 | p : String | semmle.label | p : String | -| CredentialsTest.java:17:38:17:45 | v : String | semmle.label | v : String | -| CredentialsTest.java:17:48:17:55 | q : String | semmle.label | q : String | -| CredentialsTest.java:18:36:18:36 | v | semmle.label | v | -| CredentialsTest.java:18:39:18:39 | q | semmle.label | q | -| FileCredentialTest.java:13:14:13:20 | "admin" : String | semmle.label | "admin" : String | -| FileCredentialTest.java:18:35:18:41 | "admin" | semmle.label | "admin" | -| FileCredentialTest.java:19:13:19:13 | u : String | semmle.label | u : String | -| FileCredentialTest.java:22:38:22:45 | v : String | semmle.label | v : String | -| FileCredentialTest.java:23:36:23:36 | v | semmle.label | v | -| HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | semmle.label | "ACCESS_KEY" | -| HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | semmle.label | "SECRET_KEY" | -| HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | semmle.label | "username" | -| HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | semmle.label | "password" | -| HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | semmle.label | "username" | -| HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | semmle.label | "password" | -| HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | semmle.label | "password" | -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | semmle.label | this <.method> [post update] [clientSecret] : String | -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | semmle.label | this <.method> [post update] [username] : String | -| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | semmle.label | this <.field> [post update] [username] : String | -| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | semmle.label | "username@example.onmicrosoft.com" : String | -| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | semmle.label | this <.field> [post update] [clientSecret] : String | -| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | semmle.label | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | -| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | semmle.label | parameter this [clientSecret] : String | -| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | semmle.label | parameter this [username] : String | -| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | semmle.label | this <.field> [username] : String | -| HardcodedAzureCredentials.java:18:13:18:20 | username | semmle.label | username | -| HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | semmle.label | clientSecret | -| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String | -| HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | semmle.label | parameter this [clientSecret] : String | -| HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | semmle.label | clientSecret | -| HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String | -| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | -| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | semmle.label | new HardcodedAzureCredentials(...) [username] : String | -| HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | -| HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | semmle.label | "username" | -| HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | semmle.label | "password" | -| HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | semmle.label | "Username" | -| HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | semmle.label | "Username" | -| HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | semmle.label | "password" | -| HardcodedJschCredentials.java:10:41:10:50 | "Username" | semmle.label | "Username" | -| HardcodedJschCredentials.java:11:42:11:51 | "Username" | semmle.label | "Username" | -| HardcodedJschCredentials.java:12:27:12:36 | "password" | semmle.label | "password" | -| HardcodedJschCredentials.java:13:28:13:37 | "password" : String | semmle.label | "password" : String | -| HardcodedJschCredentials.java:13:28:13:48 | getBytes(...) | semmle.label | getBytes(...) | -| HardcodedMongoCredentials.java:5:38:5:47 | "Username" | semmle.label | "Username" | -| HardcodedMongoCredentials.java:5:58:5:67 | "password" : String | semmle.label | "password" : String | -| HardcodedMongoCredentials.java:5:58:5:81 | toCharArray(...) | semmle.label | toCharArray(...) | -| HardcodedMongoCredentials.java:6:45:6:54 | "Username" | semmle.label | "Username" | -| HardcodedMongoCredentials.java:6:65:6:74 | "password" : String | semmle.label | "password" : String | -| HardcodedMongoCredentials.java:6:65:6:88 | toCharArray(...) | semmle.label | toCharArray(...) | -| HardcodedMongoCredentials.java:7:43:7:52 | "Username" | semmle.label | "Username" | -| HardcodedMongoCredentials.java:7:63:7:72 | "password" : String | semmle.label | "password" : String | -| HardcodedMongoCredentials.java:7:63:7:86 | toCharArray(...) | semmle.label | toCharArray(...) | -| HardcodedMongoCredentials.java:8:47:8:56 | "Username" | semmle.label | "Username" | -| HardcodedMongoCredentials.java:8:67:8:76 | "password" : String | semmle.label | "password" : String | -| HardcodedMongoCredentials.java:8:67:8:90 | toCharArray(...) | semmle.label | toCharArray(...) | -| HardcodedMongoCredentials.java:9:44:9:48 | "key" | semmle.label | "key" | -| HardcodedMongoCredentials.java:10:47:10:51 | "key" | semmle.label | "key" | -| HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | semmle.label | "TEST123" : String | -| HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | semmle.label | getBytes(...) | -| HardcodedShiroKey.java:18:46:18:87 | decode(...) | semmle.label | decode(...) | -| HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | semmle.label | "4AvVhmFLUs0KTA3Kprsdag==" : String | -| HardcodedShiroKey.java:26:46:26:109 | decode(...) | semmle.label | decode(...) | -| HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | semmle.label | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | -| HardcodedSshjCredentials.java:8:25:8:34 | "Username" | semmle.label | "Username" | -| HardcodedSshjCredentials.java:8:37:8:46 | "password" | semmle.label | "password" | -| HardcodedSshjCredentials.java:9:27:9:36 | "Username" | semmle.label | "Username" | -| HardcodedSshjCredentials.java:9:39:9:48 | "password" : String | semmle.label | "password" : String | -| HardcodedSshjCredentials.java:9:39:9:62 | toCharArray(...) | semmle.label | toCharArray(...) | -| HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | semmle.label | "password" | -| HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | semmle.label | "password" | -| HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | semmle.label | "key" | -| HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:15:50:15:54 | "key" : String | semmle.label | "key" : String | -| HardcodedTrileadSshCredentials.java:15:50:15:68 | toCharArray(...) | semmle.label | toCharArray(...) | -| HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | semmle.label | "password" | -| HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | semmle.label | "password" | -| Test.java:9:16:9:22 | "admin" : String | semmle.label | "admin" : String | -| Test.java:10:17:10:24 | "123456" : String | semmle.label | "123456" : String | -| Test.java:12:13:12:15 | usr : String | semmle.label | usr : String | -| Test.java:12:18:12:21 | pass : String | semmle.label | pass : String | -| Test.java:14:36:14:42 | "admin" | semmle.label | "admin" | -| Test.java:14:45:14:52 | "123456" | semmle.label | "123456" | -| Test.java:15:36:15:38 | usr | semmle.label | usr | -| Test.java:15:41:15:44 | pass | semmle.label | pass | -| Test.java:17:39:17:41 | usr | semmle.label | usr | -| Test.java:17:44:17:51 | "123456" : String | semmle.label | "123456" : String | -| Test.java:17:44:17:65 | toCharArray(...) | semmle.label | toCharArray(...) | -| Test.java:18:39:18:41 | usr | semmle.label | usr | -| Test.java:18:44:18:61 | toCharArray(...) | semmle.label | toCharArray(...) | -| Test.java:20:16:20:39 | new byte[] : byte[] | semmle.label | new byte[] : byte[] | -| Test.java:21:78:21:80 | key | semmle.label | key | -| Test.java:23:17:23:26 | "abcdefgh" : String | semmle.label | "abcdefgh" : String | -| Test.java:24:79:24:82 | key2 | semmle.label | key2 | -| Test.java:29:38:29:48 | user : String | semmle.label | user : String | -| Test.java:29:51:29:65 | password : String | semmle.label | password : String | -| Test.java:30:36:30:39 | user | semmle.label | user | -| Test.java:30:42:30:49 | password | semmle.label | password | -subpaths -#select -| CredentialsTest.java:7:34:7:41 | "123456" | CredentialsTest.java:7:34:7:41 | "123456" : String | CredentialsTest.java:13:39:13:39 | p | Hard-coded value flows to $@. | CredentialsTest.java:13:39:13:39 | p | sensitive API call | -| CredentialsTest.java:7:34:7:41 | "123456" | CredentialsTest.java:7:34:7:41 | "123456" : String | CredentialsTest.java:18:39:18:39 | q | Hard-coded value flows to $@. | CredentialsTest.java:18:39:18:39 | q | sensitive API call | -| CredentialsTest.java:11:14:11:20 | "admin" | CredentialsTest.java:11:14:11:20 | "admin" : String | CredentialsTest.java:13:36:13:36 | u | Hard-coded value flows to $@. | CredentialsTest.java:13:36:13:36 | u | sensitive API call | -| CredentialsTest.java:11:14:11:20 | "admin" | CredentialsTest.java:11:14:11:20 | "admin" : String | CredentialsTest.java:18:36:18:36 | v | Hard-coded value flows to $@. | CredentialsTest.java:18:36:18:36 | v | sensitive API call | -| FileCredentialTest.java:13:14:13:20 | "admin" | FileCredentialTest.java:13:14:13:20 | "admin" : String | FileCredentialTest.java:23:36:23:36 | v | Hard-coded value flows to $@. | FileCredentialTest.java:23:36:23:36 | v | sensitive API call | -| FileCredentialTest.java:18:35:18:41 | "admin" | FileCredentialTest.java:18:35:18:41 | "admin" | FileCredentialTest.java:18:35:18:41 | "admin" | Hard-coded value flows to $@. | FileCredentialTest.java:18:35:18:41 | "admin" | sensitive API call | -| HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | Hard-coded value flows to $@. | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | sensitive API call | -| HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | Hard-coded value flows to $@. | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | sensitive API call | -| HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | sensitive API call | -| HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | sensitive API call | -| HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | sensitive API call | -| HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | sensitive API call | -| HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | Hard-coded value flows to $@. | HardcodedApacheSshdCredentials.java:10:33:10:42 | "password" | sensitive API call | -| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" | HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:18:13:18:20 | username | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:18:13:18:20 | username | sensitive API call | -| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | sensitive API call | -| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | sensitive API call | -| HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | Hard-coded value flows to $@. | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | sensitive API call | -| HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | Hard-coded value flows to $@. | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | sensitive API call | -| HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | sensitive API call | -| HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | sensitive API call | -| HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | sensitive API call | -| HardcodedJschCredentials.java:10:41:10:50 | "Username" | HardcodedJschCredentials.java:10:41:10:50 | "Username" | HardcodedJschCredentials.java:10:41:10:50 | "Username" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:10:41:10:50 | "Username" | sensitive API call | -| HardcodedJschCredentials.java:11:42:11:51 | "Username" | HardcodedJschCredentials.java:11:42:11:51 | "Username" | HardcodedJschCredentials.java:11:42:11:51 | "Username" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:11:42:11:51 | "Username" | sensitive API call | -| HardcodedJschCredentials.java:12:27:12:36 | "password" | HardcodedJschCredentials.java:12:27:12:36 | "password" | HardcodedJschCredentials.java:12:27:12:36 | "password" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:12:27:12:36 | "password" | sensitive API call | -| HardcodedJschCredentials.java:13:28:13:37 | "password" | HardcodedJschCredentials.java:13:28:13:37 | "password" : String | HardcodedJschCredentials.java:13:28:13:48 | getBytes(...) | Hard-coded value flows to $@. | HardcodedJschCredentials.java:13:28:13:48 | getBytes(...) | sensitive API call | -| HardcodedMongoCredentials.java:5:38:5:47 | "Username" | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | sensitive API call | -| HardcodedMongoCredentials.java:5:58:5:67 | "password" | HardcodedMongoCredentials.java:5:58:5:67 | "password" : String | HardcodedMongoCredentials.java:5:58:5:81 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:5:58:5:81 | toCharArray(...) | sensitive API call | -| HardcodedMongoCredentials.java:6:45:6:54 | "Username" | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | sensitive API call | -| HardcodedMongoCredentials.java:6:65:6:74 | "password" | HardcodedMongoCredentials.java:6:65:6:74 | "password" : String | HardcodedMongoCredentials.java:6:65:6:88 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:6:65:6:88 | toCharArray(...) | sensitive API call | -| HardcodedMongoCredentials.java:7:43:7:52 | "Username" | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | sensitive API call | -| HardcodedMongoCredentials.java:7:63:7:72 | "password" | HardcodedMongoCredentials.java:7:63:7:72 | "password" : String | HardcodedMongoCredentials.java:7:63:7:86 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:7:63:7:86 | toCharArray(...) | sensitive API call | -| HardcodedMongoCredentials.java:8:47:8:56 | "Username" | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | sensitive API call | -| HardcodedMongoCredentials.java:8:67:8:76 | "password" | HardcodedMongoCredentials.java:8:67:8:76 | "password" : String | HardcodedMongoCredentials.java:8:67:8:90 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:8:67:8:90 | toCharArray(...) | sensitive API call | -| HardcodedMongoCredentials.java:9:44:9:48 | "key" | HardcodedMongoCredentials.java:9:44:9:48 | "key" | HardcodedMongoCredentials.java:9:44:9:48 | "key" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:9:44:9:48 | "key" | sensitive API call | -| HardcodedMongoCredentials.java:10:47:10:51 | "key" | HardcodedMongoCredentials.java:10:47:10:51 | "key" | HardcodedMongoCredentials.java:10:47:10:51 | "key" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:10:47:10:51 | "key" | sensitive API call | -| HardcodedShiroKey.java:9:46:9:54 | "TEST123" | HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | sensitive API call | -| HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" | HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | HardcodedShiroKey.java:18:46:18:87 | decode(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:18:46:18:87 | decode(...) | sensitive API call | -| HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" | HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | HardcodedShiroKey.java:26:46:26:109 | decode(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:26:46:26:109 | decode(...) | sensitive API call | -| HardcodedSshjCredentials.java:8:25:8:34 | "Username" | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | sensitive API call | -| HardcodedSshjCredentials.java:8:37:8:46 | "password" | HardcodedSshjCredentials.java:8:37:8:46 | "password" | HardcodedSshjCredentials.java:8:37:8:46 | "password" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:8:37:8:46 | "password" | sensitive API call | -| HardcodedSshjCredentials.java:9:27:9:36 | "Username" | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | sensitive API call | -| HardcodedSshjCredentials.java:9:39:9:48 | "password" | HardcodedSshjCredentials.java:9:39:9:48 | "password" : String | HardcodedSshjCredentials.java:9:39:9:62 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:9:39:9:62 | toCharArray(...) | sensitive API call | -| HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | sensitive API call | -| HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | sensitive API call | -| HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | sensitive API call | -| HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:44:11:53 | "password" | sensitive API call | -| HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | sensitive API call | -| HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | sensitive API call | -| HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | sensitive API call | -| HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | sensitive API call | -| HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | sensitive API call | -| HardcodedTrileadSshCredentials.java:15:50:15:54 | "key" | HardcodedTrileadSshCredentials.java:15:50:15:54 | "key" : String | HardcodedTrileadSshCredentials.java:15:50:15:68 | toCharArray(...) | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:50:15:68 | toCharArray(...) | sensitive API call | -| HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | sensitive API call | -| HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | sensitive API call | -| HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | sensitive API call | -| Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:15:36:15:38 | usr | Hard-coded value flows to $@. | Test.java:15:36:15:38 | usr | sensitive API call | -| Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:17:39:17:41 | usr | Hard-coded value flows to $@. | Test.java:17:39:17:41 | usr | sensitive API call | -| Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:18:39:18:41 | usr | Hard-coded value flows to $@. | Test.java:18:39:18:41 | usr | sensitive API call | -| Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:30:36:30:39 | user | Hard-coded value flows to $@. | Test.java:30:36:30:39 | user | sensitive API call | -| Test.java:10:17:10:24 | "123456" | Test.java:10:17:10:24 | "123456" : String | Test.java:15:41:15:44 | pass | Hard-coded value flows to $@. | Test.java:15:41:15:44 | pass | sensitive API call | -| Test.java:10:17:10:24 | "123456" | Test.java:10:17:10:24 | "123456" : String | Test.java:18:44:18:61 | toCharArray(...) | Hard-coded value flows to $@. | Test.java:18:44:18:61 | toCharArray(...) | sensitive API call | -| Test.java:10:17:10:24 | "123456" | Test.java:10:17:10:24 | "123456" : String | Test.java:30:42:30:49 | password | Hard-coded value flows to $@. | Test.java:30:42:30:49 | password | sensitive API call | -| Test.java:14:36:14:42 | "admin" | Test.java:14:36:14:42 | "admin" | Test.java:14:36:14:42 | "admin" | Hard-coded value flows to $@. | Test.java:14:36:14:42 | "admin" | sensitive API call | -| Test.java:14:45:14:52 | "123456" | Test.java:14:45:14:52 | "123456" | Test.java:14:45:14:52 | "123456" | Hard-coded value flows to $@. | Test.java:14:45:14:52 | "123456" | sensitive API call | -| Test.java:17:44:17:51 | "123456" | Test.java:17:44:17:51 | "123456" : String | Test.java:17:44:17:65 | toCharArray(...) | Hard-coded value flows to $@. | Test.java:17:44:17:65 | toCharArray(...) | sensitive API call | -| Test.java:20:16:20:39 | new byte[] | Test.java:20:16:20:39 | new byte[] : byte[] | Test.java:21:78:21:80 | key | Hard-coded value flows to $@. | Test.java:21:78:21:80 | key | sensitive API call | -| Test.java:23:17:23:26 | "abcdefgh" | Test.java:23:17:23:26 | "abcdefgh" : String | Test.java:24:79:24:82 | key2 | Hard-coded value flows to $@. | Test.java:24:79:24:82 | key2 | sensitive API call | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql new file mode 100644 index 00000000000..79ce1738f38 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql @@ -0,0 +1,20 @@ +import java +import semmle.code.java.security.HardcodedCredentialsApiCallQuery +import TestUtilities.InlineExpectationsTest + +class HardcodedCredentialsApiCallTest extends InlineExpectationsTest { + HardcodedCredentialsApiCallTest() { this = "HardcodedCredentialsApiCallTest" } + + override string getARelevantTag() { result = "HardcodedCredentialsApiCall" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "HardcodedCredentialsApiCall" and + exists(DataFlow::Node sink, HardcodedCredentialApiCallConfiguration conf | + conf.hasFlow(_, sink) + | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.qlref b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.qlref deleted file mode 100644 index 612729bd618..00000000000 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected index bd33fa49982..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.expected @@ -1 +0,0 @@ -| Test.java:36:26:36:32 | "admin" | Hard-coded value is $@ with password variable $@. | Test.java:36:10:36:33 | equals(...) | compared | Test.java:35:38:35:52 | password | password | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.ql new file mode 100644 index 00000000000..bde1851e43c --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.ql @@ -0,0 +1,18 @@ +import java +import semmle.code.java.security.HardcodedCredentialsComparison +import TestUtilities.InlineExpectationsTest + +class HardcodedCredentialsComparisonTest extends InlineExpectationsTest { + HardcodedCredentialsComparisonTest() { this = "HardcodedCredentialsComparisonTest" } + + override string getARelevantTag() { result = "HardcodedCredentialsComparison" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "HardcodedCredentialsComparison" and + exists(Expr sink | isHardcodedCredentialsComparison(sink, _, _) | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.qlref b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.qlref deleted file mode 100644 index a50b09e6e30..00000000000 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsComparison.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE/CWE-798/HardcodedCredentialsComparison.ql \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected index 0b87b0c69c8..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected @@ -1,106 +0,0 @@ -edges -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | -| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | -| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | -| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | -| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | -| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | -| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | -| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | username | -| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | -| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | -| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | -| Test.java:10:17:10:24 | "123456" : String | Test.java:26:17:26:20 | pass | -| User.java:2:30:2:39 | DEFAULT_PW : String | User.java:5:15:5:24 | DEFAULT_PW | -| User.java:2:43:2:50 | "123456" : String | User.java:2:30:2:39 | DEFAULT_PW : String | -nodes -| HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | semmle.label | "username" | -| HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | semmle.label | "password" | -| HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | semmle.label | "username" | -| HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | semmle.label | "password" | -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | semmle.label | this <.method> [post update] [clientSecret] : String | -| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | semmle.label | this <.method> [post update] [username] : String | -| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | semmle.label | this <.field> [post update] [username] : String | -| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | semmle.label | "username@example.onmicrosoft.com" : String | -| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | semmle.label | this <.field> [post update] [clientSecret] : String | -| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | semmle.label | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | -| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | semmle.label | parameter this [clientSecret] : String | -| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | semmle.label | parameter this [username] : String | -| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | semmle.label | this <.field> [username] : String | -| HardcodedAzureCredentials.java:18:13:18:20 | username | semmle.label | username | -| HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | semmle.label | clientSecret | -| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String | -| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | -| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | semmle.label | new HardcodedAzureCredentials(...) [username] : String | -| HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | semmle.label | "username" | -| HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | semmle.label | "password" | -| HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | semmle.label | "Username" | -| HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | semmle.label | "Username" | -| HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | semmle.label | "password" | -| HardcodedJschCredentials.java:10:41:10:50 | "Username" | semmle.label | "Username" | -| HardcodedJschCredentials.java:11:42:11:51 | "Username" | semmle.label | "Username" | -| HardcodedJschCredentials.java:12:27:12:36 | "password" | semmle.label | "password" | -| HardcodedMongoCredentials.java:5:38:5:47 | "Username" | semmle.label | "Username" | -| HardcodedMongoCredentials.java:6:45:6:54 | "Username" | semmle.label | "Username" | -| HardcodedMongoCredentials.java:7:43:7:52 | "Username" | semmle.label | "Username" | -| HardcodedMongoCredentials.java:8:47:8:56 | "Username" | semmle.label | "Username" | -| HardcodedMongoCredentials.java:9:44:9:48 | "key" | semmle.label | "key" | -| HardcodedMongoCredentials.java:10:47:10:51 | "key" | semmle.label | "key" | -| HardcodedSshjCredentials.java:8:25:8:34 | "Username" | semmle.label | "Username" | -| HardcodedSshjCredentials.java:8:37:8:46 | "password" | semmle.label | "password" | -| HardcodedSshjCredentials.java:9:27:9:36 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | semmle.label | "password" | -| HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | semmle.label | "key" | -| HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | semmle.label | "password" | -| HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | semmle.label | "Username" | -| HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | semmle.label | "password" | -| Test.java:10:17:10:24 | "123456" : String | semmle.label | "123456" : String | -| Test.java:26:17:26:20 | pass | semmle.label | pass | -| User.java:2:30:2:39 | DEFAULT_PW : String | semmle.label | DEFAULT_PW : String | -| User.java:2:43:2:50 | "123456" : String | semmle.label | "123456" : String | -| User.java:5:15:5:24 | DEFAULT_PW | semmle.label | DEFAULT_PW | -subpaths -#select -| HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:9:20:9:29 | "username" | sensitive call | -| HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:9:32:9:41 | "password" | sensitive call | -| HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:10:20:10:29 | "username" | sensitive call | -| HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | Hard-coded value flows to $@. | HardcodedApacheFtpCredentials.java:10:32:10:41 | "password" | sensitive call | -| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" | HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:18:13:18:20 | username | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:18:13:18:20 | username | sensitive call | -| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | sensitive call | -| HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | Hard-coded value flows to $@. | HardcodedGanymedSsh2Credentials.java:8:35:8:44 | "username" | sensitive call | -| HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | Hard-coded value flows to $@. | HardcodedGanymedSsh2Credentials.java:8:47:8:56 | "password" | sensitive call | -| HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:7:25:7:34 | "Username" | sensitive call | -| HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:8:25:8:34 | "Username" | sensitive call | -| HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | Hard-coded value flows to $@. | HardcodedJ2sshCredentials.java:9:25:9:34 | "password" | sensitive call | -| HardcodedJschCredentials.java:10:41:10:50 | "Username" | HardcodedJschCredentials.java:10:41:10:50 | "Username" | HardcodedJschCredentials.java:10:41:10:50 | "Username" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:10:41:10:50 | "Username" | sensitive call | -| HardcodedJschCredentials.java:11:42:11:51 | "Username" | HardcodedJschCredentials.java:11:42:11:51 | "Username" | HardcodedJschCredentials.java:11:42:11:51 | "Username" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:11:42:11:51 | "Username" | sensitive call | -| HardcodedJschCredentials.java:12:27:12:36 | "password" | HardcodedJschCredentials.java:12:27:12:36 | "password" | HardcodedJschCredentials.java:12:27:12:36 | "password" | Hard-coded value flows to $@. | HardcodedJschCredentials.java:12:27:12:36 | "password" | sensitive call | -| HardcodedMongoCredentials.java:5:38:5:47 | "Username" | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:5:38:5:47 | "Username" | sensitive call | -| HardcodedMongoCredentials.java:6:45:6:54 | "Username" | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:6:45:6:54 | "Username" | sensitive call | -| HardcodedMongoCredentials.java:7:43:7:52 | "Username" | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:7:43:7:52 | "Username" | sensitive call | -| HardcodedMongoCredentials.java:8:47:8:56 | "Username" | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:8:47:8:56 | "Username" | sensitive call | -| HardcodedMongoCredentials.java:9:44:9:48 | "key" | HardcodedMongoCredentials.java:9:44:9:48 | "key" | HardcodedMongoCredentials.java:9:44:9:48 | "key" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:9:44:9:48 | "key" | sensitive call | -| HardcodedMongoCredentials.java:10:47:10:51 | "key" | HardcodedMongoCredentials.java:10:47:10:51 | "key" | HardcodedMongoCredentials.java:10:47:10:51 | "key" | Hard-coded value flows to $@. | HardcodedMongoCredentials.java:10:47:10:51 | "key" | sensitive call | -| HardcodedSshjCredentials.java:8:25:8:34 | "Username" | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:8:25:8:34 | "Username" | sensitive call | -| HardcodedSshjCredentials.java:8:37:8:46 | "password" | HardcodedSshjCredentials.java:8:37:8:46 | "password" | HardcodedSshjCredentials.java:8:37:8:46 | "password" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:8:37:8:46 | "password" | sensitive call | -| HardcodedSshjCredentials.java:9:27:9:36 | "Username" | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | Hard-coded value flows to $@. | HardcodedSshjCredentials.java:9:27:9:36 | "Username" | sensitive call | -| HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:10:37:10:46 | "Username" | sensitive call | -| HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:10:49:10:58 | "password" | sensitive call | -| HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:32:11:41 | "Username" | sensitive call | -| HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:11:56:11:60 | "key" | sensitive call | -| HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:12:33:12:42 | "Username" | sensitive call | -| HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:13:36:13:45 | "Username" | sensitive call | -| HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:14:34:14:43 | "Username" | sensitive call | -| HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:38:15:47 | "Username" | sensitive call | -| HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:15:71:15:80 | "password" | sensitive call | -| HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:16:38:16:47 | "Username" | sensitive call | -| HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | Hard-coded value flows to $@. | HardcodedTrileadSshCredentials.java:16:62:16:71 | "password" | sensitive call | -| Test.java:10:17:10:24 | "123456" | Test.java:10:17:10:24 | "123456" : String | Test.java:26:17:26:20 | pass | Hard-coded value flows to $@. | Test.java:26:17:26:20 | pass | sensitive call | -| User.java:2:43:2:50 | "123456" | User.java:2:43:2:50 | "123456" : String | User.java:5:15:5:24 | DEFAULT_PW | Hard-coded value flows to $@. | User.java:5:15:5:24 | DEFAULT_PW | sensitive call | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.ql new file mode 100644 index 00000000000..3570dbe49e9 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.ql @@ -0,0 +1,20 @@ +import java +import semmle.code.java.security.HardcodedCredentialsSourceCallQuery +import TestUtilities.InlineExpectationsTest + +class HardcodedCredentialsSourceCallTest extends InlineExpectationsTest { + HardcodedCredentialsSourceCallTest() { this = "HardcodedCredentialsSourceCallTest" } + + override string getARelevantTag() { result = "HardcodedCredentialsSourceCall" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "HardcodedCredentialsSourceCall" and + exists(DataFlow::Node sink, HardcodedCredentialSourceCallConfiguration conf | + conf.hasFlow(_, sink) + | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.qlref b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.qlref deleted file mode 100644 index 7111a7a8d28..00000000000 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedGanymedSsh2Credentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedGanymedSsh2Credentials.java index b093a8b5f89..d45027c9ed5 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedGanymedSsh2Credentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedGanymedSsh2Credentials.java @@ -5,7 +5,7 @@ public class HardcodedGanymedSsh2Credentials { public static void main(Connection conn) { // BAD: Hardcoded credentials used for the session username and/or password. try { - conn.authenticateWithPassword("username", "password"); + conn.authenticateWithPassword("username", "password"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall } catch(IOException e) { } } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJ2sshCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJ2sshCredentials.java index 38831107966..8cf041929f6 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJ2sshCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJ2sshCredentials.java @@ -4,8 +4,8 @@ import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient; public class HardcodedJ2sshCredentials { public static void main(SshAuthenticationClient client1, PasswordAuthenticationClient client2) { // BAD: Hardcoded credentials used for the session username and/or password. - client1.setUsername("Username"); - client2.setUsername("Username"); - client2.setPassword("password"); + client1.setUsername("Username"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + client2.setUsername("Username"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + client2.setPassword("password"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJschCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJschCredentials.java index b2b50d1d452..18024b5dd3b 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJschCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedJschCredentials.java @@ -7,10 +7,10 @@ public class HardcodedJschCredentials { public static void main(JSch jsch) { // BAD: Hardcoded credentials used for the session username and/or password. try { - Session session = jsch.getSession("Username", "hostname"); - Session session2 = jsch.getSession("Username", "hostname", 22); - session.setPassword("password"); - session2.setPassword("password".getBytes()); + Session session = jsch.getSession("Username", "hostname"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + Session session2 = jsch.getSession("Username", "hostname", 22); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + session.setPassword("password"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + session2.setPassword("password".getBytes()); // $ HardcodedCredentialsApiCall } catch(JSchException e) { } } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedMongoCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedMongoCredentials.java index e08c96db945..fd08ac75d0c 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedMongoCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedMongoCredentials.java @@ -2,11 +2,11 @@ import com.mongodb.MongoCredential; public class HardcodedMongoCredentials { public static void test() { - MongoCredential.createCredential("Username", "blah", "password".toCharArray()); - MongoCredential.createMongoCRCredential("Username", "blah", "password".toCharArray()); - MongoCredential.createPlainCredential("Username", "blah", "password".toCharArray()); - MongoCredential.createScramSha1Credential("Username", "blah", "password".toCharArray()); - MongoCredential.createGSSAPICredential("key"); - MongoCredential.createMongoX509Credential("key"); + MongoCredential.createCredential("Username", "blah", "password".toCharArray()); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + MongoCredential.createMongoCRCredential("Username", "blah", "password".toCharArray()); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + MongoCredential.createPlainCredential("Username", "blah", "password".toCharArray()); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + MongoCredential.createScramSha1Credential("Username", "blah", "password".toCharArray()); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + MongoCredential.createGSSAPICredential("key"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + MongoCredential.createMongoX509Credential("key"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected index e5042b4f379..e69de29bb2d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.expected @@ -1 +0,0 @@ -| Test.java:33:29:33:36 | password | Sensitive field is assigned a hard-coded $@. | Test.java:33:40:33:56 | "myOtherPassword" | value | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.ql b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.ql new file mode 100644 index 00000000000..057bbbc2ab0 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.ql @@ -0,0 +1,18 @@ +import java +import semmle.code.java.security.HardcodedPasswordField +import TestUtilities.InlineExpectationsTest + +class HardcodedPasswordFieldTest extends InlineExpectationsTest { + HardcodedPasswordFieldTest() { this = "HardcodedPasswordFieldTest" } + + override string getARelevantTag() { result = "HardcodedPasswordField" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "HardcodedPasswordField" and + exists(Expr assigned | passwordFieldAssignedHardcodedValue(_, assigned) | + assigned.getLocation() = location and + element = assigned.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.qlref b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.qlref deleted file mode 100644 index 24a8f6428c1..00000000000 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedPasswordField.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE/CWE-798/HardcodedPasswordField.ql \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedShiroKey.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedShiroKey.java index 3647af01ed1..b3366f081e3 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedShiroKey.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedShiroKey.java @@ -6,16 +6,16 @@ public class HardcodedShiroKey { //BAD: hard-coded shiro key public void testHardcodedShiroKey(String input) { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); - cookieRememberMeManager.setCipherKey("TEST123".getBytes()); + cookieRememberMeManager.setCipherKey("TEST123".getBytes()); // $ HardcodedCredentialsApiCall } - //BAD: hard-coded shiro key encoded by java.util.Base64 + //BAD: hard-coded shiro key encoded by java.util.Base64 public void testHardcodedbase64ShiroKey1(String input) { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); java.util.Base64.Decoder decoder = java.util.Base64.getDecoder(); - cookieRememberMeManager.setCipherKey(decoder.decode("4AvVhmFLUs0KTA3Kprsdag==")); + cookieRememberMeManager.setCipherKey(decoder.decode("4AvVhmFLUs0KTA3Kprsdag==")); // $ HardcodedCredentialsApiCall } @@ -23,7 +23,7 @@ public class HardcodedShiroKey { //BAD: hard-coded shiro key encoded by org.apache.shiro.codec.Base64 public void testHardcodedbase64ShiroKey2(String input) { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); - cookieRememberMeManager.setCipherKey(org.apache.shiro.codec.Base64.decode("6ZmI6I2j5Y+R5aSn5ZOlAA==")); + cookieRememberMeManager.setCipherKey(org.apache.shiro.codec.Base64.decode("6ZmI6I2j5Y+R5aSn5ZOlAA==")); // $ HardcodedCredentialsApiCall } diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedSshjCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedSshjCredentials.java index d2222248053..4a063f35e56 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedSshjCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedSshjCredentials.java @@ -5,8 +5,8 @@ public class HardcodedSshjCredentials { public static void main(SSHClient client) { // BAD: Hardcoded credentials used for the session username and/or password. try { - client.authPassword("Username", "password"); - client.authPassword("Username", "password".toCharArray()); + client.authPassword("Username", "password"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + client.authPassword("Username", "password".toCharArray()); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall } catch(IOException e) { } } diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedTrileadSshCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedTrileadSshCredentials.java index 38279e49121..c8315621b4d 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedTrileadSshCredentials.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedTrileadSshCredentials.java @@ -7,13 +7,13 @@ public class HardcodedTrileadSshCredentials { public static void main(Connection conn) { // BAD: Hardcoded credentials used for the session username and/or password. try { - conn.authenticateWithPassword("Username", "password"); - conn.authenticateWithDSA("Username", "password", "key"); - conn.authenticateWithNone("Username"); - conn.getRemainingAuthMethods("Username"); - conn.isAuthMethodAvailable("Username", "method"); - conn.authenticateWithPublicKey("Username", "key".toCharArray(), "password"); - conn.authenticateWithPublicKey("Username", (File)null, "password"); + conn.authenticateWithPassword("Username", "password"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + conn.authenticateWithDSA("Username", "password", "key"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + conn.authenticateWithNone("Username"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + conn.getRemainingAuthMethods("Username"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + conn.isAuthMethodAvailable("Username", "method"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + conn.authenticateWithPublicKey("Username", "key".toCharArray(), "password"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall + conn.authenticateWithPublicKey("Username", (File)null, "password"); // $ HardcodedCredentialsApiCall $ HardcodedCredentialsSourceCall } catch(IOException e) { } } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/Test.java index af147f14469..96f770d66f2 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/Test.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/Test.java @@ -11,28 +11,28 @@ public class Test { test(url, usr, pass); // flow through method - DriverManager.getConnection(url, "admin", "123456"); // hard-coded user/pass used directly in call - DriverManager.getConnection(url, usr, pass); // hard-coded user/pass flows into API call + DriverManager.getConnection(url, "admin", "123456"); // $ HardcodedCredentialsApiCall + DriverManager.getConnection(url, usr, pass); // $ HardcodedCredentialsApiCall - new java.net.PasswordAuthentication(usr, "123456".toCharArray()); // flow into char[] array - new java.net.PasswordAuthentication(usr, pass.toCharArray()); // flow through variable, then char[] array + new java.net.PasswordAuthentication(usr, "123456".toCharArray()); // $ HardcodedCredentialsApiCall + new java.net.PasswordAuthentication(usr, pass.toCharArray()); // $ HardcodedCredentialsApiCall byte[] key = {1, 2, 3, 4, 5, 6, 7, 8}; // hard-coded cryptographic key, flowing into API call below - javax.crypto.spec.SecretKeySpec spec = new javax.crypto.spec.SecretKeySpec(key, "AES"); + javax.crypto.spec.SecretKeySpec spec = new javax.crypto.spec.SecretKeySpec(key, "AES"); // $ HardcodedCredentialsApiCall byte[] key2 = "abcdefgh".getBytes(); // hard-coded cryptographic key, flowing into API call below - javax.crypto.spec.SecretKeySpec spec2 = new javax.crypto.spec.SecretKeySpec(key2, "AES"); + javax.crypto.spec.SecretKeySpec spec2 = new javax.crypto.spec.SecretKeySpec(key2, "AES"); // $ HardcodedCredentialsApiCall - passwordCheck(pass); // flow through + passwordCheck(pass); // $ HardcodedCredentialsSourceCall } public static void test(String url, String user, String password) throws SQLException { - DriverManager.getConnection(url, user, password); // sensitive API call (flow target) + DriverManager.getConnection(url, user, password); // $ HardcodedCredentialsApiCall } - public static final String password = "myOtherPassword"; // hard-coded password + public static final String password = "myOtherPassword"; // $ HardcodedPasswordField public static boolean passwordCheck(String password) { - return password.equals("admin"); // hard-coded password comparison + return password.equals("admin"); // $ HardcodedCredentialsComparison } } diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/User.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/User.java index 2bb1944317a..65ef5582c58 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/User.java +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/User.java @@ -2,7 +2,7 @@ class User { private static final String DEFAULT_PW = "123456"; // hard-coded password private String pw; public User() { - setPassword(DEFAULT_PW); // sensitive call + setPassword(DEFAULT_PW); // $ HardcodedCredentialsSourceCall } public void setPassword(String password) { pw = password; From 8bea2a5f6ce16cf499ff40a34007decde1f3951e Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sat, 13 Aug 2022 14:20:48 +0100 Subject: [PATCH 018/659] Add missing qldoc --- .../ql/lib/semmle/code/java/security/HardcodedCredentials.qll | 4 ++++ java/ql/lib/semmle/code/java/security/SensitiveApi.qll | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentials.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentials.qll index 169bbf6778a..9dab56261ee 100644 --- a/java/ql/lib/semmle/code/java/security/HardcodedCredentials.qll +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentials.qll @@ -1,3 +1,7 @@ +/** + * Provides classes and predicates relating to hardcoded credentials. + */ + import java import SensitiveApi diff --git a/java/ql/lib/semmle/code/java/security/SensitiveApi.qll b/java/ql/lib/semmle/code/java/security/SensitiveApi.qll index 80b14a4ac1d..6435f63016f 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveApi.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveApi.qll @@ -1,3 +1,7 @@ +/** + * Provides predicates definining methods that consume sensitive data, such as usernames and passwords. + */ + import java /** From c5e46f78ecac32e2fddfdb59be5f43a7a2ff8bbe Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sat, 13 Aug 2022 14:29:17 +0100 Subject: [PATCH 019/659] Add change note --- .../change-notes/2022-08-13-more-hardcoded-credential-apis.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-08-13-more-hardcoded-credential-apis.md diff --git a/java/ql/lib/change-notes/2022-08-13-more-hardcoded-credential-apis.md b/java/ql/lib/change-notes/2022-08-13-more-hardcoded-credential-apis.md new file mode 100644 index 00000000000..7cacb393d35 --- /dev/null +++ b/java/ql/lib/change-notes/2022-08-13-more-hardcoded-credential-apis.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `java/hardcoded-credential-api-call` now recognises methods that consume usernames, passwords and keys from the JSch, Ganymed, Apache SSHD, sshj, Trilead SSH-2, Apache FTPClient and MongoDB projects. From ca4ef6578d9522efaae0b0652e0511b4c35036f5 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Sat, 13 Aug 2022 14:37:08 +0100 Subject: [PATCH 020/659] Spelling --- java/ql/lib/semmle/code/java/security/SensitiveApi.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveApi.qll b/java/ql/lib/semmle/code/java/security/SensitiveApi.qll index 6435f63016f..f9ba4f41ec5 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveApi.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveApi.qll @@ -1,5 +1,5 @@ /** - * Provides predicates definining methods that consume sensitive data, such as usernames and passwords. + * Provides predicates defining methods that consume sensitive data, such as usernames and passwords. */ import java From 38c0557d90b40bf8f0cb347e66eb08c82adf9e20 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 15 Aug 2022 11:06:06 +0100 Subject: [PATCH 021/659] Adjust test to moved and expanded stubs --- .../security/CWE-078/ExecTainted.expected | 14 +++---- .../security/CWE-078/JSchOSInjectionTest.java | 42 ++++++++++--------- .../query-tests/security/CWE-078/options | 2 +- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/java/ql/test/experimental/query-tests/security/CWE-078/ExecTainted.expected b/java/ql/test/experimental/query-tests/security/CWE-078/ExecTainted.expected index c3b0608c33e..682993380af 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-078/ExecTainted.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-078/ExecTainted.expected @@ -1,12 +1,12 @@ edges -| JSchOSInjectionTest.java:14:30:14:60 | getParameter(...) : String | JSchOSInjectionTest.java:26:48:26:64 | ... + ... | -| JSchOSInjectionTest.java:38:30:38:60 | getParameter(...) : String | JSchOSInjectionTest.java:50:32:50:48 | ... + ... | +| JSchOSInjectionTest.java:14:30:14:60 | getParameter(...) : String | JSchOSInjectionTest.java:27:52:27:68 | ... + ... | +| JSchOSInjectionTest.java:40:30:40:60 | getParameter(...) : String | JSchOSInjectionTest.java:53:36:53:52 | ... + ... | nodes | JSchOSInjectionTest.java:14:30:14:60 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| JSchOSInjectionTest.java:26:48:26:64 | ... + ... | semmle.label | ... + ... | -| JSchOSInjectionTest.java:38:30:38:60 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| JSchOSInjectionTest.java:50:32:50:48 | ... + ... | semmle.label | ... + ... | +| JSchOSInjectionTest.java:27:52:27:68 | ... + ... | semmle.label | ... + ... | +| JSchOSInjectionTest.java:40:30:40:60 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| JSchOSInjectionTest.java:53:36:53:52 | ... + ... | semmle.label | ... + ... | subpaths #select -| JSchOSInjectionTest.java:26:48:26:64 | ... + ... | JSchOSInjectionTest.java:14:30:14:60 | getParameter(...) : String | JSchOSInjectionTest.java:26:48:26:64 | ... + ... | $@ flows to here and is used in a command. | JSchOSInjectionTest.java:14:30:14:60 | getParameter(...) | User-provided value | -| JSchOSInjectionTest.java:50:32:50:48 | ... + ... | JSchOSInjectionTest.java:38:30:38:60 | getParameter(...) : String | JSchOSInjectionTest.java:50:32:50:48 | ... + ... | $@ flows to here and is used in a command. | JSchOSInjectionTest.java:38:30:38:60 | getParameter(...) | User-provided value | +| JSchOSInjectionTest.java:27:52:27:68 | ... + ... | JSchOSInjectionTest.java:14:30:14:60 | getParameter(...) : String | JSchOSInjectionTest.java:27:52:27:68 | ... + ... | $@ flows to here and is used in a command. | JSchOSInjectionTest.java:14:30:14:60 | getParameter(...) | User-provided value | +| JSchOSInjectionTest.java:53:36:53:52 | ... + ... | JSchOSInjectionTest.java:40:30:40:60 | getParameter(...) : String | JSchOSInjectionTest.java:53:36:53:52 | ... + ... | $@ flows to here and is used in a command. | JSchOSInjectionTest.java:40:30:40:60 | getParameter(...) | User-provided value | diff --git a/java/ql/test/experimental/query-tests/security/CWE-078/JSchOSInjectionTest.java b/java/ql/test/experimental/query-tests/security/CWE-078/JSchOSInjectionTest.java index 08baf0a9772..7b8c5a1181c 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-078/JSchOSInjectionTest.java +++ b/java/ql/test/experimental/query-tests/security/CWE-078/JSchOSInjectionTest.java @@ -17,17 +17,19 @@ public class JSchOSInjectionTest extends HttpServlet { config.put("StrictHostKeyChecking", "no"); JSch jsch = new JSch(); - Session session = jsch.getSession(user, host, 22); - session.setPassword(password); - session.setConfig(config); - session.connect(); + try { + Session session = jsch.getSession(user, host, 22); + session.setPassword(password); + session.setConfig(config); + session.connect(); - Channel channel = session.openChannel("exec"); - ((ChannelExec) channel).setCommand("ping " + command); - channel.setInputStream(null); - ((ChannelExec) channel).setErrStream(System.err); + Channel channel = session.openChannel("exec"); + ((ChannelExec) channel).setCommand("ping " + command); + channel.setInputStream(null); + ((ChannelExec) channel).setErrStream(System.err); - channel.connect(); + channel.connect(); + } catch (JSchException e) { } } protected void doPost(HttpServletRequest request, HttpServletResponse response) @@ -41,16 +43,18 @@ public class JSchOSInjectionTest extends HttpServlet { config.put("StrictHostKeyChecking", "no"); JSch jsch = new JSch(); - Session session = jsch.getSession(user, host, 22); - session.setPassword(password); - session.setConfig(config); - session.connect(); + try { + Session session = jsch.getSession(user, host, 22); + session.setPassword(password); + session.setConfig(config); + session.connect(); - ChannelExec channel = (ChannelExec)session.openChannel("exec"); - channel.setCommand("ping " + command); - channel.setInputStream(null); - channel.setErrStream(System.err); + ChannelExec channel = (ChannelExec)session.openChannel("exec"); + channel.setCommand("ping " + command); + channel.setInputStream(null); + channel.setErrStream(System.err); - channel.connect(); + channel.connect(); + } catch (JSchException e) { } } -} \ No newline at end of file +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-078/options b/java/ql/test/experimental/query-tests/security/CWE-078/options index eb7209ebe1e..27f8028a9d4 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-078/options +++ b/java/ql/test/experimental/query-tests/security/CWE-078/options @@ -1,2 +1,2 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jsch-0.1.55 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jsch-0.1.55 From c40ec728c6f4d8c489066d55829a9326474a1fbf Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 15 Aug 2022 11:09:17 +0100 Subject: [PATCH 022/659] Remove non-ascii char --- .../test/stubs/mongodbClient/com/mongodb/MongoCredential.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/stubs/mongodbClient/com/mongodb/MongoCredential.java b/java/ql/test/stubs/mongodbClient/com/mongodb/MongoCredential.java index 38e24b29bce..8cd1d40a8f6 100644 --- a/java/ql/test/stubs/mongodbClient/com/mongodb/MongoCredential.java +++ b/java/ql/test/stubs/mongodbClient/com/mongodb/MongoCredential.java @@ -50,7 +50,7 @@ public final class MongoCredential { return null; } - public static MongoCredential createMongoCRCredential​(String userName, String database, char[] password) { + public static MongoCredential createMongoCRCredential(String userName, String database, char[] password) { // Deprecated function removed in most recent releases of the Mongo driver. return null; } From e27d62b0b4e36a5831e3e862f20f61f0b46c20a3 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 15 Aug 2022 11:15:36 +0100 Subject: [PATCH 023/659] Fix qldoc wording --- .../code/java/security/HardcodedCredentialsApiCallQuery.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll index 2fdec983b31..fb786710d66 100644 --- a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll @@ -7,7 +7,7 @@ import semmle.code.java.dataflow.DataFlow import HardcodedCredentials /** - * Tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security. + * A data-flow configuration that tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security. */ class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { HardcodedCredentialApiCallConfiguration() { this = "HardcodedCredentialApiCallConfiguration" } From d816f7f390d11b7597172ca27a57f617675e4bd1 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 15 Aug 2022 21:52:10 +0200 Subject: [PATCH 024/659] add ql/consistent-alert-message --- .../queries/style/ConsistentAlertMessage.ql | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 ql/ql/src/queries/style/ConsistentAlertMessage.ql diff --git a/ql/ql/src/queries/style/ConsistentAlertMessage.ql b/ql/ql/src/queries/style/ConsistentAlertMessage.ql new file mode 100644 index 00000000000..a63824ea38a --- /dev/null +++ b/ql/ql/src/queries/style/ConsistentAlertMessage.ql @@ -0,0 +1,77 @@ +/** + * @name Consistent alert message + * @description The alert message should be consistent across languages. + * @kind problem + * @problem.severity warning + * @id ql/consistent-alert-message + * @tags correctness + * @precision very-high + */ + +import ql + +/** + * Gets a string representation of the entire message in `sel`. + * Ignores everything that is not a string constant. + */ +string getMessage(Select sel) { + result = + strictconcat(String e, Location l | + // is child of an expression in the select (in an uneven position, that's where the message is) + e.getParent*() = sel.getExpr(any(int i | i % 2 = 1)) and l = e.getFullLocation() + | + e.getValue(), " | " order by l.getStartLine(), l.getStartColumn() + ).trim() +} + +/** + * Gets a language agnostic fingerprint for a Select. + * The fingerPrint includes e.g. the query-id, the @kind of the query, and the number of expressions in the select. + * + * This fingerprint avoid false positives where two queries with the same ID behave differently (which is OK). + */ +string getSelectFingerPrint(Select sel) { + exists(File file, QLDoc doc | + sel.getLocation().getFile() = file and + any(TopLevel top | top.getLocation().getFile() = file).getQLDoc() = doc + | + result = + doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 2) // query ID (without lang) + + "-" + doc.getContents().regexpCapture("(?s).*@kind (\\w+)\\s.*", 1) // @kind + + "-" + + strictcount(String e | e.getParent*() = sel.getExpr(any(int i | i % 2 = 1))) // the number of string constants in the select + + "-" + count(sel.getExpr(_)) // and the total number of expressions in the select + ) +} + +/** + * Gets information about the select. + * The query-id (without language), the language, the message from the select, and a language agnostic fingerprint. + */ +Select parseSelect(string id, string lang, string msg, string fingerPrint) { + exists(File file, QLDoc doc | result.getLocation().getFile() = file | + any(TopLevel top | top.getLocation().getFile() = file).getQLDoc() = doc and + id = doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 2) and + lang = doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 1) and + fingerPrint = getSelectFingerPrint(result) and + msg = getMessage(result).toLowerCase() // case normalize, because some languages upper-case methods. + ) and + // excluding experimental + not result.getLocation().getFile().getRelativePath().matches("%/experimental/%") and + not lang = "ql" // excluding QL-for-QL +} + +from Select sel, string id, string lang, string msg, string fingerPrint, string badLangs +where + // for a select with a fingerprint + sel = parseSelect(id, lang, msg, fingerPrint) and + // there exists other languages with the same fingerprint, but other message + badLangs = + strictconcat(string bad | + bad != lang and + exists(parseSelect(id, bad, any(string otherMsg | otherMsg != msg), fingerPrint)) + | + bad, ", " + ) +select sel, + "The " + lang + "/" + id + " query does not have the same alert message as " + badLangs + "." From 5e53124217ddaf6fd803babd2e78c6a7620bfd24 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 15 Aug 2022 21:52:34 +0200 Subject: [PATCH 025/659] don't report warning for deprecated classes/predicates --- ql/ql/src/queries/style/docs/ClassDocs.ql | 3 ++- ql/ql/src/queries/style/docs/PredicateDocs.ql | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ql/ql/src/queries/style/docs/ClassDocs.ql b/ql/ql/src/queries/style/docs/ClassDocs.ql index 1dad0867996..f7e5d7ac8d8 100644 --- a/ql/ql/src/queries/style/docs/ClassDocs.ql +++ b/ql/ql/src/queries/style/docs/ClassDocs.ql @@ -22,5 +22,6 @@ predicate badStyle(string s) { from Class c where badStyle(c.getQLDoc().getContents()) and - not c.isPrivate() + not c.isPrivate() and + not c.hasAnnotation("deprecated") select c.getQLDoc(), "The QLDoc for a class should start with 'A', 'An', or 'The'." diff --git a/ql/ql/src/queries/style/docs/PredicateDocs.ql b/ql/ql/src/queries/style/docs/PredicateDocs.ql index 250fbefbbd8..a8a271e7ab8 100644 --- a/ql/ql/src/queries/style/docs/PredicateDocs.ql +++ b/ql/ql/src/queries/style/docs/PredicateDocs.ql @@ -18,6 +18,7 @@ string docLines(Predicate pred) { from Predicate pred, string message where not pred.isPrivate() and + not pred.hasAnnotation("deprecated") and // only considering qldocs that look like a class-doc, to avoid reporting way too much. docLines(pred).matches(["A", "An", "The"] + " %") and // looks like a class doc. not pred instanceof NewTypeBranch and // <- these are actually kinda class-like. From 847934078c9165cf92ff9cab5d7c1df601722bec Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 12 Aug 2022 20:51:59 +0200 Subject: [PATCH 026/659] update the version of codeql-action used by QL-for-QL --- .github/workflows/ql-for-ql-build.yml | 6 +++--- .github/workflows/ql-for-ql-dataset_measure.yml | 2 +- .github/workflows/ql-for-ql-tests.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 7c3b8ccb78c..9a5bcbba78f 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - name: Find codeql id: find-codeql - uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 + uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca with: languages: javascript # does not matter - name: Get CodeQL version @@ -158,14 +158,14 @@ jobs: env: CONF: ./ql-for-ql-config.yml - name: Initialize CodeQL - uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 + uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca with: languages: ql db-location: ${{ runner.temp }}/db config-file: ./ql-for-ql-config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980 + uses: github/codeql-action/analyze@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca with: category: "ql-for-ql" - name: Copy sarif file to CWD diff --git a/.github/workflows/ql-for-ql-dataset_measure.yml b/.github/workflows/ql-for-ql-dataset_measure.yml index a5ed2e9b266..f53c6a996f0 100644 --- a/.github/workflows/ql-for-ql-dataset_measure.yml +++ b/.github/workflows/ql-for-ql-dataset_measure.yml @@ -25,7 +25,7 @@ jobs: - name: Find codeql id: find-codeql - uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 + uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca with: languages: javascript # does not matter - uses: actions/cache@v3 diff --git a/.github/workflows/ql-for-ql-tests.yml b/.github/workflows/ql-for-ql-tests.yml index b016f21f2b9..c68df2bfa28 100644 --- a/.github/workflows/ql-for-ql-tests.yml +++ b/.github/workflows/ql-for-ql-tests.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v3 - name: Find codeql id: find-codeql - uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 + uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca with: languages: javascript # does not matter - uses: actions/cache@v3 From 427a6078438ad6f2633250718299f561a76496b6 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 15 Aug 2022 08:03:39 +0200 Subject: [PATCH 027/659] point codeql-action to the local QL-for-QL queries --- .github/workflows/ql-for-ql-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 9a5bcbba78f..68049603f4a 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -151,8 +151,8 @@ jobs: echo " - ql/ql/test" >> ${CONF} echo " - \"*/ql/lib/upgrades/\"" >> ${CONF} echo "disable-default-queries: true" >> ${CONF} - echo "packs:" >> ${CONF} - echo " - codeql/ql" >> ${CONF} + echo "queries:" >> ${CONF} + echo " - uses: ./ql/ql/src/codeql-suites/ql-code-scanning.qls" >> ${CONF} echo "Config file: " cat ${CONF} env: From ae0813045140b003868e8ee61991d1134b07f39b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 15 Aug 2022 22:42:31 +0200 Subject: [PATCH 028/659] more threads --- .github/workflows/ql-for-ql-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 68049603f4a..e790afe960b 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -37,7 +37,7 @@ jobs: if: steps.cache-queries.outputs.cache-hit != 'true' run: | cd ql/ql/src - "${CODEQL}" pack create + "${CODEQL}" pack create -j 16 cd .codeql/pack/codeql/ql/0.0.0 zip "${PACKZIP}" -r . rm -rf * From d38d810677d1b427d57c84ecb6d31ea56ff132b6 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 15 Aug 2022 22:42:40 +0200 Subject: [PATCH 029/659] include the workflow in the cache key --- .github/workflows/ql-for-ql-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index e790afe960b..6517923ef7b 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -32,7 +32,7 @@ jobs: uses: actions/cache@v3 with: path: ${{ runner.temp }}/query-pack.zip - key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }} + key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}--${{ hashFiles('.github/workflows/ql-for-ql-build.yml') }} - name: Build query pack if: steps.cache-queries.outputs.cache-hit != 'true' run: | From b3adb62adbd7135747269308d5cbdd9f0675f312 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 15 Aug 2022 22:42:51 +0200 Subject: [PATCH 030/659] move the pack cache to where it's read --- .github/workflows/ql-for-ql-build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 6517923ef7b..da0666c1a1e 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -163,6 +163,11 @@ jobs: languages: ql db-location: ${{ runner.temp }}/db config-file: ./ql-for-ql-config.yml + - name: Move pack cache + run: | + cp -r ${PACK}/.cache ql/ql/src/.cache + env: + PACK: ${{ runner.temp }}/pack - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca From dd51b7f356bca2a184fa179cd5619dde804d4861 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 Aug 2022 17:50:04 +0100 Subject: [PATCH 031/659] Swift: Add many tests. --- .../CWE-311/CleartextStorageDatabase.expected | 6 +- .../CWE-311/CleartextTransmission.expected | 6 +- .../query-tests/Security/CWE-311/test.swift | 4 - .../Security/CWE-311/testCoreData.swift | 97 +++++++++++++++++++ .../Security/CWE-311/testRealm.swift | 59 +++++++++++ .../Security/CWE-311/testSend.swift | 39 ++++++++ .../Security/CWE-311/testURL.swift | 22 +++++ 7 files changed, 227 insertions(+), 6 deletions(-) delete mode 100644 swift/ql/test/query-tests/Security/CWE-311/test.swift create mode 100644 swift/ql/test/query-tests/Security/CWE-311/testCoreData.swift create mode 100644 swift/ql/test/query-tests/Security/CWE-311/testRealm.swift create mode 100644 swift/ql/test/query-tests/Security/CWE-311/testSend.swift create mode 100644 swift/ql/test/query-tests/Security/CWE-311/testURL.swift diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index 1333ed77b7e..8aa70356dc7 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -1 +1,5 @@ -TODO +edges +nodes +subpaths +#select +| TODO | diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected index 1333ed77b7e..8aa70356dc7 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextTransmission.expected @@ -1 +1,5 @@ -TODO +edges +nodes +subpaths +#select +| TODO | diff --git a/swift/ql/test/query-tests/Security/CWE-311/test.swift b/swift/ql/test/query-tests/Security/CWE-311/test.swift deleted file mode 100644 index 986e3bc8ea3..00000000000 --- a/swift/ql/test/query-tests/Security/CWE-311/test.swift +++ /dev/null @@ -1,4 +0,0 @@ - -// --- stubs --- - -// --- tests --- diff --git a/swift/ql/test/query-tests/Security/CWE-311/testCoreData.swift b/swift/ql/test/query-tests/Security/CWE-311/testCoreData.swift new file mode 100644 index 00000000000..4a7d0a70fa5 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/testCoreData.swift @@ -0,0 +1,97 @@ + +// --- stubs --- + +class NSObject +{ +} + +class NSManagedObject : NSObject +{ + func value(forKey: String) -> Any? { return "" } + func setValue(_: Any?, forKey: String) {} + func primitiveValue(forKey: String) -> Any? { return "" } + func setPrimitiveValue(_: Any?, forKey: String) {} +} + +class MyManagedObject : NSManagedObject +{ + func setIndirect(value: String) { + setValue(value, forKey: "myKey") + } + + var myValue: String { + get { + if let v = value(forKey: "myKey") as? String + { + return v + } else { + return "" + } + } + set { + setValue(newValue, forKey: "myKey") + } + } +} + +func encrypt(_ data: String) -> String { return data } +func hash(data: inout String) { } + +func getPassword() -> String { return "" } +func doSomething(password: String) { } + +// --- tests --- + +func test1(obj : NSManagedObject, password : String, password_hash : String) { + // NSManagedObject methods... + + obj.setValue(password, forKey: "myKey") // BAD + obj.setValue(password_hash, forKey: "myKey") // GOOD (not sensitive) + + obj.setPrimitiveValue(password, forKey: "myKey") // BAD + obj.setPrimitiveValue(password_hash, forKey: "myKey") // GOOD (not sensitive) +} + +func test2(obj : MyManagedObject, password : String, password_file : String) { + // MyManagedObject methods... + + obj.setValue(password, forKey: "myKey") // BAD + obj.setValue(password_file, forKey: "myKey") // GOOD (not sensitive) + + obj.setIndirect(value: password) // BAD + obj.setIndirect(value: password_file) // GOOD (not sensitive) + + obj.myValue = password // BAD + obj.myValue = password_file // GOOD (not sensitive) +} + +func test3(obj : NSManagedObject, x : String) { + // alternative evidence of sensitivity... + + obj.setValue(x, forKey: "myKey") // BAD + doSomething(password: x); + obj.setValue(x, forKey: "myKey") // BAD + + var y = getPassword(); + obj.setValue(y, forKey: "myKey") // BAD +} + +func test4(obj : NSManagedObject, pwd : String) { + // sanitizers... + + var x = pwd; + var y = pwd; + var z = pwd; + + obj.setValue(x, forKey: "myKey") // BAD + obj.setValue(y, forKey: "myKey") // BAD + obj.setValue(z, forKey: "myKey") // BAD + + x = encrypt(x); + hash(data: &y); + z = ""; + + obj.setValue(x, forKey: "myKey") // GOOD (not sensitive) + obj.setValue(y, forKey: "myKey") // GOOD (not sensitive) + obj.setValue(z, forKey: "myKey") // GOOD (not sensitive) +} diff --git a/swift/ql/test/query-tests/Security/CWE-311/testRealm.swift b/swift/ql/test/query-tests/Security/CWE-311/testRealm.swift new file mode 100644 index 00000000000..cee7e44e8a0 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/testRealm.swift @@ -0,0 +1,59 @@ + +// --- stubs --- + +enum UpdatePolicy : Int { + case error = 1 +} + +class RealmSwiftObject { +} + +typealias Object = RealmSwiftObject + +class MyRealmSwiftObject : RealmSwiftObject { + override init() { data = "" } + + var data: String +} + +class Realm { + func add(_ object: Object, update: UpdatePolicy = .error) {} + + func create(_ type : T.Type, value: Any = [:], update: UpdatePolicy = .error) where T : RealmSwiftObject { } + + func object(ofType type: Element.Type, forPrimaryKey key: KeyType) -> Element? where Element : RealmSwiftObject { return nil } + +} + +// --- tests --- + +func test1(realm : Realm, myPassword : String, myHashedPassword : String) { + // add objects (within a transaction) ... + + let a = MyRealmSwiftObject() + a.data = myPassword + realm.add(a) // BAD + + let b = MyRealmSwiftObject() + b.data = myHashedPassword + realm.add(b) // GOOD (not sensitive) + + let c = MyRealmSwiftObject() + c.data = myPassword + realm.create(MyRealmSwiftObject.self, value: c) // BAD + + let d = MyRealmSwiftObject() + d.data = myHashedPassword + realm.create(MyRealmSwiftObject.self, value: d) // GOOD (not sensitive) + + // retrieve objects ... + + var e = realm.object(ofType: MyRealmSwiftObject.self, forPrimaryKey: "key") + e!.data = myPassword // BAD + + var f = realm.object(ofType: MyRealmSwiftObject.self, forPrimaryKey: "key") + f!.data = myHashedPassword // GOOD (not sensitive) +} + +// limitation: its possible to configure a Realm DB to be stored encrypted, if this is done correctly +// (taking care with the encryption key) then storing otherwise plaintext sensitive data would be OK. diff --git a/swift/ql/test/query-tests/Security/CWE-311/testSend.swift b/swift/ql/test/query-tests/Security/CWE-311/testSend.swift new file mode 100644 index 00000000000..8248812e081 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/testSend.swift @@ -0,0 +1,39 @@ + +// --- stubs --- + +class Data { + init(_ elements: S) {} +} + +class NWConnection { + enum SendCompletion { + case idempotent + } + + class ContentContext { + static let defaultMessage = ContentContext() + } + + func send(content: Data?, contentContext: NWConnection.ContentContext = .defaultMessage, isComplete: Bool = true, completion: NWConnection.SendCompletion) { } + func send(content: Content?, contentContext: NWConnection.ContentContext = .defaultMessage, isComplete: Bool = true, completion: NWConnection.SendCompletion) { } +} + +// --- tests --- + +func test1(passwordPlain : String, passwordHash : String) { + let nw = NWConnection() + + // ... + + nw.send(content: "123456", completion: .idempotent) // GOOD (not sensitive) + nw.send(content: passwordPlain, completion: .idempotent) // BAD + nw.send(content: passwordHash, completion: .idempotent) // GOOD (not sensitive) + + let data1 = Data("123456") + let data2 = Data(passwordPlain) + let data3 = Data(passwordHash) + + nw.send(content: data1, completion: .idempotent) // GOOD (not sensitive) + nw.send(content: data2, completion: .idempotent) // BAD + nw.send(content: data3, completion: .idempotent) // GOOD (not sensitive) +} diff --git a/swift/ql/test/query-tests/Security/CWE-311/testURL.swift b/swift/ql/test/query-tests/Security/CWE-311/testURL.swift new file mode 100644 index 00000000000..593d799d5ff --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-311/testURL.swift @@ -0,0 +1,22 @@ + +// --- stubs --- + +class URL +{ + init?(string: String) {} + init?(string: String, relativeTo: URL?) {} +} + +// --- tests --- + +func test1(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) { + let a = URL(string: "http://example.com/login?p=" + passwd); // BAD + let b = URL(string: "http://example.com/login?p=" + encrypted_passwd); // GOOD (not sensitive) + let c = URL(string: "http://example.com/login?ac=" + account_no); // BAD + let d = URL(string: "http://example.com/login?cc=" + credit_card_no); // BAD + + let base = URL(string: "http://example.com/"); // GOOD (not sensitive) + let e = URL(string: "abc", relativeTo: base); // GOOD (not sensitive) + let f = URL(string: passwd, relativeTo: base); // BAD + let g = URL(string: "abc", relativeTo: f); // BAD +} From 1d12bd1521b66f6b804d53b11cac111678a2e3f1 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 17 Aug 2022 10:06:44 +0200 Subject: [PATCH 032/659] Share SpringUrlRedirect library --- .../Security/CWE/CWE-601/SpringUrlRedirect.ql | 2 +- .../CWE/CWE-625/PermissiveDotRegex.ql | 2 +- .../CWE/CWE-625/SpringUrlRedirect.qll | 109 ------------------ .../code/java/security}/SpringUrlRedirect.qll | 17 ++- 4 files changed, 13 insertions(+), 117 deletions(-) delete mode 100644 java/ql/src/experimental/Security/CWE/CWE-625/SpringUrlRedirect.qll rename java/ql/src/experimental/{Security/CWE/CWE-601 => semmle/code/java/security}/SpringUrlRedirect.qll (91%) diff --git a/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.ql b/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.ql index a69928ba0bd..3cef2b4fc41 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.ql @@ -11,7 +11,7 @@ */ import java -import SpringUrlRedirect +import experimental.semmle.code.java.security.SpringUrlRedirect import semmle.code.java.dataflow.FlowSources import semmle.code.java.controlflow.Guards import DataFlow::PathGraph diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql index 693cc77a562..cfd85796860 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegex.ql @@ -12,13 +12,13 @@ */ import java +import experimental.semmle.code.java.security.SpringUrlRedirect import semmle.code.java.controlflow.Guards import semmle.code.java.dataflow.ExternalFlow import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.UrlRedirect import DataFlow::PathGraph import Regex -import SpringUrlRedirect /** Source model of remote flow source with servlets. */ private class GetServletUriSource extends SourceModelCsv { diff --git a/java/ql/src/experimental/Security/CWE/CWE-625/SpringUrlRedirect.qll b/java/ql/src/experimental/Security/CWE/CWE-625/SpringUrlRedirect.qll deleted file mode 100644 index 113afcded5b..00000000000 --- a/java/ql/src/experimental/Security/CWE/CWE-625/SpringUrlRedirect.qll +++ /dev/null @@ -1,109 +0,0 @@ -/** Provides methods related to Spring URL redirect from /src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll. */ - -private import java -private import semmle.code.java.dataflow.FlowSources - -/** - * A concatenate expression using the string `redirect:` or `ajaxredirect:` or `forward:` on the left. - * - * E.g: `"redirect:" + redirectUrl` - */ -class RedirectBuilderExpr extends AddExpr { - RedirectBuilderExpr() { - this.getLeftOperand().(CompileTimeConstantExpr).getStringValue() in [ - "redirect:", "ajaxredirect:", "forward:" - ] - } -} - -/** - * A call to `StringBuilder.append` or `StringBuffer.append` method, and the parameter value is - * `"redirect:"` or `"ajaxredirect:"` or `"forward:"`. - * - * E.g: `StringBuilder.append("redirect:")` - */ -class RedirectAppendCall extends MethodAccess { - RedirectAppendCall() { - this.getMethod().hasName("append") and - this.getMethod().getDeclaringType() instanceof StringBuildingType and - this.getArgument(0).(CompileTimeConstantExpr).getStringValue() in [ - "redirect:", "ajaxredirect:", "forward:" - ] - } -} - -/** A URL redirection sink from spring controller method. */ -abstract class SpringUrlRedirectSink extends DataFlow::Node { } - -/** - * A sink for URL Redirection via the Spring View classes. - */ -private class SpringViewUrlRedirectSink extends SpringUrlRedirectSink { - SpringViewUrlRedirectSink() { - // Hardcoded redirect such as "redirect:login" - this.asExpr() - .(CompileTimeConstantExpr) - .getStringValue() - .indexOf(["redirect:", "ajaxredirect:", "forward:"]) = 0 and - any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) - or - exists(RedirectBuilderExpr rbe | - rbe.getRightOperand() = this.asExpr() and - any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) - ) - or - exists(MethodAccess ma, RedirectAppendCall rac | - DataFlow2::localExprFlow(rac.getQualifier(), ma.getQualifier()) and - ma.getMethod().hasName("append") and - ma.getArgument(0) = this.asExpr() and - any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) - ) - or - exists(MethodAccess ma | - ma.getMethod().hasName("setUrl") and - ma.getMethod() - .getDeclaringType() - .hasQualifiedName("org.springframework.web.servlet.view", "AbstractUrlBasedView") and - ma.getArgument(0) = this.asExpr() - ) - or - exists(ClassInstanceExpr cie | - cie.getConstructedType() - .hasQualifiedName("org.springframework.web.servlet.view", "RedirectView") and - cie.getArgument(0) = this.asExpr() - ) - or - exists(ClassInstanceExpr cie | - cie.getConstructedType().hasQualifiedName("org.springframework.web.servlet", "ModelAndView") and - exists(RedirectBuilderExpr rbe | - rbe = cie.getArgument(0) and rbe.getRightOperand() = this.asExpr() - ) - ) - } -} - -/** - * A sink for URL Redirection via the `ResponseEntity` class. - */ -private class SpringResponseEntityUrlRedirectSink extends SpringUrlRedirectSink { - SpringResponseEntityUrlRedirectSink() { - // Find `new ResponseEntity(httpHeaders, ...)` or - // `new ResponseEntity(..., httpHeaders, ...)` sinks - exists(ClassInstanceExpr cie, Argument argument | - cie.getConstructedType() instanceof SpringResponseEntity and - argument.getType() instanceof SpringHttpHeaders and - argument = cie.getArgument([0, 1]) and - this.asExpr() = argument - ) - or - // Find `ResponseEntity.status(...).headers(taintHeaders).build()` or - // `ResponseEntity.status(...).location(URI.create(taintURL)).build()` sinks - exists(MethodAccess ma | - ma.getMethod() - .getDeclaringType() - .hasQualifiedName("org.springframework.http", "ResponseEntity$HeadersBuilder") and - ma.getMethod().getName() in ["headers", "location"] and - this.asExpr() = ma.getArgument(0) - ) - } -} diff --git a/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll b/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll similarity index 91% rename from java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll rename to java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll index 1aded71c661..8a91ff5dcf0 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-601/SpringUrlRedirect.qll +++ b/java/ql/src/experimental/semmle/code/java/security/SpringUrlRedirect.qll @@ -1,9 +1,7 @@ -import java -import DataFlow -import semmle.code.java.dataflow.FlowSources -import semmle.code.java.dataflow.DataFlow2 -import semmle.code.java.dataflow.TaintTracking -import semmle.code.java.frameworks.spring.SpringController +/** Provides classes and predicates related to Spring URL redirect. */ + +private import java +private import semmle.code.java.dataflow.FlowSources /** * A concatenate expression using the string `redirect:` or `ajaxredirect:` or `forward:` on the left. @@ -42,6 +40,13 @@ abstract class SpringUrlRedirectSink extends DataFlow::Node { } */ private class SpringViewUrlRedirectSink extends SpringUrlRedirectSink { SpringViewUrlRedirectSink() { + // Hardcoded redirect such as "redirect:login" + this.asExpr() + .(CompileTimeConstantExpr) + .getStringValue() + .indexOf(["redirect:", "ajaxredirect:", "forward:"]) = 0 and + any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) + or exists(RedirectBuilderExpr rbe | rbe.getRightOperand() = this.asExpr() and any(SpringRequestMappingMethod sqmm).polyCalls*(this.getEnclosingCallable()) From 41bdd6d4cc1a84264c04f1e8cd324fdab7ebee4a Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 5 Aug 2022 12:55:28 +0100 Subject: [PATCH 033/659] Add RSA without OEAP query and qhelp --- .../java/security/RsaWithoutOaepQuery.qll | 15 +++++++++++ .../Security/CWE/CWE-780/RsaWithoutOaep.java | 7 +++++ .../Security/CWE/CWE-780/RsaWithoutOaep.qhelp | 27 +++++++++++++++++++ .../Security/CWE/CWE-780/RsaWithoutOaep.ql | 17 ++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll create mode 100644 java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.java create mode 100644 java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp create mode 100644 java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql diff --git a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll new file mode 100644 index 00000000000..357ef5d1b24 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll @@ -0,0 +1,15 @@ +/** Definitions for the RSE without OAEP query */ + +import java +import semmle.code.java.dataflow.DataFlow + +/** Holds if `ma` is a call to `Cipher.getInstance` which initialises an RSA cipher without using OAEP padding. */ +predicate rsaWithoutOaepCall(MethodAccess ma) { + ma.getMethod().hasQualifiedName("javax.crypto", "Cipher", "getInstance") and + exists(CompileTimeConstantExpr specExpr, string spec | + specExpr.getStringValue() = spec and + DataFlow::localExprFlow(specExpr, ma.getArgument(0)) and + spec.matches("RSA/%") and + not spec.matches("%OAEP%") + ) +} diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.java b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.java new file mode 100644 index 00000000000..684b58eca73 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.java @@ -0,0 +1,7 @@ +// BAD: No padding scheme is used +Cipher rsa = Cipher.getInstance("RSA/ECB/NoPadding") +... + +//GOOD: OAEP padding is used +Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding") +... \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp new file mode 100644 index 00000000000..0b07dfd9caa --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp @@ -0,0 +1,27 @@ + + + + +

    Cryptographic algorithms often use padding schemes to make the plaintext less predictable. The OAEP scheme (Optimal Asymmetric Encryption Padding) should used with RSA encryption. + Using no padding or an outdated padding scheme such as PKCS1 can weaken the encryption by making it vulnerable to a padding oracle attack. +

    +
    + + +

    Use the OAEP scheme when using RSA encryption.

    +
    + + +

    In the following example, the BAD case shows no padding being used, whereas the GOOD case shows an OAEP scheme being used.

    + +
    + + +
    +
  • + The Padding Oracle Attack. +
  • + + diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql new file mode 100644 index 00000000000..6581e956c93 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql @@ -0,0 +1,17 @@ +/** + * @name Use of RSA algorithm without OAEP + * @description Using RSA encryption without OAEP padding can lead to a padding oracle attack, weakening the encryption. + * @kind problem + * @problem.severity warning + * @precision high + * @id java/rsa-without-oaep + * @tags security + * external/cwe/cwe-780 + */ + +import java +import semmle.code.java.security.RsaWithoutOaepQuery + +from MethodAccess ma +where rsaWithoutOaepCall(ma) +select ma, "This instance of RSA does not use OAEP padding." From 9ae652dd6ad5463e7981f1ab95351b5b768a9849 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 5 Aug 2022 17:18:43 +0100 Subject: [PATCH 034/659] Add tests --- .../Security/CWE/CWE-780/RsaWithoutOaep.java | 4 ++-- .../CWE-780/RsaWithoutOaepTest.expected | 0 .../security/CWE-780/RsaWithoutOaepTest.java | 9 +++++++++ .../security/CWE-780/RsaWithoutOaepTest.ql | 19 +++++++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.expected create mode 100644 java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.java create mode 100644 java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.java b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.java index 684b58eca73..34024a59f6e 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.java +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.java @@ -1,7 +1,7 @@ // BAD: No padding scheme is used -Cipher rsa = Cipher.getInstance("RSA/ECB/NoPadding") +Cipher rsa = Cipher.getInstance("RSA/ECB/NoPadding"); ... //GOOD: OAEP padding is used -Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding") +Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); ... \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.expected b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.java b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.java new file mode 100644 index 00000000000..a8fc28c7d1d --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.java @@ -0,0 +1,9 @@ +import javax.crypto.Cipher; + +class RsaWithoutOaep { + public void test() throws Exception { + Cipher rsaBad = Cipher.getInstance("RSA/ECB/NoPadding"); // $hasResult + + Cipher rsaGood = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql new file mode 100644 index 00000000000..29d6120a9d8 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql @@ -0,0 +1,19 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.security.RsaWithoutOaepQuery + +class HasResult extends InlineExpectationsTest { + HasResult() { this = "HasResult" } + + override string getARelevantTag() { result = "hasResult" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasResult" and + value = "" and + exists(MethodAccess ma | + rsaWithoutOaepCall(ma) and + location = ma.getLocation() and + element = ma.toString() + ) + } +} From 08b77493d203ad42c2c28657d41ba4372ed38442 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 5 Aug 2022 17:41:00 +0100 Subject: [PATCH 035/659] Add security severity and change note --- java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql | 1 + java/ql/src/change-notes/2022-08-05-rsa-without-oaep.md | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 java/ql/src/change-notes/2022-08-05-rsa-without-oaep.md diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql index 6581e956c93..22602c23482 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql @@ -3,6 +3,7 @@ * @description Using RSA encryption without OAEP padding can lead to a padding oracle attack, weakening the encryption. * @kind problem * @problem.severity warning + * @security-severity 7.5 * @precision high * @id java/rsa-without-oaep * @tags security diff --git a/java/ql/src/change-notes/2022-08-05-rsa-without-oaep.md b/java/ql/src/change-notes/2022-08-05-rsa-without-oaep.md new file mode 100644 index 00000000000..06d71cbf865 --- /dev/null +++ b/java/ql/src/change-notes/2022-08-05-rsa-without-oaep.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* A new query "Use of RSA algorithm without OAEP" (`java/rsa-without-oaep`) has been added. This query finds uses of RSA encryption that don't use the OAEP scheme. \ No newline at end of file From c77b17574a51d5ca817d3453e93c76a04ae3fb0a Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 5 Aug 2022 17:53:55 +0100 Subject: [PATCH 036/659] Use CryptoAlgoSpec rather than hadcoding Cipher.getInstance --- .../lib/semmle/code/java/security/RsaWithoutOaepQuery.qll | 8 ++++---- java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql | 7 ++++--- .../query-tests/security/CWE-780/RsaWithoutOaepTest.ql | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll index 357ef5d1b24..6fb91edcf92 100644 --- a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll +++ b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll @@ -1,14 +1,14 @@ /** Definitions for the RSE without OAEP query */ import java +import Encryption import semmle.code.java.dataflow.DataFlow -/** Holds if `ma` is a call to `Cipher.getInstance` which initialises an RSA cipher without using OAEP padding. */ -predicate rsaWithoutOaepCall(MethodAccess ma) { - ma.getMethod().hasQualifiedName("javax.crypto", "Cipher", "getInstance") and +/** Holds if `c` is a call which initialises an RSA cipher without using OAEP padding. */ +predicate rsaWithoutOaepCall(CryptoAlgoSpec c) { exists(CompileTimeConstantExpr specExpr, string spec | specExpr.getStringValue() = spec and - DataFlow::localExprFlow(specExpr, ma.getArgument(0)) and + DataFlow::localExprFlow(specExpr, c.getAlgoSpec()) and spec.matches("RSA/%") and not spec.matches("%OAEP%") ) diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql index 22602c23482..89a91c54d93 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql @@ -11,8 +11,9 @@ */ import java +import semmle.code.java.security.Encryption import semmle.code.java.security.RsaWithoutOaepQuery -from MethodAccess ma -where rsaWithoutOaepCall(ma) -select ma, "This instance of RSA does not use OAEP padding." +from CryptoAlgoSpec c +where rsaWithoutOaepCall(c) +select c, "This instance of RSA does not use OAEP padding." diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql index 29d6120a9d8..09dc1e5d194 100644 --- a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql +++ b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql @@ -10,10 +10,10 @@ class HasResult extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasResult" and value = "" and - exists(MethodAccess ma | - rsaWithoutOaepCall(ma) and - location = ma.getLocation() and - element = ma.toString() + exists(CryptoAlgoSpec c | + rsaWithoutOaepCall(c) and + location = c.getLocation() and + element = c.toString() ) } } From fe5a61bddec0de814a9d8ce17c618e18bd7b00e6 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 11 Aug 2022 14:03:31 +0100 Subject: [PATCH 037/659] Fix typos in docs and comments --- java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll | 2 +- java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll index 6fb91edcf92..2a4c8a708f2 100644 --- a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll +++ b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll @@ -1,4 +1,4 @@ -/** Definitions for the RSE without OAEP query */ +/** Definitions for the RSA without OAEP query */ import java import Encryption diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp index 0b07dfd9caa..227b3797abf 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp @@ -2,7 +2,7 @@ -

    Cryptographic algorithms often use padding schemes to make the plaintext less predictable. The OAEP scheme (Optimal Asymmetric Encryption Padding) should used with RSA encryption. +

    Cryptographic algorithms often use padding schemes to make the plaintext less predictable. The OAEP scheme (Optimal Asymmetric Encryption Padding) should be used with RSA encryption. Using no padding or an outdated padding scheme such as PKCS1 can weaken the encryption by making it vulnerable to a padding oracle attack.

    From de69827711060b03dec94575b89b6635fafd6170 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 16 Aug 2022 11:10:20 +0100 Subject: [PATCH 038/659] Use a full dataflow config rather than local flow --- .../java/security/RsaWithoutOaepQuery.qll | 24 ++++++++++++------- .../Security/CWE/CWE-780/RsaWithoutOaep.ql | 11 +++++---- .../security/CWE-780/RsaWithoutOaepTest.java | 10 +++++++- .../security/CWE-780/RsaWithoutOaepTest.ql | 17 ++++--------- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll index 2a4c8a708f2..71cbb565e00 100644 --- a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll +++ b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll @@ -4,12 +4,20 @@ import java import Encryption import semmle.code.java.dataflow.DataFlow -/** Holds if `c` is a call which initialises an RSA cipher without using OAEP padding. */ -predicate rsaWithoutOaepCall(CryptoAlgoSpec c) { - exists(CompileTimeConstantExpr specExpr, string spec | - specExpr.getStringValue() = spec and - DataFlow::localExprFlow(specExpr, c.getAlgoSpec()) and - spec.matches("RSA/%") and - not spec.matches("%OAEP%") - ) +/** A configuration for finding RSA ciphers initialized without using OAEP padding. */ +class RsaWithoutOaepConfig extends DataFlow::Configuration { + RsaWithoutOaepConfig() { this = "RsaWithoutOaepConfig" } + + override predicate isSource(DataFlow::Node src) { + exists(CompileTimeConstantExpr specExpr, string spec | + specExpr.getStringValue() = spec and + specExpr = src.asExpr() and + spec.matches("RSA/%") and + not spec.matches("%OAEP%") + ) + } + + override predicate isSink(DataFlow::Node sink) { + exists(CryptoAlgoSpec cr | sink.asExpr() = cr.getAlgoSpec()) + } } diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql index 89a91c54d93..65caac8389a 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql @@ -1,7 +1,7 @@ /** * @name Use of RSA algorithm without OAEP * @description Using RSA encryption without OAEP padding can lead to a padding oracle attack, weakening the encryption. - * @kind problem + * @kind path-problem * @problem.severity warning * @security-severity 7.5 * @precision high @@ -11,9 +11,10 @@ */ import java -import semmle.code.java.security.Encryption import semmle.code.java.security.RsaWithoutOaepQuery +import DataFlow::PathGraph -from CryptoAlgoSpec c -where rsaWithoutOaepCall(c) -select c, "This instance of RSA does not use OAEP padding." +from RsaWithoutOaepConfig conf, DataFlow::Node source, DataFlow::Node sink +where conf.hasFlow(source, sink) +select source, source, sink, + "This specification is used to initialize an RSA cipher without OAEP padding $@.", sink, "here" diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.java b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.java index a8fc28c7d1d..b8a1c73110c 100644 --- a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.java +++ b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.java @@ -2,8 +2,16 @@ import javax.crypto.Cipher; class RsaWithoutOaep { public void test() throws Exception { - Cipher rsaBad = Cipher.getInstance("RSA/ECB/NoPadding"); // $hasResult + Cipher rsaBad = Cipher.getInstance("RSA/ECB/NoPadding"); // $hasTaintFlow Cipher rsaGood = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); } + + public Cipher getCipher(String spec) throws Exception { + return Cipher.getInstance(spec); // $hasTaintFlow + } + + public void test2() throws Exception { + Cipher rsa = getCipher("RSA/ECB/NoPadding"); + } } \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql index 09dc1e5d194..bf8e8cbae21 100644 --- a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql +++ b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql @@ -1,19 +1,10 @@ import java import TestUtilities.InlineExpectationsTest +import TestUtilities.InlineFlowTest import semmle.code.java.security.RsaWithoutOaepQuery -class HasResult extends InlineExpectationsTest { - HasResult() { this = "HasResult" } +class HasFlowTest extends InlineFlowTest { + override DataFlow::Configuration getTaintFlowConfig() { result instanceof RsaWithoutOaepConfig } - override string getARelevantTag() { result = "hasResult" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "hasResult" and - value = "" and - exists(CryptoAlgoSpec c | - rsaWithoutOaepCall(c) and - location = c.getLocation() and - element = c.toString() - ) - } + override DataFlow::Configuration getValueFlowConfig() { none() } } From 5d00b871d4712c6e6d3ec838e994e22a3576994a Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 17 Aug 2022 11:58:11 +0100 Subject: [PATCH 039/659] Correct node type --- java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql index 65caac8389a..e841f5543c2 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql @@ -14,7 +14,7 @@ import java import semmle.code.java.security.RsaWithoutOaepQuery import DataFlow::PathGraph -from RsaWithoutOaepConfig conf, DataFlow::Node source, DataFlow::Node sink -where conf.hasFlow(source, sink) +from RsaWithoutOaepConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink +where conf.hasFlowPath(source, sink) select source, source, sink, "This specification is used to initialize an RSA cipher without OAEP padding $@.", sink, "here" From 1c15fc5600c0a566c1938f6a4c84319a6bb0eba3 Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 17 Aug 2022 13:36:32 +0000 Subject: [PATCH 040/659] Python: Define `Str` as an alias of `StrConst` --- python/ql/lib/semmle/python/Exprs.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/Exprs.qll b/python/ql/lib/semmle/python/Exprs.qll index 288793386ca..a4c66735f47 100644 --- a/python/ql/lib/semmle/python/Exprs.qll +++ b/python/ql/lib/semmle/python/Exprs.qll @@ -617,10 +617,10 @@ private string non_byte_prefix() { } /** A string constant. This is a placeholder class -- use `StrConst` instead. */ -class Str extends Str_ { } +class Str = StrConst; /** A string constant. */ -class StrConst extends Str, ImmutableLiteral { +class StrConst extends Str_, ImmutableLiteral { /* syntax: "hello" */ predicate isUnicode() { this.getPrefix() = unicode_prefix() From 6c085422783cd5629770e81ba0223392f931c77e Mon Sep 17 00:00:00 2001 From: Philip Ginsbach Date: Thu, 11 Aug 2022 14:48:10 +0100 Subject: [PATCH 041/659] add "Parameterised modules" section to documentation of modules --- docs/codeql/ql-language-reference/modules.rst | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/docs/codeql/ql-language-reference/modules.rst b/docs/codeql/ql-language-reference/modules.rst index b9998b63248..50b5738e97a 100644 --- a/docs/codeql/ql-language-reference/modules.rst +++ b/docs/codeql/ql-language-reference/modules.rst @@ -133,6 +133,89 @@ defined :ref:`above `: This defines an explicit module named ``M``. The body of this module defines the class ``OneTwo``. +.. _parameterised-modules: + +Parameterised modules +===================== + +Parameterised modules are QL's approach to generic programming. +Similar to explicit modules, parameterised modules are defined within other modules using the keywork ``module``. +In addition to the module name, parameterised modules define one or more parameters between the name and the module body. + +For example, consider the module ``ApplyFooThenBar``, which takes two predicate parameters and defines a new predicate +that applies them one after the other: + +.. code-block:: ql + + module ApplyFooThenBar { + bindingset[x] + int apply(int x) { + result = bar(foo(x)) + } + } + +Parameterised modules cannot be directly referenced. +Instead, they are instantiated with arguments passed between ``<`` and ``>``. +Instantiated parameterised modules can be used as a module expression, identical to explicit module references. + +For example, we can instantiate ``ApplyFooThenBar`` with two identical arguments ``increment``, creating a module +containing a predicate that adds 2: + +.. code-block:: ql + + bindingset[result] bindingset[x] + int increment(int x) { result = x + 1 } + + module IncrementTwice = ApplyFooThenBar; + + select IncrementTwice::apply(40) // 42 + +The parameters of a parameterised module are (meta-)typed with :ref:`signatures `. + +For example, in the previous two snippets, we relied on the predicate signature ``transformer``: + +.. code-block:: ql + + bindingset[x] + signature int transformer(int x); + +The instantiation of parameterised modules is applicative, meaning that repeated instantiation of a module using +identical arguments results in the same object. This is particularly relevant for type definitions inside parameterised +modules as :ref:`classes ` or via :ref:`newtype `. + +For example, the following generates an error for the second call to ``foo``, but not for the first: + +.. code-block:: ql + + bindingset[this] + signature class TSig; + + module M { + newtype A = B() or C() + } + + string foo(M::A a) { ... } + + select foo(M::B()), // valid: repeated identical instantiation of M does not duplicate A, B, C + foo(M::B()) // ERROR: M::B is not compatible with M::A + +Module parameters are dependently typed, meaning that signature expressions in parameter definitions can reference +preceding parameters. + +For example, we can declare the signature for ``T2`` dependent on ``T1``, enforcing a subtyping relationship +between the two parameters: + +.. code-block:: ql + + signature class TSig; + + module Extends { signature class Type extends T; } + + module ParameterisedModule::Type T2> { ... } + +Dependently typed parameters are particularly useful in combination with +:ref:`parameterised module signatures `. + .. _module-bodies: Module bodies From e8a1925e9c0c7560a517d31dd2ce669477705bd3 Mon Sep 17 00:00:00 2001 From: Philip Ginsbach Date: Wed, 17 Aug 2022 13:22:29 +0100 Subject: [PATCH 042/659] add reference file for signatures --- docs/codeql/ql-language-reference/index.rst | 3 + .../ql-language-reference/signatures.rst | 120 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 docs/codeql/ql-language-reference/signatures.rst diff --git a/docs/codeql/ql-language-reference/index.rst b/docs/codeql/ql-language-reference/index.rst index 5a971259cf7..19635f7befd 100644 --- a/docs/codeql/ql-language-reference/index.rst +++ b/docs/codeql/ql-language-reference/index.rst @@ -15,6 +15,8 @@ Learn all about QL, the powerful query language that underlies the code scanning - :doc:`Modules `: Modules provide a way of organizing QL code by grouping together related types, predicates, and other modules. +- :doc:`Signatures `: Signatures provide a typing mechanism to parameters of parameterised modules. + - :doc:`Aliases `: An alias is an alternative name for an existing QL entity. - :doc:`Variables `: Variables in QL are used in a similar way to variables in algebra or logic. They represent sets of values, and those values are usually restricted by a formula. @@ -44,6 +46,7 @@ Learn all about QL, the powerful query language that underlies the code scanning queries types modules + signatures aliases variables expressions diff --git a/docs/codeql/ql-language-reference/signatures.rst b/docs/codeql/ql-language-reference/signatures.rst new file mode 100644 index 00000000000..8422e328028 --- /dev/null +++ b/docs/codeql/ql-language-reference/signatures.rst @@ -0,0 +1,120 @@ +:tocdepth: 1 + +.. index:: signature + +.. _signatures: + +Signatures +########## + +Parameterised modules use signatures as a type system for their parameters. +There are three categories of signatures: **predicate signatures**, **type signatures**, and **module signatures**. + +Predicate signatures +==================== + +Predicate signatures declare module parameters that are to be substituted with predicates at module instantiation. + +The substitution of predicate signatures relies on structural typing, i.e. predicates do not have to be explicitly +defined as implementing a predicate signature - they just have to match the return and argument types. + +Predicate signatures are defined much like predicates themselves, but they do not have a body. +In detail, a predicate signature definition consists of: + +#. The keyword ``signature``. +#. The keyword ``predicate`` (allows subsitution with a :ref:`predicate without result `), + or the type of the result (allows subsitution with a :ref:`predicate with result `). +#. The name of the predicate signature. This is an `identifier `_ + starting with a lowercase letter. +#. The arguments to the predicate signature, if any, separated by commas. + For each argument, specify the argument type and an identifier for the argument variable. +#. A semicolon ``;``. + +For example: + +.. code-block:: ql + + signature int operator(int lhs, int rhs); + +Type signatures +=============== + +Type signatures declare module parameters that are to be substituted with types at module instantiation. +Type signature are the simplest category of signatures, as the only thing they allow is the specification of supertypes. + +The substitution of type signatures relies on structural typing, i.e. types do not have to be explicitly defined as +implementing a type signature - they just need to have the specified (transitive) supertypes. + +In detail, a type signature definition consists of: + +#. The keyword ``signature``. +#. The keyword ``class``. +#. The name of the type signature. This is an `identifier `_ + starting with a uppercase letter. +#. Optionally, the keyword ``extends`` followed by a list of types, separated by commas. +#. A semicolon ``;``. + +For example: + +.. code-block:: ql + + signature class ExtendsInt extends int; + +Module signatures +================= + +Module signatures declare module parameters that are to be substituted with modules at module instantiation. +Module signatures specify a collection of types and predicates that a module needs to contain under given names and +matching given signatures. + +Contrary to type signatures and predicte signatures, the substitution of type signatures relies on nominal typing, +i.e. modules need to declare at their definition the module signatures they implement. + +In detail, a type signature definition consists of: + +#. The keyword ``signature``. +#. The keyword ``module``. +#. The name of the module signature. This is an `identifier `_ + starting with a uppercase letter. +#. Optionally, a list of parameters for :ref:`parameterised module signatures `. +#. The module signature body, consisting of type signatures and predicate signatures enclosed in braces. + The ``signature`` keyword is omitted for these contained signatures. + +For example: + +.. code-block:: ql + + signature module MSig { + class T; + predicate restriction(T t); + } + + module Module implements MSig { + newtype T = A() or B(); + + predicate restriction(T t) { t = A() } + } + +.. _parameterised-module-signatures: + +Parameterised module signatures +------------------------------- + +Module signatures can themselves be paramterised in exactly the same way as parameterised modules. +This is particularly useful in combination with the dependent typing of module parameters. + +For example: + +.. code-block:: ql + + signature class NodeSig; + + signature module EdgeSig { + predicate apply(Node src, Node dst); + } + + module Reachability Edge> { + Node reachableFrom(Node src) { + Edge::apply+(src, result) + } + } From f738567f96b03e33d87d05b2113ca9df09b78e76 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 17 Aug 2022 22:56:46 +0200 Subject: [PATCH 043/659] refactor some code out into a helper class QueryDoc --- ql/ql/src/codeql_ql/ast/Ast.qll | 25 +++++++++++++++++++ .../queries/style/ConsistentAlertMessage.ql | 17 ++++++------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index f206ed9d49a..de50b58a5fc 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -176,6 +176,29 @@ class QLDoc extends TQLDoc, Comment { override AstNode getParent() { result.getQLDoc() = this } } +/** The QLDoc for a query (i.e. the top comment in a .ql file). */ +class QueryDoc extends QLDoc { + QueryDoc() { + this.getLocation().getFile().getExtension() = "ql" and + this = any(TopLevel t).getQLDoc() + } + + override string getAPrimaryQlClass() { result = "QueryDoc" } + + /** Gets the @kind for the query */ + string getQueryKind() { result = this.getContents().regexpCapture("(?s).*@kind (\\w+)\\s.*", 1) } + + /** Gets the id part (without language) of the @id */ + string getQueryId() { + result = this.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 2) + } + + /** Gets the language of the @id */ + string getQueryLanguage() { + result = this.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 1) + } +} + class BlockComment extends TBlockComment, Comment { QL::BlockComment comment; @@ -237,6 +260,8 @@ class Select extends TSelect, AstNode { } override string getAPrimaryQlClass() { result = "Select" } + + QueryDoc getQueryDoc() { result.getLocation().getFile() = this.getLocation().getFile() } } class PredicateOrBuiltin extends TPredOrBuiltin, AstNode { diff --git a/ql/ql/src/queries/style/ConsistentAlertMessage.ql b/ql/ql/src/queries/style/ConsistentAlertMessage.ql index a63824ea38a..854358d8b04 100644 --- a/ql/ql/src/queries/style/ConsistentAlertMessage.ql +++ b/ql/ql/src/queries/style/ConsistentAlertMessage.ql @@ -31,13 +31,10 @@ string getMessage(Select sel) { * This fingerprint avoid false positives where two queries with the same ID behave differently (which is OK). */ string getSelectFingerPrint(Select sel) { - exists(File file, QLDoc doc | - sel.getLocation().getFile() = file and - any(TopLevel top | top.getLocation().getFile() = file).getQLDoc() = doc - | + exists(QueryDoc doc | doc = sel.getQueryDoc() | result = - doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 2) // query ID (without lang) - + "-" + doc.getContents().regexpCapture("(?s).*@kind (\\w+)\\s.*", 1) // @kind + doc.getQueryId() // query ID (without lang) + + "-" + doc.getQueryKind() // @kind + "-" + strictcount(String e | e.getParent*() = sel.getExpr(any(int i | i % 2 = 1))) // the number of string constants in the select + "-" + count(sel.getExpr(_)) // and the total number of expressions in the select @@ -49,10 +46,10 @@ string getSelectFingerPrint(Select sel) { * The query-id (without language), the language, the message from the select, and a language agnostic fingerprint. */ Select parseSelect(string id, string lang, string msg, string fingerPrint) { - exists(File file, QLDoc doc | result.getLocation().getFile() = file | - any(TopLevel top | top.getLocation().getFile() = file).getQLDoc() = doc and - id = doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 2) and - lang = doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 1) and + exists(QueryDoc doc | + doc = result.getQueryDoc() and + id = doc.getQueryId() and + lang = doc.getQueryLanguage() and fingerPrint = getSelectFingerPrint(result) and msg = getMessage(result).toLowerCase() // case normalize, because some languages upper-case methods. ) and From cb110ba266d55569a4206e9cf468ced1c486a7a9 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 17 Aug 2022 22:57:27 +0200 Subject: [PATCH 044/659] this is an odd commit --- ql/ql/src/queries/style/ConsistentAlertMessage.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/ql/src/queries/style/ConsistentAlertMessage.ql b/ql/ql/src/queries/style/ConsistentAlertMessage.ql index 854358d8b04..eb147031f2a 100644 --- a/ql/ql/src/queries/style/ConsistentAlertMessage.ql +++ b/ql/ql/src/queries/style/ConsistentAlertMessage.ql @@ -17,7 +17,7 @@ import ql string getMessage(Select sel) { result = strictconcat(String e, Location l | - // is child of an expression in the select (in an uneven position, that's where the message is) + // is child of an expression in the select (in an odd-indexed position, that's where the message is) e.getParent*() = sel.getExpr(any(int i | i % 2 = 1)) and l = e.getFullLocation() | e.getValue(), " | " order by l.getStartLine(), l.getStartColumn() From 7850ab2dcc88a71088a483aac7cf098aef29a7fa Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 17 Aug 2022 22:58:58 +0200 Subject: [PATCH 045/659] rename badlangs to otherlangs --- ql/ql/src/queries/style/ConsistentAlertMessage.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ql/ql/src/queries/style/ConsistentAlertMessage.ql b/ql/ql/src/queries/style/ConsistentAlertMessage.ql index eb147031f2a..467254430e6 100644 --- a/ql/ql/src/queries/style/ConsistentAlertMessage.ql +++ b/ql/ql/src/queries/style/ConsistentAlertMessage.ql @@ -58,12 +58,12 @@ Select parseSelect(string id, string lang, string msg, string fingerPrint) { not lang = "ql" // excluding QL-for-QL } -from Select sel, string id, string lang, string msg, string fingerPrint, string badLangs +from Select sel, string id, string lang, string msg, string fingerPrint, string otherLangs where // for a select with a fingerprint sel = parseSelect(id, lang, msg, fingerPrint) and // there exists other languages with the same fingerprint, but other message - badLangs = + otherLangs = strictconcat(string bad | bad != lang and exists(parseSelect(id, bad, any(string otherMsg | otherMsg != msg), fingerPrint)) @@ -71,4 +71,4 @@ where bad, ", " ) select sel, - "The " + lang + "/" + id + " query does not have the same alert message as " + badLangs + "." + "The " + lang + "/" + id + " query does not have the same alert message as " + otherLangs + "." From d96dca4f5e03372f3df8537f0f962f4ad2dfb956 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 17 Aug 2022 22:59:16 +0200 Subject: [PATCH 046/659] fix typo --- ql/ql/src/queries/style/ConsistentAlertMessage.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/ql/src/queries/style/ConsistentAlertMessage.ql b/ql/ql/src/queries/style/ConsistentAlertMessage.ql index 467254430e6..c2d0c9be180 100644 --- a/ql/ql/src/queries/style/ConsistentAlertMessage.ql +++ b/ql/ql/src/queries/style/ConsistentAlertMessage.ql @@ -28,7 +28,7 @@ string getMessage(Select sel) { * Gets a language agnostic fingerprint for a Select. * The fingerPrint includes e.g. the query-id, the @kind of the query, and the number of expressions in the select. * - * This fingerprint avoid false positives where two queries with the same ID behave differently (which is OK). + * This fingerprint avoids false positives where two queries with the same ID behave differently (which is OK). */ string getSelectFingerPrint(Select sel) { exists(QueryDoc doc | doc = sel.getQueryDoc() | From 473bc92e2d45799a06b48728552e5e91986c450c Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 16 Aug 2022 11:13:47 +0200 Subject: [PATCH 047/659] move the `PrefixConstruction` module out of the `ReDoSPruning` module --- .../code/java/security/regexp/NfaUtils.qll | 207 +++++++++--------- .../javascript/security/regexp/NfaUtils.qll | 207 +++++++++--------- .../python/security/regexp/NfaUtils.qll | 207 +++++++++--------- .../codeql/ruby/security/regexp/NfaUtils.qll | 207 +++++++++--------- 4 files changed, 428 insertions(+), 400 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll index fdcb10c2f85..fe473b88f81 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll @@ -877,6 +877,101 @@ predicate isStartState(State state) { */ signature predicate isCandidateSig(State state, string pump); +/** + * Holds if `state` is a candidate for ReDoS. + */ +signature predicate isCandidateSig(State state); + +/** + * Predicates for constructing a prefix string that leads to a given state. + */ +module PrefixConstruction { + /** + * Holds if `state` is the textually last start state for the regular expression. + */ + private predicate lastStartState(State state) { + exists(RegExpRoot root | + state = + max(State s, Location l | + s = stateInPumpableRegexp() and + isStartState(s) and + getRoot(s.getRepr()) = root and + l = s.getRepr().getLocation() + | + s + order by + l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), + l.getEndLine() + ) + ) + } + + /** + * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. + */ + private predicate existsTransition(State a, State b) { delta(a, _, b) } + + /** + * Gets the minimum number of transitions it takes to reach `state` from the `start` state. + */ + int prefixLength(State start, State state) = + shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) + + /** + * Gets the minimum number of transitions it takes to reach `state` from the start state. + */ + private int lengthFromStart(State state) { result = prefixLength(_, state) } + + /** + * Gets a string for which the regular expression will reach `state`. + * + * Has at most one result for any given `state`. + * This predicate will not always have a result even if there is a ReDoS issue in + * the regular expression. + */ + string prefix(State state) { + lastStartState(state) and + result = "" + or + // the search stops past the last redos candidate state. + lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and + exists(State prev | + // select a unique predecessor (by an arbitrary measure) + prev = + min(State s, Location loc | + lengthFromStart(s) = lengthFromStart(state) - 1 and + loc = s.getRepr().getLocation() and + delta(s, _, state) + | + s + order by + loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), + s.getRepr().toString() + ) + | + // greedy search for the shortest prefix + result = prefix(prev) and delta(prev, Epsilon(), state) + or + not delta(prev, Epsilon(), state) and + result = prefix(prev) + getCanonicalEdgeChar(prev, state) + ) + } + + /** + * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. + */ + private string getCanonicalEdgeChar(State prev, State next) { + result = + min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) + } + + /** Gets a state within a regular expression that has a pumpable state. */ + pragma[noinline] + State stateInPumpableRegexp() { + exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr())) + } +} + /** * A module for pruning candidate ReDoS states. * The candidates are specified by the `isCandidate` signature predicate. @@ -910,95 +1005,9 @@ module ReDoSPruning { /** Gets a state that can reach the `accept-any` state using only epsilon steps. */ private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) } - /** - * Predicates for constructing a prefix string that leads to a given state. - */ - private module PrefixConstruction { - /** - * Holds if `state` is the textually last start state for the regular expression. - */ - private predicate lastStartState(State state) { - exists(RegExpRoot root | - state = - max(State s, Location l | - s = stateInPumpableRegexp() and - isStartState(s) and - getRoot(s.getRepr()) = root and - l = s.getRepr().getLocation() - | - s - order by - l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), - l.getEndLine() - ) - ) - } + predicate isCandidateState(State s) { isReDoSCandidate(s, _) } - /** - * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. - */ - private predicate existsTransition(State a, State b) { delta(a, _, b) } - - /** - * Gets the minimum number of transitions it takes to reach `state` from the `start` state. - */ - int prefixLength(State start, State state) = - shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) - - /** - * Gets the minimum number of transitions it takes to reach `state` from the start state. - */ - private int lengthFromStart(State state) { result = prefixLength(_, state) } - - /** - * Gets a string for which the regular expression will reach `state`. - * - * Has at most one result for any given `state`. - * This predicate will not always have a result even if there is a ReDoS issue in - * the regular expression. - */ - string prefix(State state) { - lastStartState(state) and - result = "" - or - // the search stops past the last redos candidate state. - lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and - exists(State prev | - // select a unique predecessor (by an arbitrary measure) - prev = - min(State s, Location loc | - lengthFromStart(s) = lengthFromStart(state) - 1 and - loc = s.getRepr().getLocation() and - delta(s, _, state) - | - s - order by - loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), - s.getRepr().toString() - ) - | - // greedy search for the shortest prefix - result = prefix(prev) and delta(prev, Epsilon(), state) - or - not delta(prev, Epsilon(), state) and - result = prefix(prev) + getCanonicalEdgeChar(prev, state) - ) - } - - /** - * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. - */ - private string getCanonicalEdgeChar(State prev, State next) { - result = - min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) - } - - /** Gets a state within a regular expression that has a pumpable state. */ - pragma[noinline] - State stateInPumpableRegexp() { - exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(result.getRepr())) - } - } + import PrefixConstruction as Prefix /** * Predicates for testing the presence of a rejecting suffix. @@ -1018,8 +1027,6 @@ module ReDoSPruning { * using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes. */ private module SuffixConstruction { - import PrefixConstruction - /** * Holds if all states reachable from `fork` by repeating `w` * are likely rejectable by appending some suffix. @@ -1036,7 +1043,7 @@ module ReDoSPruning { */ pragma[noinline] private predicate isLikelyRejectable(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and ( // exists a reject edge with some char. hasRejectEdge(s) @@ -1052,7 +1059,7 @@ module ReDoSPruning { * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. */ predicate isRejectState(State s) { - s = stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_) + s = Prefix::stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_) } /** @@ -1060,7 +1067,7 @@ module ReDoSPruning { */ pragma[noopt] predicate hasEdgeToLikelyRejectable(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and // all edges (at least one) with some char leads to another state that is rejectable. // the `next` states might not share a common suffix, which can cause FPs. exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | @@ -1076,7 +1083,7 @@ module ReDoSPruning { */ pragma[noinline] private string hasEdgeToLikelyRejectableHelper(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and not hasRejectEdge(s) and not isRejectState(s) and deltaClosedChar(s, result, _) @@ -1088,8 +1095,8 @@ module ReDoSPruning { * `prev` to `next` that the character symbol `char`. */ predicate deltaClosedChar(State prev, string char, State next) { - prev = stateInPumpableRegexp() and - next = stateInPumpableRegexp() and + prev = Prefix::stateInPumpableRegexp() and + next = Prefix::stateInPumpableRegexp() and deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) } @@ -1208,12 +1215,12 @@ module ReDoSPruning { predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) { isReDoSAttackable(t, pump, s) and ( - prefixMsg = "starting with '" + escape(PrefixConstruction::prefix(s)) + "' and " and - not PrefixConstruction::prefix(s) = "" + prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and + not Prefix::prefix(s) = "" or - PrefixConstruction::prefix(s) = "" and prefixMsg = "" + Prefix::prefix(s) = "" and prefixMsg = "" or - not exists(PrefixConstruction::prefix(s)) and prefixMsg = "" + not exists(Prefix::prefix(s)) and prefixMsg = "" ) } diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll b/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll index fdcb10c2f85..fe473b88f81 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll @@ -877,6 +877,101 @@ predicate isStartState(State state) { */ signature predicate isCandidateSig(State state, string pump); +/** + * Holds if `state` is a candidate for ReDoS. + */ +signature predicate isCandidateSig(State state); + +/** + * Predicates for constructing a prefix string that leads to a given state. + */ +module PrefixConstruction { + /** + * Holds if `state` is the textually last start state for the regular expression. + */ + private predicate lastStartState(State state) { + exists(RegExpRoot root | + state = + max(State s, Location l | + s = stateInPumpableRegexp() and + isStartState(s) and + getRoot(s.getRepr()) = root and + l = s.getRepr().getLocation() + | + s + order by + l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), + l.getEndLine() + ) + ) + } + + /** + * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. + */ + private predicate existsTransition(State a, State b) { delta(a, _, b) } + + /** + * Gets the minimum number of transitions it takes to reach `state` from the `start` state. + */ + int prefixLength(State start, State state) = + shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) + + /** + * Gets the minimum number of transitions it takes to reach `state` from the start state. + */ + private int lengthFromStart(State state) { result = prefixLength(_, state) } + + /** + * Gets a string for which the regular expression will reach `state`. + * + * Has at most one result for any given `state`. + * This predicate will not always have a result even if there is a ReDoS issue in + * the regular expression. + */ + string prefix(State state) { + lastStartState(state) and + result = "" + or + // the search stops past the last redos candidate state. + lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and + exists(State prev | + // select a unique predecessor (by an arbitrary measure) + prev = + min(State s, Location loc | + lengthFromStart(s) = lengthFromStart(state) - 1 and + loc = s.getRepr().getLocation() and + delta(s, _, state) + | + s + order by + loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), + s.getRepr().toString() + ) + | + // greedy search for the shortest prefix + result = prefix(prev) and delta(prev, Epsilon(), state) + or + not delta(prev, Epsilon(), state) and + result = prefix(prev) + getCanonicalEdgeChar(prev, state) + ) + } + + /** + * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. + */ + private string getCanonicalEdgeChar(State prev, State next) { + result = + min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) + } + + /** Gets a state within a regular expression that has a pumpable state. */ + pragma[noinline] + State stateInPumpableRegexp() { + exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr())) + } +} + /** * A module for pruning candidate ReDoS states. * The candidates are specified by the `isCandidate` signature predicate. @@ -910,95 +1005,9 @@ module ReDoSPruning { /** Gets a state that can reach the `accept-any` state using only epsilon steps. */ private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) } - /** - * Predicates for constructing a prefix string that leads to a given state. - */ - private module PrefixConstruction { - /** - * Holds if `state` is the textually last start state for the regular expression. - */ - private predicate lastStartState(State state) { - exists(RegExpRoot root | - state = - max(State s, Location l | - s = stateInPumpableRegexp() and - isStartState(s) and - getRoot(s.getRepr()) = root and - l = s.getRepr().getLocation() - | - s - order by - l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), - l.getEndLine() - ) - ) - } + predicate isCandidateState(State s) { isReDoSCandidate(s, _) } - /** - * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. - */ - private predicate existsTransition(State a, State b) { delta(a, _, b) } - - /** - * Gets the minimum number of transitions it takes to reach `state` from the `start` state. - */ - int prefixLength(State start, State state) = - shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) - - /** - * Gets the minimum number of transitions it takes to reach `state` from the start state. - */ - private int lengthFromStart(State state) { result = prefixLength(_, state) } - - /** - * Gets a string for which the regular expression will reach `state`. - * - * Has at most one result for any given `state`. - * This predicate will not always have a result even if there is a ReDoS issue in - * the regular expression. - */ - string prefix(State state) { - lastStartState(state) and - result = "" - or - // the search stops past the last redos candidate state. - lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and - exists(State prev | - // select a unique predecessor (by an arbitrary measure) - prev = - min(State s, Location loc | - lengthFromStart(s) = lengthFromStart(state) - 1 and - loc = s.getRepr().getLocation() and - delta(s, _, state) - | - s - order by - loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), - s.getRepr().toString() - ) - | - // greedy search for the shortest prefix - result = prefix(prev) and delta(prev, Epsilon(), state) - or - not delta(prev, Epsilon(), state) and - result = prefix(prev) + getCanonicalEdgeChar(prev, state) - ) - } - - /** - * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. - */ - private string getCanonicalEdgeChar(State prev, State next) { - result = - min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) - } - - /** Gets a state within a regular expression that has a pumpable state. */ - pragma[noinline] - State stateInPumpableRegexp() { - exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(result.getRepr())) - } - } + import PrefixConstruction as Prefix /** * Predicates for testing the presence of a rejecting suffix. @@ -1018,8 +1027,6 @@ module ReDoSPruning { * using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes. */ private module SuffixConstruction { - import PrefixConstruction - /** * Holds if all states reachable from `fork` by repeating `w` * are likely rejectable by appending some suffix. @@ -1036,7 +1043,7 @@ module ReDoSPruning { */ pragma[noinline] private predicate isLikelyRejectable(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and ( // exists a reject edge with some char. hasRejectEdge(s) @@ -1052,7 +1059,7 @@ module ReDoSPruning { * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. */ predicate isRejectState(State s) { - s = stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_) + s = Prefix::stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_) } /** @@ -1060,7 +1067,7 @@ module ReDoSPruning { */ pragma[noopt] predicate hasEdgeToLikelyRejectable(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and // all edges (at least one) with some char leads to another state that is rejectable. // the `next` states might not share a common suffix, which can cause FPs. exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | @@ -1076,7 +1083,7 @@ module ReDoSPruning { */ pragma[noinline] private string hasEdgeToLikelyRejectableHelper(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and not hasRejectEdge(s) and not isRejectState(s) and deltaClosedChar(s, result, _) @@ -1088,8 +1095,8 @@ module ReDoSPruning { * `prev` to `next` that the character symbol `char`. */ predicate deltaClosedChar(State prev, string char, State next) { - prev = stateInPumpableRegexp() and - next = stateInPumpableRegexp() and + prev = Prefix::stateInPumpableRegexp() and + next = Prefix::stateInPumpableRegexp() and deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) } @@ -1208,12 +1215,12 @@ module ReDoSPruning { predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) { isReDoSAttackable(t, pump, s) and ( - prefixMsg = "starting with '" + escape(PrefixConstruction::prefix(s)) + "' and " and - not PrefixConstruction::prefix(s) = "" + prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and + not Prefix::prefix(s) = "" or - PrefixConstruction::prefix(s) = "" and prefixMsg = "" + Prefix::prefix(s) = "" and prefixMsg = "" or - not exists(PrefixConstruction::prefix(s)) and prefixMsg = "" + not exists(Prefix::prefix(s)) and prefixMsg = "" ) } diff --git a/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll b/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll index fdcb10c2f85..fe473b88f81 100644 --- a/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll +++ b/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll @@ -877,6 +877,101 @@ predicate isStartState(State state) { */ signature predicate isCandidateSig(State state, string pump); +/** + * Holds if `state` is a candidate for ReDoS. + */ +signature predicate isCandidateSig(State state); + +/** + * Predicates for constructing a prefix string that leads to a given state. + */ +module PrefixConstruction { + /** + * Holds if `state` is the textually last start state for the regular expression. + */ + private predicate lastStartState(State state) { + exists(RegExpRoot root | + state = + max(State s, Location l | + s = stateInPumpableRegexp() and + isStartState(s) and + getRoot(s.getRepr()) = root and + l = s.getRepr().getLocation() + | + s + order by + l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), + l.getEndLine() + ) + ) + } + + /** + * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. + */ + private predicate existsTransition(State a, State b) { delta(a, _, b) } + + /** + * Gets the minimum number of transitions it takes to reach `state` from the `start` state. + */ + int prefixLength(State start, State state) = + shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) + + /** + * Gets the minimum number of transitions it takes to reach `state` from the start state. + */ + private int lengthFromStart(State state) { result = prefixLength(_, state) } + + /** + * Gets a string for which the regular expression will reach `state`. + * + * Has at most one result for any given `state`. + * This predicate will not always have a result even if there is a ReDoS issue in + * the regular expression. + */ + string prefix(State state) { + lastStartState(state) and + result = "" + or + // the search stops past the last redos candidate state. + lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and + exists(State prev | + // select a unique predecessor (by an arbitrary measure) + prev = + min(State s, Location loc | + lengthFromStart(s) = lengthFromStart(state) - 1 and + loc = s.getRepr().getLocation() and + delta(s, _, state) + | + s + order by + loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), + s.getRepr().toString() + ) + | + // greedy search for the shortest prefix + result = prefix(prev) and delta(prev, Epsilon(), state) + or + not delta(prev, Epsilon(), state) and + result = prefix(prev) + getCanonicalEdgeChar(prev, state) + ) + } + + /** + * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. + */ + private string getCanonicalEdgeChar(State prev, State next) { + result = + min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) + } + + /** Gets a state within a regular expression that has a pumpable state. */ + pragma[noinline] + State stateInPumpableRegexp() { + exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr())) + } +} + /** * A module for pruning candidate ReDoS states. * The candidates are specified by the `isCandidate` signature predicate. @@ -910,95 +1005,9 @@ module ReDoSPruning { /** Gets a state that can reach the `accept-any` state using only epsilon steps. */ private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) } - /** - * Predicates for constructing a prefix string that leads to a given state. - */ - private module PrefixConstruction { - /** - * Holds if `state` is the textually last start state for the regular expression. - */ - private predicate lastStartState(State state) { - exists(RegExpRoot root | - state = - max(State s, Location l | - s = stateInPumpableRegexp() and - isStartState(s) and - getRoot(s.getRepr()) = root and - l = s.getRepr().getLocation() - | - s - order by - l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), - l.getEndLine() - ) - ) - } + predicate isCandidateState(State s) { isReDoSCandidate(s, _) } - /** - * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. - */ - private predicate existsTransition(State a, State b) { delta(a, _, b) } - - /** - * Gets the minimum number of transitions it takes to reach `state` from the `start` state. - */ - int prefixLength(State start, State state) = - shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) - - /** - * Gets the minimum number of transitions it takes to reach `state` from the start state. - */ - private int lengthFromStart(State state) { result = prefixLength(_, state) } - - /** - * Gets a string for which the regular expression will reach `state`. - * - * Has at most one result for any given `state`. - * This predicate will not always have a result even if there is a ReDoS issue in - * the regular expression. - */ - string prefix(State state) { - lastStartState(state) and - result = "" - or - // the search stops past the last redos candidate state. - lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and - exists(State prev | - // select a unique predecessor (by an arbitrary measure) - prev = - min(State s, Location loc | - lengthFromStart(s) = lengthFromStart(state) - 1 and - loc = s.getRepr().getLocation() and - delta(s, _, state) - | - s - order by - loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), - s.getRepr().toString() - ) - | - // greedy search for the shortest prefix - result = prefix(prev) and delta(prev, Epsilon(), state) - or - not delta(prev, Epsilon(), state) and - result = prefix(prev) + getCanonicalEdgeChar(prev, state) - ) - } - - /** - * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. - */ - private string getCanonicalEdgeChar(State prev, State next) { - result = - min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) - } - - /** Gets a state within a regular expression that has a pumpable state. */ - pragma[noinline] - State stateInPumpableRegexp() { - exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(result.getRepr())) - } - } + import PrefixConstruction as Prefix /** * Predicates for testing the presence of a rejecting suffix. @@ -1018,8 +1027,6 @@ module ReDoSPruning { * using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes. */ private module SuffixConstruction { - import PrefixConstruction - /** * Holds if all states reachable from `fork` by repeating `w` * are likely rejectable by appending some suffix. @@ -1036,7 +1043,7 @@ module ReDoSPruning { */ pragma[noinline] private predicate isLikelyRejectable(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and ( // exists a reject edge with some char. hasRejectEdge(s) @@ -1052,7 +1059,7 @@ module ReDoSPruning { * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. */ predicate isRejectState(State s) { - s = stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_) + s = Prefix::stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_) } /** @@ -1060,7 +1067,7 @@ module ReDoSPruning { */ pragma[noopt] predicate hasEdgeToLikelyRejectable(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and // all edges (at least one) with some char leads to another state that is rejectable. // the `next` states might not share a common suffix, which can cause FPs. exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | @@ -1076,7 +1083,7 @@ module ReDoSPruning { */ pragma[noinline] private string hasEdgeToLikelyRejectableHelper(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and not hasRejectEdge(s) and not isRejectState(s) and deltaClosedChar(s, result, _) @@ -1088,8 +1095,8 @@ module ReDoSPruning { * `prev` to `next` that the character symbol `char`. */ predicate deltaClosedChar(State prev, string char, State next) { - prev = stateInPumpableRegexp() and - next = stateInPumpableRegexp() and + prev = Prefix::stateInPumpableRegexp() and + next = Prefix::stateInPumpableRegexp() and deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) } @@ -1208,12 +1215,12 @@ module ReDoSPruning { predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) { isReDoSAttackable(t, pump, s) and ( - prefixMsg = "starting with '" + escape(PrefixConstruction::prefix(s)) + "' and " and - not PrefixConstruction::prefix(s) = "" + prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and + not Prefix::prefix(s) = "" or - PrefixConstruction::prefix(s) = "" and prefixMsg = "" + Prefix::prefix(s) = "" and prefixMsg = "" or - not exists(PrefixConstruction::prefix(s)) and prefixMsg = "" + not exists(Prefix::prefix(s)) and prefixMsg = "" ) } diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll b/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll index fdcb10c2f85..fe473b88f81 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll @@ -877,6 +877,101 @@ predicate isStartState(State state) { */ signature predicate isCandidateSig(State state, string pump); +/** + * Holds if `state` is a candidate for ReDoS. + */ +signature predicate isCandidateSig(State state); + +/** + * Predicates for constructing a prefix string that leads to a given state. + */ +module PrefixConstruction { + /** + * Holds if `state` is the textually last start state for the regular expression. + */ + private predicate lastStartState(State state) { + exists(RegExpRoot root | + state = + max(State s, Location l | + s = stateInPumpableRegexp() and + isStartState(s) and + getRoot(s.getRepr()) = root and + l = s.getRepr().getLocation() + | + s + order by + l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), + l.getEndLine() + ) + ) + } + + /** + * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. + */ + private predicate existsTransition(State a, State b) { delta(a, _, b) } + + /** + * Gets the minimum number of transitions it takes to reach `state` from the `start` state. + */ + int prefixLength(State start, State state) = + shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) + + /** + * Gets the minimum number of transitions it takes to reach `state` from the start state. + */ + private int lengthFromStart(State state) { result = prefixLength(_, state) } + + /** + * Gets a string for which the regular expression will reach `state`. + * + * Has at most one result for any given `state`. + * This predicate will not always have a result even if there is a ReDoS issue in + * the regular expression. + */ + string prefix(State state) { + lastStartState(state) and + result = "" + or + // the search stops past the last redos candidate state. + lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and + exists(State prev | + // select a unique predecessor (by an arbitrary measure) + prev = + min(State s, Location loc | + lengthFromStart(s) = lengthFromStart(state) - 1 and + loc = s.getRepr().getLocation() and + delta(s, _, state) + | + s + order by + loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), + s.getRepr().toString() + ) + | + // greedy search for the shortest prefix + result = prefix(prev) and delta(prev, Epsilon(), state) + or + not delta(prev, Epsilon(), state) and + result = prefix(prev) + getCanonicalEdgeChar(prev, state) + ) + } + + /** + * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. + */ + private string getCanonicalEdgeChar(State prev, State next) { + result = + min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) + } + + /** Gets a state within a regular expression that has a pumpable state. */ + pragma[noinline] + State stateInPumpableRegexp() { + exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr())) + } +} + /** * A module for pruning candidate ReDoS states. * The candidates are specified by the `isCandidate` signature predicate. @@ -910,95 +1005,9 @@ module ReDoSPruning { /** Gets a state that can reach the `accept-any` state using only epsilon steps. */ private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) } - /** - * Predicates for constructing a prefix string that leads to a given state. - */ - private module PrefixConstruction { - /** - * Holds if `state` is the textually last start state for the regular expression. - */ - private predicate lastStartState(State state) { - exists(RegExpRoot root | - state = - max(State s, Location l | - s = stateInPumpableRegexp() and - isStartState(s) and - getRoot(s.getRepr()) = root and - l = s.getRepr().getLocation() - | - s - order by - l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(), - l.getEndLine() - ) - ) - } + predicate isCandidateState(State s) { isReDoSCandidate(s, _) } - /** - * Holds if there exists any transition (Epsilon() or other) from `a` to `b`. - */ - private predicate existsTransition(State a, State b) { delta(a, _, b) } - - /** - * Gets the minimum number of transitions it takes to reach `state` from the `start` state. - */ - int prefixLength(State start, State state) = - shortestDistances(lastStartState/1, existsTransition/2)(start, state, result) - - /** - * Gets the minimum number of transitions it takes to reach `state` from the start state. - */ - private int lengthFromStart(State state) { result = prefixLength(_, state) } - - /** - * Gets a string for which the regular expression will reach `state`. - * - * Has at most one result for any given `state`. - * This predicate will not always have a result even if there is a ReDoS issue in - * the regular expression. - */ - string prefix(State state) { - lastStartState(state) and - result = "" - or - // the search stops past the last redos candidate state. - lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and - exists(State prev | - // select a unique predecessor (by an arbitrary measure) - prev = - min(State s, Location loc | - lengthFromStart(s) = lengthFromStart(state) - 1 and - loc = s.getRepr().getLocation() and - delta(s, _, state) - | - s - order by - loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(), - s.getRepr().toString() - ) - | - // greedy search for the shortest prefix - result = prefix(prev) and delta(prev, Epsilon(), state) - or - not delta(prev, Epsilon(), state) and - result = prefix(prev) + getCanonicalEdgeChar(prev, state) - ) - } - - /** - * Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA. - */ - private string getCanonicalEdgeChar(State prev, State next) { - result = - min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) - } - - /** Gets a state within a regular expression that has a pumpable state. */ - pragma[noinline] - State stateInPumpableRegexp() { - exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(result.getRepr())) - } - } + import PrefixConstruction as Prefix /** * Predicates for testing the presence of a rejecting suffix. @@ -1018,8 +1027,6 @@ module ReDoSPruning { * using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes. */ private module SuffixConstruction { - import PrefixConstruction - /** * Holds if all states reachable from `fork` by repeating `w` * are likely rejectable by appending some suffix. @@ -1036,7 +1043,7 @@ module ReDoSPruning { */ pragma[noinline] private predicate isLikelyRejectable(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and ( // exists a reject edge with some char. hasRejectEdge(s) @@ -1052,7 +1059,7 @@ module ReDoSPruning { * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. */ predicate isRejectState(State s) { - s = stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_) + s = Prefix::stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_) } /** @@ -1060,7 +1067,7 @@ module ReDoSPruning { */ pragma[noopt] predicate hasEdgeToLikelyRejectable(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and // all edges (at least one) with some char leads to another state that is rejectable. // the `next` states might not share a common suffix, which can cause FPs. exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | @@ -1076,7 +1083,7 @@ module ReDoSPruning { */ pragma[noinline] private string hasEdgeToLikelyRejectableHelper(State s) { - s = stateInPumpableRegexp() and + s = Prefix::stateInPumpableRegexp() and not hasRejectEdge(s) and not isRejectState(s) and deltaClosedChar(s, result, _) @@ -1088,8 +1095,8 @@ module ReDoSPruning { * `prev` to `next` that the character symbol `char`. */ predicate deltaClosedChar(State prev, string char, State next) { - prev = stateInPumpableRegexp() and - next = stateInPumpableRegexp() and + prev = Prefix::stateInPumpableRegexp() and + next = Prefix::stateInPumpableRegexp() and deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) } @@ -1208,12 +1215,12 @@ module ReDoSPruning { predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) { isReDoSAttackable(t, pump, s) and ( - prefixMsg = "starting with '" + escape(PrefixConstruction::prefix(s)) + "' and " and - not PrefixConstruction::prefix(s) = "" + prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and + not Prefix::prefix(s) = "" or - PrefixConstruction::prefix(s) = "" and prefixMsg = "" + Prefix::prefix(s) = "" and prefixMsg = "" or - not exists(PrefixConstruction::prefix(s)) and prefixMsg = "" + not exists(Prefix::prefix(s)) and prefixMsg = "" ) } From de3e1c39e47614f3ab0d1fc3dc131eafa9f26de2 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 18 Aug 2022 10:05:31 +0200 Subject: [PATCH 048/659] use the shared regular expression libraries in `js/case-sensitive-middleware-path` --- .../CWE-178/CaseSensitiveMiddlewarePath.ql | 91 +++++++++++++------ .../CaseSensitiveMiddlewarePath.expected | 2 +- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index ccf659bf024..61952328511 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -41,34 +41,29 @@ predicate isLikelyCaseSensitiveRegExp(RegExpTerm term) { ) } -/** - * Gets a string matched by `term`, or part of such a string. - */ -string getExampleString(RegExpTerm term) { - result = term.getAMatchedString() - or - // getAMatchedString does not recurse into sequences. Perform one step manually. - exists(RegExpSequence seq | seq = term | - result = - strictconcat(RegExpTerm child, int i, string text | - child = seq.getChild(i) and - ( - text = child.getAMatchedString() - or - not exists(child.getAMatchedString()) and - text = "" - ) - | - text order by i - ) +import semmle.javascript.security.regexp.NfaUtils as NfaUtils + +/** Holds if `s` is a relevant regexp term were we want to compute a string that matches the term (for `getCaseSensitiveBypassExample`). */ +predicate isCand(NfaUtils::State s) { + s.getRepr().isRootTerm() and + exists(DataFlow::RegExpCreationNode creation | + isCaseSensitiveMiddleware(_, creation, _) and + s.getRepr().getRootTerm() = creation.getRoot() ) } +import NfaUtils::PrefixConstruction as Prefix + +/** Gets a string matched by `term`. */ +string getExampleString(RegExpTerm term) { + result = Prefix::prefix(any(NfaUtils::State s | s.getRepr() = term)) +} + string getCaseSensitiveBypassExample(RegExpTerm term) { - exists(string example | - example = getExampleString(term) and - result = toOtherCase(example) and - result != example // getting an example string is approximate; ensure we got a proper case-change example + exists(string byPassExample | + byPassExample = getExampleString(term) and + result = toOtherCase(byPassExample) and + result != byPassExample // getting an byPassExample string is approximate; ensure we got a proper case-change byPassExample ) } @@ -108,14 +103,54 @@ predicate isGuardedCaseInsensitiveEndpoint( ) } +/** + * Gets an byPassExample path that will hit `endpoint`. + * Query parameters (e.g. the ":param" in "/foo/:param") have been replaced with byPassExample values. + */ +string getAnEndpointExample(Routing::RouteSetup endpoint) { + exists(string raw | + raw = endpoint.getRelativePath().toLowerCase() and + result = raw.regexpReplaceAll(":\\w+\\b", ["a", "1"]) + ) +} + +import semmle.javascript.security.regexp.RegexpMatching as RegexpMatching + +/** + * Holds if the regexp matcher should test whether `root` matches `str`. + * The result is used to test whether a case-sensitive bypass exists. + */ +predicate isMatchingCandidate( + RegexpMatching::RootTerm root, string str, boolean ignorePrefix, boolean testWithGroups +) { + exists( + Routing::RouteSetup middleware, Routing::RouteSetup endPoint, + DataFlow::RegExpCreationNode regexp + | + isCaseSensitiveMiddleware(middleware, regexp, _) and + isGuardedCaseInsensitiveEndpoint(endPoint, middleware) + | + root = regexp.getRoot() and + exists(getCaseSensitiveBypassExample(root)) and + ignorePrefix = true and + testWithGroups = false and + str = [getCaseSensitiveBypassExample(root), getAnEndpointExample(endPoint)] + ) +} + +import RegexpMatching::RegexpMatching as Matcher + from DataFlow::RegExpCreationNode regexp, Routing::RouteSetup middleware, Routing::RouteSetup endpoint, - DataFlow::Node arg, string example + DataFlow::Node arg, string byPassExample where isCaseSensitiveMiddleware(middleware, regexp, arg) and - example = getCaseSensitiveBypassExample(regexp.getRoot()) and + byPassExample = getCaseSensitiveBypassExample(regexp.getRoot()) and isGuardedCaseInsensitiveEndpoint(endpoint, middleware) and - exists(endpoint.getRelativePath().toLowerCase().indexOf(example.toLowerCase())) + exists(string endpointExample | endpointExample = getAnEndpointExample(endpoint) | + Matcher::matches(regexp.getRoot(), endpointExample) and + not Matcher::matches(regexp.getRoot(), byPassExample) + ) select arg, "This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '" - + example + "' will bypass the middleware.", regexp, "pattern", endpoint, "here" + + byPassExample + "' will bypass the middleware.", regexp, "pattern", endpoint, "here" diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected index a79b3100a80..788b5c08726 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected @@ -1,3 +1,3 @@ | tst.js:8:9:8:19 | /\\/foo\\/.*/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/' will bypass the middleware. | tst.js:8:9:8:19 | /\\/foo\\/.*/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | | tst.js:14:5:14:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO' will bypass the middleware. | tst.js:14:5:14:28 | new Reg ... (.*)?') | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | -| tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | +| tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/0' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | From 5704995b62607a88b99c9cf48207e5088182d5db Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 18 Aug 2022 13:23:39 +0100 Subject: [PATCH 049/659] C++: Fix joins in 'cpp/using-expired-stack-address'. --- .../UsingExpiredStackAddress.ql | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql index 3f3997315d4..1f9743cf9d3 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql @@ -106,6 +106,26 @@ predicate inheritanceConversionTypes( toType = convert.getResultType() } +private signature class ConversionInstruction extends UnaryInstruction; + +module Conversion { + signature predicate hasTypes(I instr, Type fromType, Type toType); + + module Using { + pragma[nomagic] + predicate hasOperandAndTypes(I convert, Instruction unary, Type fromType, Type toType) { + project(convert, fromType, toType) and + unary = convert.getUnary() + } + } +} + +pragma[nomagic] +predicate hasObjectAndField(FieldAddressInstruction fai, Instruction object, Field f) { + fai.getObjectAddress() = object and + fai.getField() = f +} + /** Gets the HashCons value of an address computed by `instr`, if any. */ TGlobalAddress globalAddress(Instruction instr) { result = TGlobalVariable(instr.(VariableAddressInstruction).getAstVariable()) @@ -117,25 +137,27 @@ TGlobalAddress globalAddress(Instruction instr) { result = TLoad(globalAddress(load.getSourceAddress())) ) or - exists(ConvertInstruction convert, Type fromType, Type toType | instr = convert | - uncheckedConversionTypes(convert, fromType, toType) and - result = TConversion("unchecked", globalAddress(convert.getUnary()), fromType, toType) + exists(Type fromType, Type toType, Instruction unary | + Conversion::Using::hasOperandAndTypes(instr, + unary, fromType, toType) and + result = TConversion("unchecked", globalAddress(unary), fromType, toType) ) or - exists(CheckedConvertOrNullInstruction convert, Type fromType, Type toType | instr = convert | - checkedConversionTypes(convert, fromType, toType) and - result = TConversion("checked", globalAddress(convert.getUnary()), fromType, toType) + exists(Type fromType, Type toType, Instruction unary | + Conversion::Using::hasOperandAndTypes(instr, + unary, fromType, toType) and + result = TConversion("checked", globalAddress(unary), fromType, toType) ) or - exists(InheritanceConversionInstruction convert, Type fromType, Type toType | instr = convert | - inheritanceConversionTypes(convert, fromType, toType) and - result = TConversion("inheritance", globalAddress(convert.getUnary()), fromType, toType) + exists(Type fromType, Type toType, Instruction unary | + Conversion::Using::hasOperandAndTypes(instr, + unary, fromType, toType) and + result = TConversion("inheritance", globalAddress(unary), fromType, toType) ) or - exists(FieldAddressInstruction fai | instr = fai | - result = - TFieldAddress(globalAddress(pragma[only_bind_into](fai.getObjectAddress())), - pragma[only_bind_out](fai.getField())) + exists(FieldAddressInstruction fai, Instruction object, Field f | instr = fai | + hasObjectAndField(fai, object, f) and + result = TFieldAddress(globalAddress(object), f) ) or result = globalAddress(instr.(PointerOffsetInstruction).getLeft()) From 26fcf6b25be25793f5a003675038b190b44b9da7 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 18 Aug 2022 15:00:57 +0200 Subject: [PATCH 050/659] apply suggestions from review --- .../Security/CWE-178/CaseSensitiveMiddlewarePath.ql | 6 +++--- .../CWE-178/CaseSensitiveMiddlewarePath.expected | 1 + .../ql/test/query-tests/Security/CWE-178/tst.js | 13 +++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index 61952328511..ba031b5a88a 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -104,13 +104,13 @@ predicate isGuardedCaseInsensitiveEndpoint( } /** - * Gets an byPassExample path that will hit `endpoint`. - * Query parameters (e.g. the ":param" in "/foo/:param") have been replaced with byPassExample values. + * Gets an example path that will hit `endpoint`. + * Query parameters (e.g. the ":param" in "/foo/:param") have been replaced with example values. */ string getAnEndpointExample(Routing::RouteSetup endpoint) { exists(string raw | raw = endpoint.getRelativePath().toLowerCase() and - result = raw.regexpReplaceAll(":\\w+\\b", ["a", "1"]) + result = raw.regexpReplaceAll(":\\w+\\b|\\*", ["a", "1"]) ) } diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected index 788b5c08726..f6364edcddf 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected @@ -1,3 +1,4 @@ | tst.js:8:9:8:19 | /\\/foo\\/.*/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/' will bypass the middleware. | tst.js:8:9:8:19 | /\\/foo\\/.*/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | | tst.js:14:5:14:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO' will bypass the middleware. | tst.js:14:5:14:28 | new Reg ... (.*)?') | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/0' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | +| tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/BAR' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:73:1:74:2 | app.get ... ware\\n}) | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-178/tst.js b/javascript/ql/test/query-tests/Security/CWE-178/tst.js index 1acb57b16ea..6e3ef8797e8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-178/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-178/tst.js @@ -59,3 +59,16 @@ app.use(/\/foo\/([0-9]+)/i, (req, res) => { // OK - not middleware (also case in app.get('/foo/:param', (req, res) => { // OK - not a middleware }); + +app.get( + new RegExp('^/bar(.*)?'), // NOT OK - case sensitive + unknown(), + function(req, res, next) { + if (req.params.blah) { + next(); + } + } +); + +app.get('/bar/*', (req, res) => { // OK - not a middleware +}); From e8f027dab28f188fb4c511572c266411b8d6b9c4 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 18 Aug 2022 14:21:40 +0100 Subject: [PATCH 051/659] Apply docs suggestions from code review Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp | 4 ++-- java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp index 227b3797abf..03b0e032520 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.qhelp @@ -2,8 +2,8 @@ -

    Cryptographic algorithms often use padding schemes to make the plaintext less predictable. The OAEP scheme (Optimal Asymmetric Encryption Padding) should be used with RSA encryption. - Using no padding or an outdated padding scheme such as PKCS1 can weaken the encryption by making it vulnerable to a padding oracle attack. +

    Cryptographic algorithms often use padding schemes to make the plaintext less predictable. The OAEP (Optimal Asymmetric Encryption Padding) scheme should be used with RSA encryption. + Using an outdated padding scheme such as PKCS1, or no padding at all, can weaken the encryption by making it vulnerable to a padding oracle attack.

    diff --git a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql index e841f5543c2..a5c8b954d27 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql @@ -1,6 +1,6 @@ /** * @name Use of RSA algorithm without OAEP - * @description Using RSA encryption without OAEP padding can lead to a padding oracle attack, weakening the encryption. + * @description Using RSA encryption without OAEP padding can result in a padding oracle attack, leading to a weaker encryption. * @kind path-problem * @problem.severity warning * @security-severity 7.5 From f275885258b923a32ea73a68919158c736c3a90a Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 19 May 2020 15:05:13 +0200 Subject: [PATCH 052/659] C#: Add a cshtml-based XSS test --- .../CWE-079/XSS/Index.cshtml | 1 + .../CWE-079/XSS/Index.cshtml.g.cs | 62 +++++++++++++++++++ .../CWE-079/XSS/XSS.expected | 4 ++ .../CWE-079/XSS/XSSAspNet.cs | 2 - .../CWE-079/XSS/XSSAspNetCore.cs | 2 - 5 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-079/XSS/Index.cshtml create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-079/XSS/Index.cshtml.g.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/Index.cshtml b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/Index.cshtml new file mode 100644 index 00000000000..cfa374bdb67 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/Index.cshtml @@ -0,0 +1 @@ +// empty \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/Index.cshtml.g.cs b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/Index.cshtml.g.cs new file mode 100644 index 00000000000..bbd3b9a66ff --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/Index.cshtml.g.cs @@ -0,0 +1,62 @@ +// A hand-written test file that mimics the output of compiling a `.cshtml` file +#pragma checksum "Index.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "c4ae76542f1958092cebd8f57beef899d20fc548" +// +#pragma warning disable 1591 +[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(dotnetweb.Pages.Pages_Index), @"mvc.1.0.razor-page", @"Index.cshtml")] +namespace dotnetweb.Pages +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; +#nullable restore +using dotnetweb; + +#line default +#line hidden +#nullable disable + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"c4ae76542f1958092cebd8f57beef899d20fc548", @"Index.cshtml")] + // [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"c13da96c2597d5ddb7d415fb4892c644a268f50b", @"/Pages/_ViewImports.cshtml")] + public class Pages_Index : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { +#nullable restore +#line 3 "Index.cshtml" + + ViewData["Title"] = "ASP.NET Core"; + var message = Request.Query["m"]; + +#line default +#line hidden +#nullable disable + WriteLiteral("
    \n
    \n"); +#nullable restore +#line 14 "Index.cshtml" +Write(Html.Raw(message)); // BAD + +#line default +#line hidden +#nullable disable + WriteLiteral("\n
    \n
    \n\n\n"); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)PageContext?.ViewData; + } +} +#pragma warning restore 1591 diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSS.expected b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSS.expected index b5bf1f609f3..added443400 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSS.expected @@ -1,4 +1,5 @@ edges +| Index.cshtml:5:19:5:31 | access to property Query : IQueryCollection | Index.cshtml:14:16:14:22 | call to operator implicit conversion | | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:19:25:19:52 | access to indexer : String | | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:26:30:26:34 | access to local variable sayHi | | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:36:40:36:44 | access to local variable sayHi | @@ -14,6 +15,8 @@ edges | XSSAspNetCore.cs:61:44:61:63 | access to indexer : StringValues | XSSAspNetCore.cs:61:44:61:66 | access to indexer | | XSSAspNetCore.cs:72:51:72:65 | access to property Headers : IHeaderDictionary | XSSAspNetCore.cs:72:51:72:72 | call to operator implicit conversion | nodes +| Index.cshtml:5:19:5:31 | access to property Query : IQueryCollection | semmle.label | access to property Query : IQueryCollection | +| Index.cshtml:14:16:14:22 | call to operator implicit conversion | semmle.label | call to operator implicit conversion | | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | | XSSAspNet.cs:19:25:19:52 | access to indexer : String | semmle.label | access to indexer : String | | XSSAspNet.cs:26:30:26:34 | access to local variable sayHi | semmle.label | access to local variable sayHi | @@ -36,6 +39,7 @@ nodes | XSSAspNetCore.cs:72:51:72:72 | call to operator implicit conversion | semmle.label | call to operator implicit conversion | subpaths #select +| Index.cshtml:14:16:14:22 | call to operator implicit conversion | Index.cshtml:5:19:5:31 | access to property Query : IQueryCollection | Index.cshtml:14:16:14:22 | call to operator implicit conversion | $@ flows to here and is written to HTML or JavaScript: Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.Raw() method. | Index.cshtml:5:19:5:31 | access to property Query : IQueryCollection | User-provided value | | XSSAspNet.cs:26:30:26:34 | access to local variable sayHi | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:26:30:26:34 | access to local variable sayHi | $@ flows to here and is written to HTML or JavaScript: System.Web.WebPages.WebPage.WriteLiteral() method. | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | User-provided value | | XSSAspNet.cs:36:40:36:44 | access to local variable sayHi | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:36:40:36:44 | access to local variable sayHi | $@ flows to here and is written to HTML or JavaScript: System.Web.WebPages.WebPage.WriteLiteralTo() method. | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | User-provided value | | XSSAspNet.cs:43:28:43:55 | access to indexer | XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | XSSAspNet.cs:43:28:43:55 | access to indexer | $@ flows to here and is written to HTML or JavaScript. | XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | User-provided value | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSSAspNet.cs b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSSAspNet.cs index ae004ed100c..c9779db5bc6 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSSAspNet.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSSAspNet.cs @@ -46,5 +46,3 @@ namespace ASP } } } - -// source-extractor-options: /r:${testdir}/../../../../../packages/Microsoft.AspNet.WebPages.3.2.3/lib/net45/System.Web.WebPages.dll /r:${testdir}/../../../../../packages/Microsoft.AspNet.Mvc.5.2.3/lib/net45/System.Web.Mvc.dll /r:System.Dynamic.Runtime.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Expressions.dll /r:System.Web.dll /r:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Web.dll /r:System.Collections.Specialized.dll diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSSAspNetCore.cs b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSSAspNetCore.cs index 0740598a9e4..89d7ca98f96 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSSAspNetCore.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/XSS/XSSAspNetCore.cs @@ -75,5 +75,3 @@ namespace Testing.Controllers } } } - -// initial-extractor-options: /r:netstandard.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Mvc.1.1.3/lib/net451/Microsoft.AspNetCore.Mvc.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Mvc.Core.1.1.3/lib/net451/Microsoft.AspNetCore.Mvc.Core.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Antiforgery.1.1.2/lib/net451/Microsoft.AspNetCore.Antiforgery.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Mvc.ViewFeatures.1.1.3/lib/net451/Microsoft.AspNetCore.Mvc.ViewFeatures.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Mvc.Abstractions.1.1.3/lib/net451/Microsoft.AspNetCore.Mvc.Abstractions.dll /r:${testdir}/../../../../../packages\Microsoft.AspNetCore.Http.Abstractions.1.1.2\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Html.Abstractions.1.1.2/lib/netstandard1.0/Microsoft.AspNetCore.Html.Abstractions.dll /r:${testdir}/../../../../../packages/Microsoft.AspNetCore.Http.Features.1.1.2\lib\net451\Microsoft.AspNetCore.Http.Features.dll /r:${testdir}/../../../../../packages\Microsoft.Extensions.Primitives.2.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll /r:System.Linq.dll /r:System.Linq.Expressions.dll /r:System.Linq.Queryable.dll From 17dd1f64ecdd9d4de01c5ceeebac0980de1819dc Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 18 Aug 2022 12:01:09 +0100 Subject: [PATCH 053/659] Java: pick an arbitrary representative location when an entity has many candidate locations. --- java/ql/lib/semmle/code/Location.qll | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/Location.qll b/java/ql/lib/semmle/code/Location.qll index 8bb81becb11..c906b9f2407 100755 --- a/java/ql/lib/semmle/code/Location.qll +++ b/java/ql/lib/semmle/code/Location.qll @@ -205,5 +205,19 @@ cached private predicate fixedHasLocation(Top l, Location loc, File f) { hasSourceLocation(l, loc, f) or - hasLocation(l, loc) and not hasSourceLocation(l, _, _) and locations_default(loc, f, _, _, _, _) + // When an entity has more than one location, as it might due to + // e.g. a parameterized generic being seen and extracted in several + // different directories or JAR files, select an arbitrary representative + // location to avoid needlessly duplicating alerts. + // + // Don't do this when the relevant location is in a source file, because + // that is much more unusual and we would rather notice the bug than mask it here. + loc = + min(Location candidateLoc | + hasLocation(l, candidateLoc) + | + candidateLoc order by candidateLoc.getFile().toString() + ) and + not hasSourceLocation(l, _, _) and + locations_default(loc, f, _, _, _, _) } From ec1cc72669681f5ca4e948ff184fbda5c7286b8d Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 18 Aug 2022 15:02:16 +0100 Subject: [PATCH 054/659] Note support for Java 19 --- docs/codeql/support/reusables/versions-compilers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/support/reusables/versions-compilers.rst b/docs/codeql/support/reusables/versions-compilers.rst index 4dfadcfb276..c734cf65ff3 100644 --- a/docs/codeql/support/reusables/versions-compilers.rst +++ b/docs/codeql/support/reusables/versions-compilers.rst @@ -30,7 +30,7 @@ .. [1] C++20 support is currently in beta. Supported for GCC on Linux only. Modules are *not* supported. .. [2] Support for the clang-cl compiler is preliminary. .. [3] Support for the Arm Compiler (armcc) is preliminary. - .. [4] Builds that execute on Java 7 to 18 can be analyzed. The analysis understands Java 18 standard language features. + .. [4] Builds that execute on Java 7 to 19 can be analyzed. The analysis understands Java 19 standard language features. .. [5] ECJ is supported when the build invokes it via the Maven Compiler plugin or the Takari Lifecycle plugin. .. [6] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files. .. [7] Requires glibc 2.17. From 38b4c02508eb70735ecfb2546f3a0d157e6fa24b Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 27 Jun 2022 18:01:09 +0200 Subject: [PATCH 055/659] C++: Support link targets for global and namespace variables --- cpp/ql/lib/semmle/code/cpp/Linkage.qll | 9 +++++++++ cpp/ql/lib/semmle/code/cpp/Variable.qll | 3 +++ 2 files changed, 12 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/Linkage.qll b/cpp/ql/lib/semmle/code/cpp/Linkage.qll index 54a6099eaef..766ddd188c1 100644 --- a/cpp/ql/lib/semmle/code/cpp/Linkage.qll +++ b/cpp/ql/lib/semmle/code/cpp/Linkage.qll @@ -41,6 +41,15 @@ class LinkTarget extends @link_target { * translation units which contributed to this link target. */ Class getAClass() { link_parent(unresolveElement(result), this) } + + /** + * Gets a global or namespace variable which was compiled into this + * link target, or had its declaration included by one of the translation + * units which contributed to this link target. + */ + GlobalOrNamespaceVariable getAGlobalOrNamespaceVariable() { + link_parent(unresolveElement(result), this) + } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/Variable.qll b/cpp/ql/lib/semmle/code/cpp/Variable.qll index 7e188980b9c..022eb22c7f5 100644 --- a/cpp/ql/lib/semmle/code/cpp/Variable.qll +++ b/cpp/ql/lib/semmle/code/cpp/Variable.qll @@ -471,6 +471,9 @@ class GlobalOrNamespaceVariable extends Variable, @globalvariable { override Type getType() { globalvariables(underlyingElement(this), unresolveElement(result), _) } override Element getEnclosingElement() { none() } + + /** Gets a link target which compiled or referenced this global or namespace variable. */ + LinkTarget getALinkTarget() { this = result.getAGlobalOrNamespaceVariable() } } /** From 8eb5d001f766e6848ccb6fc271b713db4716d892 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 18 Aug 2022 16:22:04 +0100 Subject: [PATCH 056/659] Upgrade Go extractor to latest golang and x-packages --- go/go.mod | 6 +- go/go.sum | 6 + go/vendor/golang.org/x/mod/modfile/read.go | 1 - go/vendor/golang.org/x/mod/modfile/rule.go | 563 ++++++++++------ go/vendor/golang.org/x/mod/modfile/work.go | 234 +++++++ go/vendor/golang.org/x/mod/module/module.go | 15 +- go/vendor/golang.org/x/mod/semver/semver.go | 10 - go/vendor/golang.org/x/sys/AUTHORS | 3 - go/vendor/golang.org/x/sys/CONTRIBUTORS | 3 - go/vendor/golang.org/x/sys/execabs/execabs.go | 2 +- .../golang.org/x/sys/execabs/execabs_go118.go | 12 + .../golang.org/x/sys/execabs/execabs_go119.go | 15 + go/vendor/golang.org/x/tools/AUTHORS | 3 - go/vendor/golang.org/x/tools/CONTRIBUTORS | 3 - .../x/tools/go/gcexportdata/gcexportdata.go | 72 ++- .../x/tools/go/gcexportdata/importer.go | 2 + .../x/tools/go/internal/gcimporter/bexport.go | 43 +- .../x/tools/go/internal/gcimporter/bimport.go | 52 +- .../go/internal/gcimporter/exportdata.go | 16 +- .../go/internal/gcimporter/gcimporter.go | 171 +++-- .../x/tools/go/internal/gcimporter/iexport.go | 323 +++++++-- .../x/tools/go/internal/gcimporter/iimport.go | 342 ++++++++-- .../go/internal/gcimporter/support_go117.go | 16 + .../go/internal/gcimporter/support_go118.go | 23 + .../go/internal/gcimporter/unified_no.go | 10 + .../go/internal/gcimporter/unified_yes.go | 10 + .../go/internal/gcimporter/ureader_no.go | 19 + .../go/internal/gcimporter/ureader_yes.go | 612 ++++++++++++++++++ .../x/tools/go/internal/pkgbits/codes.go | 77 +++ .../x/tools/go/internal/pkgbits/decoder.go | 433 +++++++++++++ .../x/tools/go/internal/pkgbits/doc.go | 32 + .../x/tools/go/internal/pkgbits/encoder.go | 379 +++++++++++ .../x/tools/go/internal/pkgbits/flags.go | 9 + .../x/tools/go/internal/pkgbits/frames_go1.go | 21 + .../tools/go/internal/pkgbits/frames_go17.go | 28 + .../x/tools/go/internal/pkgbits/reloc.go | 42 ++ .../x/tools/go/internal/pkgbits/support.go | 17 + .../x/tools/go/internal/pkgbits/sync.go | 113 ++++ .../go/internal/pkgbits/syncmarker_string.go | 89 +++ .../golang.org/x/tools/go/packages/doc.go | 1 - .../golang.org/x/tools/go/packages/golist.go | 92 ++- .../x/tools/go/packages/loadmode_string.go | 4 +- .../x/tools/go/packages/packages.go | 78 ++- .../x/tools/internal/gocommand/invoke.go | 22 +- .../x/tools/internal/gocommand/vendor.go | 22 +- .../internal/packagesinternal/packages.go | 2 + .../x/tools/internal/typeparams/common.go | 179 +++++ .../x/tools/internal/typeparams/coretype.go | 122 ++++ .../internal/typeparams/enabled_go117.go | 12 + .../internal/typeparams/enabled_go118.go | 15 + .../x/tools/internal/typeparams/normalize.go | 218 +++++++ .../x/tools/internal/typeparams/termlist.go | 163 +++++ .../internal/typeparams/typeparams_go117.go | 197 ++++++ .../internal/typeparams/typeparams_go118.go | 151 +++++ .../x/tools/internal/typeparams/typeterm.go | 170 +++++ .../tools/internal/typesinternal/errorcode.go | 158 +++++ .../typesinternal/errorcode_string.go | 18 +- .../x/tools/internal/typesinternal/types.go | 11 +- .../tools/internal/typesinternal/types_118.go | 19 + go/vendor/golang.org/x/xerrors/LICENSE | 27 - go/vendor/golang.org/x/xerrors/PATENTS | 22 - go/vendor/golang.org/x/xerrors/README | 2 - go/vendor/golang.org/x/xerrors/adaptor.go | 193 ------ go/vendor/golang.org/x/xerrors/codereview.cfg | 1 - go/vendor/golang.org/x/xerrors/doc.go | 22 - go/vendor/golang.org/x/xerrors/errors.go | 33 - go/vendor/golang.org/x/xerrors/fmt.go | 187 ------ go/vendor/golang.org/x/xerrors/format.go | 34 - go/vendor/golang.org/x/xerrors/frame.go | 56 -- .../golang.org/x/xerrors/internal/internal.go | 8 - go/vendor/golang.org/x/xerrors/wrap.go | 106 --- go/vendor/modules.txt | 12 +- 72 files changed, 4945 insertions(+), 1239 deletions(-) create mode 100644 go/vendor/golang.org/x/mod/modfile/work.go delete mode 100644 go/vendor/golang.org/x/sys/AUTHORS delete mode 100644 go/vendor/golang.org/x/sys/CONTRIBUTORS create mode 100644 go/vendor/golang.org/x/sys/execabs/execabs_go118.go create mode 100644 go/vendor/golang.org/x/sys/execabs/execabs_go119.go delete mode 100644 go/vendor/golang.org/x/tools/AUTHORS delete mode 100644 go/vendor/golang.org/x/tools/CONTRIBUTORS create mode 100644 go/vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/support.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go create mode 100644 go/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/common.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/coretype.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/normalize.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/termlist.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go create mode 100644 go/vendor/golang.org/x/tools/internal/typeparams/typeterm.go create mode 100644 go/vendor/golang.org/x/tools/internal/typesinternal/types_118.go delete mode 100644 go/vendor/golang.org/x/xerrors/LICENSE delete mode 100644 go/vendor/golang.org/x/xerrors/PATENTS delete mode 100644 go/vendor/golang.org/x/xerrors/README delete mode 100644 go/vendor/golang.org/x/xerrors/adaptor.go delete mode 100644 go/vendor/golang.org/x/xerrors/codereview.cfg delete mode 100644 go/vendor/golang.org/x/xerrors/doc.go delete mode 100644 go/vendor/golang.org/x/xerrors/errors.go delete mode 100644 go/vendor/golang.org/x/xerrors/fmt.go delete mode 100644 go/vendor/golang.org/x/xerrors/format.go delete mode 100644 go/vendor/golang.org/x/xerrors/frame.go delete mode 100644 go/vendor/golang.org/x/xerrors/internal/internal.go delete mode 100644 go/vendor/golang.org/x/xerrors/wrap.go diff --git a/go/go.mod b/go/go.mod index 25e2d87d342..48bdb72b158 100644 --- a/go/go.mod +++ b/go/go.mod @@ -3,11 +3,11 @@ module github.com/github/codeql-go go 1.18 require ( - golang.org/x/mod v0.5.0 - golang.org/x/tools v0.1.5 + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 + golang.org/x/tools v0.1.12 ) require ( - golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect + golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect ) diff --git a/go/go.sum b/go/go.sum index 57b82477ee7..9054efe904e 100644 --- a/go/go.sum +++ b/go/go.sum @@ -4,6 +4,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= @@ -15,6 +17,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -22,6 +26,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= diff --git a/go/vendor/golang.org/x/mod/modfile/read.go b/go/vendor/golang.org/x/mod/modfile/read.go index 956f30cbb39..70947ee7794 100644 --- a/go/vendor/golang.org/x/mod/modfile/read.go +++ b/go/vendor/golang.org/x/mod/modfile/read.go @@ -285,7 +285,6 @@ func (x *Line) Span() (start, end Position) { // "x" // "y" // ) -// type LineBlock struct { Comments Start Position diff --git a/go/vendor/golang.org/x/mod/modfile/rule.go b/go/vendor/golang.org/x/mod/modfile/rule.go index 78f83fa7144..ed2f31aa70e 100644 --- a/go/vendor/golang.org/x/mod/modfile/rule.go +++ b/go/vendor/golang.org/x/mod/modfile/rule.go @@ -423,68 +423,12 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a } case "replace": - arrow := 2 - if len(args) >= 2 && args[1] == "=>" { - arrow = 1 - } - if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { - errorf("usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory", verb, verb) + replace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix) + if wrappederr != nil { + *errs = append(*errs, *wrappederr) return } - s, err := parseString(&args[0]) - if err != nil { - errorf("invalid quoted string: %v", err) - return - } - pathMajor, err := modulePathMajor(s) - if err != nil { - wrapModPathError(s, err) - return - } - var v string - if arrow == 2 { - v, err = parseVersion(verb, s, &args[1], fix) - if err != nil { - wrapError(err) - return - } - if err := module.CheckPathMajor(v, pathMajor); err != nil { - wrapModPathError(s, err) - return - } - } - ns, err := parseString(&args[arrow+1]) - if err != nil { - errorf("invalid quoted string: %v", err) - return - } - nv := "" - if len(args) == arrow+2 { - if !IsDirectoryPath(ns) { - errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)") - return - } - if filepath.Separator == '/' && strings.Contains(ns, `\`) { - errorf("replacement directory appears to be Windows path (on a non-windows system)") - return - } - } - if len(args) == arrow+3 { - nv, err = parseVersion(verb, ns, &args[arrow+2], fix) - if err != nil { - wrapError(err) - return - } - if IsDirectoryPath(ns) { - errorf("replacement module directory path %q cannot have version", ns) - return - } - } - f.Replace = append(f.Replace, &Replace{ - Old: module.Version{Path: s, Version: v}, - New: module.Version{Path: ns, Version: nv}, - Syntax: line, - }) + f.Replace = append(f.Replace, replace) case "retract": rationale := parseDirectiveComment(block, line) @@ -515,6 +459,83 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a } } +func parseReplace(filename string, line *Line, verb string, args []string, fix VersionFixer) (*Replace, *Error) { + wrapModPathError := func(modPath string, err error) *Error { + return &Error{ + Filename: filename, + Pos: line.Start, + ModPath: modPath, + Verb: verb, + Err: err, + } + } + wrapError := func(err error) *Error { + return &Error{ + Filename: filename, + Pos: line.Start, + Err: err, + } + } + errorf := func(format string, args ...interface{}) *Error { + return wrapError(fmt.Errorf(format, args...)) + } + + arrow := 2 + if len(args) >= 2 && args[1] == "=>" { + arrow = 1 + } + if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { + return nil, errorf("usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory", verb, verb) + } + s, err := parseString(&args[0]) + if err != nil { + return nil, errorf("invalid quoted string: %v", err) + } + pathMajor, err := modulePathMajor(s) + if err != nil { + return nil, wrapModPathError(s, err) + + } + var v string + if arrow == 2 { + v, err = parseVersion(verb, s, &args[1], fix) + if err != nil { + return nil, wrapError(err) + } + if err := module.CheckPathMajor(v, pathMajor); err != nil { + return nil, wrapModPathError(s, err) + } + } + ns, err := parseString(&args[arrow+1]) + if err != nil { + return nil, errorf("invalid quoted string: %v", err) + } + nv := "" + if len(args) == arrow+2 { + if !IsDirectoryPath(ns) { + return nil, errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)") + } + if filepath.Separator == '/' && strings.Contains(ns, `\`) { + return nil, errorf("replacement directory appears to be Windows path (on a non-windows system)") + } + } + if len(args) == arrow+3 { + nv, err = parseVersion(verb, ns, &args[arrow+2], fix) + if err != nil { + return nil, wrapError(err) + } + if IsDirectoryPath(ns) { + return nil, errorf("replacement module directory path %q cannot have version", ns) + + } + } + return &Replace{ + Old: module.Version{Path: s, Version: v}, + New: module.Version{Path: ns, Version: nv}, + Syntax: line, + }, nil +} + // fixRetract applies fix to each retract directive in f, appending any errors // to errs. // @@ -556,6 +577,63 @@ func (f *File) fixRetract(fix VersionFixer, errs *ErrorList) { } } +func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string, fix VersionFixer) { + wrapError := func(err error) { + *errs = append(*errs, Error{ + Filename: f.Syntax.Name, + Pos: line.Start, + Err: err, + }) + } + errorf := func(format string, args ...interface{}) { + wrapError(fmt.Errorf(format, args...)) + } + + switch verb { + default: + errorf("unknown directive: %s", verb) + + case "go": + if f.Go != nil { + errorf("repeated go statement") + return + } + if len(args) != 1 { + errorf("go directive expects exactly one argument") + return + } else if !GoVersionRE.MatchString(args[0]) { + errorf("invalid go version '%s': must match format 1.23", args[0]) + return + } + + f.Go = &Go{Syntax: line} + f.Go.Version = args[0] + + case "use": + if len(args) != 1 { + errorf("usage: %s local/dir", verb) + return + } + s, err := parseString(&args[0]) + if err != nil { + errorf("invalid quoted string: %v", err) + return + } + f.Use = append(f.Use, &Use{ + Path: s, + Syntax: line, + }) + + case "replace": + replace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix) + if wrappederr != nil { + *errs = append(*errs, *wrappederr) + return + } + f.Replace = append(f.Replace, replace) + } +} + // IsDirectoryPath reports whether the given path should be interpreted // as a directory path. Just like on the go command line, relative paths // and rooted paths are directory paths; the rest are module paths. @@ -956,170 +1034,217 @@ func (f *File) SetRequire(req []*Require) { // SetRequireSeparateIndirect updates the requirements of f to contain the given // requirements. Comment contents (except for 'indirect' markings) are retained -// from the first existing requirement for each module path, and block structure -// is maintained as long as the indirect markings match. +// from the first existing requirement for each module path. Like SetRequire, +// SetRequireSeparateIndirect adds requirements for new paths in req, +// updates the version and "// indirect" comment on existing requirements, +// and deletes requirements on paths not in req. Existing duplicate requirements +// are deleted. // -// Any requirements on paths not already present in the file are added. Direct -// requirements are added to the last block containing *any* other direct -// requirement. Indirect requirements are added to the last block containing -// *only* other indirect requirements. If no suitable block exists, a new one is -// added, with the last block containing a direct dependency (if any) -// immediately before the first block containing only indirect dependencies. +// As its name suggests, SetRequireSeparateIndirect puts direct and indirect +// requirements into two separate blocks, one containing only direct +// requirements, and the other containing only indirect requirements. +// SetRequireSeparateIndirect may move requirements between these two blocks +// when their indirect markings change. However, SetRequireSeparateIndirect +// won't move requirements from other blocks, especially blocks with comments. // -// The Syntax field is ignored for requirements in the given blocks. +// If the file initially has one uncommented block of requirements, +// SetRequireSeparateIndirect will split it into a direct-only and indirect-only +// block. This aids in the transition to separate blocks. func (f *File) SetRequireSeparateIndirect(req []*Require) { - type modKey struct { - path string - indirect bool - } - need := make(map[modKey]string) - for _, r := range req { - need[modKey{r.Mod.Path, r.Indirect}] = r.Mod.Version + // hasComments returns whether a line or block has comments + // other than "indirect". + hasComments := func(c Comments) bool { + return len(c.Before) > 0 || len(c.After) > 0 || len(c.Suffix) > 1 || + (len(c.Suffix) == 1 && + strings.TrimSpace(strings.TrimPrefix(c.Suffix[0].Token, string(slashSlash))) != "indirect") } - comments := make(map[string]Comments) - for _, r := range f.Require { - v, ok := need[modKey{r.Mod.Path, r.Indirect}] - if !ok { - if _, ok := need[modKey{r.Mod.Path, !r.Indirect}]; ok { - if _, dup := comments[r.Mod.Path]; !dup { - comments[r.Mod.Path] = r.Syntax.Comments - } + // moveReq adds r to block. If r was in another block, moveReq deletes + // it from that block and transfers its comments. + moveReq := func(r *Require, block *LineBlock) { + var line *Line + if r.Syntax == nil { + line = &Line{Token: []string{AutoQuote(r.Mod.Path), r.Mod.Version}} + r.Syntax = line + if r.Indirect { + r.setIndirect(true) } - r.markRemoved() - continue + } else { + line = new(Line) + *line = *r.Syntax + if !line.InBlock && len(line.Token) > 0 && line.Token[0] == "require" { + line.Token = line.Token[1:] + } + r.Syntax.Token = nil // Cleanup will delete the old line. + r.Syntax = line } - r.setVersion(v) - delete(need, modKey{r.Mod.Path, r.Indirect}) + line.InBlock = true + block.Line = append(block.Line, line) } + // Examine existing require lines and blocks. var ( - lastDirectOrMixedBlock Expr - firstIndirectOnlyBlock Expr - lastIndirectOnlyBlock Expr + // We may insert new requirements into the last uncommented + // direct-only and indirect-only blocks. We may also move requirements + // to the opposite block if their indirect markings change. + lastDirectIndex = -1 + lastIndirectIndex = -1 + + // If there are no direct-only or indirect-only blocks, a new block may + // be inserted after the last require line or block. + lastRequireIndex = -1 + + // If there's only one require line or block, and it's uncommented, + // we'll move its requirements to the direct-only or indirect-only blocks. + requireLineOrBlockCount = 0 + + // Track the block each requirement belongs to (if any) so we can + // move them later. + lineToBlock = make(map[*Line]*LineBlock) ) - for _, stmt := range f.Syntax.Stmt { + for i, stmt := range f.Syntax.Stmt { switch stmt := stmt.(type) { case *Line: if len(stmt.Token) == 0 || stmt.Token[0] != "require" { continue } - if isIndirect(stmt) { - lastIndirectOnlyBlock = stmt - } else { - lastDirectOrMixedBlock = stmt + lastRequireIndex = i + requireLineOrBlockCount++ + if !hasComments(stmt.Comments) { + if isIndirect(stmt) { + lastIndirectIndex = i + } else { + lastDirectIndex = i + } } + case *LineBlock: if len(stmt.Token) == 0 || stmt.Token[0] != "require" { continue } - indirectOnly := true + lastRequireIndex = i + requireLineOrBlockCount++ + allDirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments) + allIndirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments) for _, line := range stmt.Line { - if len(line.Token) == 0 { - continue - } - if !isIndirect(line) { - indirectOnly = false - break - } - } - if indirectOnly { - lastIndirectOnlyBlock = stmt - if firstIndirectOnlyBlock == nil { - firstIndirectOnlyBlock = stmt - } - } else { - lastDirectOrMixedBlock = stmt - } - } - } - - isOrContainsStmt := func(stmt Expr, target Expr) bool { - if stmt == target { - return true - } - if stmt, ok := stmt.(*LineBlock); ok { - if target, ok := target.(*Line); ok { - for _, line := range stmt.Line { - if line == target { - return true - } - } - } - } - return false - } - - addRequire := func(path, vers string, indirect bool, comments Comments) { - var line *Line - if indirect { - if lastIndirectOnlyBlock != nil { - line = f.Syntax.addLine(lastIndirectOnlyBlock, "require", path, vers) - } else { - // Add a new require block after the last direct-only or mixed "require" - // block (if any). - // - // (f.Syntax.addLine would add the line to an existing "require" block if - // present, but here the existing "require" blocks are all direct-only, so - // we know we need to add a new block instead.) - line = &Line{Token: []string{"require", path, vers}} - lastIndirectOnlyBlock = line - firstIndirectOnlyBlock = line // only block implies first block - if lastDirectOrMixedBlock == nil { - f.Syntax.Stmt = append(f.Syntax.Stmt, line) + lineToBlock[line] = stmt + if hasComments(line.Comments) { + allDirect = false + allIndirect = false + } else if isIndirect(line) { + allDirect = false } else { - for i, stmt := range f.Syntax.Stmt { - if isOrContainsStmt(stmt, lastDirectOrMixedBlock) { - f.Syntax.Stmt = append(f.Syntax.Stmt, nil) // increase size - copy(f.Syntax.Stmt[i+2:], f.Syntax.Stmt[i+1:]) // shuffle elements up - f.Syntax.Stmt[i+1] = line - break - } - } + allIndirect = false } } + if allDirect { + lastDirectIndex = i + } + if allIndirect { + lastIndirectIndex = i + } + } + } + + oneFlatUncommentedBlock := requireLineOrBlockCount == 1 && + !hasComments(*f.Syntax.Stmt[lastRequireIndex].Comment()) + + // Create direct and indirect blocks if needed. Convert lines into blocks + // if needed. If we end up with an empty block or a one-line block, + // Cleanup will delete it or convert it to a line later. + insertBlock := func(i int) *LineBlock { + block := &LineBlock{Token: []string{"require"}} + f.Syntax.Stmt = append(f.Syntax.Stmt, nil) + copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:]) + f.Syntax.Stmt[i] = block + return block + } + + ensureBlock := func(i int) *LineBlock { + switch stmt := f.Syntax.Stmt[i].(type) { + case *LineBlock: + return stmt + case *Line: + block := &LineBlock{ + Token: []string{"require"}, + Line: []*Line{stmt}, + } + stmt.Token = stmt.Token[1:] // remove "require" + stmt.InBlock = true + f.Syntax.Stmt[i] = block + return block + default: + panic(fmt.Sprintf("unexpected statement: %v", stmt)) + } + } + + var lastDirectBlock *LineBlock + if lastDirectIndex < 0 { + if lastIndirectIndex >= 0 { + lastDirectIndex = lastIndirectIndex + lastIndirectIndex++ + } else if lastRequireIndex >= 0 { + lastDirectIndex = lastRequireIndex + 1 } else { - if lastDirectOrMixedBlock != nil { - line = f.Syntax.addLine(lastDirectOrMixedBlock, "require", path, vers) + lastDirectIndex = len(f.Syntax.Stmt) + } + lastDirectBlock = insertBlock(lastDirectIndex) + } else { + lastDirectBlock = ensureBlock(lastDirectIndex) + } + + var lastIndirectBlock *LineBlock + if lastIndirectIndex < 0 { + lastIndirectIndex = lastDirectIndex + 1 + lastIndirectBlock = insertBlock(lastIndirectIndex) + } else { + lastIndirectBlock = ensureBlock(lastIndirectIndex) + } + + // Delete requirements we don't want anymore. + // Update versions and indirect comments on requirements we want to keep. + // If a requirement is in last{Direct,Indirect}Block with the wrong + // indirect marking after this, or if the requirement is in an single + // uncommented mixed block (oneFlatUncommentedBlock), move it to the + // correct block. + // + // Some blocks may be empty after this. Cleanup will remove them. + need := make(map[string]*Require) + for _, r := range req { + need[r.Mod.Path] = r + } + have := make(map[string]*Require) + for _, r := range f.Require { + path := r.Mod.Path + if need[path] == nil || have[path] != nil { + // Requirement not needed, or duplicate requirement. Delete. + r.markRemoved() + continue + } + have[r.Mod.Path] = r + r.setVersion(need[path].Mod.Version) + r.setIndirect(need[path].Indirect) + if need[path].Indirect && + (oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastDirectBlock) { + moveReq(r, lastIndirectBlock) + } else if !need[path].Indirect && + (oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastIndirectBlock) { + moveReq(r, lastDirectBlock) + } + } + + // Add new requirements. + for path, r := range need { + if have[path] == nil { + if r.Indirect { + moveReq(r, lastIndirectBlock) } else { - // Add a new require block before the first indirect block (if any). - // - // That way if the file initially contains only indirect lines, - // the direct lines still appear before it: we preserve existing - // structure, but only to the extent that that structure already - // reflects the direct/indirect split. - line = &Line{Token: []string{"require", path, vers}} - lastDirectOrMixedBlock = line - if firstIndirectOnlyBlock == nil { - f.Syntax.Stmt = append(f.Syntax.Stmt, line) - } else { - for i, stmt := range f.Syntax.Stmt { - if isOrContainsStmt(stmt, firstIndirectOnlyBlock) { - f.Syntax.Stmt = append(f.Syntax.Stmt, nil) // increase size - copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:]) // shuffle elements up - f.Syntax.Stmt[i] = line - break - } - } - } + moveReq(r, lastDirectBlock) } + f.Require = append(f.Require, r) } - - line.Comments.Before = commentsAdd(line.Comments.Before, comments.Before) - line.Comments.Suffix = commentsAdd(line.Comments.Suffix, comments.Suffix) - - r := &Require{ - Mod: module.Version{Path: path, Version: vers}, - Indirect: indirect, - Syntax: line, - } - r.setIndirect(indirect) - f.Require = append(f.Require, r) } - for k, vers := range need { - addRequire(k.path, vers, k.indirect, comments[k.path]) - } f.SortBlocks() } @@ -1165,6 +1290,10 @@ func (f *File) DropExclude(path, vers string) error { } func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { + return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers) +} + +func addReplace(syntax *FileSyntax, replace *[]*Replace, oldPath, oldVers, newPath, newVers string) error { need := true old := module.Version{Path: oldPath, Version: oldVers} new := module.Version{Path: newPath, Version: newVers} @@ -1178,12 +1307,12 @@ func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { } var hint *Line - for _, r := range f.Replace { + for _, r := range *replace { if r.Old.Path == oldPath && (oldVers == "" || r.Old.Version == oldVers) { if need { // Found replacement for old; update to use new. r.New = new - f.Syntax.updateLine(r.Syntax, tokens...) + syntax.updateLine(r.Syntax, tokens...) need = false continue } @@ -1196,7 +1325,7 @@ func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { } } if need { - f.Replace = append(f.Replace, &Replace{Old: old, New: new, Syntax: f.Syntax.addLine(hint, tokens...)}) + *replace = append(*replace, &Replace{Old: old, New: new, Syntax: syntax.addLine(hint, tokens...)}) } return nil } @@ -1282,30 +1411,36 @@ func (f *File) SortBlocks() { // retract directives are not de-duplicated since comments are // meaningful, and versions may be retracted multiple times. func (f *File) removeDups() { + removeDups(f.Syntax, &f.Exclude, &f.Replace) +} + +func removeDups(syntax *FileSyntax, exclude *[]*Exclude, replace *[]*Replace) { kill := make(map[*Line]bool) // Remove duplicate excludes. - haveExclude := make(map[module.Version]bool) - for _, x := range f.Exclude { - if haveExclude[x.Mod] { - kill[x.Syntax] = true - continue + if exclude != nil { + haveExclude := make(map[module.Version]bool) + for _, x := range *exclude { + if haveExclude[x.Mod] { + kill[x.Syntax] = true + continue + } + haveExclude[x.Mod] = true } - haveExclude[x.Mod] = true - } - var excl []*Exclude - for _, x := range f.Exclude { - if !kill[x.Syntax] { - excl = append(excl, x) + var excl []*Exclude + for _, x := range *exclude { + if !kill[x.Syntax] { + excl = append(excl, x) + } } + *exclude = excl } - f.Exclude = excl // Remove duplicate replacements. // Later replacements take priority over earlier ones. haveReplace := make(map[module.Version]bool) - for i := len(f.Replace) - 1; i >= 0; i-- { - x := f.Replace[i] + for i := len(*replace) - 1; i >= 0; i-- { + x := (*replace)[i] if haveReplace[x.Old] { kill[x.Syntax] = true continue @@ -1313,18 +1448,18 @@ func (f *File) removeDups() { haveReplace[x.Old] = true } var repl []*Replace - for _, x := range f.Replace { + for _, x := range *replace { if !kill[x.Syntax] { repl = append(repl, x) } } - f.Replace = repl + *replace = repl // Duplicate require and retract directives are not removed. // Drop killed statements from the syntax tree. var stmts []Expr - for _, stmt := range f.Syntax.Stmt { + for _, stmt := range syntax.Stmt { switch stmt := stmt.(type) { case *Line: if kill[stmt] { @@ -1344,7 +1479,7 @@ func (f *File) removeDups() { } stmts = append(stmts, stmt) } - f.Syntax.Stmt = stmts + syntax.Stmt = stmts } // lineLess returns whether li should be sorted before lj. It sorts diff --git a/go/vendor/golang.org/x/mod/modfile/work.go b/go/vendor/golang.org/x/mod/modfile/work.go new file mode 100644 index 00000000000..0c0e521525a --- /dev/null +++ b/go/vendor/golang.org/x/mod/modfile/work.go @@ -0,0 +1,234 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modfile + +import ( + "fmt" + "sort" + "strings" +) + +// A WorkFile is the parsed, interpreted form of a go.work file. +type WorkFile struct { + Go *Go + Use []*Use + Replace []*Replace + + Syntax *FileSyntax +} + +// A Use is a single directory statement. +type Use struct { + Path string // Use path of module. + ModulePath string // Module path in the comment. + Syntax *Line +} + +// ParseWork parses and returns a go.work file. +// +// file is the name of the file, used in positions and errors. +// +// data is the content of the file. +// +// fix is an optional function that canonicalizes module versions. +// If fix is nil, all module versions must be canonical (module.CanonicalVersion +// must return the same string). +func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) { + fs, err := parse(file, data) + if err != nil { + return nil, err + } + f := &WorkFile{ + Syntax: fs, + } + var errs ErrorList + + for _, x := range fs.Stmt { + switch x := x.(type) { + case *Line: + f.add(&errs, x, x.Token[0], x.Token[1:], fix) + + case *LineBlock: + if len(x.Token) > 1 { + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) + continue + } + switch x.Token[0] { + default: + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) + continue + case "use", "replace": + for _, l := range x.Line { + f.add(&errs, l, x.Token[0], l.Token, fix) + } + } + } + } + + if len(errs) > 0 { + return nil, errs + } + return f, nil +} + +// Cleanup cleans up the file f after any edit operations. +// To avoid quadratic behavior, modifications like DropRequire +// clear the entry but do not remove it from the slice. +// Cleanup cleans out all the cleared entries. +func (f *WorkFile) Cleanup() { + w := 0 + for _, r := range f.Use { + if r.Path != "" { + f.Use[w] = r + w++ + } + } + f.Use = f.Use[:w] + + w = 0 + for _, r := range f.Replace { + if r.Old.Path != "" { + f.Replace[w] = r + w++ + } + } + f.Replace = f.Replace[:w] + + f.Syntax.Cleanup() +} + +func (f *WorkFile) AddGoStmt(version string) error { + if !GoVersionRE.MatchString(version) { + return fmt.Errorf("invalid language version string %q", version) + } + if f.Go == nil { + stmt := &Line{Token: []string{"go", version}} + f.Go = &Go{ + Version: version, + Syntax: stmt, + } + // Find the first non-comment-only block that's and add + // the go statement before it. That will keep file comments at the top. + i := 0 + for i = 0; i < len(f.Syntax.Stmt); i++ { + if _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok { + break + } + } + f.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...) + } else { + f.Go.Version = version + f.Syntax.updateLine(f.Go.Syntax, "go", version) + } + return nil +} + +func (f *WorkFile) AddUse(diskPath, modulePath string) error { + need := true + for _, d := range f.Use { + if d.Path == diskPath { + if need { + d.ModulePath = modulePath + f.Syntax.updateLine(d.Syntax, "use", AutoQuote(diskPath)) + need = false + } else { + d.Syntax.markRemoved() + *d = Use{} + } + } + } + + if need { + f.AddNewUse(diskPath, modulePath) + } + return nil +} + +func (f *WorkFile) AddNewUse(diskPath, modulePath string) { + line := f.Syntax.addLine(nil, "use", AutoQuote(diskPath)) + f.Use = append(f.Use, &Use{Path: diskPath, ModulePath: modulePath, Syntax: line}) +} + +func (f *WorkFile) SetUse(dirs []*Use) { + need := make(map[string]string) + for _, d := range dirs { + need[d.Path] = d.ModulePath + } + + for _, d := range f.Use { + if modulePath, ok := need[d.Path]; ok { + d.ModulePath = modulePath + } else { + d.Syntax.markRemoved() + *d = Use{} + } + } + + // TODO(#45713): Add module path to comment. + + for diskPath, modulePath := range need { + f.AddNewUse(diskPath, modulePath) + } + f.SortBlocks() +} + +func (f *WorkFile) DropUse(path string) error { + for _, d := range f.Use { + if d.Path == path { + d.Syntax.markRemoved() + *d = Use{} + } + } + return nil +} + +func (f *WorkFile) AddReplace(oldPath, oldVers, newPath, newVers string) error { + return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers) +} + +func (f *WorkFile) DropReplace(oldPath, oldVers string) error { + for _, r := range f.Replace { + if r.Old.Path == oldPath && r.Old.Version == oldVers { + r.Syntax.markRemoved() + *r = Replace{} + } + } + return nil +} + +func (f *WorkFile) SortBlocks() { + f.removeDups() // otherwise sorting is unsafe + + for _, stmt := range f.Syntax.Stmt { + block, ok := stmt.(*LineBlock) + if !ok { + continue + } + sort.SliceStable(block.Line, func(i, j int) bool { + return lineLess(block.Line[i], block.Line[j]) + }) + } +} + +// removeDups removes duplicate replace directives. +// +// Later replace directives take priority. +// +// require directives are not de-duplicated. That's left up to higher-level +// logic (MVS). +// +// retract directives are not de-duplicated since comments are +// meaningful, and versions may be retracted multiple times. +func (f *WorkFile) removeDups() { + removeDups(f.Syntax, nil, &f.Replace) +} diff --git a/go/vendor/golang.org/x/mod/module/module.go b/go/vendor/golang.org/x/mod/module/module.go index ba97ac356e9..c26d1d29ec3 100644 --- a/go/vendor/golang.org/x/mod/module/module.go +++ b/go/vendor/golang.org/x/mod/module/module.go @@ -15,7 +15,7 @@ // but additional checking functions, most notably Check, verify that // a particular path, version pair is valid. // -// Escaped Paths +// # Escaped Paths // // Module paths appear as substrings of file system paths // (in the download cache) and of web server URLs in the proxy protocol. @@ -55,7 +55,7 @@ // Import paths have never allowed exclamation marks, so there is no // need to define how to escape a literal !. // -// Unicode Restrictions +// # Unicode Restrictions // // Today, paths are disallowed from using Unicode. // @@ -102,9 +102,9 @@ import ( "strings" "unicode" "unicode/utf8" + "errors" "golang.org/x/mod/semver" - errors "golang.org/x/xerrors" ) // A Version (for clients, a module.Version) is defined by a module path and version pair. @@ -286,12 +286,7 @@ func fileNameOK(r rune) bool { if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' { return true } - for i := 0; i < len(allowed); i++ { - if rune(allowed[i]) == r { - return true - } - } - return false + return strings.ContainsRune(allowed, r) } // It may be OK to add more ASCII punctuation here, but only carefully. // For example Windows disallows < > \, and macOS disallows :, so we must not allow those. @@ -803,6 +798,7 @@ func unescapeString(escaped string) (string, bool) { // GOPRIVATE environment variable, as described by 'go help module-private'. // // It ignores any empty or malformed patterns in the list. +// Trailing slashes on patterns are ignored. func MatchPrefixPatterns(globs, target string) bool { for globs != "" { // Extract next non-empty glob in comma-separated list. @@ -812,6 +808,7 @@ func MatchPrefixPatterns(globs, target string) bool { } else { glob, globs = globs, "" } + glob = strings.TrimSuffix(glob, "/") if glob == "" { continue } diff --git a/go/vendor/golang.org/x/mod/semver/semver.go b/go/vendor/golang.org/x/mod/semver/semver.go index 7be398f80d3..a30a22bf20f 100644 --- a/go/vendor/golang.org/x/mod/semver/semver.go +++ b/go/vendor/golang.org/x/mod/semver/semver.go @@ -32,7 +32,6 @@ type parsed struct { short string prerelease string build string - err string } // IsValid reports whether v is a valid semantic version string. @@ -172,12 +171,10 @@ func Sort(list []string) { func parse(v string) (p parsed, ok bool) { if v == "" || v[0] != 'v' { - p.err = "missing v prefix" return } p.major, v, ok = parseInt(v[1:]) if !ok { - p.err = "bad major version" return } if v == "" { @@ -187,13 +184,11 @@ func parse(v string) (p parsed, ok bool) { return } if v[0] != '.' { - p.err = "bad minor prefix" ok = false return } p.minor, v, ok = parseInt(v[1:]) if !ok { - p.err = "bad minor version" return } if v == "" { @@ -202,31 +197,26 @@ func parse(v string) (p parsed, ok bool) { return } if v[0] != '.' { - p.err = "bad patch prefix" ok = false return } p.patch, v, ok = parseInt(v[1:]) if !ok { - p.err = "bad patch version" return } if len(v) > 0 && v[0] == '-' { p.prerelease, v, ok = parsePrerelease(v) if !ok { - p.err = "bad prerelease" return } } if len(v) > 0 && v[0] == '+' { p.build, v, ok = parseBuild(v) if !ok { - p.err = "bad build" return } } if v != "" { - p.err = "junk on end" ok = false return } diff --git a/go/vendor/golang.org/x/sys/AUTHORS b/go/vendor/golang.org/x/sys/AUTHORS deleted file mode 100644 index 15167cd746c..00000000000 --- a/go/vendor/golang.org/x/sys/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/go/vendor/golang.org/x/sys/CONTRIBUTORS b/go/vendor/golang.org/x/sys/CONTRIBUTORS deleted file mode 100644 index 1c4577e9680..00000000000 --- a/go/vendor/golang.org/x/sys/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/go/vendor/golang.org/x/sys/execabs/execabs.go b/go/vendor/golang.org/x/sys/execabs/execabs.go index 78192498db0..b981cfbb4ae 100644 --- a/go/vendor/golang.org/x/sys/execabs/execabs.go +++ b/go/vendor/golang.org/x/sys/execabs/execabs.go @@ -53,7 +53,7 @@ func relError(file, path string) error { // LookPath instead returns an error. func LookPath(file string) (string, error) { path, err := exec.LookPath(file) - if err != nil { + if err != nil && !isGo119ErrDot(err) { return "", err } if filepath.Base(file) == file && !filepath.IsAbs(path) { diff --git a/go/vendor/golang.org/x/sys/execabs/execabs_go118.go b/go/vendor/golang.org/x/sys/execabs/execabs_go118.go new file mode 100644 index 00000000000..6ab5f50894e --- /dev/null +++ b/go/vendor/golang.org/x/sys/execabs/execabs_go118.go @@ -0,0 +1,12 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.19 +// +build !go1.19 + +package execabs + +func isGo119ErrDot(err error) bool { + return false +} diff --git a/go/vendor/golang.org/x/sys/execabs/execabs_go119.go b/go/vendor/golang.org/x/sys/execabs/execabs_go119.go new file mode 100644 index 00000000000..1e7a9ada0b0 --- /dev/null +++ b/go/vendor/golang.org/x/sys/execabs/execabs_go119.go @@ -0,0 +1,15 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.19 +// +build go1.19 + +package execabs + +import "strings" + +func isGo119ErrDot(err error) bool { + // TODO: return errors.Is(err, exec.ErrDot) + return strings.Contains(err.Error(), "current directory") +} diff --git a/go/vendor/golang.org/x/tools/AUTHORS b/go/vendor/golang.org/x/tools/AUTHORS deleted file mode 100644 index 15167cd746c..00000000000 --- a/go/vendor/golang.org/x/tools/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/go/vendor/golang.org/x/tools/CONTRIBUTORS b/go/vendor/golang.org/x/tools/CONTRIBUTORS deleted file mode 100644 index 1c4577e9680..00000000000 --- a/go/vendor/golang.org/x/tools/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/go/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/go/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go index fc8beea5d8a..2ed25a75024 100644 --- a/go/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ b/go/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -17,32 +17,47 @@ // developer tools, which will then be able to consume both Go 1.7 and // Go 1.8 export data files, so they will work before and after the // Go update. (See discussion at https://golang.org/issue/15651.) -// package gcexportdata // import "golang.org/x/tools/go/gcexportdata" import ( "bufio" "bytes" + "encoding/json" "fmt" "go/token" "go/types" "io" "io/ioutil" + "os/exec" "golang.org/x/tools/go/internal/gcimporter" ) // Find returns the name of an object (.o) or archive (.a) file // containing type information for the specified import path, -// using the workspace layout conventions of go/build. +// using the go command. // If no file was found, an empty filename is returned. // // A relative srcDir is interpreted relative to the current working directory. // // Find also returns the package's resolved (canonical) import path, // reflecting the effects of srcDir and vendoring on importPath. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. func Find(importPath, srcDir string) (filename, path string) { - return gcimporter.FindPkg(importPath, srcDir) + cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) + cmd.Dir = srcDir + out, err := cmd.CombinedOutput() + if err != nil { + return "", "" + } + var data struct { + ImportPath string + Export string + } + json.Unmarshal(out, &data) + return data.Export, data.ImportPath } // NewReader returns a reader for the export data section of an object @@ -50,11 +65,24 @@ func Find(importPath, srcDir string) (filename, path string) { // additional trailing data beyond the end of the export data. func NewReader(r io.Reader) (io.Reader, error) { buf := bufio.NewReader(r) - _, err := gcimporter.FindExportData(buf) - // If we ever switch to a zip-like archive format with the ToC - // at the end, we can return the correct portion of export data, - // but for now we must return the entire rest of the file. - return buf, err + _, size, err := gcimporter.FindExportData(buf) + if err != nil { + return nil, err + } + + if size >= 0 { + // We were given an archive and found the __.PKGDEF in it. + // This tells us the size of the export data, and we don't + // need to return the entire file. + return &io.LimitedReader{ + R: buf, + N: size, + }, nil + } else { + // We were given an object file. As such, we don't know how large + // the export data is and must return the entire file. + return buf, nil + } } // Read reads export data from in, decodes it, and returns type @@ -88,13 +116,29 @@ func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, // The indexed export format starts with an 'i'; the older // binary export format starts with a 'c', 'd', or 'v' // (from "version"). Select appropriate importer. - if len(data) > 0 && data[0] == 'i' { - _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) - return pkg, err - } + if len(data) > 0 { + switch data[0] { + case 'i': + _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) + return pkg, err - _, pkg, err := gcimporter.BImportData(fset, imports, data, path) - return pkg, err + case 'v', 'c', 'd': + _, pkg, err := gcimporter.BImportData(fset, imports, data, path) + return pkg, err + + case 'u': + _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) + return pkg, err + + default: + l := len(data) + if l > 10 { + l = 10 + } + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) + } + } + return nil, fmt.Errorf("empty export data for %s", path) } // Write writes encoded type information for the specified package to out. diff --git a/go/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/go/vendor/golang.org/x/tools/go/gcexportdata/importer.go index efe221e7e14..37a7247e268 100644 --- a/go/vendor/golang.org/x/tools/go/gcexportdata/importer.go +++ b/go/vendor/golang.org/x/tools/go/gcexportdata/importer.go @@ -23,6 +23,8 @@ import ( // or to control the FileSet or access the imports map populated during // package loading. // +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { return importer{fset, imports} } diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go index a807d0aaa28..196cb3f9b41 100644 --- a/go/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go @@ -34,20 +34,19 @@ import ( // (suspected) format errors, and whenever a change is made to the format. const debugFormat = false // default: false -// If trace is set, debugging output is printed to std out. -const trace = false // default: false - // Current export format version. Increase with each format change. +// // Note: The latest binary (non-indexed) export format is at version 6. -// This exporter is still at level 4, but it doesn't matter since -// the binary importer can handle older versions just fine. -// 6: package height (CL 105038) -- NOT IMPLEMENTED HERE -// 5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMEMTED HERE -// 4: type name objects support type aliases, uses aliasTag -// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used) -// 2: removed unused bool in ODCL export (compiler only) -// 1: header format change (more regular), export package for _ struct fields -// 0: Go1.7 encoding +// This exporter is still at level 4, but it doesn't matter since +// the binary importer can handle older versions just fine. +// +// 6: package height (CL 105038) -- NOT IMPLEMENTED HERE +// 5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMENTED HERE +// 4: type name objects support type aliases, uses aliasTag +// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used) +// 2: removed unused bool in ODCL export (compiler only) +// 1: header format change (more regular), export package for _ struct fields +// 0: Go1.7 encoding const exportVersion = 4 // trackAllTypes enables cycle tracking for all types, not just named @@ -92,16 +91,18 @@ func internalErrorf(format string, args ...interface{}) error { // BExportData returns binary export data for pkg. // If no file set is provided, position info will be missing. func BExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) { - defer func() { - if e := recover(); e != nil { - if ierr, ok := e.(internalError); ok { - err = ierr - return + if !debug { + defer func() { + if e := recover(); e != nil { + if ierr, ok := e.(internalError); ok { + err = ierr + return + } + // Not an internal error; panic again. + panic(e) } - // Not an internal error; panic again. - panic(e) - } - }() + }() + } p := exporter{ fset: fset, diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go index e9f73d14a18..b85de014700 100644 --- a/go/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go @@ -74,9 +74,10 @@ func BImportData(fset *token.FileSet, imports map[string]*types.Package, data [] pathList: []string{""}, // empty string is mapped to 0 fake: fakeFileSet{ fset: fset, - files: make(map[string]*token.File), + files: make(map[string]*fileInfo), }, } + defer p.fake.setLines() // set lines for files in fset // read version info var versionstr string @@ -338,37 +339,49 @@ func (p *importer) pos() token.Pos { // Synthesize a token.Pos type fakeFileSet struct { fset *token.FileSet - files map[string]*token.File + files map[string]*fileInfo } +type fileInfo struct { + file *token.File + lastline int +} + +const maxlines = 64 * 1024 + func (s *fakeFileSet) pos(file string, line, column int) token.Pos { // TODO(mdempsky): Make use of column. - // Since we don't know the set of needed file positions, we - // reserve maxlines positions per file. - const maxlines = 64 * 1024 + // Since we don't know the set of needed file positions, we reserve maxlines + // positions per file. We delay calling token.File.SetLines until all + // positions have been calculated (by way of fakeFileSet.setLines), so that + // we can avoid setting unnecessary lines. See also golang/go#46586. f := s.files[file] if f == nil { - f = s.fset.AddFile(file, -1, maxlines) + f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} s.files[file] = f - // Allocate the fake linebreak indices on first use. - // TODO(adonovan): opt: save ~512KB using a more complex scheme? - fakeLinesOnce.Do(func() { - fakeLines = make([]int, maxlines) - for i := range fakeLines { - fakeLines[i] = i - } - }) - f.SetLines(fakeLines) } - if line > maxlines { line = 1 } + if line > f.lastline { + f.lastline = line + } - // Treat the file as if it contained only newlines - // and column=1: use the line number as the offset. - return f.Pos(line - 1) + // Return a fake position assuming that f.file consists only of newlines. + return token.Pos(f.file.Base() + line - 1) +} + +func (s *fakeFileSet) setLines() { + fakeLinesOnce.Do(func() { + fakeLines = make([]int, maxlines) + for i := range fakeLines { + fakeLines[i] = i + } + }) + for _, f := range s.files { + f.file.SetLines(fakeLines[:f.lastline]) + } } var ( @@ -1029,6 +1042,7 @@ func predeclared() []types.Type { // used internally by gc; never used by this package or in .a files anyType{}, } + predecl = append(predecl, additionalPredeclared()...) }) return predecl } diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go index f33dc5613e7..f6437feb1cf 100644 --- a/go/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go @@ -16,7 +16,7 @@ import ( "strings" ) -func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { +func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) { // See $GOROOT/include/ar.h. hdr := make([]byte, 16+12+6+6+8+10+2) _, err = io.ReadFull(r, hdr) @@ -28,7 +28,8 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { fmt.Printf("header: %s", hdr) } s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) - size, err = strconv.Atoi(s) + length, err := strconv.Atoi(s) + size = int64(length) if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { err = fmt.Errorf("invalid archive header") return @@ -42,8 +43,8 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { // file by reading from it. The reader must be positioned at the // start of the file before calling this function. The hdr result // is the string before the export data, either "$$" or "$$B". -// -func FindExportData(r *bufio.Reader) (hdr string, err error) { +// The size result is the length of the export data in bytes, or -1 if not known. +func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) { // Read first line to make sure this is an object file. line, err := r.ReadSlice('\n') if err != nil { @@ -54,7 +55,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) { if string(line) == "!\n" { // Archive file. Scan to __.PKGDEF. var name string - if name, _, err = readGopackHeader(r); err != nil { + if name, size, err = readGopackHeader(r); err != nil { return } @@ -70,6 +71,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) { err = fmt.Errorf("can't find export data (%v)", err) return } + size -= int64(len(line)) } // Now at __.PKGDEF in archive or still at beginning of file. @@ -86,8 +88,12 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) { err = fmt.Errorf("can't find export data (%v)", err) return } + size -= int64(len(line)) } hdr = string(line) + if size < 0 { + size = -1 + } return } diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go index e8cba6b2375..e96c39600d1 100644 --- a/go/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go @@ -29,8 +29,14 @@ import ( "text/scanner" ) -// debugging/development support -const debug = false +const ( + // Enable debug during development: it adds some additional checks, and + // prevents errors from being recovered. + debug = false + + // If trace is set, debugging output is printed to std out. + trace = false +) var pkgExts = [...]string{".a", ".o"} @@ -39,7 +45,6 @@ var pkgExts = [...]string{".a", ".o"} // the build.Default build.Context). A relative srcDir is interpreted // relative to the current working directory. // If no file was found, an empty filename is returned. -// func FindPkg(path, srcDir string) (filename, id string) { if path == "" { return @@ -103,7 +108,6 @@ func FindPkg(path, srcDir string) (filename, id string) { // If packages[id] contains the completely imported package, that package // can be used directly, and there is no need to call this function (but // there is also no harm but for extra time used). -// func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) { // support for parser error handling defer func() { @@ -127,7 +131,6 @@ func ImportData(packages map[string]*types.Package, filename, id string, data io // Import imports a gc-generated package given its import path and srcDir, adds // the corresponding package object to the packages map, and returns the object. // The packages map must contain all packages already imported. -// func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) { var rc io.ReadCloser var filename, id string @@ -178,8 +181,9 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func defer rc.Close() var hdr string + var size int64 buf := bufio.NewReader(rc) - if hdr, err = FindExportData(buf); err != nil { + if hdr, size, err = FindExportData(buf); err != nil { return } @@ -207,10 +211,27 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func // The indexed export format starts with an 'i'; the older // binary export format starts with a 'c', 'd', or 'v' // (from "version"). Select appropriate importer. - if len(data) > 0 && data[0] == 'i' { - _, pkg, err = IImportData(fset, packages, data[1:], id) - } else { - _, pkg, err = BImportData(fset, packages, data, id) + if len(data) > 0 { + switch data[0] { + case 'i': + _, pkg, err := IImportData(fset, packages, data[1:], id) + return pkg, err + + case 'v', 'c', 'd': + _, pkg, err := BImportData(fset, packages, data, id) + return pkg, err + + case 'u': + _, pkg, err := UImportData(fset, packages, data[1:size], id) + return pkg, err + + default: + l := len(data) + if l > 10 { + l = 10 + } + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id) + } } default: @@ -342,8 +363,9 @@ func (p *parser) expectKeyword(keyword string) { // ---------------------------------------------------------------------------- // Qualified and unqualified names -// PackageId = string_lit . +// parsePackageID parses a PackageId: // +// PackageId = string_lit . func (p *parser) parsePackageID() string { id, err := strconv.Unquote(p.expect(scanner.String)) if err != nil { @@ -357,13 +379,16 @@ func (p *parser) parsePackageID() string { return id } -// PackageName = ident . +// parsePackageName parse a PackageName: // +// PackageName = ident . func (p *parser) parsePackageName() string { return p.expect(scanner.Ident) } -// dotIdentifier = ( ident | '·' ) { ident | int | '·' } . +// parseDotIdent parses a dotIdentifier: +// +// dotIdentifier = ( ident | '·' ) { ident | int | '·' } . func (p *parser) parseDotIdent() string { ident := "" if p.tok != scanner.Int { @@ -380,8 +405,9 @@ func (p *parser) parseDotIdent() string { return ident } -// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) . +// parseQualifiedName parses a QualifiedName: // +// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) . func (p *parser) parseQualifiedName() (id, name string) { p.expect('@') id = p.parsePackageID() @@ -404,7 +430,6 @@ func (p *parser) parseQualifiedName() (id, name string) { // id identifies a package, usually by a canonical package path like // "encoding/json" but possibly by a non-canonical import path like // "./json". -// func (p *parser) getPkg(id, name string) *types.Package { // package unsafe is not in the packages maps - handle explicitly if id == "unsafe" { @@ -440,7 +465,6 @@ func (p *parser) getPkg(id, name string) *types.Package { // parseExportedName is like parseQualifiedName, but // the package id is resolved to an imported *types.Package. -// func (p *parser) parseExportedName() (pkg *types.Package, name string) { id, name := p.parseQualifiedName() pkg = p.getPkg(id, "") @@ -450,8 +474,9 @@ func (p *parser) parseExportedName() (pkg *types.Package, name string) { // ---------------------------------------------------------------------------- // Types -// BasicType = identifier . +// parseBasicType parses a BasicType: // +// BasicType = identifier . func (p *parser) parseBasicType() types.Type { id := p.expect(scanner.Ident) obj := types.Universe.Lookup(id) @@ -462,8 +487,9 @@ func (p *parser) parseBasicType() types.Type { return nil } -// ArrayType = "[" int_lit "]" Type . +// parseArrayType parses an ArrayType: // +// ArrayType = "[" int_lit "]" Type . func (p *parser) parseArrayType(parent *types.Package) types.Type { // "[" already consumed and lookahead known not to be "]" lit := p.expect(scanner.Int) @@ -476,8 +502,9 @@ func (p *parser) parseArrayType(parent *types.Package) types.Type { return types.NewArray(elem, n) } -// MapType = "map" "[" Type "]" Type . +// parseMapType parses a MapType: // +// MapType = "map" "[" Type "]" Type . func (p *parser) parseMapType(parent *types.Package) types.Type { p.expectKeyword("map") p.expect('[') @@ -487,7 +514,9 @@ func (p *parser) parseMapType(parent *types.Package) types.Type { return types.NewMap(key, elem) } -// Name = identifier | "?" | QualifiedName . +// parseName parses a Name: +// +// Name = identifier | "?" | QualifiedName . // // For unqualified and anonymous names, the returned package is the parent // package unless parent == nil, in which case the returned package is the @@ -499,7 +528,6 @@ func (p *parser) parseMapType(parent *types.Package) types.Type { // it doesn't exist yet) unless materializePkg is set (which creates an // unnamed package with valid package path). In the latter case, a // subsequent import clause is expected to provide a name for the package. -// func (p *parser) parseName(parent *types.Package, materializePkg bool) (pkg *types.Package, name string) { pkg = parent if pkg == nil { @@ -533,8 +561,9 @@ func deref(typ types.Type) types.Type { return typ } -// Field = Name Type [ string_lit ] . +// parseField parses a Field: // +// Field = Name Type [ string_lit ] . func (p *parser) parseField(parent *types.Package) (*types.Var, string) { pkg, name := p.parseName(parent, true) @@ -577,9 +606,10 @@ func (p *parser) parseField(parent *types.Package) (*types.Var, string) { return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag } -// StructType = "struct" "{" [ FieldList ] "}" . -// FieldList = Field { ";" Field } . +// parseStructType parses a StructType: // +// StructType = "struct" "{" [ FieldList ] "}" . +// FieldList = Field { ";" Field } . func (p *parser) parseStructType(parent *types.Package) types.Type { var fields []*types.Var var tags []string @@ -604,8 +634,9 @@ func (p *parser) parseStructType(parent *types.Package) types.Type { return types.NewStruct(fields, tags) } -// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] . +// parseParameter parses a Parameter: // +// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] . func (p *parser) parseParameter() (par *types.Var, isVariadic bool) { _, name := p.parseName(nil, false) // remove gc-specific parameter numbering @@ -629,9 +660,10 @@ func (p *parser) parseParameter() (par *types.Var, isVariadic bool) { return } -// Parameters = "(" [ ParameterList ] ")" . -// ParameterList = { Parameter "," } Parameter . +// parseParameters parses a Parameters: // +// Parameters = "(" [ ParameterList ] ")" . +// ParameterList = { Parameter "," } Parameter . func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) { p.expect('(') for p.tok != ')' && p.tok != scanner.EOF { @@ -652,9 +684,10 @@ func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) { return } -// Signature = Parameters [ Result ] . -// Result = Type | Parameters . +// parseSignature parses a Signature: // +// Signature = Parameters [ Result ] . +// Result = Type | Parameters . func (p *parser) parseSignature(recv *types.Var) *types.Signature { params, isVariadic := p.parseParameters() @@ -671,14 +704,15 @@ func (p *parser) parseSignature(recv *types.Var) *types.Signature { return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic) } -// InterfaceType = "interface" "{" [ MethodList ] "}" . -// MethodList = Method { ";" Method } . -// Method = Name Signature . +// parseInterfaceType parses an InterfaceType: +// +// InterfaceType = "interface" "{" [ MethodList ] "}" . +// MethodList = Method { ";" Method } . +// Method = Name Signature . // // The methods of embedded interfaces are always "inlined" // by the compiler and thus embedded interfaces are never // visible in the export data. -// func (p *parser) parseInterfaceType(parent *types.Package) types.Type { var methods []*types.Func @@ -699,8 +733,9 @@ func (p *parser) parseInterfaceType(parent *types.Package) types.Type { return newInterface(methods, nil).Complete() } -// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type . +// parseChanType parses a ChanType: // +// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type . func (p *parser) parseChanType(parent *types.Package) types.Type { dir := types.SendRecv if p.tok == scanner.Ident { @@ -718,17 +753,18 @@ func (p *parser) parseChanType(parent *types.Package) types.Type { return types.NewChan(dir, elem) } -// Type = -// BasicType | TypeName | ArrayType | SliceType | StructType | -// PointerType | FuncType | InterfaceType | MapType | ChanType | -// "(" Type ")" . +// parseType parses a Type: // -// BasicType = ident . -// TypeName = ExportedName . -// SliceType = "[" "]" Type . -// PointerType = "*" Type . -// FuncType = "func" Signature . +// Type = +// BasicType | TypeName | ArrayType | SliceType | StructType | +// PointerType | FuncType | InterfaceType | MapType | ChanType | +// "(" Type ")" . // +// BasicType = ident . +// TypeName = ExportedName . +// SliceType = "[" "]" Type . +// PointerType = "*" Type . +// FuncType = "func" Signature . func (p *parser) parseType(parent *types.Package) types.Type { switch p.tok { case scanner.Ident: @@ -780,16 +816,18 @@ func (p *parser) parseType(parent *types.Package) types.Type { // ---------------------------------------------------------------------------- // Declarations -// ImportDecl = "import" PackageName PackageId . +// parseImportDecl parses an ImportDecl: // +// ImportDecl = "import" PackageName PackageId . func (p *parser) parseImportDecl() { p.expectKeyword("import") name := p.parsePackageName() p.getPkg(p.parsePackageID(), name) } -// int_lit = [ "+" | "-" ] { "0" ... "9" } . +// parseInt parses an int_lit: // +// int_lit = [ "+" | "-" ] { "0" ... "9" } . func (p *parser) parseInt() string { s := "" switch p.tok { @@ -802,8 +840,9 @@ func (p *parser) parseInt() string { return s + p.expect(scanner.Int) } -// number = int_lit [ "p" int_lit ] . +// parseNumber parses a number: // +// number = int_lit [ "p" int_lit ] . func (p *parser) parseNumber() (typ *types.Basic, val constant.Value) { // mantissa mant := constant.MakeFromLiteral(p.parseInt(), token.INT, 0) @@ -838,13 +877,14 @@ func (p *parser) parseNumber() (typ *types.Basic, val constant.Value) { return } -// ConstDecl = "const" ExportedName [ Type ] "=" Literal . -// Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit . -// bool_lit = "true" | "false" . -// complex_lit = "(" float_lit "+" float_lit "i" ")" . -// rune_lit = "(" int_lit "+" int_lit ")" . -// string_lit = `"` { unicode_char } `"` . +// parseConstDecl parses a ConstDecl: // +// ConstDecl = "const" ExportedName [ Type ] "=" Literal . +// Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit . +// bool_lit = "true" | "false" . +// complex_lit = "(" float_lit "+" float_lit "i" ")" . +// rune_lit = "(" int_lit "+" int_lit ")" . +// string_lit = `"` { unicode_char } `"` . func (p *parser) parseConstDecl() { p.expectKeyword("const") pkg, name := p.parseExportedName() @@ -914,8 +954,9 @@ func (p *parser) parseConstDecl() { pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val)) } -// TypeDecl = "type" ExportedName Type . +// parseTypeDecl parses a TypeDecl: // +// TypeDecl = "type" ExportedName Type . func (p *parser) parseTypeDecl() { p.expectKeyword("type") pkg, name := p.parseExportedName() @@ -933,8 +974,9 @@ func (p *parser) parseTypeDecl() { } } -// VarDecl = "var" ExportedName Type . +// parseVarDecl parses a VarDecl: // +// VarDecl = "var" ExportedName Type . func (p *parser) parseVarDecl() { p.expectKeyword("var") pkg, name := p.parseExportedName() @@ -942,9 +984,10 @@ func (p *parser) parseVarDecl() { pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ)) } -// Func = Signature [ Body ] . -// Body = "{" ... "}" . +// parseFunc parses a Func: // +// Func = Signature [ Body ] . +// Body = "{" ... "}" . func (p *parser) parseFunc(recv *types.Var) *types.Signature { sig := p.parseSignature(recv) if p.tok == '{' { @@ -961,9 +1004,10 @@ func (p *parser) parseFunc(recv *types.Var) *types.Signature { return sig } -// MethodDecl = "func" Receiver Name Func . -// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" . +// parseMethodDecl parses a MethodDecl: // +// MethodDecl = "func" Receiver Name Func . +// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" . func (p *parser) parseMethodDecl() { // "func" already consumed p.expect('(') @@ -986,8 +1030,9 @@ func (p *parser) parseMethodDecl() { base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) } -// FuncDecl = "func" ExportedName Func . +// parseFuncDecl parses a FuncDecl: // +// FuncDecl = "func" ExportedName Func . func (p *parser) parseFuncDecl() { // "func" already consumed pkg, name := p.parseExportedName() @@ -995,8 +1040,9 @@ func (p *parser) parseFuncDecl() { pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ)) } -// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" . +// parseDecl parses a Decl: // +// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" . func (p *parser) parseDecl() { if p.tok == scanner.Ident { switch p.lit { @@ -1023,9 +1069,10 @@ func (p *parser) parseDecl() { // ---------------------------------------------------------------------------- // Export -// Export = "PackageClause { Decl } "$$" . -// PackageClause = "package" PackageName [ "safe" ] "\n" . +// parseExport parses an Export: // +// Export = "PackageClause { Decl } "$$" . +// PackageClause = "package" PackageName [ "safe" ] "\n" . func (p *parser) parseExport() *types.Package { p.expectKeyword("package") name := p.parsePackageName() diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go index d2fc8b6fa3e..9a4ff329e12 100644 --- a/go/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go @@ -11,6 +11,7 @@ package gcimporter import ( "bytes" "encoding/binary" + "fmt" "go/ast" "go/constant" "go/token" @@ -19,11 +20,11 @@ import ( "math/big" "reflect" "sort" -) + "strconv" + "strings" -// Current indexed export format version. Increase with each format change. -// 0: Go1.11 encoding -const iexportVersion = 0 + "golang.org/x/tools/internal/typeparams" +) // Current bundled export format version. Increase with each format change. // 0: initial implementation @@ -35,31 +36,35 @@ const bundleVersion = 0 // The package path of the top-level package will not be recorded, // so that calls to IImportData can override with a provided package path. func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error { - return iexportCommon(out, fset, false, []*types.Package{pkg}) + return iexportCommon(out, fset, false, iexportVersion, []*types.Package{pkg}) } // IExportBundle writes an indexed export bundle for pkgs to out. func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { - return iexportCommon(out, fset, true, pkgs) + return iexportCommon(out, fset, true, iexportVersion, pkgs) } -func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*types.Package) (err error) { - defer func() { - if e := recover(); e != nil { - if ierr, ok := e.(internalError); ok { - err = ierr - return +func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, version int, pkgs []*types.Package) (err error) { + if !debug { + defer func() { + if e := recover(); e != nil { + if ierr, ok := e.(internalError); ok { + err = ierr + return + } + // Not an internal error; panic again. + panic(e) } - // Not an internal error; panic again. - panic(e) - } - }() + }() + } p := iexporter{ fset: fset, + version: version, allPkgs: map[*types.Package]bool{}, stringIndex: map[string]uint64{}, declIndex: map[types.Object]uint64{}, + tparamNames: map[types.Object]string{}, typIndex: map[types.Type]uint64{}, } if !bundle { @@ -119,7 +124,7 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type if bundle { hdr.uint64(bundleVersion) } - hdr.uint64(iexportVersion) + hdr.uint64(uint64(p.version)) hdr.uint64(uint64(p.strings.Len())) hdr.uint64(dataLen) @@ -136,8 +141,12 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type // non-compiler tools and includes a complete package description // (i.e., name and height). func (w *exportWriter) writeIndex(index map[types.Object]uint64) { + type pkgObj struct { + obj types.Object + name string // qualified name; differs from obj.Name for type params + } // Build a map from packages to objects from that package. - pkgObjs := map[*types.Package][]types.Object{} + pkgObjs := map[*types.Package][]pkgObj{} // For the main index, make sure to include every package that // we reference, even if we're not exporting (or reexporting) @@ -150,7 +159,8 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) { } for obj := range index { - pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], obj) + name := w.p.exportName(obj) + pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name}) } var pkgs []*types.Package @@ -158,7 +168,7 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) { pkgs = append(pkgs, pkg) sort.Slice(objs, func(i, j int) bool { - return objs[i].Name() < objs[j].Name() + return objs[i].name < objs[j].name }) } @@ -175,15 +185,25 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) { objs := pkgObjs[pkg] w.uint64(uint64(len(objs))) for _, obj := range objs { - w.string(obj.Name()) - w.uint64(index[obj]) + w.string(obj.name) + w.uint64(index[obj.obj]) } } } +// exportName returns the 'exported' name of an object. It differs from +// obj.Name() only for type parameters (see tparamExportName for details). +func (p *iexporter) exportName(obj types.Object) (res string) { + if name := p.tparamNames[obj]; name != "" { + return name + } + return obj.Name() +} + type iexporter struct { - fset *token.FileSet - out *bytes.Buffer + fset *token.FileSet + out *bytes.Buffer + version int localpkg *types.Package @@ -197,9 +217,21 @@ type iexporter struct { strings intWriter stringIndex map[string]uint64 - data0 intWriter - declIndex map[types.Object]uint64 - typIndex map[types.Type]uint64 + data0 intWriter + declIndex map[types.Object]uint64 + tparamNames map[types.Object]string // typeparam->exported name + typIndex map[types.Type]uint64 + + indent int // for tracing support +} + +func (p *iexporter) trace(format string, args ...interface{}) { + if !trace { + // Call sites should also be guarded, but having this check here allows + // easily enabling/disabling debug trace statements. + return + } + fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) } // stringOff returns the offset of s within the string section. @@ -219,13 +251,16 @@ func (p *iexporter) stringOff(s string) uint64 { // pushDecl adds n to the declaration work queue, if not already present. func (p *iexporter) pushDecl(obj types.Object) { // Package unsafe is known to the compiler and predeclared. - assert(obj.Pkg() != types.Unsafe) + // Caller should not ask us to do export it. + if obj.Pkg() == types.Unsafe { + panic("cannot export package unsafe") + } if _, ok := p.declIndex[obj]; ok { return } - p.declIndex[obj] = ^uint64(0) // mark n present in work queue + p.declIndex[obj] = ^uint64(0) // mark obj present in work queue p.declTodo.pushTail(obj) } @@ -233,10 +268,11 @@ func (p *iexporter) pushDecl(obj types.Object) { type exportWriter struct { p *iexporter - data intWriter - currPkg *types.Package - prevFile string - prevLine int64 + data intWriter + currPkg *types.Package + prevFile string + prevLine int64 + prevColumn int64 } func (w *exportWriter) exportPath(pkg *types.Package) string { @@ -247,6 +283,14 @@ func (w *exportWriter) exportPath(pkg *types.Package) string { } func (p *iexporter) doDecl(obj types.Object) { + if trace { + p.trace("exporting decl %v (%T)", obj, obj) + p.indent++ + defer func() { + p.indent-- + p.trace("=> %s", obj) + }() + } w := p.newWriter() w.setPkg(obj.Pkg(), false) @@ -261,8 +305,24 @@ func (p *iexporter) doDecl(obj types.Object) { if sig.Recv() != nil { panic(internalErrorf("unexpected method: %v", sig)) } - w.tag('F') + + // Function. + if typeparams.ForSignature(sig).Len() == 0 { + w.tag('F') + } else { + w.tag('G') + } w.pos(obj.Pos()) + // The tparam list of the function type is the declaration of the type + // params. So, write out the type params right now. Then those type params + // will be referenced via their type offset (via typOff) in all other + // places in the signature and function where they are used. + // + // While importing the type parameters, tparamList computes and records + // their export name, so that it can be later used when writing the index. + if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 { + w.tparamList(obj.Name(), tparams, obj.Pkg()) + } w.signature(sig) case *types.Const: @@ -271,30 +331,56 @@ func (p *iexporter) doDecl(obj types.Object) { w.value(obj.Type(), obj.Val()) case *types.TypeName: + t := obj.Type() + + if tparam, ok := t.(*typeparams.TypeParam); ok { + w.tag('P') + w.pos(obj.Pos()) + constraint := tparam.Constraint() + if p.version >= iexportVersionGo1_18 { + implicit := false + if iface, _ := constraint.(*types.Interface); iface != nil { + implicit = typeparams.IsImplicit(iface) + } + w.bool(implicit) + } + w.typ(constraint, obj.Pkg()) + break + } + if obj.IsAlias() { w.tag('A') w.pos(obj.Pos()) - w.typ(obj.Type(), obj.Pkg()) + w.typ(t, obj.Pkg()) break } // Defined type. - w.tag('T') + named, ok := t.(*types.Named) + if !ok { + panic(internalErrorf("%s is not a defined type", t)) + } + + if typeparams.ForNamed(named).Len() == 0 { + w.tag('T') + } else { + w.tag('U') + } w.pos(obj.Pos()) + if typeparams.ForNamed(named).Len() > 0 { + // While importing the type parameters, tparamList computes and records + // their export name, so that it can be later used when writing the index. + w.tparamList(obj.Name(), typeparams.ForNamed(named), obj.Pkg()) + } + underlying := obj.Type().Underlying() w.typ(underlying, obj.Pkg()) - t := obj.Type() if types.IsInterface(t) { break } - named, ok := t.(*types.Named) - if !ok { - panic(internalErrorf("%s is not a defined type", t)) - } - n := named.NumMethods() w.uint64(uint64(n)) for i := 0; i < n; i++ { @@ -302,6 +388,17 @@ func (p *iexporter) doDecl(obj types.Object) { w.pos(m.Pos()) w.string(m.Name()) sig, _ := m.Type().(*types.Signature) + + // Receiver type parameters are type arguments of the receiver type, so + // their name must be qualified before exporting recv. + if rparams := typeparams.RecvTypeParams(sig); rparams.Len() > 0 { + prefix := obj.Name() + "." + m.Name() + for i := 0; i < rparams.Len(); i++ { + rparam := rparams.At(i) + name := tparamExportName(prefix, rparam) + w.p.tparamNames[rparam.Obj()] = name + } + } w.param(sig.Recv()) w.signature(sig) } @@ -318,6 +415,48 @@ func (w *exportWriter) tag(tag byte) { } func (w *exportWriter) pos(pos token.Pos) { + if w.p.version >= iexportVersionPosCol { + w.posV1(pos) + } else { + w.posV0(pos) + } +} + +func (w *exportWriter) posV1(pos token.Pos) { + if w.p.fset == nil { + w.int64(0) + return + } + + p := w.p.fset.Position(pos) + file := p.Filename + line := int64(p.Line) + column := int64(p.Column) + + deltaColumn := (column - w.prevColumn) << 1 + deltaLine := (line - w.prevLine) << 1 + + if file != w.prevFile { + deltaLine |= 1 + } + if deltaLine != 0 { + deltaColumn |= 1 + } + + w.int64(deltaColumn) + if deltaColumn&1 != 0 { + w.int64(deltaLine) + if deltaLine&1 != 0 { + w.string(file) + } + } + + w.prevFile = file + w.prevLine = line + w.prevColumn = column +} + +func (w *exportWriter) posV0(pos token.Pos) { if w.p.fset == nil { w.int64(0) return @@ -359,10 +498,11 @@ func (w *exportWriter) pkg(pkg *types.Package) { } func (w *exportWriter) qualifiedIdent(obj types.Object) { + name := w.p.exportName(obj) + // Ensure any referenced declarations are written out too. w.p.pushDecl(obj) - - w.string(obj.Name()) + w.string(name) w.pkg(obj.Pkg()) } @@ -396,11 +536,32 @@ func (w *exportWriter) startType(k itag) { } func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { + if trace { + w.p.trace("exporting type %s (%T)", t, t) + w.p.indent++ + defer func() { + w.p.indent-- + w.p.trace("=> %s", t) + }() + } switch t := t.(type) { case *types.Named: + if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 { + w.startType(instanceType) + // TODO(rfindley): investigate if this position is correct, and if it + // matters. + w.pos(t.Obj().Pos()) + w.typeList(targs, pkg) + w.typ(typeparams.NamedTypeOrigin(t), pkg) + return + } w.startType(definedType) w.qualifiedIdent(t.Obj()) + case *typeparams.TypeParam: + w.startType(typeParamType) + w.qualifiedIdent(t.Obj()) + case *types.Pointer: w.startType(pointerType) w.typ(t.Elem(), pkg) @@ -461,9 +622,14 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { n := t.NumEmbeddeds() w.uint64(uint64(n)) for i := 0; i < n; i++ { - f := t.Embedded(i) - w.pos(f.Obj().Pos()) - w.typ(f.Obj().Type(), f.Obj().Pkg()) + ft := t.EmbeddedType(i) + tPkg := pkg + if named, _ := ft.(*types.Named); named != nil { + w.pos(named.Obj().Pos()) + } else { + w.pos(token.NoPos) + } + w.typ(ft, tPkg) } n = t.NumExplicitMethods() @@ -476,6 +642,16 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { w.signature(sig) } + case *typeparams.Union: + w.startType(unionType) + nt := t.Len() + w.uint64(uint64(nt)) + for i := 0; i < nt; i++ { + term := t.Term(i) + w.bool(term.Tilde()) + w.typ(term.Type(), pkg) + } + default: panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t))) } @@ -497,6 +673,56 @@ func (w *exportWriter) signature(sig *types.Signature) { } } +func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) { + w.uint64(uint64(ts.Len())) + for i := 0; i < ts.Len(); i++ { + w.typ(ts.At(i), pkg) + } +} + +func (w *exportWriter) tparamList(prefix string, list *typeparams.TypeParamList, pkg *types.Package) { + ll := uint64(list.Len()) + w.uint64(ll) + for i := 0; i < list.Len(); i++ { + tparam := list.At(i) + // Set the type parameter exportName before exporting its type. + exportName := tparamExportName(prefix, tparam) + w.p.tparamNames[tparam.Obj()] = exportName + w.typ(list.At(i), pkg) + } +} + +const blankMarker = "$" + +// tparamExportName returns the 'exported' name of a type parameter, which +// differs from its actual object name: it is prefixed with a qualifier, and +// blank type parameter names are disambiguated by their index in the type +// parameter list. +func tparamExportName(prefix string, tparam *typeparams.TypeParam) string { + assert(prefix != "") + name := tparam.Obj().Name() + if name == "_" { + name = blankMarker + strconv.Itoa(tparam.Index()) + } + return prefix + "." + name +} + +// tparamName returns the real name of a type parameter, after stripping its +// qualifying prefix and reverting blank-name encoding. See tparamExportName +// for details. +func tparamName(exportName string) string { + // Remove the "path" from the type param name that makes it unique. + ix := strings.LastIndex(exportName, ".") + if ix < 0 { + errorf("malformed type parameter export name %s: missing prefix", exportName) + } + name := exportName[ix+1:] + if strings.HasPrefix(name, blankMarker) { + return "_" + } + return name +} + func (w *exportWriter) paramList(tup *types.Tuple) { n := tup.Len() w.uint64(uint64(n)) @@ -513,6 +739,9 @@ func (w *exportWriter) param(obj types.Object) { func (w *exportWriter) value(typ types.Type, v constant.Value) { w.typ(typ, nil) + if w.p.version >= iexportVersionGo1_18 { + w.int64(int64(v.Kind())) + } switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { case types.IsBoolean: diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go index 8ed8bc62d68..4caa0f55d9d 100644 --- a/go/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -17,7 +17,11 @@ import ( "go/token" "go/types" "io" + "math/big" "sort" + "strings" + + "golang.org/x/tools/internal/typeparams" ) type intReader struct { @@ -41,6 +45,19 @@ func (r *intReader) uint64() uint64 { return i } +// Keep this in sync with constants in iexport.go. +const ( + iexportVersionGo1_11 = 0 + iexportVersionPosCol = 1 + iexportVersionGo1_18 = 2 + iexportVersionGenerics = 2 +) + +type ident struct { + pkg *types.Package + name string +} + const predeclReserved = 32 type itag uint64 @@ -56,6 +73,9 @@ const ( signatureType structType interfaceType + typeParamType + instanceType + unionType ) // IImportData imports a package from the serialized package data @@ -78,15 +98,19 @@ func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string) (pkgs []*types.Package, err error) { const currentVersion = 1 version := int64(-1) - defer func() { - if e := recover(); e != nil { - if version > currentVersion { - err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) - } else { - err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e) + if !debug { + defer func() { + if e := recover(); e != nil { + if bundle { + err = fmt.Errorf("%v", e) + } else if version > currentVersion { + err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) + } else { + err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e) + } } - } - }() + }() + } r := &intReader{bytes.NewReader(data), path} @@ -101,9 +125,13 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data version = int64(r.uint64()) switch version { - case currentVersion, 0: + case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: default: - errorf("unknown iexport format version %d", version) + if version > iexportVersionGo1_18 { + errorf("unstable iexport format version %d, just rebuild compiler and std library", version) + } else { + errorf("unknown iexport format version %d", version) + } } sLen := int64(r.uint64()) @@ -115,8 +143,8 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data r.Seek(sLen+dLen, io.SeekCurrent) p := iimporter{ - ipath: path, version: int(version), + ipath: path, stringData: stringData, stringCache: make(map[uint64]string), @@ -125,12 +153,16 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data declData: declData, pkgIndex: make(map[*types.Package]map[string]uint64), typCache: make(map[uint64]types.Type), + // Separate map for typeparams, keyed by their package and unique + // name. + tparamIndex: make(map[ident]types.Type), fake: fakeFileSet{ fset: fset, - files: make(map[string]*token.File), + files: make(map[string]*fileInfo), }, } + defer p.fake.setLines() // set lines for files in fset for i, pt := range predeclared() { p.typCache[uint64(i)] = pt @@ -208,6 +240,15 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data pkg.MarkComplete() } + // SetConstraint can't be called if the constraint type is not yet complete. + // When type params are created in the 'P' case of (*importReader).obj(), + // the associated constraint type may not be complete due to recursion. + // Therefore, we defer calling SetConstraint there, and call it here instead + // after all types are complete. + for _, d := range p.later { + typeparams.SetTypeParamConstraint(d.t, d.constraint) + } + for _, typ := range p.interfaceList { typ.Complete() } @@ -215,23 +256,51 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data return pkgs, nil } +type setConstraintArgs struct { + t *typeparams.TypeParam + constraint types.Type +} + type iimporter struct { - ipath string version int + ipath string stringData []byte stringCache map[uint64]string pkgCache map[uint64]*types.Package - declData []byte - pkgIndex map[*types.Package]map[string]uint64 - typCache map[uint64]types.Type + declData []byte + pkgIndex map[*types.Package]map[string]uint64 + typCache map[uint64]types.Type + tparamIndex map[ident]types.Type fake fakeFileSet interfaceList []*types.Interface + + // Arguments for calls to SetConstraint that are deferred due to recursive types + later []setConstraintArgs + + indent int // for tracing support +} + +func (p *iimporter) trace(format string, args ...interface{}) { + if !trace { + // Call sites should also be guarded, but having this check here allows + // easily enabling/disabling debug trace statements. + return + } + fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) } func (p *iimporter) doDecl(pkg *types.Package, name string) { + if debug { + p.trace("import decl %s", name) + p.indent++ + defer func() { + p.indent-- + p.trace("=> %s", name) + }() + } // See if we've already imported this declaration. if obj := pkg.Scope().Lookup(name); obj != nil { return @@ -273,7 +342,7 @@ func (p *iimporter) pkgAt(off uint64) *types.Package { } func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { - if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) { + if t, ok := p.typCache[off]; ok && canReuse(base, t) { return t } @@ -285,12 +354,30 @@ func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { r.declReader.Reset(p.declData[off-predeclReserved:]) t := r.doType(base) - if base == nil || !isInterface(t) { + if canReuse(base, t) { p.typCache[off] = t } return t } +// canReuse reports whether the type rhs on the RHS of the declaration for def +// may be re-used. +// +// Specifically, if def is non-nil and rhs is an interface type with methods, it +// may not be re-used because we have a convention of setting the receiver type +// for interface methods to def. +func canReuse(def *types.Named, rhs types.Type) bool { + if def == nil { + return true + } + iface, _ := rhs.(*types.Interface) + if iface == nil { + return true + } + // Don't use iface.Empty() here as iface may not be complete. + return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 +} + type importReader struct { p *iimporter declReader bytes.Reader @@ -315,17 +402,26 @@ func (r *importReader) obj(name string) { r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) - case 'F': - sig := r.signature(nil) - + case 'F', 'G': + var tparams []*typeparams.TypeParam + if tag == 'G' { + tparams = r.tparamList() + } + sig := r.signature(nil, nil, tparams) r.declare(types.NewFunc(pos, r.currPkg, name, sig)) - case 'T': + case 'T', 'U': // Types can be recursive. We need to setup a stub // declaration before recursing. obj := types.NewTypeName(pos, r.currPkg, name, nil) named := types.NewNamed(obj, nil, nil) + // Declare obj before calling r.tparamList, so the new type name is recognized + // if used in the constraint of one of its own typeparams (see #48280). r.declare(obj) + if tag == 'U' { + tparams := r.tparamList() + typeparams.SetForNamed(named, tparams) + } underlying := r.p.typAt(r.uint64(), named).Underlying() named.SetUnderlying(underlying) @@ -335,12 +431,59 @@ func (r *importReader) obj(name string) { mpos := r.pos() mname := r.ident() recv := r.param() - msig := r.signature(recv) + + // If the receiver has any targs, set those as the + // rparams of the method (since those are the + // typeparams being used in the method sig/body). + base := baseType(recv.Type()) + assert(base != nil) + targs := typeparams.NamedTypeArgs(base) + var rparams []*typeparams.TypeParam + if targs.Len() > 0 { + rparams = make([]*typeparams.TypeParam, targs.Len()) + for i := range rparams { + rparams[i] = targs.At(i).(*typeparams.TypeParam) + } + } + msig := r.signature(recv, rparams, nil) named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) } } + case 'P': + // We need to "declare" a typeparam in order to have a name that + // can be referenced recursively (if needed) in the type param's + // bound. + if r.p.version < iexportVersionGenerics { + errorf("unexpected type param type") + } + name0 := tparamName(name) + tn := types.NewTypeName(pos, r.currPkg, name0, nil) + t := typeparams.NewTypeParam(tn, nil) + + // To handle recursive references to the typeparam within its + // bound, save the partial type in tparamIndex before reading the bounds. + id := ident{r.currPkg, name} + r.p.tparamIndex[id] = t + var implicit bool + if r.p.version >= iexportVersionGo1_18 { + implicit = r.bool() + } + constraint := r.typ() + if implicit { + iface, _ := constraint.(*types.Interface) + if iface == nil { + errorf("non-interface constraint marked implicit") + } + typeparams.MarkImplicit(iface) + } + // The constraint type may not be complete, if we + // are in the middle of a type recursion involving type + // constraints. So, we defer SetConstraint until we have + // completely set up all types in ImportData. + r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) + case 'V': typ := r.typ() @@ -357,6 +500,10 @@ func (r *importReader) declare(obj types.Object) { func (r *importReader) value() (typ types.Type, val constant.Value) { typ = r.typ() + if r.p.version >= iexportVersionGo1_18 { + // TODO: add support for using the kind. + _ = constant.Kind(r.int64()) + } switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { case types.IsBoolean: @@ -366,7 +513,9 @@ func (r *importReader) value() (typ types.Type, val constant.Value) { val = constant.MakeString(r.string()) case types.IsInteger: - val = r.mpint(b) + var x big.Int + r.mpint(&x, b) + val = constant.Make(&x) case types.IsFloat: val = r.mpfloat(b) @@ -415,8 +564,8 @@ func intSize(b *types.Basic) (signed bool, maxBytes uint) { return } -func (r *importReader) mpint(b *types.Basic) constant.Value { - signed, maxBytes := intSize(b) +func (r *importReader) mpint(x *big.Int, typ *types.Basic) { + signed, maxBytes := intSize(typ) maxSmall := 256 - maxBytes if signed { @@ -435,7 +584,8 @@ func (r *importReader) mpint(b *types.Basic) constant.Value { v = ^v } } - return constant.MakeInt64(v) + x.SetInt64(v) + return } v := -n @@ -445,47 +595,23 @@ func (r *importReader) mpint(b *types.Basic) constant.Value { if v < 1 || uint(v) > maxBytes { errorf("weird decoding: %v, %v => %v", n, signed, v) } - - buf := make([]byte, v) - io.ReadFull(&r.declReader, buf) - - // convert to little endian - // TODO(gri) go/constant should have a more direct conversion function - // (e.g., once it supports a big.Float based implementation) - for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 { - buf[i], buf[j] = buf[j], buf[i] - } - - x := constant.MakeFromBytes(buf) + b := make([]byte, v) + io.ReadFull(&r.declReader, b) + x.SetBytes(b) if signed && n&1 != 0 { - x = constant.UnaryOp(token.SUB, x, 0) + x.Neg(x) } - return x } -func (r *importReader) mpfloat(b *types.Basic) constant.Value { - x := r.mpint(b) - if constant.Sign(x) == 0 { - return x +func (r *importReader) mpfloat(typ *types.Basic) constant.Value { + var mant big.Int + r.mpint(&mant, typ) + var f big.Float + f.SetInt(&mant) + if f.Sign() != 0 { + f.SetMantExp(&f, int(r.int64())) } - - exp := r.int64() - switch { - case exp > 0: - x = constant.Shift(x, token.SHL, uint(exp)) - // Ensure that the imported Kind is Float, else this constant may run into - // bitsize limits on overlarge integers. Eventually we can instead adopt - // the approach of CL 288632, but that CL relies on go/constant APIs that - // were introduced in go1.13. - // - // TODO(rFindley): sync the logic here with tip Go once we no longer - // support go1.12. - x = constant.ToFloat(x) - case exp < 0: - d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) - x = constant.BinaryOp(x, token.QUO, d) - } - return x + return constant.Make(&f) } func (r *importReader) ident() string { @@ -499,7 +625,7 @@ func (r *importReader) qualifiedIdent() (*types.Package, string) { } func (r *importReader) pos() token.Pos { - if r.p.version >= 1 { + if r.p.version >= iexportVersionPosCol { r.posv1() } else { r.posv0() @@ -547,8 +673,17 @@ func isInterface(t types.Type) bool { func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } -func (r *importReader) doType(base *types.Named) types.Type { - switch k := r.kind(); k { +func (r *importReader) doType(base *types.Named) (res types.Type) { + k := r.kind() + if debug { + r.p.trace("importing type %d (base: %s)", k, base) + r.p.indent++ + defer func() { + r.p.indent-- + r.p.trace("=> %s", res) + }() + } + switch k { default: errorf("unexpected kind tag in %q: %v", r.p.ipath, k) return nil @@ -571,7 +706,7 @@ func (r *importReader) doType(base *types.Named) types.Type { return types.NewMap(r.typ(), r.typ()) case signatureType: r.currPkg = r.pkg() - return r.signature(nil) + return r.signature(nil, nil, nil) case structType: r.currPkg = r.pkg() @@ -611,13 +746,56 @@ func (r *importReader) doType(base *types.Named) types.Type { recv = types.NewVar(token.NoPos, r.currPkg, "", base) } - msig := r.signature(recv) + msig := r.signature(recv, nil, nil) methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig) } typ := newInterface(methods, embeddeds) r.p.interfaceList = append(r.p.interfaceList, typ) return typ + + case typeParamType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected type param type") + } + pkg, name := r.qualifiedIdent() + id := ident{pkg, name} + if t, ok := r.p.tparamIndex[id]; ok { + // We're already in the process of importing this typeparam. + return t + } + // Otherwise, import the definition of the typeparam now. + r.p.doDecl(pkg, name) + return r.p.tparamIndex[id] + + case instanceType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected instantiation type") + } + // pos does not matter for instances: they are positioned on the original + // type. + _ = r.pos() + len := r.uint64() + targs := make([]types.Type, len) + for i := range targs { + targs[i] = r.typ() + } + baseType := r.typ() + // The imported instantiated type doesn't include any methods, so + // we must always use the methods of the base (orig) type. + // TODO provide a non-nil *Environment + t, _ := typeparams.Instantiate(nil, baseType, targs, false) + return t + + case unionType: + if r.p.version < iexportVersionGenerics { + errorf("unexpected instantiation type") + } + terms := make([]*typeparams.Term, r.uint64()) + for i := range terms { + terms[i] = typeparams.NewTerm(r.bool(), r.typ()) + } + return typeparams.NewUnion(terms) } } @@ -625,11 +803,25 @@ func (r *importReader) kind() itag { return itag(r.uint64()) } -func (r *importReader) signature(recv *types.Var) *types.Signature { +func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature { params := r.paramList() results := r.paramList() variadic := params.Len() > 0 && r.bool() - return types.NewSignature(recv, params, results, variadic) + return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic) +} + +func (r *importReader) tparamList() []*typeparams.TypeParam { + n := r.uint64() + if n == 0 { + return nil + } + xs := make([]*typeparams.TypeParam, n) + for i := range xs { + // Note: the standard library importer is tolerant of nil types here, + // though would panic in SetTypeParams. + xs[i] = r.typ().(*typeparams.TypeParam) + } + return xs } func (r *importReader) paramList() *types.Tuple { @@ -674,3 +866,13 @@ func (r *importReader) byte() byte { } return x } + +func baseType(typ types.Type) *types.Named { + // pointer receivers are never types.Named types + if p, _ := typ.(*types.Pointer); p != nil { + typ = p.Elem() + } + // receiver base types are always (possibly generic) types.Named types + n, _ := typ.(*types.Named) + return n +} diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go new file mode 100644 index 00000000000..d892273efb6 --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/support_go117.go @@ -0,0 +1,16 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.18 +// +build !go1.18 + +package gcimporter + +import "go/types" + +const iexportVersion = iexportVersionGo1_11 + +func additionalPredeclared() []types.Type { + return nil +} diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go new file mode 100644 index 00000000000..a993843230c --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go @@ -0,0 +1,23 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.18 +// +build go1.18 + +package gcimporter + +import "go/types" + +const iexportVersion = iexportVersionGenerics + +// additionalPredeclared returns additional predeclared types in go.1.18. +func additionalPredeclared() []types.Type { + return []types.Type{ + // comparable + types.Universe.Lookup("comparable").Type(), + + // any + types.Universe.Lookup("any").Type(), + } +} diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go new file mode 100644 index 00000000000..286bf445483 --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go @@ -0,0 +1,10 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !(go1.18 && goexperiment.unified) +// +build !go1.18 !goexperiment.unified + +package gcimporter + +const unifiedIR = false diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go new file mode 100644 index 00000000000..b5d69ffbe68 --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go @@ -0,0 +1,10 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.18 && goexperiment.unified +// +build go1.18,goexperiment.unified + +package gcimporter + +const unifiedIR = true diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go new file mode 100644 index 00000000000..8eb20729c2a --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go @@ -0,0 +1,19 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.18 +// +build !go1.18 + +package gcimporter + +import ( + "fmt" + "go/token" + "go/types" +) + +func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data") + return +} diff --git a/go/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go b/go/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go new file mode 100644 index 00000000000..3c1a4375435 --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go @@ -0,0 +1,612 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Derived from go/internal/gcimporter/ureader.go + +//go:build go1.18 +// +build go1.18 + +package gcimporter + +import ( + "go/token" + "go/types" + "strings" + + "golang.org/x/tools/go/internal/pkgbits" +) + +// A pkgReader holds the shared state for reading a unified IR package +// description. +type pkgReader struct { + pkgbits.PkgDecoder + + fake fakeFileSet + + ctxt *types.Context + imports map[string]*types.Package // previously imported packages, indexed by path + + // lazily initialized arrays corresponding to the unified IR + // PosBase, Pkg, and Type sections, respectively. + posBases []string // position bases (i.e., file names) + pkgs []*types.Package + typs []types.Type + + // laterFns holds functions that need to be invoked at the end of + // import reading. + laterFns []func() +} + +// later adds a function to be invoked at the end of import reading. +func (pr *pkgReader) later(fn func()) { + pr.laterFns = append(pr.laterFns, fn) +} + +// See cmd/compile/internal/noder.derivedInfo. +type derivedInfo struct { + idx pkgbits.Index + needed bool +} + +// See cmd/compile/internal/noder.typeInfo. +type typeInfo struct { + idx pkgbits.Index + derived bool +} + +func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + s := string(data) + s = s[:strings.LastIndex(s, "\n$$\n")] + input := pkgbits.NewPkgDecoder(path, s) + pkg = readUnifiedPackage(fset, nil, imports, input) + return +} + +// readUnifiedPackage reads a package description from the given +// unified IR export data decoder. +func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { + pr := pkgReader{ + PkgDecoder: input, + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*fileInfo), + }, + + ctxt: ctxt, + imports: imports, + + posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), + pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), + typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), + } + defer pr.fake.setLines() + + r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) + pkg := r.pkg() + r.Bool() // has init + + for i, n := 0, r.Len(); i < n; i++ { + // As if r.obj(), but avoiding the Scope.Lookup call, + // to avoid eager loading of imports. + r.Sync(pkgbits.SyncObject) + assert(!r.Bool()) + r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + assert(r.Len() == 0) + } + + r.Sync(pkgbits.SyncEOF) + + for _, fn := range pr.laterFns { + fn() + } + + pkg.MarkComplete() + return pkg +} + +// A reader holds the state for reading a single unified IR element +// within a package. +type reader struct { + pkgbits.Decoder + + p *pkgReader + + dict *readerDict +} + +// A readerDict holds the state for type parameters that parameterize +// the current unified IR element. +type readerDict struct { + // bounds is a slice of typeInfos corresponding to the underlying + // bounds of the element's type parameters. + bounds []typeInfo + + // tparams is a slice of the constructed TypeParams for the element. + tparams []*types.TypeParam + + // devived is a slice of types derived from tparams, which may be + // instantiated while reading the current element. + derived []derivedInfo + derivedTypes []types.Type // lazily instantiated from derived +} + +func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { + return &reader{ + Decoder: pr.NewDecoder(k, idx, marker), + p: pr, + } +} + +// @@@ Positions + +func (r *reader) pos() token.Pos { + r.Sync(pkgbits.SyncPos) + if !r.Bool() { + return token.NoPos + } + + // TODO(mdempsky): Delta encoding. + posBase := r.posBase() + line := r.Uint() + col := r.Uint() + return r.p.fake.pos(posBase, int(line), int(col)) +} + +func (r *reader) posBase() string { + return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) +} + +func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { + if b := pr.posBases[idx]; b != "" { + return b + } + + r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) + + // Within types2, position bases have a lot more details (e.g., + // keeping track of where //line directives appeared exactly). + // + // For go/types, we just track the file name. + + filename := r.String() + + if r.Bool() { // file base + // Was: "b = token.NewTrimmedFileBase(filename, true)" + } else { // line base + pos := r.pos() + line := r.Uint() + col := r.Uint() + + // Was: "b = token.NewLineBase(pos, filename, true, line, col)" + _, _, _ = pos, line, col + } + + b := filename + pr.posBases[idx] = b + return b +} + +// @@@ Packages + +func (r *reader) pkg() *types.Package { + r.Sync(pkgbits.SyncPkg) + return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) +} + +func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { + // TODO(mdempsky): Consider using some non-nil pointer to indicate + // the universe scope, so we don't need to keep re-reading it. + if pkg := pr.pkgs[idx]; pkg != nil { + return pkg + } + + pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() + pr.pkgs[idx] = pkg + return pkg +} + +func (r *reader) doPkg() *types.Package { + path := r.String() + switch path { + case "": + path = r.p.PkgPath() + case "builtin": + return nil // universe + case "unsafe": + return types.Unsafe + } + + if pkg := r.p.imports[path]; pkg != nil { + return pkg + } + + name := r.String() + + pkg := types.NewPackage(path, name) + r.p.imports[path] = pkg + + imports := make([]*types.Package, r.Len()) + for i := range imports { + imports[i] = r.pkg() + } + pkg.SetImports(imports) + + return pkg +} + +// @@@ Types + +func (r *reader) typ() types.Type { + return r.p.typIdx(r.typInfo(), r.dict) +} + +func (r *reader) typInfo() typeInfo { + r.Sync(pkgbits.SyncType) + if r.Bool() { + return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} + } + return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} +} + +func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { + idx := info.idx + var where *types.Type + if info.derived { + where = &dict.derivedTypes[idx] + idx = dict.derived[idx].idx + } else { + where = &pr.typs[idx] + } + + if typ := *where; typ != nil { + return typ + } + + r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) + r.dict = dict + + typ := r.doTyp() + assert(typ != nil) + + // See comment in pkgReader.typIdx explaining how this happens. + if prev := *where; prev != nil { + return prev + } + + *where = typ + return typ +} + +func (r *reader) doTyp() (res types.Type) { + switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { + default: + errorf("unhandled type tag: %v", tag) + panic("unreachable") + + case pkgbits.TypeBasic: + return types.Typ[r.Len()] + + case pkgbits.TypeNamed: + obj, targs := r.obj() + name := obj.(*types.TypeName) + if len(targs) != 0 { + t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) + return t + } + return name.Type() + + case pkgbits.TypeTypeParam: + return r.dict.tparams[r.Len()] + + case pkgbits.TypeArray: + len := int64(r.Uint64()) + return types.NewArray(r.typ(), len) + case pkgbits.TypeChan: + dir := types.ChanDir(r.Len()) + return types.NewChan(dir, r.typ()) + case pkgbits.TypeMap: + return types.NewMap(r.typ(), r.typ()) + case pkgbits.TypePointer: + return types.NewPointer(r.typ()) + case pkgbits.TypeSignature: + return r.signature(nil, nil, nil) + case pkgbits.TypeSlice: + return types.NewSlice(r.typ()) + case pkgbits.TypeStruct: + return r.structType() + case pkgbits.TypeInterface: + return r.interfaceType() + case pkgbits.TypeUnion: + return r.unionType() + } +} + +func (r *reader) structType() *types.Struct { + fields := make([]*types.Var, r.Len()) + var tags []string + for i := range fields { + pos := r.pos() + pkg, name := r.selector() + ftyp := r.typ() + tag := r.String() + embedded := r.Bool() + + fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) + if tag != "" { + for len(tags) < i { + tags = append(tags, "") + } + tags = append(tags, tag) + } + } + return types.NewStruct(fields, tags) +} + +func (r *reader) unionType() *types.Union { + terms := make([]*types.Term, r.Len()) + for i := range terms { + terms[i] = types.NewTerm(r.Bool(), r.typ()) + } + return types.NewUnion(terms) +} + +func (r *reader) interfaceType() *types.Interface { + methods := make([]*types.Func, r.Len()) + embeddeds := make([]types.Type, r.Len()) + implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() + + for i := range methods { + pos := r.pos() + pkg, name := r.selector() + mtyp := r.signature(nil, nil, nil) + methods[i] = types.NewFunc(pos, pkg, name, mtyp) + } + + for i := range embeddeds { + embeddeds[i] = r.typ() + } + + iface := types.NewInterfaceType(methods, embeddeds) + if implicit { + iface.MarkImplicit() + } + return iface +} + +func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { + r.Sync(pkgbits.SyncSignature) + + params := r.params() + results := r.params() + variadic := r.Bool() + + return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) +} + +func (r *reader) params() *types.Tuple { + r.Sync(pkgbits.SyncParams) + + params := make([]*types.Var, r.Len()) + for i := range params { + params[i] = r.param() + } + + return types.NewTuple(params...) +} + +func (r *reader) param() *types.Var { + r.Sync(pkgbits.SyncParam) + + pos := r.pos() + pkg, name := r.localIdent() + typ := r.typ() + + return types.NewParam(pos, pkg, name, typ) +} + +// @@@ Objects + +func (r *reader) obj() (types.Object, []types.Type) { + r.Sync(pkgbits.SyncObject) + + assert(!r.Bool()) + + pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + obj := pkgScope(pkg).Lookup(name) + + targs := make([]types.Type, r.Len()) + for i := range targs { + targs[i] = r.typ() + } + + return obj, targs +} + +func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { + rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) + + objPkg, objName := rname.qualifiedIdent() + assert(objName != "") + + tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) + + if tag == pkgbits.ObjStub { + assert(objPkg == nil || objPkg == types.Unsafe) + return objPkg, objName + } + + if objPkg.Scope().Lookup(objName) == nil { + dict := pr.objDictIdx(idx) + + r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) + r.dict = dict + + declare := func(obj types.Object) { + objPkg.Scope().Insert(obj) + } + + switch tag { + default: + panic("weird") + + case pkgbits.ObjAlias: + pos := r.pos() + typ := r.typ() + declare(types.NewTypeName(pos, objPkg, objName, typ)) + + case pkgbits.ObjConst: + pos := r.pos() + typ := r.typ() + val := r.Value() + declare(types.NewConst(pos, objPkg, objName, typ, val)) + + case pkgbits.ObjFunc: + pos := r.pos() + tparams := r.typeParamNames() + sig := r.signature(nil, nil, tparams) + declare(types.NewFunc(pos, objPkg, objName, sig)) + + case pkgbits.ObjType: + pos := r.pos() + + obj := types.NewTypeName(pos, objPkg, objName, nil) + named := types.NewNamed(obj, nil, nil) + declare(obj) + + named.SetTypeParams(r.typeParamNames()) + + // TODO(mdempsky): Rewrite receiver types to underlying is an + // Interface? The go/types importer does this (I think because + // unit tests expected that), but cmd/compile doesn't care + // about it, so maybe we can avoid worrying about that here. + rhs := r.typ() + r.p.later(func() { + underlying := rhs.Underlying() + named.SetUnderlying(underlying) + }) + + for i, n := 0, r.Len(); i < n; i++ { + named.AddMethod(r.method()) + } + + case pkgbits.ObjVar: + pos := r.pos() + typ := r.typ() + declare(types.NewVar(pos, objPkg, objName, typ)) + } + } + + return objPkg, objName +} + +func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { + r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) + + var dict readerDict + + if implicits := r.Len(); implicits != 0 { + errorf("unexpected object with %v implicit type parameter(s)", implicits) + } + + dict.bounds = make([]typeInfo, r.Len()) + for i := range dict.bounds { + dict.bounds[i] = r.typInfo() + } + + dict.derived = make([]derivedInfo, r.Len()) + dict.derivedTypes = make([]types.Type, len(dict.derived)) + for i := range dict.derived { + dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()} + } + + // function references follow, but reader doesn't need those + + return &dict +} + +func (r *reader) typeParamNames() []*types.TypeParam { + r.Sync(pkgbits.SyncTypeParamNames) + + // Note: This code assumes it only processes objects without + // implement type parameters. This is currently fine, because + // reader is only used to read in exported declarations, which are + // always package scoped. + + if len(r.dict.bounds) == 0 { + return nil + } + + // Careful: Type parameter lists may have cycles. To allow for this, + // we construct the type parameter list in two passes: first we + // create all the TypeNames and TypeParams, then we construct and + // set the bound type. + + r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds)) + for i := range r.dict.bounds { + pos := r.pos() + pkg, name := r.localIdent() + + tname := types.NewTypeName(pos, pkg, name, nil) + r.dict.tparams[i] = types.NewTypeParam(tname, nil) + } + + typs := make([]types.Type, len(r.dict.bounds)) + for i, bound := range r.dict.bounds { + typs[i] = r.p.typIdx(bound, r.dict) + } + + // TODO(mdempsky): This is subtle, elaborate further. + // + // We have to save tparams outside of the closure, because + // typeParamNames() can be called multiple times with the same + // dictionary instance. + // + // Also, this needs to happen later to make sure SetUnderlying has + // been called. + // + // TODO(mdempsky): Is it safe to have a single "later" slice or do + // we need to have multiple passes? See comments on CL 386002 and + // go.dev/issue/52104. + tparams := r.dict.tparams + r.p.later(func() { + for i, typ := range typs { + tparams[i].SetConstraint(typ) + } + }) + + return r.dict.tparams +} + +func (r *reader) method() *types.Func { + r.Sync(pkgbits.SyncMethod) + pos := r.pos() + pkg, name := r.selector() + + rparams := r.typeParamNames() + sig := r.signature(r.param(), rparams, nil) + + _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. + return types.NewFunc(pos, pkg, name, sig) +} + +func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } +func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } +func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } + +func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { + r.Sync(marker) + return r.pkg(), r.String() +} + +// pkgScope returns pkg.Scope(). +// If pkg is nil, it returns types.Universe instead. +// +// TODO(mdempsky): Remove after x/tools can depend on Go 1.19. +func pkgScope(pkg *types.Package) *types.Scope { + if pkg != nil { + return pkg.Scope() + } + return types.Universe +} diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go new file mode 100644 index 00000000000..f0cabde96eb --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go @@ -0,0 +1,77 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +// A Code is an enum value that can be encoded into bitstreams. +// +// Code types are preferable for enum types, because they allow +// Decoder to detect desyncs. +type Code interface { + // Marker returns the SyncMarker for the Code's dynamic type. + Marker() SyncMarker + + // Value returns the Code's ordinal value. + Value() int +} + +// A CodeVal distinguishes among go/constant.Value encodings. +type CodeVal int + +func (c CodeVal) Marker() SyncMarker { return SyncVal } +func (c CodeVal) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + ValBool CodeVal = iota + ValString + ValInt64 + ValBigInt + ValBigRat + ValBigFloat +) + +// A CodeType distinguishes among go/types.Type encodings. +type CodeType int + +func (c CodeType) Marker() SyncMarker { return SyncType } +func (c CodeType) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + TypeBasic CodeType = iota + TypeNamed + TypePointer + TypeSlice + TypeArray + TypeChan + TypeMap + TypeSignature + TypeStruct + TypeInterface + TypeUnion + TypeTypeParam +) + +// A CodeObj distinguishes among go/types.Object encodings. +type CodeObj int + +func (c CodeObj) Marker() SyncMarker { return SyncCodeObj } +func (c CodeObj) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + ObjAlias CodeObj = iota + ObjConst + ObjType + ObjFunc + ObjVar + ObjStub +) diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go new file mode 100644 index 00000000000..2bc793668ec --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go @@ -0,0 +1,433 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +import ( + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "math/big" + "os" + "runtime" + "strings" +) + +// A PkgDecoder provides methods for decoding a package's Unified IR +// export data. +type PkgDecoder struct { + // version is the file format version. + version uint32 + + // sync indicates whether the file uses sync markers. + sync bool + + // pkgPath is the package path for the package to be decoded. + // + // TODO(mdempsky): Remove; unneeded since CL 391014. + pkgPath string + + // elemData is the full data payload of the encoded package. + // Elements are densely and contiguously packed together. + // + // The last 8 bytes of elemData are the package fingerprint. + elemData string + + // elemEnds stores the byte-offset end positions of element + // bitstreams within elemData. + // + // For example, element I's bitstream data starts at elemEnds[I-1] + // (or 0, if I==0) and ends at elemEnds[I]. + // + // Note: elemEnds is indexed by absolute indices, not + // section-relative indices. + elemEnds []uint32 + + // elemEndsEnds stores the index-offset end positions of relocation + // sections within elemEnds. + // + // For example, section K's end positions start at elemEndsEnds[K-1] + // (or 0, if K==0) and end at elemEndsEnds[K]. + elemEndsEnds [numRelocs]uint32 +} + +// PkgPath returns the package path for the package +// +// TODO(mdempsky): Remove; unneeded since CL 391014. +func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath } + +// SyncMarkers reports whether pr uses sync markers. +func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync } + +// NewPkgDecoder returns a PkgDecoder initialized to read the Unified +// IR export data from input. pkgPath is the package path for the +// compilation unit that produced the export data. +// +// TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014. +func NewPkgDecoder(pkgPath, input string) PkgDecoder { + pr := PkgDecoder{ + pkgPath: pkgPath, + } + + // TODO(mdempsky): Implement direct indexing of input string to + // avoid copying the position information. + + r := strings.NewReader(input) + + assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil) + + switch pr.version { + default: + panic(fmt.Errorf("unsupported version: %v", pr.version)) + case 0: + // no flags + case 1: + var flags uint32 + assert(binary.Read(r, binary.LittleEndian, &flags) == nil) + pr.sync = flags&flagSyncMarkers != 0 + } + + assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil) + + pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1]) + assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil) + + pos, err := r.Seek(0, os.SEEK_CUR) + assert(err == nil) + + pr.elemData = input[pos:] + assert(len(pr.elemData)-8 == int(pr.elemEnds[len(pr.elemEnds)-1])) + + return pr +} + +// NumElems returns the number of elements in section k. +func (pr *PkgDecoder) NumElems(k RelocKind) int { + count := int(pr.elemEndsEnds[k]) + if k > 0 { + count -= int(pr.elemEndsEnds[k-1]) + } + return count +} + +// TotalElems returns the total number of elements across all sections. +func (pr *PkgDecoder) TotalElems() int { + return len(pr.elemEnds) +} + +// Fingerprint returns the package fingerprint. +func (pr *PkgDecoder) Fingerprint() [8]byte { + var fp [8]byte + copy(fp[:], pr.elemData[len(pr.elemData)-8:]) + return fp +} + +// AbsIdx returns the absolute index for the given (section, index) +// pair. +func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int { + absIdx := int(idx) + if k > 0 { + absIdx += int(pr.elemEndsEnds[k-1]) + } + if absIdx >= int(pr.elemEndsEnds[k]) { + errorf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) + } + return absIdx +} + +// DataIdx returns the raw element bitstream for the given (section, +// index) pair. +func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string { + absIdx := pr.AbsIdx(k, idx) + + var start uint32 + if absIdx > 0 { + start = pr.elemEnds[absIdx-1] + } + end := pr.elemEnds[absIdx] + + return pr.elemData[start:end] +} + +// StringIdx returns the string value for the given string index. +func (pr *PkgDecoder) StringIdx(idx Index) string { + return pr.DataIdx(RelocString, idx) +} + +// NewDecoder returns a Decoder for the given (section, index) pair, +// and decodes the given SyncMarker from the element bitstream. +func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { + r := pr.NewDecoderRaw(k, idx) + r.Sync(marker) + return r +} + +// NewDecoderRaw returns a Decoder for the given (section, index) pair. +// +// Most callers should use NewDecoder instead. +func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder { + r := Decoder{ + common: pr, + k: k, + Idx: idx, + } + + // TODO(mdempsky) r.data.Reset(...) after #44505 is resolved. + r.Data = *strings.NewReader(pr.DataIdx(k, idx)) + + r.Sync(SyncRelocs) + r.Relocs = make([]RelocEnt, r.Len()) + for i := range r.Relocs { + r.Sync(SyncReloc) + r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} + } + + return r +} + +// A Decoder provides methods for decoding an individual element's +// bitstream data. +type Decoder struct { + common *PkgDecoder + + Relocs []RelocEnt + Data strings.Reader + + k RelocKind + Idx Index +} + +func (r *Decoder) checkErr(err error) { + if err != nil { + errorf("unexpected decoding error: %w", err) + } +} + +func (r *Decoder) rawUvarint() uint64 { + x, err := binary.ReadUvarint(&r.Data) + r.checkErr(err) + return x +} + +func (r *Decoder) rawVarint() int64 { + ux := r.rawUvarint() + + // Zig-zag decode. + x := int64(ux >> 1) + if ux&1 != 0 { + x = ^x + } + return x +} + +func (r *Decoder) rawReloc(k RelocKind, idx int) Index { + e := r.Relocs[idx] + assert(e.Kind == k) + return e.Idx +} + +// Sync decodes a sync marker from the element bitstream and asserts +// that it matches the expected marker. +// +// If r.common.sync is false, then Sync is a no-op. +func (r *Decoder) Sync(mWant SyncMarker) { + if !r.common.sync { + return + } + + pos, _ := r.Data.Seek(0, os.SEEK_CUR) // TODO(mdempsky): io.SeekCurrent after #44505 is resolved + mHave := SyncMarker(r.rawUvarint()) + writerPCs := make([]int, r.rawUvarint()) + for i := range writerPCs { + writerPCs[i] = int(r.rawUvarint()) + } + + if mHave == mWant { + return + } + + // There's some tension here between printing: + // + // (1) full file paths that tools can recognize (e.g., so emacs + // hyperlinks the "file:line" text for easy navigation), or + // + // (2) short file paths that are easier for humans to read (e.g., by + // omitting redundant or irrelevant details, so it's easier to + // focus on the useful bits that remain). + // + // The current formatting favors the former, as it seems more + // helpful in practice. But perhaps the formatting could be improved + // to better address both concerns. For example, use relative file + // paths if they would be shorter, or rewrite file paths to contain + // "$GOROOT" (like objabi.AbsFile does) if tools can be taught how + // to reliably expand that again. + + fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos) + + fmt.Printf("\nfound %v, written at:\n", mHave) + if len(writerPCs) == 0 { + fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath) + } + for _, pc := range writerPCs { + fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc))) + } + + fmt.Printf("\nexpected %v, reading at:\n", mWant) + var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size? + n := runtime.Callers(2, readerPCs[:]) + for _, pc := range fmtFrames(readerPCs[:n]...) { + fmt.Printf("\t%s\n", pc) + } + + // We already printed a stack trace for the reader, so now we can + // simply exit. Printing a second one with panic or base.Fatalf + // would just be noise. + os.Exit(1) +} + +// Bool decodes and returns a bool value from the element bitstream. +func (r *Decoder) Bool() bool { + r.Sync(SyncBool) + x, err := r.Data.ReadByte() + r.checkErr(err) + assert(x < 2) + return x != 0 +} + +// Int64 decodes and returns an int64 value from the element bitstream. +func (r *Decoder) Int64() int64 { + r.Sync(SyncInt64) + return r.rawVarint() +} + +// Int64 decodes and returns a uint64 value from the element bitstream. +func (r *Decoder) Uint64() uint64 { + r.Sync(SyncUint64) + return r.rawUvarint() +} + +// Len decodes and returns a non-negative int value from the element bitstream. +func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v } + +// Int decodes and returns an int value from the element bitstream. +func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v } + +// Uint decodes and returns a uint value from the element bitstream. +func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v } + +// Code decodes a Code value from the element bitstream and returns +// its ordinal value. It's the caller's responsibility to convert the +// result to an appropriate Code type. +// +// TODO(mdempsky): Ideally this method would have signature "Code[T +// Code] T" instead, but we don't allow generic methods and the +// compiler can't depend on generics yet anyway. +func (r *Decoder) Code(mark SyncMarker) int { + r.Sync(mark) + return r.Len() +} + +// Reloc decodes a relocation of expected section k from the element +// bitstream and returns an index to the referenced element. +func (r *Decoder) Reloc(k RelocKind) Index { + r.Sync(SyncUseReloc) + return r.rawReloc(k, r.Len()) +} + +// String decodes and returns a string value from the element +// bitstream. +func (r *Decoder) String() string { + r.Sync(SyncString) + return r.common.StringIdx(r.Reloc(RelocString)) +} + +// Strings decodes and returns a variable-length slice of strings from +// the element bitstream. +func (r *Decoder) Strings() []string { + res := make([]string, r.Len()) + for i := range res { + res[i] = r.String() + } + return res +} + +// Value decodes and returns a constant.Value from the element +// bitstream. +func (r *Decoder) Value() constant.Value { + r.Sync(SyncValue) + isComplex := r.Bool() + val := r.scalar() + if isComplex { + val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar())) + } + return val +} + +func (r *Decoder) scalar() constant.Value { + switch tag := CodeVal(r.Code(SyncVal)); tag { + default: + panic(fmt.Errorf("unexpected scalar tag: %v", tag)) + + case ValBool: + return constant.MakeBool(r.Bool()) + case ValString: + return constant.MakeString(r.String()) + case ValInt64: + return constant.MakeInt64(r.Int64()) + case ValBigInt: + return constant.Make(r.bigInt()) + case ValBigRat: + num := r.bigInt() + denom := r.bigInt() + return constant.Make(new(big.Rat).SetFrac(num, denom)) + case ValBigFloat: + return constant.Make(r.bigFloat()) + } +} + +func (r *Decoder) bigInt() *big.Int { + v := new(big.Int).SetBytes([]byte(r.String())) + if r.Bool() { + v.Neg(v) + } + return v +} + +func (r *Decoder) bigFloat() *big.Float { + v := new(big.Float).SetPrec(512) + assert(v.UnmarshalText([]byte(r.String())) == nil) + return v +} + +// @@@ Helpers + +// TODO(mdempsky): These should probably be removed. I think they're a +// smell that the export data format is not yet quite right. + +// PeekPkgPath returns the package path for the specified package +// index. +func (pr *PkgDecoder) PeekPkgPath(idx Index) string { + r := pr.NewDecoder(RelocPkg, idx, SyncPkgDef) + path := r.String() + if path == "" { + path = pr.pkgPath + } + return path +} + +// PeekObj returns the package path, object name, and CodeObj for the +// specified object index. +func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) { + r := pr.NewDecoder(RelocName, idx, SyncObject1) + r.Sync(SyncSym) + r.Sync(SyncPkg) + path := pr.PeekPkgPath(r.Reloc(RelocPkg)) + name := r.String() + assert(name != "") + + tag := CodeObj(r.Code(SyncCodeObj)) + + return path, name, tag +} diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go new file mode 100644 index 00000000000..c8a2796b5e4 --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go @@ -0,0 +1,32 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package pkgbits implements low-level coding abstractions for +// Unified IR's export data format. +// +// At a low-level, a package is a collection of bitstream elements. +// Each element has a "kind" and a dense, non-negative index. +// Elements can be randomly accessed given their kind and index. +// +// Individual elements are sequences of variable-length values (e.g., +// integers, booleans, strings, go/constant values, cross-references +// to other elements). Package pkgbits provides APIs for encoding and +// decoding these low-level values, but the details of mapping +// higher-level Go constructs into elements is left to higher-level +// abstractions. +// +// Elements may cross-reference each other with "relocations." For +// example, an element representing a pointer type has a relocation +// referring to the element type. +// +// Go constructs may be composed as a constellation of multiple +// elements. For example, a declared function may have one element to +// describe the object (e.g., its name, type, position), and a +// separate element to describe its function body. This allows readers +// some flexibility in efficiently seeking or re-reading data (e.g., +// inlining requires re-reading the function body for each inlined +// call, without needing to re-read the object-level details). +// +// This is a copy of internal/pkgbits in the Go implementation. +package pkgbits diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go new file mode 100644 index 00000000000..c50c838caae --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go @@ -0,0 +1,379 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +import ( + "bytes" + "crypto/md5" + "encoding/binary" + "go/constant" + "io" + "math/big" + "runtime" +) + +// currentVersion is the current version number. +// +// - v0: initial prototype +// +// - v1: adds the flags uint32 word +const currentVersion uint32 = 1 + +// A PkgEncoder provides methods for encoding a package's Unified IR +// export data. +type PkgEncoder struct { + // elems holds the bitstream for previously encoded elements. + elems [numRelocs][]string + + // stringsIdx maps previously encoded strings to their index within + // the RelocString section, to allow deduplication. That is, + // elems[RelocString][stringsIdx[s]] == s (if present). + stringsIdx map[string]Index + + // syncFrames is the number of frames to write at each sync + // marker. A negative value means sync markers are omitted. + syncFrames int +} + +// SyncMarkers reports whether pw uses sync markers. +func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 } + +// NewPkgEncoder returns an initialized PkgEncoder. +// +// syncFrames is the number of caller frames that should be serialized +// at Sync points. Serializing additional frames results in larger +// export data files, but can help diagnosing desync errors in +// higher-level Unified IR reader/writer code. If syncFrames is +// negative, then sync markers are omitted entirely. +func NewPkgEncoder(syncFrames int) PkgEncoder { + return PkgEncoder{ + stringsIdx: make(map[string]Index), + syncFrames: syncFrames, + } +} + +// DumpTo writes the package's encoded data to out0 and returns the +// package fingerprint. +func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { + h := md5.New() + out := io.MultiWriter(out0, h) + + writeUint32 := func(x uint32) { + assert(binary.Write(out, binary.LittleEndian, x) == nil) + } + + writeUint32(currentVersion) + + var flags uint32 + if pw.SyncMarkers() { + flags |= flagSyncMarkers + } + writeUint32(flags) + + // Write elemEndsEnds. + var sum uint32 + for _, elems := range &pw.elems { + sum += uint32(len(elems)) + writeUint32(sum) + } + + // Write elemEnds. + sum = 0 + for _, elems := range &pw.elems { + for _, elem := range elems { + sum += uint32(len(elem)) + writeUint32(sum) + } + } + + // Write elemData. + for _, elems := range &pw.elems { + for _, elem := range elems { + _, err := io.WriteString(out, elem) + assert(err == nil) + } + } + + // Write fingerprint. + copy(fingerprint[:], h.Sum(nil)) + _, err := out0.Write(fingerprint[:]) + assert(err == nil) + + return +} + +// StringIdx adds a string value to the strings section, if not +// already present, and returns its index. +func (pw *PkgEncoder) StringIdx(s string) Index { + if idx, ok := pw.stringsIdx[s]; ok { + assert(pw.elems[RelocString][idx] == s) + return idx + } + + idx := Index(len(pw.elems[RelocString])) + pw.elems[RelocString] = append(pw.elems[RelocString], s) + pw.stringsIdx[s] = idx + return idx +} + +// NewEncoder returns an Encoder for a new element within the given +// section, and encodes the given SyncMarker as the start of the +// element bitstream. +func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder { + e := pw.NewEncoderRaw(k) + e.Sync(marker) + return e +} + +// NewEncoderRaw returns an Encoder for a new element within the given +// section. +// +// Most callers should use NewEncoder instead. +func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder { + idx := Index(len(pw.elems[k])) + pw.elems[k] = append(pw.elems[k], "") // placeholder + + return Encoder{ + p: pw, + k: k, + Idx: idx, + } +} + +// An Encoder provides methods for encoding an individual element's +// bitstream data. +type Encoder struct { + p *PkgEncoder + + Relocs []RelocEnt + Data bytes.Buffer // accumulated element bitstream data + + encodingRelocHeader bool + + k RelocKind + Idx Index // index within relocation section +} + +// Flush finalizes the element's bitstream and returns its Index. +func (w *Encoder) Flush() Index { + var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved + + // Backup the data so we write the relocations at the front. + var tmp bytes.Buffer + io.Copy(&tmp, &w.Data) + + // TODO(mdempsky): Consider writing these out separately so they're + // easier to strip, along with function bodies, so that we can prune + // down to just the data that's relevant to go/types. + if w.encodingRelocHeader { + panic("encodingRelocHeader already true; recursive flush?") + } + w.encodingRelocHeader = true + w.Sync(SyncRelocs) + w.Len(len(w.Relocs)) + for _, rEnt := range w.Relocs { + w.Sync(SyncReloc) + w.Len(int(rEnt.Kind)) + w.Len(int(rEnt.Idx)) + } + + io.Copy(&sb, &w.Data) + io.Copy(&sb, &tmp) + w.p.elems[w.k][w.Idx] = sb.String() + + return w.Idx +} + +func (w *Encoder) checkErr(err error) { + if err != nil { + errorf("unexpected encoding error: %v", err) + } +} + +func (w *Encoder) rawUvarint(x uint64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutUvarint(buf[:], x) + _, err := w.Data.Write(buf[:n]) + w.checkErr(err) +} + +func (w *Encoder) rawVarint(x int64) { + // Zig-zag encode. + ux := uint64(x) << 1 + if x < 0 { + ux = ^ux + } + + w.rawUvarint(ux) +} + +func (w *Encoder) rawReloc(r RelocKind, idx Index) int { + // TODO(mdempsky): Use map for lookup; this takes quadratic time. + for i, rEnt := range w.Relocs { + if rEnt.Kind == r && rEnt.Idx == idx { + return i + } + } + + i := len(w.Relocs) + w.Relocs = append(w.Relocs, RelocEnt{r, idx}) + return i +} + +func (w *Encoder) Sync(m SyncMarker) { + if !w.p.SyncMarkers() { + return + } + + // Writing out stack frame string references requires working + // relocations, but writing out the relocations themselves involves + // sync markers. To prevent infinite recursion, we simply trim the + // stack frame for sync markers within the relocation header. + var frames []string + if !w.encodingRelocHeader && w.p.syncFrames > 0 { + pcs := make([]uintptr, w.p.syncFrames) + n := runtime.Callers(2, pcs) + frames = fmtFrames(pcs[:n]...) + } + + // TODO(mdempsky): Save space by writing out stack frames as a + // linked list so we can share common stack frames. + w.rawUvarint(uint64(m)) + w.rawUvarint(uint64(len(frames))) + for _, frame := range frames { + w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame)))) + } +} + +// Bool encodes and writes a bool value into the element bitstream, +// and then returns the bool value. +// +// For simple, 2-alternative encodings, the idiomatic way to call Bool +// is something like: +// +// if w.Bool(x != 0) { +// // alternative #1 +// } else { +// // alternative #2 +// } +// +// For multi-alternative encodings, use Code instead. +func (w *Encoder) Bool(b bool) bool { + w.Sync(SyncBool) + var x byte + if b { + x = 1 + } + err := w.Data.WriteByte(x) + w.checkErr(err) + return b +} + +// Int64 encodes and writes an int64 value into the element bitstream. +func (w *Encoder) Int64(x int64) { + w.Sync(SyncInt64) + w.rawVarint(x) +} + +// Uint64 encodes and writes a uint64 value into the element bitstream. +func (w *Encoder) Uint64(x uint64) { + w.Sync(SyncUint64) + w.rawUvarint(x) +} + +// Len encodes and writes a non-negative int value into the element bitstream. +func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) } + +// Int encodes and writes an int value into the element bitstream. +func (w *Encoder) Int(x int) { w.Int64(int64(x)) } + +// Len encodes and writes a uint value into the element bitstream. +func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) } + +// Reloc encodes and writes a relocation for the given (section, +// index) pair into the element bitstream. +// +// Note: Only the index is formally written into the element +// bitstream, so bitstream decoders must know from context which +// section an encoded relocation refers to. +func (w *Encoder) Reloc(r RelocKind, idx Index) { + w.Sync(SyncUseReloc) + w.Len(w.rawReloc(r, idx)) +} + +// Code encodes and writes a Code value into the element bitstream. +func (w *Encoder) Code(c Code) { + w.Sync(c.Marker()) + w.Len(c.Value()) +} + +// String encodes and writes a string value into the element +// bitstream. +// +// Internally, strings are deduplicated by adding them to the strings +// section (if not already present), and then writing a relocation +// into the element bitstream. +func (w *Encoder) String(s string) { + w.Sync(SyncString) + w.Reloc(RelocString, w.p.StringIdx(s)) +} + +// Strings encodes and writes a variable-length slice of strings into +// the element bitstream. +func (w *Encoder) Strings(ss []string) { + w.Len(len(ss)) + for _, s := range ss { + w.String(s) + } +} + +// Value encodes and writes a constant.Value into the element +// bitstream. +func (w *Encoder) Value(val constant.Value) { + w.Sync(SyncValue) + if w.Bool(val.Kind() == constant.Complex) { + w.scalar(constant.Real(val)) + w.scalar(constant.Imag(val)) + } else { + w.scalar(val) + } +} + +func (w *Encoder) scalar(val constant.Value) { + switch v := constant.Val(val).(type) { + default: + errorf("unhandled %v (%v)", val, val.Kind()) + case bool: + w.Code(ValBool) + w.Bool(v) + case string: + w.Code(ValString) + w.String(v) + case int64: + w.Code(ValInt64) + w.Int64(v) + case *big.Int: + w.Code(ValBigInt) + w.bigInt(v) + case *big.Rat: + w.Code(ValBigRat) + w.bigInt(v.Num()) + w.bigInt(v.Denom()) + case *big.Float: + w.Code(ValBigFloat) + w.bigFloat(v) + } +} + +func (w *Encoder) bigInt(v *big.Int) { + b := v.Bytes() + w.String(string(b)) // TODO: More efficient encoding. + w.Bool(v.Sign() < 0) +} + +func (w *Encoder) bigFloat(v *big.Float) { + b := v.Append(nil, 'p', -1) + w.String(string(b)) // TODO: More efficient encoding. +} diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go new file mode 100644 index 00000000000..654222745fa --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go @@ -0,0 +1,9 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +const ( + flagSyncMarkers = 1 << iota // file format contains sync markers +) diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go new file mode 100644 index 00000000000..5294f6a63ed --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go @@ -0,0 +1,21 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.7 +// +build !go1.7 + +// TODO(mdempsky): Remove after #44505 is resolved + +package pkgbits + +import "runtime" + +func walkFrames(pcs []uintptr, visit frameVisitor) { + for _, pc := range pcs { + fn := runtime.FuncForPC(pc) + file, line := fn.FileLine(pc) + + visit(file, line, fn.Name(), pc-fn.Entry()) + } +} diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go new file mode 100644 index 00000000000..2324ae7adfe --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go @@ -0,0 +1,28 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.7 +// +build go1.7 + +package pkgbits + +import "runtime" + +// walkFrames calls visit for each call frame represented by pcs. +// +// pcs should be a slice of PCs, as returned by runtime.Callers. +func walkFrames(pcs []uintptr, visit frameVisitor) { + if len(pcs) == 0 { + return + } + + frames := runtime.CallersFrames(pcs) + for { + frame, more := frames.Next() + visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) + if !more { + return + } + } +} diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go new file mode 100644 index 00000000000..7a8f04ab3fc --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go @@ -0,0 +1,42 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +// A RelocKind indicates a particular section within a unified IR export. +type RelocKind int + +// An Index represents a bitstream element index within a particular +// section. +type Index int + +// A relocEnt (relocation entry) is an entry in an element's local +// reference table. +// +// TODO(mdempsky): Rename this too. +type RelocEnt struct { + Kind RelocKind + Idx Index +} + +// Reserved indices within the meta relocation section. +const ( + PublicRootIdx Index = 0 + PrivateRootIdx Index = 1 +) + +const ( + RelocString RelocKind = iota + RelocMeta + RelocPosBase + RelocPkg + RelocName + RelocType + RelocObj + RelocObjExt + RelocObjDict + RelocBody + + numRelocs = iota +) diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/support.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/support.go new file mode 100644 index 00000000000..ad26d3b28ca --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/support.go @@ -0,0 +1,17 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +import "fmt" + +func assert(b bool) { + if !b { + panic("assertion failed") + } +} + +func errorf(format string, args ...interface{}) { + panic(fmt.Errorf(format, args...)) +} diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go new file mode 100644 index 00000000000..5bd51ef7170 --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go @@ -0,0 +1,113 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +import ( + "fmt" + "strings" +) + +// fmtFrames formats a backtrace for reporting reader/writer desyncs. +func fmtFrames(pcs ...uintptr) []string { + res := make([]string, 0, len(pcs)) + walkFrames(pcs, func(file string, line int, name string, offset uintptr) { + // Trim package from function name. It's just redundant noise. + name = strings.TrimPrefix(name, "cmd/compile/internal/noder.") + + res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset)) + }) + return res +} + +type frameVisitor func(file string, line int, name string, offset uintptr) + +// SyncMarker is an enum type that represents markers that may be +// written to export data to ensure the reader and writer stay +// synchronized. +type SyncMarker int + +//go:generate stringer -type=SyncMarker -trimprefix=Sync + +const ( + _ SyncMarker = iota + + // Public markers (known to go/types importers). + + // Low-level coding markers. + SyncEOF + SyncBool + SyncInt64 + SyncUint64 + SyncString + SyncValue + SyncVal + SyncRelocs + SyncReloc + SyncUseReloc + + // Higher-level object and type markers. + SyncPublic + SyncPos + SyncPosBase + SyncObject + SyncObject1 + SyncPkg + SyncPkgDef + SyncMethod + SyncType + SyncTypeIdx + SyncTypeParamNames + SyncSignature + SyncParams + SyncParam + SyncCodeObj + SyncSym + SyncLocalIdent + SyncSelector + + // Private markers (only known to cmd/compile). + SyncPrivate + + SyncFuncExt + SyncVarExt + SyncTypeExt + SyncPragma + + SyncExprList + SyncExprs + SyncExpr + SyncExprType + SyncAssign + SyncOp + SyncFuncLit + SyncCompLit + + SyncDecl + SyncFuncBody + SyncOpenScope + SyncCloseScope + SyncCloseAnotherScope + SyncDeclNames + SyncDeclName + + SyncStmts + SyncBlockStmt + SyncIfStmt + SyncForStmt + SyncSwitchStmt + SyncRangeStmt + SyncCaseClause + SyncCommClause + SyncSelectStmt + SyncDecls + SyncLabeledStmt + SyncUseObjLocal + SyncAddLocal + SyncLinkname + SyncStmt1 + SyncStmtsEnd + SyncLabel + SyncOptLabel +) diff --git a/go/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go b/go/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go new file mode 100644 index 00000000000..4a5b0ca5f2f --- /dev/null +++ b/go/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go @@ -0,0 +1,89 @@ +// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT. + +package pkgbits + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[SyncEOF-1] + _ = x[SyncBool-2] + _ = x[SyncInt64-3] + _ = x[SyncUint64-4] + _ = x[SyncString-5] + _ = x[SyncValue-6] + _ = x[SyncVal-7] + _ = x[SyncRelocs-8] + _ = x[SyncReloc-9] + _ = x[SyncUseReloc-10] + _ = x[SyncPublic-11] + _ = x[SyncPos-12] + _ = x[SyncPosBase-13] + _ = x[SyncObject-14] + _ = x[SyncObject1-15] + _ = x[SyncPkg-16] + _ = x[SyncPkgDef-17] + _ = x[SyncMethod-18] + _ = x[SyncType-19] + _ = x[SyncTypeIdx-20] + _ = x[SyncTypeParamNames-21] + _ = x[SyncSignature-22] + _ = x[SyncParams-23] + _ = x[SyncParam-24] + _ = x[SyncCodeObj-25] + _ = x[SyncSym-26] + _ = x[SyncLocalIdent-27] + _ = x[SyncSelector-28] + _ = x[SyncPrivate-29] + _ = x[SyncFuncExt-30] + _ = x[SyncVarExt-31] + _ = x[SyncTypeExt-32] + _ = x[SyncPragma-33] + _ = x[SyncExprList-34] + _ = x[SyncExprs-35] + _ = x[SyncExpr-36] + _ = x[SyncExprType-37] + _ = x[SyncAssign-38] + _ = x[SyncOp-39] + _ = x[SyncFuncLit-40] + _ = x[SyncCompLit-41] + _ = x[SyncDecl-42] + _ = x[SyncFuncBody-43] + _ = x[SyncOpenScope-44] + _ = x[SyncCloseScope-45] + _ = x[SyncCloseAnotherScope-46] + _ = x[SyncDeclNames-47] + _ = x[SyncDeclName-48] + _ = x[SyncStmts-49] + _ = x[SyncBlockStmt-50] + _ = x[SyncIfStmt-51] + _ = x[SyncForStmt-52] + _ = x[SyncSwitchStmt-53] + _ = x[SyncRangeStmt-54] + _ = x[SyncCaseClause-55] + _ = x[SyncCommClause-56] + _ = x[SyncSelectStmt-57] + _ = x[SyncDecls-58] + _ = x[SyncLabeledStmt-59] + _ = x[SyncUseObjLocal-60] + _ = x[SyncAddLocal-61] + _ = x[SyncLinkname-62] + _ = x[SyncStmt1-63] + _ = x[SyncStmtsEnd-64] + _ = x[SyncLabel-65] + _ = x[SyncOptLabel-66] +} + +const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel" + +var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458} + +func (i SyncMarker) String() string { + i -= 1 + if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) { + return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]] +} diff --git a/go/vendor/golang.org/x/tools/go/packages/doc.go b/go/vendor/golang.org/x/tools/go/packages/doc.go index 4bfe28a51ff..da4ab89fe63 100644 --- a/go/vendor/golang.org/x/tools/go/packages/doc.go +++ b/go/vendor/golang.org/x/tools/go/packages/doc.go @@ -67,7 +67,6 @@ Most tools should pass their command-line arguments (after any flags) uninterpreted to the loader, so that the loader can interpret them according to the conventions of the underlying build system. See the Example function for typical usage. - */ package packages // import "golang.org/x/tools/go/packages" diff --git a/go/vendor/golang.org/x/tools/go/packages/golist.go b/go/vendor/golang.org/x/tools/go/packages/golist.go index 0e1e7f11fee..de881562de1 100644 --- a/go/vendor/golang.org/x/tools/go/packages/golist.go +++ b/go/vendor/golang.org/x/tools/go/packages/golist.go @@ -26,7 +26,6 @@ import ( "golang.org/x/tools/go/internal/packagesdriver" "golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/packagesinternal" - "golang.org/x/xerrors" ) // debug controls verbose logging. @@ -303,11 +302,12 @@ func (state *golistState) runContainsQueries(response *responseDeduper, queries } dirResponse, err := state.createDriverResponse(pattern) - // If there was an error loading the package, or the package is returned - // with errors, try to load the file as an ad-hoc package. + // If there was an error loading the package, or no packages are returned, + // or the package is returned with errors, try to load the file as an + // ad-hoc package. // Usually the error will appear in a returned package, but may not if we're // in module mode and the ad-hoc is located outside a module. - if err != nil || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && + if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && len(dirResponse.Packages[0].Errors) == 1 { var queryErr error if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { @@ -393,6 +393,8 @@ type jsonPackage struct { CompiledGoFiles []string IgnoredGoFiles []string IgnoredOtherFiles []string + EmbedPatterns []string + EmbedFiles []string CFiles []string CgoFiles []string CXXFiles []string @@ -444,7 +446,11 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse // Run "go list" for complete // information on the specified packages. - buf, err := state.invokeGo("list", golistargs(state.cfg, words)...) + goVersion, err := state.getGoVersion() + if err != nil { + return nil, err + } + buf, err := state.invokeGo("list", golistargs(state.cfg, words, goVersion)...) if err != nil { return nil, err } @@ -565,6 +571,8 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles), OtherFiles: absJoin(p.Dir, otherFiles(p)...), + EmbedFiles: absJoin(p.Dir, p.EmbedFiles), + EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns), IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles), forTest: p.ForTest, depsErrors: p.DepsErrors, @@ -805,17 +813,83 @@ func absJoin(dir string, fileses ...[]string) (res []string) { return res } -func golistargs(cfg *Config, words []string) []string { +func jsonFlag(cfg *Config, goVersion int) string { + if goVersion < 19 { + return "-json" + } + var fields []string + added := make(map[string]bool) + addFields := func(fs ...string) { + for _, f := range fs { + if !added[f] { + added[f] = true + fields = append(fields, f) + } + } + } + addFields("Name", "ImportPath", "Error") // These fields are always needed + if cfg.Mode&NeedFiles != 0 || cfg.Mode&NeedTypes != 0 { + addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles", + "CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles", + "SwigFiles", "SwigCXXFiles", "SysoFiles") + if cfg.Tests { + addFields("TestGoFiles", "XTestGoFiles") + } + } + if cfg.Mode&NeedTypes != 0 { + // CompiledGoFiles seems to be required for the test case TestCgoNoSyntax, + // even when -compiled isn't passed in. + // TODO(#52435): Should we make the test ask for -compiled, or automatically + // request CompiledGoFiles in certain circumstances? + addFields("Dir", "CompiledGoFiles") + } + if cfg.Mode&NeedCompiledGoFiles != 0 { + addFields("Dir", "CompiledGoFiles", "Export") + } + if cfg.Mode&NeedImports != 0 { + // When imports are requested, DepOnly is used to distinguish between packages + // explicitly requested and transitive imports of those packages. + addFields("DepOnly", "Imports", "ImportMap") + if cfg.Tests { + addFields("TestImports", "XTestImports") + } + } + if cfg.Mode&NeedDeps != 0 { + addFields("DepOnly") + } + if usesExportData(cfg) { + // Request Dir in the unlikely case Export is not absolute. + addFields("Dir", "Export") + } + if cfg.Mode&needInternalForTest != 0 { + addFields("ForTest") + } + if cfg.Mode&needInternalDepsErrors != 0 { + addFields("DepsErrors") + } + if cfg.Mode&NeedModule != 0 { + addFields("Module") + } + if cfg.Mode&NeedEmbedFiles != 0 { + addFields("EmbedFiles") + } + if cfg.Mode&NeedEmbedPatterns != 0 { + addFields("EmbedPatterns") + } + return "-json=" + strings.Join(fields, ",") +} + +func golistargs(cfg *Config, words []string, goVersion int) []string { const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo fullargs := []string{ - "-e", "-json", + "-e", jsonFlag(cfg, goVersion), fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0), fmt.Sprintf("-test=%t", cfg.Tests), fmt.Sprintf("-export=%t", usesExportData(cfg)), fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0), // go list doesn't let you pass -test and -find together, // probably because you'd just get the TestMain. - fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0), + fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)), } fullargs = append(fullargs, cfg.BuildFlags...) fullargs = append(fullargs, "--") @@ -879,7 +953,7 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, if !ok { // Catastrophic error: // - context cancellation - return nil, xerrors.Errorf("couldn't run 'go': %w", err) + return nil, fmt.Errorf("couldn't run 'go': %w", err) } // Old go version? diff --git a/go/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/go/vendor/golang.org/x/tools/go/packages/loadmode_string.go index 7ea37e7eeac..5c080d21b54 100644 --- a/go/vendor/golang.org/x/tools/go/packages/loadmode_string.go +++ b/go/vendor/golang.org/x/tools/go/packages/loadmode_string.go @@ -15,7 +15,7 @@ var allModes = []LoadMode{ NeedCompiledGoFiles, NeedImports, NeedDeps, - NeedExportsFile, + NeedExportFile, NeedTypes, NeedSyntax, NeedTypesInfo, @@ -28,7 +28,7 @@ var modeStrings = []string{ "NeedCompiledGoFiles", "NeedImports", "NeedDeps", - "NeedExportsFile", + "NeedExportFile", "NeedTypes", "NeedSyntax", "NeedTypesInfo", diff --git a/go/vendor/golang.org/x/tools/go/packages/packages.go b/go/vendor/golang.org/x/tools/go/packages/packages.go index 8a1a2d68100..a93dc6add4d 100644 --- a/go/vendor/golang.org/x/tools/go/packages/packages.go +++ b/go/vendor/golang.org/x/tools/go/packages/packages.go @@ -26,6 +26,7 @@ import ( "golang.org/x/tools/go/gcexportdata" "golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/packagesinternal" + "golang.org/x/tools/internal/typeparams" "golang.org/x/tools/internal/typesinternal" ) @@ -38,9 +39,6 @@ import ( // Load may return more information than requested. type LoadMode int -// TODO(matloob): When a V2 of go/packages is released, rename NeedExportsFile to -// NeedExportFile to make it consistent with the Package field it's adding. - const ( // NeedName adds Name and PkgPath. NeedName LoadMode = 1 << iota @@ -58,8 +56,8 @@ const ( // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. NeedDeps - // NeedExportsFile adds ExportFile. - NeedExportsFile + // NeedExportFile adds ExportFile. + NeedExportFile // NeedTypes adds Types, Fset, and IllTyped. NeedTypes @@ -73,12 +71,25 @@ const ( // NeedTypesSizes adds TypesSizes. NeedTypesSizes + // needInternalDepsErrors adds the internal deps errors field for use by gopls. + needInternalDepsErrors + + // needInternalForTest adds the internal forTest field. + // Tests must also be set on the context for this field to be populated. + needInternalForTest + // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. // Modifies CompiledGoFiles and Types, and has no effect on its own. typecheckCgo // NeedModule adds Module. NeedModule + + // NeedEmbedFiles adds EmbedFiles. + NeedEmbedFiles + + // NeedEmbedPatterns adds EmbedPatterns. + NeedEmbedPatterns ) const ( @@ -101,6 +112,9 @@ const ( // Deprecated: LoadAllSyntax exists for historical compatibility // and should not be used. Please directly specify the needed fields using the Need values. LoadAllSyntax = LoadSyntax | NeedDeps + + // Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile. + NeedExportsFile = NeedExportFile ) // A Config specifies details about how packages should be loaded. @@ -295,6 +309,14 @@ type Package struct { // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. OtherFiles []string + // EmbedFiles lists the absolute file paths of the package's files + // embedded with go:embed. + EmbedFiles []string + + // EmbedPatterns lists the absolute file patterns of the package's + // files embedded with go:embed. + EmbedPatterns []string + // IgnoredFiles lists source files that are not part of the package // using the current build configuration but that might be part of // the package using other build configurations. @@ -327,6 +349,9 @@ type Package struct { // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. // If NeedDeps and NeedImports are also set, this field will also be populated // for dependencies. + // + // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are + // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles. Syntax []*ast.File // TypesInfo provides type information about the package's syntax trees. @@ -385,6 +410,8 @@ func init() { config.(*Config).modFlag = value } packagesinternal.TypecheckCgo = int(typecheckCgo) + packagesinternal.DepsErrors = int(needInternalDepsErrors) + packagesinternal.ForTest = int(needInternalForTest) } // An Error describes a problem with a package's metadata, syntax, or types. @@ -427,6 +454,8 @@ type flatPackage struct { GoFiles []string `json:",omitempty"` CompiledGoFiles []string `json:",omitempty"` OtherFiles []string `json:",omitempty"` + EmbedFiles []string `json:",omitempty"` + EmbedPatterns []string `json:",omitempty"` IgnoredFiles []string `json:",omitempty"` ExportFile string `json:",omitempty"` Imports map[string]string `json:",omitempty"` @@ -450,6 +479,8 @@ func (p *Package) MarshalJSON() ([]byte, error) { GoFiles: p.GoFiles, CompiledGoFiles: p.CompiledGoFiles, OtherFiles: p.OtherFiles, + EmbedFiles: p.EmbedFiles, + EmbedPatterns: p.EmbedPatterns, IgnoredFiles: p.IgnoredFiles, ExportFile: p.ExportFile, } @@ -477,6 +508,8 @@ func (p *Package) UnmarshalJSON(b []byte) error { GoFiles: flat.GoFiles, CompiledGoFiles: flat.CompiledGoFiles, OtherFiles: flat.OtherFiles, + EmbedFiles: flat.EmbedFiles, + EmbedPatterns: flat.EmbedPatterns, ExportFile: flat.ExportFile, } if len(flat.Imports) > 0 { @@ -610,7 +643,7 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) { needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || // ... or if we need types and the exportData is invalid. We fall back to (incompletely) // typechecking packages from source if they fail to compile. - (ld.Mode&NeedTypes|NeedTypesInfo != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" + (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" lpkg := &loaderPackage{ Package: pkg, needtypes: needtypes, @@ -748,13 +781,19 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) { ld.pkgs[i].OtherFiles = nil ld.pkgs[i].IgnoredFiles = nil } + if ld.requestedMode&NeedEmbedFiles == 0 { + ld.pkgs[i].EmbedFiles = nil + } + if ld.requestedMode&NeedEmbedPatterns == 0 { + ld.pkgs[i].EmbedPatterns = nil + } if ld.requestedMode&NeedCompiledGoFiles == 0 { ld.pkgs[i].CompiledGoFiles = nil } if ld.requestedMode&NeedImports == 0 { ld.pkgs[i].Imports = nil } - if ld.requestedMode&NeedExportsFile == 0 { + if ld.requestedMode&NeedExportFile == 0 { ld.pkgs[i].ExportFile = "" } if ld.requestedMode&NeedTypes == 0 { @@ -910,6 +949,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { Scopes: make(map[ast.Node]*types.Scope), Selections: make(map[*ast.SelectorExpr]*types.Selection), } + typeparams.InitInstanceInfo(lpkg.TypesInfo) lpkg.TypesSizes = ld.sizes importer := importerFunc(func(path string) (*types.Package, error) { @@ -1048,7 +1088,6 @@ func (ld *loader) parseFile(filename string) (*ast.File, error) { // // Because files are scanned in parallel, the token.Pos // positions of the resulting ast.Files are not ordered. -// func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { var wg sync.WaitGroup n := len(filenames) @@ -1092,7 +1131,6 @@ func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { // sameFile returns true if x and y have the same basename and denote // the same file. -// func sameFile(x, y string) bool { if x == y { // It could be the case that y doesn't exist. @@ -1205,8 +1243,13 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error if err != nil { return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) } + if _, ok := view["go.shape"]; ok { + // Account for the pseudopackage "go.shape" that gets + // created by generic code. + viewLen++ + } if viewLen != len(view) { - log.Fatalf("Unexpected package creation during export data loading") + log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath) } lpkg.Types = tpkg @@ -1217,17 +1260,8 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error // impliedLoadMode returns loadMode with its dependencies. func impliedLoadMode(loadMode LoadMode) LoadMode { - if loadMode&NeedTypesInfo != 0 && loadMode&NeedImports == 0 { - // If NeedTypesInfo, go/packages needs to do typechecking itself so it can - // associate type info with the AST. To do so, we need the export data - // for dependencies, which means we need to ask for the direct dependencies. - // NeedImports is used to ask for the direct dependencies. - loadMode |= NeedImports - } - - if loadMode&NeedDeps != 0 && loadMode&NeedImports == 0 { - // With NeedDeps we need to load at least direct dependencies. - // NeedImports is used to ask for the direct dependencies. + if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 { + // All these things require knowing the import graph. loadMode |= NeedImports } @@ -1235,5 +1269,5 @@ func impliedLoadMode(loadMode LoadMode) LoadMode { } func usesExportData(cfg *Config) bool { - return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 + return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 } diff --git a/go/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/go/vendor/golang.org/x/tools/internal/gocommand/invoke.go index 8659a0c5da6..67256dc3974 100644 --- a/go/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ b/go/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -9,7 +9,6 @@ import ( "bytes" "context" "fmt" - exec "golang.org/x/sys/execabs" "io" "os" "regexp" @@ -18,6 +17,8 @@ import ( "sync" "time" + exec "golang.org/x/sys/execabs" + "golang.org/x/tools/internal/event" ) @@ -131,9 +132,16 @@ type Invocation struct { Verb string Args []string BuildFlags []string - ModFlag string - ModFile string - Overlay string + + // If ModFlag is set, the go command is invoked with -mod=ModFlag. + ModFlag string + + // If ModFile is set, the go command is invoked with -modfile=ModFile. + ModFile string + + // If Overlay is set, the go command is invoked with -overlay=Overlay. + Overlay string + // If CleanEnv is set, the invocation will run only with the environment // in Env, not starting with os.Environ. CleanEnv bool @@ -256,8 +264,10 @@ func cmdDebugStr(cmd *exec.Cmd) string { env := make(map[string]string) for _, kv := range cmd.Env { split := strings.SplitN(kv, "=", 2) - k, v := split[0], split[1] - env[k] = v + if len(split) == 2 { + k, v := split[0], split[1] + env[k] = v + } } var args []string diff --git a/go/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/go/vendor/golang.org/x/tools/internal/gocommand/vendor.go index 5e75bd6d8fa..2d3d408c0be 100644 --- a/go/vendor/golang.org/x/tools/internal/gocommand/vendor.go +++ b/go/vendor/golang.org/x/tools/internal/gocommand/vendor.go @@ -38,10 +38,10 @@ var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) // with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, // of which only Verb and Args are modified to run the appropriate Go command. // Inspired by setDefaultBuildMod in modload/init.go -func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { +func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) { mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) if err != nil { - return nil, false, err + return false, nil, err } // We check the GOFLAGS to see if there is anything overridden or not. @@ -49,7 +49,7 @@ func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, inv.Args = []string{"GOFLAGS"} stdout, err := r.Run(ctx, inv) if err != nil { - return nil, false, err + return false, nil, err } goflags := string(bytes.TrimSpace(stdout.Bytes())) matches := modFlagRegexp.FindStringSubmatch(goflags) @@ -57,25 +57,27 @@ func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, if len(matches) != 0 { modFlag = matches[1] } - if modFlag != "" { - // Don't override an explicit '-mod=' argument. - return mainMod, modFlag == "vendor", nil + // Don't override an explicit '-mod=' argument. + if modFlag == "vendor" { + return true, mainMod, nil + } else if modFlag != "" { + return false, nil, nil } if mainMod == nil || !go114 { - return mainMod, false, nil + return false, nil, nil } // Check 1.14's automatic vendor mode. if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { // The Go version is at least 1.14, and a vendor directory exists. // Set -mod=vendor by default. - return mainMod, true, nil + return true, mainMod, nil } } - return mainMod, false, nil + return false, nil, nil } -// getMainModuleAnd114 gets the main module's information and whether the +// getMainModuleAnd114 gets one of the main modules' information and whether the // go command in use is 1.14+. This is the information needed to figure out // if vendoring should be enabled. func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { diff --git a/go/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/go/vendor/golang.org/x/tools/internal/packagesinternal/packages.go index 9702094c59e..d9950b1f0be 100644 --- a/go/vendor/golang.org/x/tools/internal/packagesinternal/packages.go +++ b/go/vendor/golang.org/x/tools/internal/packagesinternal/packages.go @@ -23,6 +23,8 @@ var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil } var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {} var TypecheckCgo int +var DepsErrors int // must be set as a LoadMode to call GetDepsErrors +var ForTest int // must be set as a LoadMode to call GetForTest var SetModFlag = func(config interface{}, value string) {} var SetModFile = func(config interface{}, value string) {} diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/common.go b/go/vendor/golang.org/x/tools/internal/typeparams/common.go new file mode 100644 index 00000000000..25a1426d30e --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/common.go @@ -0,0 +1,179 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package typeparams contains common utilities for writing tools that interact +// with generic Go code, as introduced with Go 1.18. +// +// Many of the types and functions in this package are proxies for the new APIs +// introduced in the standard library with Go 1.18. For example, the +// typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec +// function returns the value of the go/ast.TypeSpec.TypeParams field. At Go +// versions older than 1.18 these helpers are implemented as stubs, allowing +// users of this package to write code that handles generic constructs inline, +// even if the Go version being used to compile does not support generics. +// +// Additionally, this package contains common utilities for working with the +// new generic constructs, to supplement the standard library APIs. Notably, +// the StructuralTerms API computes a minimal representation of the structural +// restrictions on a type parameter. +// +// An external version of these APIs is available in the +// golang.org/x/exp/typeparams module. +package typeparams + +import ( + "go/ast" + "go/token" + "go/types" +) + +// UnpackIndexExpr extracts data from AST nodes that represent index +// expressions. +// +// For an ast.IndexExpr, the resulting indices slice will contain exactly one +// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable +// number of index expressions. +// +// For nodes that don't represent index expressions, the first return value of +// UnpackIndexExpr will be nil. +func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) { + switch e := n.(type) { + case *ast.IndexExpr: + return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack + case *IndexListExpr: + return e.X, e.Lbrack, e.Indices, e.Rbrack + } + return nil, token.NoPos, nil, token.NoPos +} + +// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on +// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 +// will panic. +func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { + switch len(indices) { + case 0: + panic("empty indices") + case 1: + return &ast.IndexExpr{ + X: x, + Lbrack: lbrack, + Index: indices[0], + Rbrack: rbrack, + } + default: + return &IndexListExpr{ + X: x, + Lbrack: lbrack, + Indices: indices, + Rbrack: rbrack, + } + } +} + +// IsTypeParam reports whether t is a type parameter. +func IsTypeParam(t types.Type) bool { + _, ok := t.(*TypeParam) + return ok +} + +// OriginMethod returns the origin method associated with the method fn. +// For methods on a non-generic receiver base type, this is just +// fn. However, for methods with a generic receiver, OriginMethod returns the +// corresponding method in the method set of the origin type. +// +// As a special case, if fn is not a method (has no receiver), OriginMethod +// returns fn. +func OriginMethod(fn *types.Func) *types.Func { + recv := fn.Type().(*types.Signature).Recv() + if recv == nil { + + return fn + } + base := recv.Type() + p, isPtr := base.(*types.Pointer) + if isPtr { + base = p.Elem() + } + named, isNamed := base.(*types.Named) + if !isNamed { + // Receiver is a *types.Interface. + return fn + } + if ForNamed(named).Len() == 0 { + // Receiver base has no type parameters, so we can avoid the lookup below. + return fn + } + orig := NamedTypeOrigin(named) + gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name()) + return gfn.(*types.Func) +} + +// GenericAssignableTo is a generalization of types.AssignableTo that +// implements the following rule for uninstantiated generic types: +// +// If V and T are generic named types, then V is considered assignable to T if, +// for every possible instantation of V[A_1, ..., A_N], the instantiation +// T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N]. +// +// If T has structural constraints, they must be satisfied by V. +// +// For example, consider the following type declarations: +// +// type Interface[T any] interface { +// Accept(T) +// } +// +// type Container[T any] struct { +// Element T +// } +// +// func (c Container[T]) Accept(t T) { c.Element = t } +// +// In this case, GenericAssignableTo reports that instantiations of Container +// are assignable to the corresponding instantiation of Interface. +func GenericAssignableTo(ctxt *Context, V, T types.Type) bool { + // If V and T are not both named, or do not have matching non-empty type + // parameter lists, fall back on types.AssignableTo. + + VN, Vnamed := V.(*types.Named) + TN, Tnamed := T.(*types.Named) + if !Vnamed || !Tnamed { + return types.AssignableTo(V, T) + } + + vtparams := ForNamed(VN) + ttparams := ForNamed(TN) + if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 { + return types.AssignableTo(V, T) + } + + // V and T have the same (non-zero) number of type params. Instantiate both + // with the type parameters of V. This must always succeed for V, and will + // succeed for T if and only if the type set of each type parameter of V is a + // subset of the type set of the corresponding type parameter of T, meaning + // that every instantiation of V corresponds to a valid instantiation of T. + + // Minor optimization: ensure we share a context across the two + // instantiations below. + if ctxt == nil { + ctxt = NewContext() + } + + var targs []types.Type + for i := 0; i < vtparams.Len(); i++ { + targs = append(targs, vtparams.At(i)) + } + + vinst, err := Instantiate(ctxt, V, targs, true) + if err != nil { + panic("type parameters should satisfy their own constraints") + } + + tinst, err := Instantiate(ctxt, T, targs, true) + if err != nil { + return false + } + + return types.AssignableTo(vinst, tinst) +} diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/go/vendor/golang.org/x/tools/internal/typeparams/coretype.go new file mode 100644 index 00000000000..993135ec90e --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/coretype.go @@ -0,0 +1,122 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typeparams + +import ( + "go/types" +) + +// CoreType returns the core type of T or nil if T does not have a core type. +// +// See https://go.dev/ref/spec#Core_types for the definition of a core type. +func CoreType(T types.Type) types.Type { + U := T.Underlying() + if _, ok := U.(*types.Interface); !ok { + return U // for non-interface types, + } + + terms, err := _NormalTerms(U) + if len(terms) == 0 || err != nil { + // len(terms) -> empty type set of interface. + // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set. + return nil // no core type. + } + + U = terms[0].Type().Underlying() + var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying()) + for identical = 1; identical < len(terms); identical++ { + if !types.Identical(U, terms[identical].Type().Underlying()) { + break + } + } + + if identical == len(terms) { + // https://go.dev/ref/spec#Core_types + // "There is a single type U which is the underlying type of all types in the type set of T" + return U + } + ch, ok := U.(*types.Chan) + if !ok { + return nil // no core type as identical < len(terms) and U is not a channel. + } + // https://go.dev/ref/spec#Core_types + // "the type chan E if T contains only bidirectional channels, or the type chan<- E or + // <-chan E depending on the direction of the directional channels present." + for chans := identical; chans < len(terms); chans++ { + curr, ok := terms[chans].Type().Underlying().(*types.Chan) + if !ok { + return nil + } + if !types.Identical(ch.Elem(), curr.Elem()) { + return nil // channel elements are not identical. + } + if ch.Dir() == types.SendRecv { + // ch is bidirectional. We can safely always use curr's direction. + ch = curr + } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() { + // ch and curr are not bidirectional and not the same direction. + return nil + } + } + return ch +} + +// _NormalTerms returns a slice of terms representing the normalized structural +// type restrictions of a type, if any. +// +// For all types other than *types.TypeParam, *types.Interface, and +// *types.Union, this is just a single term with Tilde() == false and +// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see +// below. +// +// Structural type restrictions of a type parameter are created via +// non-interface types embedded in its constraint interface (directly, or via a +// chain of interface embeddings). For example, in the declaration type +// T[P interface{~int; m()}] int the structural restriction of the type +// parameter P is ~int. +// +// With interface embedding and unions, the specification of structural type +// restrictions may be arbitrarily complex. For example, consider the +// following: +// +// type A interface{ ~string|~[]byte } +// +// type B interface{ int|string } +// +// type C interface { ~string|~int } +// +// type T[P interface{ A|B; C }] int +// +// In this example, the structural type restriction of P is ~string|int: A|B +// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, +// which when intersected with C (~string|~int) yields ~string|int. +// +// _NormalTerms computes these expansions and reductions, producing a +// "normalized" form of the embeddings. A structural restriction is normalized +// if it is a single union containing no interface terms, and is minimal in the +// sense that removing any term changes the set of types satisfying the +// constraint. It is left as a proof for the reader that, modulo sorting, there +// is exactly one such normalized form. +// +// Because the minimal representation always takes this form, _NormalTerms +// returns a slice of tilde terms corresponding to the terms of the union in +// the normalized structural restriction. An error is returned if the type is +// invalid, exceeds complexity bounds, or has an empty type set. In the latter +// case, _NormalTerms returns ErrEmptyTypeSet. +// +// _NormalTerms makes no guarantees about the order of terms, except that it +// is deterministic. +func _NormalTerms(typ types.Type) ([]*Term, error) { + switch typ := typ.(type) { + case *TypeParam: + return StructuralTerms(typ) + case *Union: + return UnionTermSet(typ) + case *types.Interface: + return InterfaceTermSet(typ) + default: + return []*Term{NewTerm(false, typ)}, nil + } +} diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go b/go/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go new file mode 100644 index 00000000000..18212390e19 --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go @@ -0,0 +1,12 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.18 +// +build !go1.18 + +package typeparams + +// Enabled reports whether type parameters are enabled in the current build +// environment. +const Enabled = false diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go b/go/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go new file mode 100644 index 00000000000..d67148823c4 --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.18 +// +build go1.18 + +package typeparams + +// Note: this constant is in a separate file as this is the only acceptable +// diff between the <1.18 API of this package and the 1.18 API. + +// Enabled reports whether type parameters are enabled in the current build +// environment. +const Enabled = true diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/go/vendor/golang.org/x/tools/internal/typeparams/normalize.go new file mode 100644 index 00000000000..9c631b6512d --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/normalize.go @@ -0,0 +1,218 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package typeparams + +import ( + "errors" + "fmt" + "go/types" + "os" + "strings" +) + +//go:generate go run copytermlist.go + +const debug = false + +var ErrEmptyTypeSet = errors.New("empty type set") + +// StructuralTerms returns a slice of terms representing the normalized +// structural type restrictions of a type parameter, if any. +// +// Structural type restrictions of a type parameter are created via +// non-interface types embedded in its constraint interface (directly, or via a +// chain of interface embeddings). For example, in the declaration +// +// type T[P interface{~int; m()}] int +// +// the structural restriction of the type parameter P is ~int. +// +// With interface embedding and unions, the specification of structural type +// restrictions may be arbitrarily complex. For example, consider the +// following: +// +// type A interface{ ~string|~[]byte } +// +// type B interface{ int|string } +// +// type C interface { ~string|~int } +// +// type T[P interface{ A|B; C }] int +// +// In this example, the structural type restriction of P is ~string|int: A|B +// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, +// which when intersected with C (~string|~int) yields ~string|int. +// +// StructuralTerms computes these expansions and reductions, producing a +// "normalized" form of the embeddings. A structural restriction is normalized +// if it is a single union containing no interface terms, and is minimal in the +// sense that removing any term changes the set of types satisfying the +// constraint. It is left as a proof for the reader that, modulo sorting, there +// is exactly one such normalized form. +// +// Because the minimal representation always takes this form, StructuralTerms +// returns a slice of tilde terms corresponding to the terms of the union in +// the normalized structural restriction. An error is returned if the +// constraint interface is invalid, exceeds complexity bounds, or has an empty +// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. +// +// StructuralTerms makes no guarantees about the order of terms, except that it +// is deterministic. +func StructuralTerms(tparam *TypeParam) ([]*Term, error) { + constraint := tparam.Constraint() + if constraint == nil { + return nil, fmt.Errorf("%s has nil constraint", tparam) + } + iface, _ := constraint.Underlying().(*types.Interface) + if iface == nil { + return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) + } + return InterfaceTermSet(iface) +} + +// InterfaceTermSet computes the normalized terms for a constraint interface, +// returning an error if the term set cannot be computed or is empty. In the +// latter case, the error will be ErrEmptyTypeSet. +// +// See the documentation of StructuralTerms for more information on +// normalization. +func InterfaceTermSet(iface *types.Interface) ([]*Term, error) { + return computeTermSet(iface) +} + +// UnionTermSet computes the normalized terms for a union, returning an error +// if the term set cannot be computed or is empty. In the latter case, the +// error will be ErrEmptyTypeSet. +// +// See the documentation of StructuralTerms for more information on +// normalization. +func UnionTermSet(union *Union) ([]*Term, error) { + return computeTermSet(union) +} + +func computeTermSet(typ types.Type) ([]*Term, error) { + tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) + if err != nil { + return nil, err + } + if tset.terms.isEmpty() { + return nil, ErrEmptyTypeSet + } + if tset.terms.isAll() { + return nil, nil + } + var terms []*Term + for _, term := range tset.terms { + terms = append(terms, NewTerm(term.tilde, term.typ)) + } + return terms, nil +} + +// A termSet holds the normalized set of terms for a given type. +// +// The name termSet is intentionally distinct from 'type set': a type set is +// all types that implement a type (and includes method restrictions), whereas +// a term set just represents the structural restrictions on a type. +type termSet struct { + complete bool + terms termlist +} + +func indentf(depth int, format string, args ...interface{}) { + fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) +} + +func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { + if t == nil { + panic("nil type") + } + + if debug { + indentf(depth, "%s", t.String()) + defer func() { + if err != nil { + indentf(depth, "=> %s", err) + } else { + indentf(depth, "=> %s", res.terms.String()) + } + }() + } + + const maxTermCount = 100 + if tset, ok := seen[t]; ok { + if !tset.complete { + return nil, fmt.Errorf("cycle detected in the declaration of %s", t) + } + return tset, nil + } + + // Mark the current type as seen to avoid infinite recursion. + tset := new(termSet) + defer func() { + tset.complete = true + }() + seen[t] = tset + + switch u := t.Underlying().(type) { + case *types.Interface: + // The term set of an interface is the intersection of the term sets of its + // embedded types. + tset.terms = allTermlist + for i := 0; i < u.NumEmbeddeds(); i++ { + embedded := u.EmbeddedType(i) + if _, ok := embedded.Underlying().(*TypeParam); ok { + return nil, fmt.Errorf("invalid embedded type %T", embedded) + } + tset2, err := computeTermSetInternal(embedded, seen, depth+1) + if err != nil { + return nil, err + } + tset.terms = tset.terms.intersect(tset2.terms) + } + case *Union: + // The term set of a union is the union of term sets of its terms. + tset.terms = nil + for i := 0; i < u.Len(); i++ { + t := u.Term(i) + var terms termlist + switch t.Type().Underlying().(type) { + case *types.Interface: + tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) + if err != nil { + return nil, err + } + terms = tset2.terms + case *TypeParam, *Union: + // A stand-alone type parameter or union is not permitted as union + // term. + return nil, fmt.Errorf("invalid union term %T", t) + default: + if t.Type() == types.Typ[types.Invalid] { + continue + } + terms = termlist{{t.Tilde(), t.Type()}} + } + tset.terms = tset.terms.union(terms) + if len(tset.terms) > maxTermCount { + return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) + } + } + case *TypeParam: + panic("unreachable") + default: + // For all other types, the term set is just a single non-tilde term + // holding the type itself. + if u != types.Typ[types.Invalid] { + tset.terms = termlist{{false, t}} + } + } + return tset, nil +} + +// under is a facade for the go/types internal function of the same name. It is +// used by typeterm.go. +func under(t types.Type) types.Type { + return t.Underlying() +} diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/go/vendor/golang.org/x/tools/internal/typeparams/termlist.go new file mode 100644 index 00000000000..933106a23dd --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/termlist.go @@ -0,0 +1,163 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by copytermlist.go DO NOT EDIT. + +package typeparams + +import ( + "bytes" + "go/types" +) + +// A termlist represents the type set represented by the union +// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. +// A termlist is in normal form if all terms are disjoint. +// termlist operations don't require the operands to be in +// normal form. +type termlist []*term + +// allTermlist represents the set of all types. +// It is in normal form. +var allTermlist = termlist{new(term)} + +// String prints the termlist exactly (without normalization). +func (xl termlist) String() string { + if len(xl) == 0 { + return "∅" + } + var buf bytes.Buffer + for i, x := range xl { + if i > 0 { + buf.WriteString(" ∪ ") + } + buf.WriteString(x.String()) + } + return buf.String() +} + +// isEmpty reports whether the termlist xl represents the empty set of types. +func (xl termlist) isEmpty() bool { + // If there's a non-nil term, the entire list is not empty. + // If the termlist is in normal form, this requires at most + // one iteration. + for _, x := range xl { + if x != nil { + return false + } + } + return true +} + +// isAll reports whether the termlist xl represents the set of all types. +func (xl termlist) isAll() bool { + // If there's a 𝓤 term, the entire list is 𝓤. + // If the termlist is in normal form, this requires at most + // one iteration. + for _, x := range xl { + if x != nil && x.typ == nil { + return true + } + } + return false +} + +// norm returns the normal form of xl. +func (xl termlist) norm() termlist { + // Quadratic algorithm, but good enough for now. + // TODO(gri) fix asymptotic performance + used := make([]bool, len(xl)) + var rl termlist + for i, xi := range xl { + if xi == nil || used[i] { + continue + } + for j := i + 1; j < len(xl); j++ { + xj := xl[j] + if xj == nil || used[j] { + continue + } + if u1, u2 := xi.union(xj); u2 == nil { + // If we encounter a 𝓤 term, the entire list is 𝓤. + // Exit early. + // (Note that this is not just an optimization; + // if we continue, we may end up with a 𝓤 term + // and other terms and the result would not be + // in normal form.) + if u1.typ == nil { + return allTermlist + } + xi = u1 + used[j] = true // xj is now unioned into xi - ignore it in future iterations + } + } + rl = append(rl, xi) + } + return rl +} + +// union returns the union xl ∪ yl. +func (xl termlist) union(yl termlist) termlist { + return append(xl, yl...).norm() +} + +// intersect returns the intersection xl ∩ yl. +func (xl termlist) intersect(yl termlist) termlist { + if xl.isEmpty() || yl.isEmpty() { + return nil + } + + // Quadratic algorithm, but good enough for now. + // TODO(gri) fix asymptotic performance + var rl termlist + for _, x := range xl { + for _, y := range yl { + if r := x.intersect(y); r != nil { + rl = append(rl, r) + } + } + } + return rl.norm() +} + +// equal reports whether xl and yl represent the same type set. +func (xl termlist) equal(yl termlist) bool { + // TODO(gri) this should be more efficient + return xl.subsetOf(yl) && yl.subsetOf(xl) +} + +// includes reports whether t ∈ xl. +func (xl termlist) includes(t types.Type) bool { + for _, x := range xl { + if x.includes(t) { + return true + } + } + return false +} + +// supersetOf reports whether y ⊆ xl. +func (xl termlist) supersetOf(y *term) bool { + for _, x := range xl { + if y.subsetOf(x) { + return true + } + } + return false +} + +// subsetOf reports whether xl ⊆ yl. +func (xl termlist) subsetOf(yl termlist) bool { + if yl.isEmpty() { + return xl.isEmpty() + } + + // each term x of xl must be a subset of yl + for _, x := range xl { + if !yl.supersetOf(x) { + return false // x is not a subset yl + } + } + return true +} diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go b/go/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go new file mode 100644 index 00000000000..b4788978ff4 --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go @@ -0,0 +1,197 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.18 +// +build !go1.18 + +package typeparams + +import ( + "go/ast" + "go/token" + "go/types" +) + +func unsupported() { + panic("type parameters are unsupported at this go version") +} + +// IndexListExpr is a placeholder type, as type parameters are not supported at +// this Go version. Its methods panic on use. +type IndexListExpr struct { + ast.Expr + X ast.Expr // expression + Lbrack token.Pos // position of "[" + Indices []ast.Expr // index expressions + Rbrack token.Pos // position of "]" +} + +// ForTypeSpec returns an empty field list, as type parameters on not supported +// at this Go version. +func ForTypeSpec(*ast.TypeSpec) *ast.FieldList { + return nil +} + +// ForFuncType returns an empty field list, as type parameters are not +// supported at this Go version. +func ForFuncType(*ast.FuncType) *ast.FieldList { + return nil +} + +// TypeParam is a placeholder type, as type parameters are not supported at +// this Go version. Its methods panic on use. +type TypeParam struct{ types.Type } + +func (*TypeParam) Index() int { unsupported(); return 0 } +func (*TypeParam) Constraint() types.Type { unsupported(); return nil } +func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil } + +// TypeParamList is a placeholder for an empty type parameter list. +type TypeParamList struct{} + +func (*TypeParamList) Len() int { return 0 } +func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil } + +// TypeList is a placeholder for an empty type list. +type TypeList struct{} + +func (*TypeList) Len() int { return 0 } +func (*TypeList) At(int) types.Type { unsupported(); return nil } + +// NewTypeParam is unsupported at this Go version, and panics. +func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam { + unsupported() + return nil +} + +// SetTypeParamConstraint is unsupported at this Go version, and panics. +func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) { + unsupported() +} + +// NewSignatureType calls types.NewSignature, panicking if recvTypeParams or +// typeParams is non-empty. +func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature { + if len(recvTypeParams) != 0 || len(typeParams) != 0 { + panic("signatures cannot have type parameters at this Go version") + } + return types.NewSignature(recv, params, results, variadic) +} + +// ForSignature returns an empty slice. +func ForSignature(*types.Signature) *TypeParamList { + return nil +} + +// RecvTypeParams returns a nil slice. +func RecvTypeParams(sig *types.Signature) *TypeParamList { + return nil +} + +// IsComparable returns false, as no interfaces are type-restricted at this Go +// version. +func IsComparable(*types.Interface) bool { + return false +} + +// IsMethodSet returns true, as no interfaces are type-restricted at this Go +// version. +func IsMethodSet(*types.Interface) bool { + return true +} + +// IsImplicit returns false, as no interfaces are implicit at this Go version. +func IsImplicit(*types.Interface) bool { + return false +} + +// MarkImplicit does nothing, because this Go version does not have implicit +// interfaces. +func MarkImplicit(*types.Interface) {} + +// ForNamed returns an empty type parameter list, as type parameters are not +// supported at this Go version. +func ForNamed(*types.Named) *TypeParamList { + return nil +} + +// SetForNamed panics if tparams is non-empty. +func SetForNamed(_ *types.Named, tparams []*TypeParam) { + if len(tparams) > 0 { + unsupported() + } +} + +// NamedTypeArgs returns nil. +func NamedTypeArgs(*types.Named) *TypeList { + return nil +} + +// NamedTypeOrigin is the identity method at this Go version. +func NamedTypeOrigin(named *types.Named) types.Type { + return named +} + +// Term holds information about a structural type restriction. +type Term struct { + tilde bool + typ types.Type +} + +func (m *Term) Tilde() bool { return m.tilde } +func (m *Term) Type() types.Type { return m.typ } +func (m *Term) String() string { + pre := "" + if m.tilde { + pre = "~" + } + return pre + m.typ.String() +} + +// NewTerm is unsupported at this Go version, and panics. +func NewTerm(tilde bool, typ types.Type) *Term { + return &Term{tilde, typ} +} + +// Union is a placeholder type, as type parameters are not supported at this Go +// version. Its methods panic on use. +type Union struct{ types.Type } + +func (*Union) Len() int { return 0 } +func (*Union) Term(i int) *Term { unsupported(); return nil } + +// NewUnion is unsupported at this Go version, and panics. +func NewUnion(terms []*Term) *Union { + unsupported() + return nil +} + +// InitInstanceInfo is a noop at this Go version. +func InitInstanceInfo(*types.Info) {} + +// Instance is a placeholder type, as type parameters are not supported at this +// Go version. +type Instance struct { + TypeArgs *TypeList + Type types.Type +} + +// GetInstances returns a nil map, as type parameters are not supported at this +// Go version. +func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil } + +// Context is a placeholder type, as type parameters are not supported at +// this Go version. +type Context struct{} + +// NewContext returns a placeholder Context instance. +func NewContext() *Context { + return &Context{} +} + +// Instantiate is unsupported on this Go version, and panics. +func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { + unsupported() + return nil, nil +} diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go b/go/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go new file mode 100644 index 00000000000..114a36b866b --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go @@ -0,0 +1,151 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.18 +// +build go1.18 + +package typeparams + +import ( + "go/ast" + "go/types" +) + +// IndexListExpr is an alias for ast.IndexListExpr. +type IndexListExpr = ast.IndexListExpr + +// ForTypeSpec returns n.TypeParams. +func ForTypeSpec(n *ast.TypeSpec) *ast.FieldList { + if n == nil { + return nil + } + return n.TypeParams +} + +// ForFuncType returns n.TypeParams. +func ForFuncType(n *ast.FuncType) *ast.FieldList { + if n == nil { + return nil + } + return n.TypeParams +} + +// TypeParam is an alias for types.TypeParam +type TypeParam = types.TypeParam + +// TypeParamList is an alias for types.TypeParamList +type TypeParamList = types.TypeParamList + +// TypeList is an alias for types.TypeList +type TypeList = types.TypeList + +// NewTypeParam calls types.NewTypeParam. +func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam { + return types.NewTypeParam(name, constraint) +} + +// SetTypeParamConstraint calls tparam.SetConstraint(constraint). +func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) { + tparam.SetConstraint(constraint) +} + +// NewSignatureType calls types.NewSignatureType. +func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature { + return types.NewSignatureType(recv, recvTypeParams, typeParams, params, results, variadic) +} + +// ForSignature returns sig.TypeParams() +func ForSignature(sig *types.Signature) *TypeParamList { + return sig.TypeParams() +} + +// RecvTypeParams returns sig.RecvTypeParams(). +func RecvTypeParams(sig *types.Signature) *TypeParamList { + return sig.RecvTypeParams() +} + +// IsComparable calls iface.IsComparable(). +func IsComparable(iface *types.Interface) bool { + return iface.IsComparable() +} + +// IsMethodSet calls iface.IsMethodSet(). +func IsMethodSet(iface *types.Interface) bool { + return iface.IsMethodSet() +} + +// IsImplicit calls iface.IsImplicit(). +func IsImplicit(iface *types.Interface) bool { + return iface.IsImplicit() +} + +// MarkImplicit calls iface.MarkImplicit(). +func MarkImplicit(iface *types.Interface) { + iface.MarkImplicit() +} + +// ForNamed extracts the (possibly empty) type parameter object list from +// named. +func ForNamed(named *types.Named) *TypeParamList { + return named.TypeParams() +} + +// SetForNamed sets the type params tparams on n. Each tparam must be of +// dynamic type *types.TypeParam. +func SetForNamed(n *types.Named, tparams []*TypeParam) { + n.SetTypeParams(tparams) +} + +// NamedTypeArgs returns named.TypeArgs(). +func NamedTypeArgs(named *types.Named) *TypeList { + return named.TypeArgs() +} + +// NamedTypeOrigin returns named.Orig(). +func NamedTypeOrigin(named *types.Named) types.Type { + return named.Origin() +} + +// Term is an alias for types.Term. +type Term = types.Term + +// NewTerm calls types.NewTerm. +func NewTerm(tilde bool, typ types.Type) *Term { + return types.NewTerm(tilde, typ) +} + +// Union is an alias for types.Union +type Union = types.Union + +// NewUnion calls types.NewUnion. +func NewUnion(terms []*Term) *Union { + return types.NewUnion(terms) +} + +// InitInstanceInfo initializes info to record information about type and +// function instances. +func InitInstanceInfo(info *types.Info) { + info.Instances = make(map[*ast.Ident]types.Instance) +} + +// Instance is an alias for types.Instance. +type Instance = types.Instance + +// GetInstances returns info.Instances. +func GetInstances(info *types.Info) map[*ast.Ident]Instance { + return info.Instances +} + +// Context is an alias for types.Context. +type Context = types.Context + +// NewContext calls types.NewContext. +func NewContext() *Context { + return types.NewContext() +} + +// Instantiate calls types.Instantiate. +func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { + return types.Instantiate(ctxt, typ, targs, validate) +} diff --git a/go/vendor/golang.org/x/tools/internal/typeparams/typeterm.go b/go/vendor/golang.org/x/tools/internal/typeparams/typeterm.go new file mode 100644 index 00000000000..7ddee28d987 --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typeparams/typeterm.go @@ -0,0 +1,170 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by copytermlist.go DO NOT EDIT. + +package typeparams + +import "go/types" + +// A term describes elementary type sets: +// +// ∅: (*term)(nil) == ∅ // set of no types (empty set) +// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) +// T: &term{false, T} == {T} // set of type T +// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t +// +type term struct { + tilde bool // valid if typ != nil + typ types.Type +} + +func (x *term) String() string { + switch { + case x == nil: + return "∅" + case x.typ == nil: + return "𝓤" + case x.tilde: + return "~" + x.typ.String() + default: + return x.typ.String() + } +} + +// equal reports whether x and y represent the same type set. +func (x *term) equal(y *term) bool { + // easy cases + switch { + case x == nil || y == nil: + return x == y + case x.typ == nil || y.typ == nil: + return x.typ == y.typ + } + // ∅ ⊂ x, y ⊂ 𝓤 + + return x.tilde == y.tilde && types.Identical(x.typ, y.typ) +} + +// union returns the union x ∪ y: zero, one, or two non-nil terms. +func (x *term) union(y *term) (_, _ *term) { + // easy cases + switch { + case x == nil && y == nil: + return nil, nil // ∅ ∪ ∅ == ∅ + case x == nil: + return y, nil // ∅ ∪ y == y + case y == nil: + return x, nil // x ∪ ∅ == x + case x.typ == nil: + return x, nil // 𝓤 ∪ y == 𝓤 + case y.typ == nil: + return y, nil // x ∪ 𝓤 == 𝓤 + } + // ∅ ⊂ x, y ⊂ 𝓤 + + if x.disjoint(y) { + return x, y // x ∪ y == (x, y) if x ∩ y == ∅ + } + // x.typ == y.typ + + // ~t ∪ ~t == ~t + // ~t ∪ T == ~t + // T ∪ ~t == ~t + // T ∪ T == T + if x.tilde || !y.tilde { + return x, nil + } + return y, nil +} + +// intersect returns the intersection x ∩ y. +func (x *term) intersect(y *term) *term { + // easy cases + switch { + case x == nil || y == nil: + return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ + case x.typ == nil: + return y // 𝓤 ∩ y == y + case y.typ == nil: + return x // x ∩ 𝓤 == x + } + // ∅ ⊂ x, y ⊂ 𝓤 + + if x.disjoint(y) { + return nil // x ∩ y == ∅ if x ∩ y == ∅ + } + // x.typ == y.typ + + // ~t ∩ ~t == ~t + // ~t ∩ T == T + // T ∩ ~t == T + // T ∩ T == T + if !x.tilde || y.tilde { + return x + } + return y +} + +// includes reports whether t ∈ x. +func (x *term) includes(t types.Type) bool { + // easy cases + switch { + case x == nil: + return false // t ∈ ∅ == false + case x.typ == nil: + return true // t ∈ 𝓤 == true + } + // ∅ ⊂ x ⊂ 𝓤 + + u := t + if x.tilde { + u = under(u) + } + return types.Identical(x.typ, u) +} + +// subsetOf reports whether x ⊆ y. +func (x *term) subsetOf(y *term) bool { + // easy cases + switch { + case x == nil: + return true // ∅ ⊆ y == true + case y == nil: + return false // x ⊆ ∅ == false since x != ∅ + case y.typ == nil: + return true // x ⊆ 𝓤 == true + case x.typ == nil: + return false // 𝓤 ⊆ y == false since y != 𝓤 + } + // ∅ ⊂ x, y ⊂ 𝓤 + + if x.disjoint(y) { + return false // x ⊆ y == false if x ∩ y == ∅ + } + // x.typ == y.typ + + // ~t ⊆ ~t == true + // ~t ⊆ T == false + // T ⊆ ~t == true + // T ⊆ T == true + return !x.tilde || y.tilde +} + +// disjoint reports whether x ∩ y == ∅. +// x.typ and y.typ must not be nil. +func (x *term) disjoint(y *term) bool { + if debug && (x.typ == nil || y.typ == nil) { + panic("invalid argument(s)") + } + ux := x.typ + if y.tilde { + ux = under(ux) + } + uy := y.typ + if x.tilde { + uy = under(uy) + } + return !types.Identical(ux, uy) +} diff --git a/go/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/go/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go index fa2834e2ab8..d38ee3c27cd 100644 --- a/go/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go +++ b/go/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go @@ -1365,4 +1365,162 @@ const ( // return i // } InvalidGo + + // All codes below were added in Go 1.17. + + /* decl */ + + // BadDecl occurs when a declaration has invalid syntax. + BadDecl + + // RepeatedDecl occurs when an identifier occurs more than once on the left + // hand side of a short variable declaration. + // + // Example: + // func _() { + // x, y, y := 1, 2, 3 + // } + RepeatedDecl + + /* unsafe */ + + // InvalidUnsafeAdd occurs when unsafe.Add is called with a + // length argument that is not of integer type. + // + // Example: + // import "unsafe" + // + // var p unsafe.Pointer + // var _ = unsafe.Add(p, float64(1)) + InvalidUnsafeAdd + + // InvalidUnsafeSlice occurs when unsafe.Slice is called with a + // pointer argument that is not of pointer type or a length argument + // that is not of integer type, negative, or out of bounds. + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(x, 1) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, float64(1)) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, -1) + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Slice(&x, uint64(1) << 63) + InvalidUnsafeSlice + + // All codes below were added in Go 1.18. + + /* features */ + + // UnsupportedFeature occurs when a language feature is used that is not + // supported at this Go version. + UnsupportedFeature + + /* type params */ + + // NotAGenericType occurs when a non-generic type is used where a generic + // type is expected: in type or function instantiation. + // + // Example: + // type T int + // + // var _ T[int] + NotAGenericType + + // WrongTypeArgCount occurs when a type or function is instantiated with an + // incorrent number of type arguments, including when a generic type or + // function is used without instantiation. + // + // Errors inolving failed type inference are assigned other error codes. + // + // Example: + // type T[p any] int + // + // var _ T[int, string] + // + // Example: + // func f[T any]() {} + // + // var x = f + WrongTypeArgCount + + // CannotInferTypeArgs occurs when type or function type argument inference + // fails to infer all type arguments. + // + // Example: + // func f[T any]() {} + // + // func _() { + // f() + // } + // + // Example: + // type N[P, Q any] struct{} + // + // var _ N[int] + CannotInferTypeArgs + + // InvalidTypeArg occurs when a type argument does not satisfy its + // corresponding type parameter constraints. + // + // Example: + // type T[P ~int] struct{} + // + // var _ T[string] + InvalidTypeArg // arguments? InferenceFailed + + // InvalidInstanceCycle occurs when an invalid cycle is detected + // within the instantiation graph. + // + // Example: + // func f[T any]() { f[*T]() } + InvalidInstanceCycle + + // InvalidUnion occurs when an embedded union or approximation element is + // not valid. + // + // Example: + // type _ interface { + // ~int | interface{ m() } + // } + InvalidUnion + + // MisplacedConstraintIface occurs when a constraint-type interface is used + // outside of constraint position. + // + // Example: + // type I interface { ~int } + // + // var _ I + MisplacedConstraintIface + + // InvalidMethodTypeParams occurs when methods have type parameters. + // + // It cannot be encountered with an AST parsed using go/parser. + InvalidMethodTypeParams + + // MisplacedTypeParam occurs when a type parameter is used in a place where + // it is not permitted. + // + // Example: + // type T[P any] P + // + // Example: + // type T[P any] struct{ *P } + MisplacedTypeParam ) diff --git a/go/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/go/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go index 3e5842a5f0f..de90e9515ae 100644 --- a/go/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go +++ b/go/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go @@ -138,11 +138,25 @@ func _() { _ = x[UnusedResults-128] _ = x[InvalidDefer-129] _ = x[InvalidGo-130] + _ = x[BadDecl-131] + _ = x[RepeatedDecl-132] + _ = x[InvalidUnsafeAdd-133] + _ = x[InvalidUnsafeSlice-134] + _ = x[UnsupportedFeature-135] + _ = x[NotAGenericType-136] + _ = x[WrongTypeArgCount-137] + _ = x[CannotInferTypeArgs-138] + _ = x[InvalidTypeArg-139] + _ = x[InvalidInstanceCycle-140] + _ = x[InvalidUnion-141] + _ = x[MisplacedConstraintIface-142] + _ = x[InvalidMethodTypeParams-143] + _ = x[MisplacedTypeParam-144] } -const _ErrorCode_name = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGo" +const _ErrorCode_name = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParam" -var _ErrorCode_index = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 215, 231, 250, 258, 274, 292, 309, 327, 351, 359, 374, 390, 408, 425, 440, 447, 458, 481, 496, 508, 519, 534, 548, 563, 578, 591, 600, 614, 629, 640, 655, 664, 680, 700, 718, 737, 749, 768, 787, 803, 820, 839, 853, 864, 879, 892, 907, 923, 937, 953, 968, 985, 1003, 1018, 1028, 1038, 1055, 1077, 1091, 1105, 1125, 1143, 1163, 1181, 1204, 1220, 1235, 1248, 1258, 1270, 1281, 1295, 1308, 1319, 1329, 1344, 1355, 1366, 1379, 1395, 1412, 1436, 1453, 1468, 1478, 1487, 1500, 1516, 1532, 1543, 1558, 1574, 1588, 1604, 1618, 1635, 1655, 1668, 1684, 1698, 1715, 1732, 1749, 1764, 1778, 1792, 1803, 1815, 1828, 1845, 1858, 1869, 1882, 1894, 1903} +var _ErrorCode_index = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 215, 231, 250, 258, 274, 292, 309, 327, 351, 359, 374, 390, 408, 425, 440, 447, 458, 481, 496, 508, 519, 534, 548, 563, 578, 591, 600, 614, 629, 640, 655, 664, 680, 700, 718, 737, 749, 768, 787, 803, 820, 839, 853, 864, 879, 892, 907, 923, 937, 953, 968, 985, 1003, 1018, 1028, 1038, 1055, 1077, 1091, 1105, 1125, 1143, 1163, 1181, 1204, 1220, 1235, 1248, 1258, 1270, 1281, 1295, 1308, 1319, 1329, 1344, 1355, 1366, 1379, 1395, 1412, 1436, 1453, 1468, 1478, 1487, 1500, 1516, 1532, 1543, 1558, 1574, 1588, 1604, 1618, 1635, 1655, 1668, 1684, 1698, 1715, 1732, 1749, 1764, 1778, 1792, 1803, 1815, 1828, 1845, 1858, 1869, 1882, 1894, 1903, 1910, 1922, 1938, 1956, 1974, 1989, 2006, 2025, 2039, 2059, 2071, 2095, 2118, 2136} func (i ErrorCode) String() string { i -= 1 diff --git a/go/vendor/golang.org/x/tools/internal/typesinternal/types.go b/go/vendor/golang.org/x/tools/internal/typesinternal/types.go index c3e1a397dbf..ce7d4351b22 100644 --- a/go/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ b/go/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -30,10 +30,15 @@ func SetUsesCgo(conf *types.Config) bool { return true } -func ReadGo116ErrorData(terr types.Error) (ErrorCode, token.Pos, token.Pos, bool) { +// ReadGo116ErrorData extracts additional information from types.Error values +// generated by Go version 1.16 and later: the error code, start position, and +// end position. If all positions are valid, start <= err.Pos <= end. +// +// If the data could not be read, the final result parameter will be false. +func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) { var data [3]int // By coincidence all of these fields are ints, which simplifies things. - v := reflect.ValueOf(terr) + v := reflect.ValueOf(err) for i, name := range []string{"go116code", "go116start", "go116end"} { f := v.FieldByName(name) if !f.IsValid() { @@ -43,3 +48,5 @@ func ReadGo116ErrorData(terr types.Error) (ErrorCode, token.Pos, token.Pos, bool } return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true } + +var SetGoVersion = func(conf *types.Config, version string) bool { return false } diff --git a/go/vendor/golang.org/x/tools/internal/typesinternal/types_118.go b/go/vendor/golang.org/x/tools/internal/typesinternal/types_118.go new file mode 100644 index 00000000000..a42b072a67d --- /dev/null +++ b/go/vendor/golang.org/x/tools/internal/typesinternal/types_118.go @@ -0,0 +1,19 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.18 +// +build go1.18 + +package typesinternal + +import ( + "go/types" +) + +func init() { + SetGoVersion = func(conf *types.Config, version string) bool { + conf.GoVersion = version + return true + } +} diff --git a/go/vendor/golang.org/x/xerrors/LICENSE b/go/vendor/golang.org/x/xerrors/LICENSE deleted file mode 100644 index e4a47e17f14..00000000000 --- a/go/vendor/golang.org/x/xerrors/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2019 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/go/vendor/golang.org/x/xerrors/PATENTS b/go/vendor/golang.org/x/xerrors/PATENTS deleted file mode 100644 index 733099041f8..00000000000 --- a/go/vendor/golang.org/x/xerrors/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/go/vendor/golang.org/x/xerrors/README b/go/vendor/golang.org/x/xerrors/README deleted file mode 100644 index aac7867a560..00000000000 --- a/go/vendor/golang.org/x/xerrors/README +++ /dev/null @@ -1,2 +0,0 @@ -This repository holds the transition packages for the new Go 1.13 error values. -See golang.org/design/29934-error-values. diff --git a/go/vendor/golang.org/x/xerrors/adaptor.go b/go/vendor/golang.org/x/xerrors/adaptor.go deleted file mode 100644 index 4317f248331..00000000000 --- a/go/vendor/golang.org/x/xerrors/adaptor.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xerrors - -import ( - "bytes" - "fmt" - "io" - "reflect" - "strconv" -) - -// FormatError calls the FormatError method of f with an errors.Printer -// configured according to s and verb, and writes the result to s. -func FormatError(f Formatter, s fmt.State, verb rune) { - // Assuming this function is only called from the Format method, and given - // that FormatError takes precedence over Format, it cannot be called from - // any package that supports errors.Formatter. It is therefore safe to - // disregard that State may be a specific printer implementation and use one - // of our choice instead. - - // limitations: does not support printing error as Go struct. - - var ( - sep = " " // separator before next error - p = &state{State: s} - direct = true - ) - - var err error = f - - switch verb { - // Note that this switch must match the preference order - // for ordinary string printing (%#v before %+v, and so on). - - case 'v': - if s.Flag('#') { - if stringer, ok := err.(fmt.GoStringer); ok { - io.WriteString(&p.buf, stringer.GoString()) - goto exit - } - // proceed as if it were %v - } else if s.Flag('+') { - p.printDetail = true - sep = "\n - " - } - case 's': - case 'q', 'x', 'X': - // Use an intermediate buffer in the rare cases that precision, - // truncation, or one of the alternative verbs (q, x, and X) are - // specified. - direct = false - - default: - p.buf.WriteString("%!") - p.buf.WriteRune(verb) - p.buf.WriteByte('(') - switch { - case err != nil: - p.buf.WriteString(reflect.TypeOf(f).String()) - default: - p.buf.WriteString("") - } - p.buf.WriteByte(')') - io.Copy(s, &p.buf) - return - } - -loop: - for { - switch v := err.(type) { - case Formatter: - err = v.FormatError((*printer)(p)) - case fmt.Formatter: - v.Format(p, 'v') - break loop - default: - io.WriteString(&p.buf, v.Error()) - break loop - } - if err == nil { - break - } - if p.needColon || !p.printDetail { - p.buf.WriteByte(':') - p.needColon = false - } - p.buf.WriteString(sep) - p.inDetail = false - p.needNewline = false - } - -exit: - width, okW := s.Width() - prec, okP := s.Precision() - - if !direct || (okW && width > 0) || okP { - // Construct format string from State s. - format := []byte{'%'} - if s.Flag('-') { - format = append(format, '-') - } - if s.Flag('+') { - format = append(format, '+') - } - if s.Flag(' ') { - format = append(format, ' ') - } - if okW { - format = strconv.AppendInt(format, int64(width), 10) - } - if okP { - format = append(format, '.') - format = strconv.AppendInt(format, int64(prec), 10) - } - format = append(format, string(verb)...) - fmt.Fprintf(s, string(format), p.buf.String()) - } else { - io.Copy(s, &p.buf) - } -} - -var detailSep = []byte("\n ") - -// state tracks error printing state. It implements fmt.State. -type state struct { - fmt.State - buf bytes.Buffer - - printDetail bool - inDetail bool - needColon bool - needNewline bool -} - -func (s *state) Write(b []byte) (n int, err error) { - if s.printDetail { - if len(b) == 0 { - return 0, nil - } - if s.inDetail && s.needColon { - s.needNewline = true - if b[0] == '\n' { - b = b[1:] - } - } - k := 0 - for i, c := range b { - if s.needNewline { - if s.inDetail && s.needColon { - s.buf.WriteByte(':') - s.needColon = false - } - s.buf.Write(detailSep) - s.needNewline = false - } - if c == '\n' { - s.buf.Write(b[k:i]) - k = i + 1 - s.needNewline = true - } - } - s.buf.Write(b[k:]) - if !s.inDetail { - s.needColon = true - } - } else if !s.inDetail { - s.buf.Write(b) - } - return len(b), nil -} - -// printer wraps a state to implement an xerrors.Printer. -type printer state - -func (s *printer) Print(args ...interface{}) { - if !s.inDetail || s.printDetail { - fmt.Fprint((*state)(s), args...) - } -} - -func (s *printer) Printf(format string, args ...interface{}) { - if !s.inDetail || s.printDetail { - fmt.Fprintf((*state)(s), format, args...) - } -} - -func (s *printer) Detail() bool { - s.inDetail = true - return s.printDetail -} diff --git a/go/vendor/golang.org/x/xerrors/codereview.cfg b/go/vendor/golang.org/x/xerrors/codereview.cfg deleted file mode 100644 index 3f8b14b64e8..00000000000 --- a/go/vendor/golang.org/x/xerrors/codereview.cfg +++ /dev/null @@ -1 +0,0 @@ -issuerepo: golang/go diff --git a/go/vendor/golang.org/x/xerrors/doc.go b/go/vendor/golang.org/x/xerrors/doc.go deleted file mode 100644 index eef99d9d54d..00000000000 --- a/go/vendor/golang.org/x/xerrors/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package xerrors implements functions to manipulate errors. -// -// This package is based on the Go 2 proposal for error values: -// https://golang.org/design/29934-error-values -// -// These functions were incorporated into the standard library's errors package -// in Go 1.13: -// - Is -// - As -// - Unwrap -// -// Also, Errorf's %w verb was incorporated into fmt.Errorf. -// -// Use this package to get equivalent behavior in all supported Go versions. -// -// No other features of this package were included in Go 1.13, and at present -// there are no plans to include any of them. -package xerrors // import "golang.org/x/xerrors" diff --git a/go/vendor/golang.org/x/xerrors/errors.go b/go/vendor/golang.org/x/xerrors/errors.go deleted file mode 100644 index e88d3772d86..00000000000 --- a/go/vendor/golang.org/x/xerrors/errors.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xerrors - -import "fmt" - -// errorString is a trivial implementation of error. -type errorString struct { - s string - frame Frame -} - -// New returns an error that formats as the given text. -// -// The returned error contains a Frame set to the caller's location and -// implements Formatter to show this information when printed with details. -func New(text string) error { - return &errorString{text, Caller(1)} -} - -func (e *errorString) Error() string { - return e.s -} - -func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) } - -func (e *errorString) FormatError(p Printer) (next error) { - p.Print(e.s) - e.frame.Format(p) - return nil -} diff --git a/go/vendor/golang.org/x/xerrors/fmt.go b/go/vendor/golang.org/x/xerrors/fmt.go deleted file mode 100644 index 829862ddf6a..00000000000 --- a/go/vendor/golang.org/x/xerrors/fmt.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xerrors - -import ( - "fmt" - "strings" - "unicode" - "unicode/utf8" - - "golang.org/x/xerrors/internal" -) - -const percentBangString = "%!" - -// Errorf formats according to a format specifier and returns the string as a -// value that satisfies error. -// -// The returned error includes the file and line number of the caller when -// formatted with additional detail enabled. If the last argument is an error -// the returned error's Format method will return it if the format string ends -// with ": %s", ": %v", or ": %w". If the last argument is an error and the -// format string ends with ": %w", the returned error implements an Unwrap -// method returning it. -// -// If the format specifier includes a %w verb with an error operand in a -// position other than at the end, the returned error will still implement an -// Unwrap method returning the operand, but the error's Format method will not -// return the wrapped error. -// -// It is invalid to include more than one %w verb or to supply it with an -// operand that does not implement the error interface. The %w verb is otherwise -// a synonym for %v. -func Errorf(format string, a ...interface{}) error { - format = formatPlusW(format) - // Support a ": %[wsv]" suffix, which works well with xerrors.Formatter. - wrap := strings.HasSuffix(format, ": %w") - idx, format2, ok := parsePercentW(format) - percentWElsewhere := !wrap && idx >= 0 - if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) { - err := errorAt(a, len(a)-1) - if err == nil { - return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)} - } - // TODO: this is not entirely correct. The error value could be - // printed elsewhere in format if it mixes numbered with unnumbered - // substitutions. With relatively small changes to doPrintf we can - // have it optionally ignore extra arguments and pass the argument - // list in its entirety. - msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...) - frame := Frame{} - if internal.EnableTrace { - frame = Caller(1) - } - if wrap { - return &wrapError{msg, err, frame} - } - return &noWrapError{msg, err, frame} - } - // Support %w anywhere. - // TODO: don't repeat the wrapped error's message when %w occurs in the middle. - msg := fmt.Sprintf(format2, a...) - if idx < 0 { - return &noWrapError{msg, nil, Caller(1)} - } - err := errorAt(a, idx) - if !ok || err == nil { - // Too many %ws or argument of %w is not an error. Approximate the Go - // 1.13 fmt.Errorf message. - return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)} - } - frame := Frame{} - if internal.EnableTrace { - frame = Caller(1) - } - return &wrapError{msg, err, frame} -} - -func errorAt(args []interface{}, i int) error { - if i < 0 || i >= len(args) { - return nil - } - err, ok := args[i].(error) - if !ok { - return nil - } - return err -} - -// formatPlusW is used to avoid the vet check that will barf at %w. -func formatPlusW(s string) string { - return s -} - -// Return the index of the only %w in format, or -1 if none. -// Also return a rewritten format string with %w replaced by %v, and -// false if there is more than one %w. -// TODO: handle "%[N]w". -func parsePercentW(format string) (idx int, newFormat string, ok bool) { - // Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go. - idx = -1 - ok = true - n := 0 - sz := 0 - var isW bool - for i := 0; i < len(format); i += sz { - if format[i] != '%' { - sz = 1 - continue - } - // "%%" is not a format directive. - if i+1 < len(format) && format[i+1] == '%' { - sz = 2 - continue - } - sz, isW = parsePrintfVerb(format[i:]) - if isW { - if idx >= 0 { - ok = false - } else { - idx = n - } - // "Replace" the last character, the 'w', with a 'v'. - p := i + sz - 1 - format = format[:p] + "v" + format[p+1:] - } - n++ - } - return idx, format, ok -} - -// Parse the printf verb starting with a % at s[0]. -// Return how many bytes it occupies and whether the verb is 'w'. -func parsePrintfVerb(s string) (int, bool) { - // Assume only that the directive is a sequence of non-letters followed by a single letter. - sz := 0 - var r rune - for i := 1; i < len(s); i += sz { - r, sz = utf8.DecodeRuneInString(s[i:]) - if unicode.IsLetter(r) { - return i + sz, r == 'w' - } - } - return len(s), false -} - -type noWrapError struct { - msg string - err error - frame Frame -} - -func (e *noWrapError) Error() string { - return fmt.Sprint(e) -} - -func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } - -func (e *noWrapError) FormatError(p Printer) (next error) { - p.Print(e.msg) - e.frame.Format(p) - return e.err -} - -type wrapError struct { - msg string - err error - frame Frame -} - -func (e *wrapError) Error() string { - return fmt.Sprint(e) -} - -func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } - -func (e *wrapError) FormatError(p Printer) (next error) { - p.Print(e.msg) - e.frame.Format(p) - return e.err -} - -func (e *wrapError) Unwrap() error { - return e.err -} diff --git a/go/vendor/golang.org/x/xerrors/format.go b/go/vendor/golang.org/x/xerrors/format.go deleted file mode 100644 index 1bc9c26b97f..00000000000 --- a/go/vendor/golang.org/x/xerrors/format.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xerrors - -// A Formatter formats error messages. -type Formatter interface { - error - - // FormatError prints the receiver's first error and returns the next error in - // the error chain, if any. - FormatError(p Printer) (next error) -} - -// A Printer formats error messages. -// -// The most common implementation of Printer is the one provided by package fmt -// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message -// typically provide their own implementations. -type Printer interface { - // Print appends args to the message output. - Print(args ...interface{}) - - // Printf writes a formatted string. - Printf(format string, args ...interface{}) - - // Detail reports whether error detail is requested. - // After the first call to Detail, all text written to the Printer - // is formatted as additional detail, or ignored when - // detail has not been requested. - // If Detail returns false, the caller can avoid printing the detail at all. - Detail() bool -} diff --git a/go/vendor/golang.org/x/xerrors/frame.go b/go/vendor/golang.org/x/xerrors/frame.go deleted file mode 100644 index 0de628ec501..00000000000 --- a/go/vendor/golang.org/x/xerrors/frame.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xerrors - -import ( - "runtime" -) - -// A Frame contains part of a call stack. -type Frame struct { - // Make room for three PCs: the one we were asked for, what it called, - // and possibly a PC for skipPleaseUseCallersFrames. See: - // https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169 - frames [3]uintptr -} - -// Caller returns a Frame that describes a frame on the caller's stack. -// The argument skip is the number of frames to skip over. -// Caller(0) returns the frame for the caller of Caller. -func Caller(skip int) Frame { - var s Frame - runtime.Callers(skip+1, s.frames[:]) - return s -} - -// location reports the file, line, and function of a frame. -// -// The returned function may be "" even if file and line are not. -func (f Frame) location() (function, file string, line int) { - frames := runtime.CallersFrames(f.frames[:]) - if _, ok := frames.Next(); !ok { - return "", "", 0 - } - fr, ok := frames.Next() - if !ok { - return "", "", 0 - } - return fr.Function, fr.File, fr.Line -} - -// Format prints the stack as error detail. -// It should be called from an error's Format implementation -// after printing any other error detail. -func (f Frame) Format(p Printer) { - if p.Detail() { - function, file, line := f.location() - if function != "" { - p.Printf("%s\n ", function) - } - if file != "" { - p.Printf("%s:%d\n", file, line) - } - } -} diff --git a/go/vendor/golang.org/x/xerrors/internal/internal.go b/go/vendor/golang.org/x/xerrors/internal/internal.go deleted file mode 100644 index 89f4eca5df7..00000000000 --- a/go/vendor/golang.org/x/xerrors/internal/internal.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package internal - -// EnableTrace indicates whether stack information should be recorded in errors. -var EnableTrace = true diff --git a/go/vendor/golang.org/x/xerrors/wrap.go b/go/vendor/golang.org/x/xerrors/wrap.go deleted file mode 100644 index 9a3b510374e..00000000000 --- a/go/vendor/golang.org/x/xerrors/wrap.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xerrors - -import ( - "reflect" -) - -// A Wrapper provides context around another error. -type Wrapper interface { - // Unwrap returns the next error in the error chain. - // If there is no next error, Unwrap returns nil. - Unwrap() error -} - -// Opaque returns an error with the same error formatting as err -// but that does not match err and cannot be unwrapped. -func Opaque(err error) error { - return noWrapper{err} -} - -type noWrapper struct { - error -} - -func (e noWrapper) FormatError(p Printer) (next error) { - if f, ok := e.error.(Formatter); ok { - return f.FormatError(p) - } - p.Print(e.error) - return nil -} - -// Unwrap returns the result of calling the Unwrap method on err, if err implements -// Unwrap. Otherwise, Unwrap returns nil. -func Unwrap(err error) error { - u, ok := err.(Wrapper) - if !ok { - return nil - } - return u.Unwrap() -} - -// Is reports whether any error in err's chain matches target. -// -// An error is considered to match a target if it is equal to that target or if -// it implements a method Is(error) bool such that Is(target) returns true. -func Is(err, target error) bool { - if target == nil { - return err == target - } - - isComparable := reflect.TypeOf(target).Comparable() - for { - if isComparable && err == target { - return true - } - if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { - return true - } - // TODO: consider supporing target.Is(err). This would allow - // user-definable predicates, but also may allow for coping with sloppy - // APIs, thereby making it easier to get away with them. - if err = Unwrap(err); err == nil { - return false - } - } -} - -// As finds the first error in err's chain that matches the type to which target -// points, and if so, sets the target to its value and returns true. An error -// matches a type if it is assignable to the target type, or if it has a method -// As(interface{}) bool such that As(target) returns true. As will panic if target -// is not a non-nil pointer to a type which implements error or is of interface type. -// -// The As method should set the target to its value and return true if err -// matches the type to which target points. -func As(err error, target interface{}) bool { - if target == nil { - panic("errors: target cannot be nil") - } - val := reflect.ValueOf(target) - typ := val.Type() - if typ.Kind() != reflect.Ptr || val.IsNil() { - panic("errors: target must be a non-nil pointer") - } - if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) { - panic("errors: *target must be interface or implement error") - } - targetType := typ.Elem() - for err != nil { - if reflect.TypeOf(err).AssignableTo(targetType) { - val.Elem().Set(reflect.ValueOf(err)) - return true - } - if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { - return true - } - err = Unwrap(err) - } - return false -} - -var errorType = reflect.TypeOf((*error)(nil)).Elem() diff --git a/go/vendor/modules.txt b/go/vendor/modules.txt index 4b567fe9635..47121546873 100644 --- a/go/vendor/modules.txt +++ b/go/vendor/modules.txt @@ -1,17 +1,18 @@ -# golang.org/x/mod v0.5.0 +# golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 ## explicit; go 1.17 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/sys v0.0.0-20210510120138-977fb7262007 +# golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f ## explicit; go 1.17 golang.org/x/sys/execabs -# golang.org/x/tools v0.1.5 -## explicit; go 1.17 +# golang.org/x/tools v0.1.12 +## explicit; go 1.18 golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/internal/gcimporter golang.org/x/tools/go/internal/packagesdriver +golang.org/x/tools/go/internal/pkgbits golang.org/x/tools/go/packages golang.org/x/tools/internal/event golang.org/x/tools/internal/event/core @@ -19,8 +20,7 @@ golang.org/x/tools/internal/event/keys golang.org/x/tools/internal/event/label golang.org/x/tools/internal/gocommand golang.org/x/tools/internal/packagesinternal +golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal # golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ## explicit; go 1.11 -golang.org/x/xerrors -golang.org/x/xerrors/internal From d2055283de0683be1a548a9915819883d647432c Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 18 Aug 2022 17:47:13 +0100 Subject: [PATCH 057/659] Add models for go 1.19's new atomic pointer typex --- .../go/frameworks/stdlib/SyncAtomic.qll | 16 ++- .../frameworks/StdlibTaintFlow/SyncAtomic.go | 120 +++++++++++++++++- 2 files changed, 128 insertions(+), 8 deletions(-) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/SyncAtomic.qll b/go/ql/lib/semmle/go/frameworks/stdlib/SyncAtomic.qll index 373ea1d71ca..df86fe53df7 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/SyncAtomic.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/SyncAtomic.qll @@ -69,13 +69,15 @@ module SyncAtomic { FunctionOutput outp; MethodModels() { - // signature: func (*Value) Load() (x interface{}) - hasQualifiedName("sync/atomic", "Value", "Load") and - (inp.isReceiver() and outp.isResult()) - or - // signature: func (*Value) Store(x interface{}) - hasQualifiedName("sync/atomic", "Value", "Store") and - (inp.isParameter(0) and outp.isReceiver()) + exists(string containerType | containerType = ["Value", "Pointer", "Uintptr"] | + // signature: func (*Containertype) Load/Swap() (x containedtype) + hasQualifiedName("sync/atomic", containerType, ["Load", "Swap"]) and + (inp.isReceiver() and outp.isResult()) + or + // signature: func (*Containertype) Store/Swap(x containedtype) [(x containedtype)] + hasQualifiedName("sync/atomic", containerType, ["Store", "Swap"]) and + (inp.isParameter(0) and outp.isReceiver()) + ) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/SyncAtomic.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/SyncAtomic.go index 2034edb7fb2..dd7a8f77800 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/SyncAtomic.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/SyncAtomic.go @@ -1,4 +1,5 @@ -// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT. +// Code partially generated by https://github.com/gagliardetto/codebox, with manual additions +// for atomic.Pointer and Uintptr, as well as atomic.Value's Swap method. package main @@ -99,6 +100,73 @@ func TaintStepTest_SyncAtomicValueStore_B0I0O0(sourceCQL interface{}) interface{ return intoValue631 } +func TaintStepTest_SyncAtomicValueSwap(sourceCQL interface{}) interface{} { + fromInterface598 := sourceCQL.(interface{}) + var intoValue631 atomic.Value + intoValue631.Swap(fromInterface598) + return intoValue631 +} + +func TaintStepTest_SyncAtomicValueSwap2(sourceCQL interface{}) interface{} { + fromValue246 := sourceCQL.(atomic.Value) + intoInterface898 := fromValue246.Swap("clean") + return intoInterface898 +} + +func TaintStepTest_SyncAtomicPointerLoad_B0I0O0(sourceCQL interface{}) interface{} { + fromValue246 := sourceCQL.(atomic.Pointer[string]) + intoInterface898 := fromValue246.Load() + return intoInterface898 +} + +func TaintStepTest_SyncAtomicPointerStore_B0I0O0(sourceCQL interface{}) interface{} { + fromInterface598 := sourceCQL.(*string) + var intoValue631 atomic.Pointer[string] + intoValue631.Store(fromInterface598) + return intoValue631 +} + +func TaintStepTest_SyncAtomicPointerSwap(sourceCQL interface{}) interface{} { + fromInterface598 := sourceCQL.(*string) + var intoValue631 atomic.Pointer[string] + intoValue631.Swap(fromInterface598) + return intoValue631 +} + +func TaintStepTest_SyncAtomicPointerSwap2(sourceCQL interface{}) interface{} { + fromValue246 := sourceCQL.(atomic.Pointer[string]) + clean := "Clean" + intoInterface898 := fromValue246.Swap(&clean) + return intoInterface898 +} + +func TaintStepTest_SyncAtomicUintptrLoad_B0I0O0(sourceCQL interface{}) interface{} { + fromValue246 := sourceCQL.(atomic.Uintptr) + intoInterface898 := fromValue246.Load() + return intoInterface898 +} + +func TaintStepTest_SyncAtomicUintptrStore_B0I0O0(sourceCQL interface{}) interface{} { + fromInterface598 := sourceCQL.(uintptr) + var intoValue631 atomic.Uintptr + intoValue631.Store(fromInterface598) + return intoValue631 +} + +func TaintStepTest_SyncAtomicUintptrSwap(sourceCQL interface{}) interface{} { + fromInterface598 := sourceCQL.(uintptr) + var intoValue631 atomic.Uintptr + intoValue631.Swap(fromInterface598) + return intoValue631 +} + +func TaintStepTest_SyncAtomicUintptrSwap2(sourceCQL interface{}) interface{} { + fromValue246 := sourceCQL.(atomic.Uintptr) + clean := "Clean" + intoInterface898 := fromValue246.Swap(uintptr(unsafe.Pointer(&clean))) + return intoInterface898 +} + func RunAllTaints_SyncAtomic() { { source := newSource(0) @@ -170,4 +238,54 @@ func RunAllTaints_SyncAtomic() { out := TaintStepTest_SyncAtomicValueStore_B0I0O0(source) sink(13, out) } + { + source := newSource(14) + out := TaintStepTest_SyncAtomicValueSwap(source) + sink(14, out) + } + { + source := newSource(15) + out := TaintStepTest_SyncAtomicValueSwap2(source) + sink(15, out) + } + { + source := newSource(16) + out := TaintStepTest_SyncAtomicPointerLoad_B0I0O0(source) + sink(16, out) + } + { + source := newSource(17) + out := TaintStepTest_SyncAtomicPointerStore_B0I0O0(source) + sink(17, out) + } + { + source := newSource(18) + out := TaintStepTest_SyncAtomicPointerSwap(source) + sink(18, out) + } + { + source := newSource(19) + out := TaintStepTest_SyncAtomicPointerSwap2(source) + sink(19, out) + } + { + source := newSource(20) + out := TaintStepTest_SyncAtomicUintptrLoad_B0I0O0(source) + sink(20, out) + } + { + source := newSource(21) + out := TaintStepTest_SyncAtomicUintptrStore_B0I0O0(source) + sink(21, out) + } + { + source := newSource(22) + out := TaintStepTest_SyncAtomicUintptrSwap(source) + sink(22, out) + } + { + source := newSource(23) + out := TaintStepTest_SyncAtomicUintptrSwap2(source) + sink(23, out) + } } From 328e47834e3abbc9f89e8e4c04bdb55d283a8ce0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 15 Aug 2022 11:16:10 +0200 Subject: [PATCH 058/659] C#: Add ASP.NET Core MapGet routing end point example. --- .../flowsources/aspremote/AspRemoteFlowSource.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs index a62c94d8686..d9995ac7afc 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; namespace Testing @@ -20,4 +21,19 @@ namespace Testing throw null; } } + + public class AspRoutingEndpoints + { + + public void M1(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + var app = builder.Build(); + + // The delegate parameters are considered flow sources. + app.MapGet("/api/redirect/{newUrl}", (string newUrl) => { }); + + app.Run(); + } + } } \ No newline at end of file From c8afb1bb948a67822ce0b8893bb84fb39e5e2705 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 15 Aug 2022 11:21:22 +0200 Subject: [PATCH 059/659] C#: Update expected test case with new line numbers. --- .../flowsources/aspremote/aspRemoteFlowSource.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected index e2e07cb08c6..9ef5145d9b1 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected @@ -1,4 +1,4 @@ remoteFlowSourceMembers -| AspRemoteFlowSource.cs:8:23:8:31 | RequestId | +| AspRemoteFlowSource.cs:9:23:9:31 | RequestId | remoteFlowSources -| AspRemoteFlowSource.cs:18:42:18:50 | viewModel | +| AspRemoteFlowSource.cs:19:42:19:50 | viewModel | From bd6d3c73474c178bacae605f788069a1314c4238 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 15 Aug 2022 16:26:32 +0200 Subject: [PATCH 060/659] C#: Consider parameters passed to lambdas in MapGet remote flow sources. --- .../csharp/frameworks/microsoft/AspNetCore.qll | 12 ++++++++++++ .../security/dataflow/flowsources/Remote.qll | 16 ++++++++++++++++ .../aspremote/aspRemoteFlowSource.expected | 1 + 3 files changed, 29 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll index a918b603818..3f5cc91c88e 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll @@ -357,3 +357,15 @@ class MicrosoftAspNetCoreHttpHtmlString extends Class { this.hasQualifiedName("Microsoft.AspNetCore.Html", "HtmlString") } } + +/** + * The `Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions` class. + */ +class MicrosoftAspNetCoreBuilderEndpointRouteBuilderExtensions extends Class { + MicrosoftAspNetCoreBuilderEndpointRouteBuilderExtensions() { + this.hasQualifiedName("Microsoft.AspNetCore.Builder", "EndpointRouteBuilderExtensions") + } + + /** Gets the `UseMap` extension method. */ + Method getMapGetMethod() { result = this.getAMethod("MapGet") } +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll index 241f16d06ed..b5cdbc0c4ba 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll @@ -171,6 +171,22 @@ class ActionMethodParameter extends RemoteFlowSource, DataFlow::ParameterNode { /** A data flow source of remote user input (ASP.NET Core). */ abstract class AspNetCoreRemoteFlowSource extends RemoteFlowSource { } +/** A parameter to a routing method delegate. */ +class RoutingMethodParameter extends AspNetCoreRemoteFlowSource, DataFlow::ParameterNode { + RoutingMethodParameter() { + exists(Parameter p, MethodCall m | + p = this.getParameter() and + p.fromSource() + | + m.getTarget() = + any(MicrosoftAspNetCoreBuilderEndpointRouteBuilderExtensions c).getMapGetMethod() and + p = m.getArgument(2).(AnonymousFunctionExpr).getAParameter() + ) + } + + override string getSourceType() { result = "ASP.NET Core routing endpoint." } +} + /** * Data flow for ASP.NET Core. * diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected index 9ef5145d9b1..b350ad17f2d 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected @@ -2,3 +2,4 @@ remoteFlowSourceMembers | AspRemoteFlowSource.cs:9:23:9:31 | RequestId | remoteFlowSources | AspRemoteFlowSource.cs:19:42:19:50 | viewModel | +| AspRemoteFlowSource.cs:34:58:34:63 | newUrl | From 6e5a412150ac3c6982821d5880d48c1aff24ce4e Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 16 Aug 2022 13:03:34 +0200 Subject: [PATCH 061/659] C#: Make one more ASP.NET routing example. --- .../dataflow/flowsources/aspremote/AspRemoteFlowSource.cs | 2 +- .../flowsources/aspremote/aspRemoteFlowSource.expected | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs index d9995ac7afc..c47d5a02058 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs @@ -24,7 +24,6 @@ namespace Testing public class AspRoutingEndpoints { - public void M1(string[] args) { var builder = WebApplication.CreateBuilder(args); @@ -32,6 +31,7 @@ namespace Testing // The delegate parameters are considered flow sources. app.MapGet("/api/redirect/{newUrl}", (string newUrl) => { }); + app.MapGet("/{myApi}/redirect/{myUrl}", (string myApi, string myUrl) => { } ); app.Run(); } diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected index b350ad17f2d..a0354b3e68b 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected @@ -2,4 +2,6 @@ remoteFlowSourceMembers | AspRemoteFlowSource.cs:9:23:9:31 | RequestId | remoteFlowSources | AspRemoteFlowSource.cs:19:42:19:50 | viewModel | -| AspRemoteFlowSource.cs:34:58:34:63 | newUrl | +| AspRemoteFlowSource.cs:33:58:33:63 | newUrl | +| AspRemoteFlowSource.cs:34:61:34:65 | myApi | +| AspRemoteFlowSource.cs:34:75:34:79 | myUrl | From aaf14b0184f6283e7cdc715e06317c93a771e9a1 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 16 Aug 2022 13:35:34 +0200 Subject: [PATCH 062/659] C#: Improve solution (pair programming with @hvitved). --- .../security/dataflow/flowsources/Remote.qll | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll index b5cdbc0c4ba..01ebce07dbf 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll @@ -171,16 +171,30 @@ class ActionMethodParameter extends RemoteFlowSource, DataFlow::ParameterNode { /** A data flow source of remote user input (ASP.NET Core). */ abstract class AspNetCoreRemoteFlowSource extends RemoteFlowSource { } +private predicate reachesMapGetArg(DataFlow::Node n) { + exists(MethodCall mc | + mc.getTarget() = + any(MicrosoftAspNetCoreBuilderEndpointRouteBuilderExtensions c).getMapGetMethod() and + n.asExpr() = mc.getArgument(2) + ) + or + exists(DataFlow::Node mid | reachesMapGetArg(mid) | + DataFlow::localFlowStep(n, mid) or + n.asExpr() = mid.asExpr().(DelegateCreation).getArgument() + ) +} + /** A parameter to a routing method delegate. */ -class RoutingMethodParameter extends AspNetCoreRemoteFlowSource, DataFlow::ParameterNode { - RoutingMethodParameter() { - exists(Parameter p, MethodCall m | - p = this.getParameter() and - p.fromSource() +class AspNetCoreRoutingMethodParameter extends AspNetCoreRemoteFlowSource, DataFlow::ParameterNode { + AspNetCoreRoutingMethodParameter() { + exists(DataFlow::Node n, Callable c | + reachesMapGetArg(n) and + c.getAParameter() = this.asParameter() and + c.isSourceDeclaration() | - m.getTarget() = - any(MicrosoftAspNetCoreBuilderEndpointRouteBuilderExtensions c).getMapGetMethod() and - p = m.getArgument(2).(AnonymousFunctionExpr).getAParameter() + n.asExpr() = c + or + n.asExpr().(CallableAccess).getTarget().getUnboundDeclaration() = c ) } From d2c526613930eb883658b1af31127c736aa4ceee Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 16 Aug 2022 14:56:56 +0200 Subject: [PATCH 063/659] C#: Add more test examples. --- .../flowsources/aspremote/AspRemoteFlowSource.cs | 12 +++++++++++- .../aspremote/aspRemoteFlowSource.expected | 12 +++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs index c47d5a02058..06090935e2b 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; +using System; namespace Testing { @@ -24,6 +25,10 @@ namespace Testing public class AspRoutingEndpoints { + public delegate void MapGetHandler(string delegateparam); + + public void HandlerMethod(string param) { } + public void M1(string[] args) { var builder = WebApplication.CreateBuilder(args); @@ -31,8 +36,13 @@ namespace Testing // The delegate parameters are considered flow sources. app.MapGet("/api/redirect/{newUrl}", (string newUrl) => { }); - app.MapGet("/{myApi}/redirect/{myUrl}", (string myApi, string myUrl) => { } ); + app.MapGet("/{myApi}/redirect/{myUrl}", (string myApi, string myUrl) => { }); + Action handler = (string lambdaParam) => { }; + app.MapGet("/api/redirect/{lambdaParam}", handler); + + MapGetHandler handler2 = HandlerMethod; + app.MapGet("/api/redirect/{param}", handler2); app.Run(); } } diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected index a0354b3e68b..4d5162029c8 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected @@ -1,7 +1,9 @@ remoteFlowSourceMembers -| AspRemoteFlowSource.cs:9:23:9:31 | RequestId | +| AspRemoteFlowSource.cs:10:23:10:31 | RequestId | remoteFlowSources -| AspRemoteFlowSource.cs:19:42:19:50 | viewModel | -| AspRemoteFlowSource.cs:33:58:33:63 | newUrl | -| AspRemoteFlowSource.cs:34:61:34:65 | myApi | -| AspRemoteFlowSource.cs:34:75:34:79 | myUrl | +| AspRemoteFlowSource.cs:20:42:20:50 | viewModel | +| AspRemoteFlowSource.cs:30:42:30:46 | param | +| AspRemoteFlowSource.cs:38:58:38:63 | newUrl | +| AspRemoteFlowSource.cs:39:61:39:65 | myApi | +| AspRemoteFlowSource.cs:39:75:39:79 | myUrl | +| AspRemoteFlowSource.cs:41:46:41:56 | lambdaParam | From 424d909201d220bd6b0f3eed73a29f7a9b9e7dcf Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 16 Aug 2022 16:03:44 +0200 Subject: [PATCH 064/659] C#: Add more Map like method delegate parameter as flow sources. --- .../frameworks/microsoft/AspNetCore.qll | 23 ++++++++++++++++++- .../security/dataflow/flowsources/Remote.qll | 3 +-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll index 3f5cc91c88e..2ebd9a93c29 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll @@ -366,6 +366,27 @@ class MicrosoftAspNetCoreBuilderEndpointRouteBuilderExtensions extends Class { this.hasQualifiedName("Microsoft.AspNetCore.Builder", "EndpointRouteBuilderExtensions") } - /** Gets the `UseMap` extension method. */ + /** Gets the `Map` extension method. */ + Method getMapMethod() { result = this.getAMethod("Map") } + + /** Gets the `MapGet` extension method. */ Method getMapGetMethod() { result = this.getAMethod("MapGet") } + + /** Gets the `MapPost` extension method. */ + Method getMapPostMethod() { result = this.getAMethod("MapPost") } + + /** Gets the `MapPut` extension method. */ + Method getMapPutMethod() { result = this.getAMethod("MapPut") } + + /** Gets the `MapDelete` extension method. */ + Method getMapDeleteMethod() { result = this.getAMethod("MapDelete") } + + /** Get a `Map` like extenion methods. */ + Method getAMapMethod() { + result = + [ + this.getMapMethod(), this.getMapGetMethod(), this.getMapPostMethod(), + this.getMapPutMethod(), this.getMapDeleteMethod() + ] + } } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll index 01ebce07dbf..4badf4e2070 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll @@ -173,8 +173,7 @@ abstract class AspNetCoreRemoteFlowSource extends RemoteFlowSource { } private predicate reachesMapGetArg(DataFlow::Node n) { exists(MethodCall mc | - mc.getTarget() = - any(MicrosoftAspNetCoreBuilderEndpointRouteBuilderExtensions c).getMapGetMethod() and + mc.getTarget() = any(MicrosoftAspNetCoreBuilderEndpointRouteBuilderExtensions c).getAMapMethod() and n.asExpr() = mc.getArgument(2) ) or From bbb6ba088b8905cb918e46aabfce12e772475ee6 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 16 Aug 2022 16:06:49 +0200 Subject: [PATCH 065/659] C#: Add more Map like remote flow source testcases. --- .../flowsources/aspremote/AspRemoteFlowSource.cs | 9 +++++++-- .../flowsources/aspremote/aspRemoteFlowSource.expected | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs index 06090935e2b..6f22212b775 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs @@ -25,7 +25,7 @@ namespace Testing public class AspRoutingEndpoints { - public delegate void MapGetHandler(string delegateparam); + public delegate void MapGetHandler(string param); public void HandlerMethod(string param) { } @@ -42,7 +42,12 @@ namespace Testing app.MapGet("/api/redirect/{lambdaParam}", handler); MapGetHandler handler2 = HandlerMethod; - app.MapGet("/api/redirect/{param}", handler2); + app.MapGet("/api/redirect/{mapGetParam}", handler2); + + app.MapPost("/api/redirect/{mapPostParam}", (string mapPostParam) => { }); + app.MapPut("/api/redirect/{mapPutParam}", (string mapPutParam) => { }); + app.MapDelete("/api/redirect/{mapDeleteParam}", (string mapDeleteParam) => { }); + app.Run(); } } diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected index 4d5162029c8..a952c3c8365 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected @@ -7,3 +7,6 @@ remoteFlowSources | AspRemoteFlowSource.cs:39:61:39:65 | myApi | | AspRemoteFlowSource.cs:39:75:39:79 | myUrl | | AspRemoteFlowSource.cs:41:46:41:56 | lambdaParam | +| AspRemoteFlowSource.cs:47:65:47:76 | mapPostParam | +| AspRemoteFlowSource.cs:48:63:48:73 | mapPutParam | +| AspRemoteFlowSource.cs:49:69:49:82 | mapDeleteParam | From 058541c0d6d5e55e93a38b59934f97d7c38e286d Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 16 Aug 2022 16:23:45 +0200 Subject: [PATCH 066/659] C#: Added change note. --- .../change-notes/2022-08-16-aspnetcore-remoteflowsources.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/src/change-notes/2022-08-16-aspnetcore-remoteflowsources.md diff --git a/csharp/ql/src/change-notes/2022-08-16-aspnetcore-remoteflowsources.md b/csharp/ql/src/change-notes/2022-08-16-aspnetcore-remoteflowsources.md new file mode 100644 index 00000000000..efabbfdcb97 --- /dev/null +++ b/csharp/ql/src/change-notes/2022-08-16-aspnetcore-remoteflowsources.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Parameters of delegates passed to routing endpoint calls like `MapGet` in ASP.NET Core are now considered remote flow sources. \ No newline at end of file From c3e0388a75545eb24a898fd90269111323f51519 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 19 Aug 2022 08:51:39 +0200 Subject: [PATCH 067/659] C#: Add testcase for complex models. --- .../aspremote/AspRemoteFlowSource.cs | 7 +++++++ .../aspremote/aspRemoteFlowSource.expected | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs index 6f22212b775..7f110e5c6fd 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs @@ -23,6 +23,11 @@ namespace Testing } } + public class Item + { + public string Tainted { get; set; } + } + public class AspRoutingEndpoints { public delegate void MapGetHandler(string param); @@ -48,6 +53,8 @@ namespace Testing app.MapPut("/api/redirect/{mapPutParam}", (string mapPutParam) => { }); app.MapDelete("/api/redirect/{mapDeleteParam}", (string mapDeleteParam) => { }); + app.MapPost("/items", (Item item) => { }); + app.Run(); } } diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected index a952c3c8365..199ed69f28f 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected @@ -1,12 +1,14 @@ remoteFlowSourceMembers | AspRemoteFlowSource.cs:10:23:10:31 | RequestId | +| AspRemoteFlowSource.cs:28:23:28:29 | Tainted | remoteFlowSources | AspRemoteFlowSource.cs:20:42:20:50 | viewModel | -| AspRemoteFlowSource.cs:30:42:30:46 | param | -| AspRemoteFlowSource.cs:38:58:38:63 | newUrl | -| AspRemoteFlowSource.cs:39:61:39:65 | myApi | -| AspRemoteFlowSource.cs:39:75:39:79 | myUrl | -| AspRemoteFlowSource.cs:41:46:41:56 | lambdaParam | -| AspRemoteFlowSource.cs:47:65:47:76 | mapPostParam | -| AspRemoteFlowSource.cs:48:63:48:73 | mapPutParam | -| AspRemoteFlowSource.cs:49:69:49:82 | mapDeleteParam | +| AspRemoteFlowSource.cs:35:42:35:46 | param | +| AspRemoteFlowSource.cs:43:58:43:63 | newUrl | +| AspRemoteFlowSource.cs:44:61:44:65 | myApi | +| AspRemoteFlowSource.cs:44:75:44:79 | myUrl | +| AspRemoteFlowSource.cs:46:46:46:56 | lambdaParam | +| AspRemoteFlowSource.cs:52:65:52:76 | mapPostParam | +| AspRemoteFlowSource.cs:53:63:53:73 | mapPutParam | +| AspRemoteFlowSource.cs:54:69:54:82 | mapDeleteParam | +| AspRemoteFlowSource.cs:56:41:56:44 | item | From 50a53008cd26699b4e1d97f43b05592e4dcb30e3 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 18 Aug 2022 19:04:36 +0200 Subject: [PATCH 068/659] QL: Refine 'redundant override' query --- ql/ql/src/queries/style/RedundantOverride.ql | 40 +++- .../RedundantOverride.expected | 15 +- .../RedundantOverride/RedundantOverride.qll | 202 +++++++++++++++--- 3 files changed, 217 insertions(+), 40 deletions(-) diff --git a/ql/ql/src/queries/style/RedundantOverride.ql b/ql/ql/src/queries/style/RedundantOverride.ql index dbaf5694d30..e95df3cf8a3 100644 --- a/ql/ql/src/queries/style/RedundantOverride.ql +++ b/ql/ql/src/queries/style/RedundantOverride.ql @@ -10,15 +10,14 @@ import ql -private predicate redundantOverride(ClassPredicate pred, ClassPredicate sup) { +/** Holds if `pred` overrides super predicate `sup` by forwarding via `mc`. */ +private predicate forwardingOverride(ClassPredicate pred, MemberCall mc, ClassPredicate sup) { pred.overrides(sup) and - // Can be made more precise, but rules out overrides needed for disambiguation - count(pred.getDeclaringType().getASuperType()) <= 1 and - exists(MemberCall mc | - mc.getBase() instanceof Super and - mc.getTarget() = sup and - not exists(pred.getQLDoc()) - | + mc.getBase() instanceof Super and + mc.getTarget() = sup and + not exists(pred.getQLDoc()) and + forall(int i, VarDecl p | p = pred.getParameter(i) | mc.getArgument(i) = p.getAnAccess()) and + ( pred.getBody() = any(ComparisonFormula comp | comp.getOperator() = "=" and @@ -31,6 +30,31 @@ private predicate redundantOverride(ClassPredicate pred, ClassPredicate sup) { ) } +private predicate forwardingOverrideProj(ClassPredicate pred, ClassPredicate sup) { + forwardingOverride(pred, _, sup) +} + +private ClassPredicate getUltimateDef(ClassPredicate p) { + forwardingOverrideProj*(p, result) and + not forwardingOverrideProj(result, _) +} + +private predicate redundantOverride(ClassPredicate pred, ClassPredicate sup) { + exists(MemberCall mc | + forwardingOverride(pred, mc, sup) and + // overridden to provide more precise QL doc + not exists(pred.getQLDoc()) and + // overridden to disambiguate + not exists(ClassPredicate other | + getUltimateDef(sup) != getUltimateDef(other) and + pred.getDeclaringType().getASuperType+() = other.getDeclaringType() and + not sup.overrides*(other) and + other.getName() = pred.getName() and + other.getArity() = pred.getArity() + ) + ) +} + from ClassPredicate pred, ClassPredicate sup where redundantOverride(pred, sup) select pred, "Redundant override of $@ predicate", sup, "this" diff --git a/ql/ql/test/queries/style/RedundantOverride/RedundantOverride.expected b/ql/ql/test/queries/style/RedundantOverride/RedundantOverride.expected index 32d11091cd5..dbb5c60174f 100644 --- a/ql/ql/test/queries/style/RedundantOverride/RedundantOverride.expected +++ b/ql/ql/test/queries/style/RedundantOverride/RedundantOverride.expected @@ -1,4 +1,11 @@ -| RedundantOverride.qll:12:16:12:19 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:4:7:4:10 | ClassPredicate pred | this | -| RedundantOverride.qll:16:16:16:19 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:4:7:4:10 | ClassPredicate pred | this | -| RedundantOverride.qll:47:22:47:26 | ClassPredicate pred3 | Redundant override of $@ predicate | RedundantOverride.qll:8:13:8:17 | ClassPredicate pred3 | this | -| RedundantOverride.qll:51:16:51:19 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:4:7:4:10 | ClassPredicate pred | this | +| RedundantOverride.qll:9:18:9:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:5:9:5:12 | ClassPredicate pred | this | +| RedundantOverride.qll:21:18:21:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:17:9:17:12 | ClassPredicate pred | this | +| RedundantOverride.qll:110:24:110:27 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:106:15:106:18 | ClassPredicate pred | this | +| RedundantOverride.qll:124:18:124:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:118:9:118:12 | ClassPredicate pred | this | +| RedundantOverride.qll:128:18:128:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:118:9:118:12 | ClassPredicate pred | this | +| RedundantOverride.qll:132:18:132:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:128:18:128:21 | ClassPredicate pred | this | +| RedundantOverride.qll:150:18:150:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:140:9:140:12 | ClassPredicate pred | this | +| RedundantOverride.qll:164:18:164:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:158:9:158:12 | ClassPredicate pred | this | +| RedundantOverride.qll:168:18:168:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:158:9:158:12 | ClassPredicate pred | this | +| RedundantOverride.qll:172:18:172:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:168:18:168:21 | ClassPredicate pred | this | +| RedundantOverride.qll:176:18:176:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:168:18:168:21 | ClassPredicate pred | this | diff --git a/ql/ql/test/queries/style/RedundantOverride/RedundantOverride.qll b/ql/ql/test/queries/style/RedundantOverride/RedundantOverride.qll index 4111b0d8b14..35df3b3194c 100644 --- a/ql/ql/test/queries/style/RedundantOverride/RedundantOverride.qll +++ b/ql/ql/test/queries/style/RedundantOverride/RedundantOverride.qll @@ -1,52 +1,198 @@ -class Foo extends string { - Foo() { this = "Foo" } +module Test1 { + class Foo extends int { + Foo() { this = 1 } - Foo pred() { none() } + Foo pred() { result = this } + } - Foo pred2() { none() } - - predicate pred3() { none() } + class Bar extends Foo { + override Foo pred() { result = Foo.super.pred() } // BAD + } } -class Bar1 extends Foo { - override Foo pred() { result = Foo.super.pred() } // BAD +module Test2 { + class Foo extends int { + Foo() { this = 1 } + + Foo pred() { result = this } + } + + class Bar extends Foo { + override Foo pred() { result = super.pred() } // BAD + } } -class Bar2 extends Foo { - override Foo pred() { result = super.pred() } // BAD +module Test3 { + class Foo extends int { + Foo() { this = [1 .. 3] } + + Foo pred() { any() } + } + + class Bar extends Foo { + Bar() { this = 2 } + } + + class Baz extends Foo { + Baz() { this = 3 } + + override Bar pred() { result = super.pred() } // GOOD (refined return type) + } } -class Bar3 extends Foo { - override Bar3 pred() { result = super.pred() } // GOOD (refined return type) +module Test4 { + class Foo extends int { + Foo() { this = [1, 2] } + + Foo pred() { result = 2 } + } + + class Bar extends Foo { + Bar() { this = 1 } + + override Foo pred() { result = this } // GOOD + } } -class Bar4 extends Foo { - override Foo pred() { any() } // GOOD +module Test5 { + class Foo extends int { + Foo() { this = 1 } + + Foo pred() { result = this } + } + + class Bar extends Foo { + /** My own overriding QL doc. */ + override Foo pred() { result = super.pred() } // GOOD + } } -class Bar5 extends Foo { - /** My own overriding QL doc. */ - override Foo pred() { result = super.pred() } // GOOD +module Test6 { + class Foo extends int { + Foo() { this = [1, 2] } + + Foo pred() { result = 1 } + + Foo pred2() { result = 2 } + } + + class Bar extends Foo { + override Foo pred() { result = super.pred2() } // GOOD + } } -class Bar6 extends Foo { - override Foo pred() { result = super.pred2() } // GOOD +module Test7 { + class Foo extends int { + Foo() { this = [1, 2] } + + Foo pred() { result = 2 } + } + + class Bar extends int { + Bar() { this = 1 } + + Foo pred() { result = this } + } + + class Baz extends Foo, Bar { + override Foo pred() { result = Foo.super.pred() } // GOOD (disambiguate) + } } -class Bar7 extends string { - Bar7() { this = "Bar7" } +module Test8 { + class Foo extends int { + Foo() { this = 1 } - Foo pred() { any() } + predicate pred(Foo f) { f = this } + } + + class Bar extends Foo { + override predicate pred(Foo f) { super.pred(f) } // BAD + } } -class Bar8 extends Foo, Bar7 { - override Foo pred() { result = Foo.super.pred() } // GOOD +module Test9 { + class Foo extends int { + Foo() { this = [1, 2] } + + Foo pred() { result = this } + } + + class Bar extends Foo { + Bar() { this = 1 } + + override Foo pred() { Foo.super.pred() = result } // BAD + } + + class Baz1 extends Foo, Bar { + override Foo pred() { Foo.super.pred() = result } // BAD + } + + class Baz2 extends Foo, Baz1 { + override Foo pred() { Baz1.super.pred() = result } // BAD + } } -class Bar9 extends Foo { - override predicate pred3() { super.pred3() } // BAD +module Test10 { + class Foo extends int { + Foo() { this = [1, 2] } + + Foo pred() { result = 1 } + } + + class Bar extends int { + Bar() { this = 1 } + + Foo pred(int i) { none() } + } + + class Baz1 extends Foo, Bar { + override Foo pred() { result = Foo.super.pred() } // BAD + } } -class Bar10 extends Foo { - override Foo pred() { Foo.super.pred() = result } // BAD +module Test11 { + class Foo extends int { + Foo() { this = [1 .. 4] } + + Foo pred() { result = 1 } + } + + class Bar1 extends Foo { + Bar1() { this = [1 .. 3] } + + override Foo pred() { Foo.super.pred() = result } // BAD + } + + class Bar2 extends Foo, Bar1 { + override Foo pred() { Foo.super.pred() = result } // BAD + } + + class Bar3 extends Foo, Bar2 { + override Foo pred() { Bar2.super.pred() = result } // BAD + } + + class Bar4 extends Bar2, Bar3 { + override Foo pred() { result = Bar2.super.pred() } // BAD + } + + class Bar5 extends Foo { + Bar5() { this = [1 .. 2] } + + override Foo pred() { result = this } // GOOD + } + + class Bar6 extends Bar4, Bar5 { + override Foo pred() { result = Bar4.super.pred() } // GOOD (dismambiguate) + } + + class Bar7 extends Bar6 { + Bar7() { this = 1 } + + override Foo pred() { result = 2 } // GOOD + } + + class Bar8 extends Bar6, Bar7 { + override Foo pred() { result = Bar6.super.pred() } // GOOD (specialize) + } } From c86c9ec2c30d0cadc29ddec8517d5ce4436cc7ff Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 19 Aug 2022 10:35:47 +0200 Subject: [PATCH 069/659] QL: Move query logic into library --- .../style/RedundantOverrideQuery.qll | 46 +++++++++++++++++++ ql/ql/src/queries/style/RedundantOverride.ql | 46 +------------------ 2 files changed, 47 insertions(+), 45 deletions(-) create mode 100644 ql/ql/src/codeql_ql/style/RedundantOverrideQuery.qll diff --git a/ql/ql/src/codeql_ql/style/RedundantOverrideQuery.qll b/ql/ql/src/codeql_ql/style/RedundantOverrideQuery.qll new file mode 100644 index 00000000000..5d8abd4e170 --- /dev/null +++ b/ql/ql/src/codeql_ql/style/RedundantOverrideQuery.qll @@ -0,0 +1,46 @@ +import ql + +/** Holds if `pred` overrides super predicate `sup` by forwarding via `mc`. */ +private predicate forwardingOverride(ClassPredicate pred, MemberCall mc, ClassPredicate sup) { + pred.overrides(sup) and + mc.getBase() instanceof Super and + mc.getTarget() = sup and + not exists(pred.getQLDoc()) and + forall(int i, VarDecl p | p = pred.getParameter(i) | mc.getArgument(i) = p.getAnAccess()) and + ( + pred.getBody() = + any(ComparisonFormula comp | + comp.getOperator() = "=" and + comp.getAnOperand() instanceof ResultAccess and + comp.getAnOperand() = mc and + pred.getReturnType() = sup.getReturnType() + ) + or + pred.getBody() = mc + ) +} + +private predicate forwardingOverrideProj(ClassPredicate pred, ClassPredicate sup) { + forwardingOverride(pred, _, sup) +} + +private ClassPredicate getUltimateDef(ClassPredicate p) { + forwardingOverrideProj*(p, result) and + not forwardingOverrideProj(result, _) +} + +predicate redundantOverride(ClassPredicate pred, ClassPredicate sup) { + exists(MemberCall mc | + forwardingOverride(pred, mc, sup) and + // overridden to provide more precise QL doc + not exists(pred.getQLDoc()) and + // overridden to disambiguate + not exists(ClassPredicate other | + getUltimateDef(sup) != getUltimateDef(other) and + pred.getDeclaringType().getASuperType+() = other.getDeclaringType() and + not sup.overrides*(other) and + other.getName() = pred.getName() and + other.getArity() = pred.getArity() + ) + ) +} diff --git a/ql/ql/src/queries/style/RedundantOverride.ql b/ql/ql/src/queries/style/RedundantOverride.ql index e95df3cf8a3..53b17be1992 100644 --- a/ql/ql/src/queries/style/RedundantOverride.ql +++ b/ql/ql/src/queries/style/RedundantOverride.ql @@ -9,51 +9,7 @@ */ import ql - -/** Holds if `pred` overrides super predicate `sup` by forwarding via `mc`. */ -private predicate forwardingOverride(ClassPredicate pred, MemberCall mc, ClassPredicate sup) { - pred.overrides(sup) and - mc.getBase() instanceof Super and - mc.getTarget() = sup and - not exists(pred.getQLDoc()) and - forall(int i, VarDecl p | p = pred.getParameter(i) | mc.getArgument(i) = p.getAnAccess()) and - ( - pred.getBody() = - any(ComparisonFormula comp | - comp.getOperator() = "=" and - comp.getAnOperand() instanceof ResultAccess and - comp.getAnOperand() = mc and - pred.getReturnType() = sup.getReturnType() - ) - or - pred.getBody() = mc - ) -} - -private predicate forwardingOverrideProj(ClassPredicate pred, ClassPredicate sup) { - forwardingOverride(pred, _, sup) -} - -private ClassPredicate getUltimateDef(ClassPredicate p) { - forwardingOverrideProj*(p, result) and - not forwardingOverrideProj(result, _) -} - -private predicate redundantOverride(ClassPredicate pred, ClassPredicate sup) { - exists(MemberCall mc | - forwardingOverride(pred, mc, sup) and - // overridden to provide more precise QL doc - not exists(pred.getQLDoc()) and - // overridden to disambiguate - not exists(ClassPredicate other | - getUltimateDef(sup) != getUltimateDef(other) and - pred.getDeclaringType().getASuperType+() = other.getDeclaringType() and - not sup.overrides*(other) and - other.getName() = pred.getName() and - other.getArity() = pred.getArity() - ) - ) -} +import codeql_ql.style.RedundantOverrideQuery from ClassPredicate pred, ClassPredicate sup where redundantOverride(pred, sup) From 6068f63e9ed29cbda33aa00cae1581e86a962249 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 18 Aug 2022 18:36:28 +0100 Subject: [PATCH 070/659] Add taint models for go 1.19's new fmt.Append functions --- go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll | 20 ++--- .../Security/CWE-352/ConstantOauth2State.ql | 2 +- .../go/frameworks/StdlibTaintFlow/Fmt.go | 84 ++++++++++++++++++- 3 files changed, 92 insertions(+), 14 deletions(-) diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll index 836003c342f..bc89557e437 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Fmt.qll @@ -6,24 +6,20 @@ import go /** Provides models of commonly used functions in the `fmt` package. */ module Fmt { - /** The `Sprint` function or one of its variants. */ - class Sprinter extends TaintTracking::FunctionModel { - Sprinter() { - // signature: func Sprint(a ...interface{}) string - this.hasQualifiedName("fmt", "Sprint") - or - // signature: func Sprintf(format string, a ...interface{}) string - this.hasQualifiedName("fmt", "Sprintf") - or - // signature: func Sprintln(a ...interface{}) string - this.hasQualifiedName("fmt", "Sprintln") - } + /** The `Sprint` or `Append` functions or one of their variants. */ + class AppenderOrSprinter extends TaintTracking::FunctionModel { + AppenderOrSprinter() { this.hasQualifiedName("fmt", ["Append", "Sprint"] + ["", "f", "ln"]) } override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { inp.isParameter(_) and outp.isResult() } } + /** The `Sprint` function or one of its variants. */ + class Sprinter extends AppenderOrSprinter { + Sprinter() { this.getName().matches("Sprint%") } + } + /** The `Print` function or one of its variants. */ class Printer extends Function { Printer() { this.hasQualifiedName("fmt", ["Print", "Printf", "Println"]) } diff --git a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql index 17bb0314255..72fcd16059c 100644 --- a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql +++ b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql @@ -106,7 +106,7 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration { TaintTracking::referenceStep(pred, succ) or // Propagate across Sprintf and similar calls - any(Fmt::Sprinter s).taintStep(pred, succ) + any(Fmt::AppenderOrSprinter s).taintStep(pred, succ) } predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) { diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Fmt.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Fmt.go index 53feb714802..61df2336701 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Fmt.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Fmt.go @@ -1,4 +1,5 @@ -// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT. +// Code generated by https://github.com/gagliardetto/codebox, with manual additions for +// go 1.19's new Append[f, ln] functions. package main @@ -99,6 +100,52 @@ func TaintStepTest_FmtSprintln_B0I0O0(sourceCQL interface{}) interface{} { return intoString631 } +func TaintStepTest_FmtAppend_B0I0O0(sourceCQL interface{}) interface{} { + fromInterface494 := sourceCQL.(interface{}) + buf := make([]byte, 4) + intoString873 := fmt.Append(buf, fromInterface494) + return intoString873 +} + +func TaintStepTest_FmtAppendf_B0I0O0(sourceCQL interface{}) interface{} { + fromString599 := sourceCQL.(string) + buf := make([]byte, 4) + intoString409 := fmt.Appendf(buf, fromString599, nil) + return intoString409 +} + +func TaintStepTest_FmtAppendf_B0I1O0(sourceCQL interface{}) interface{} { + fromInterface246 := sourceCQL.(interface{}) + buf := make([]byte, 4) + intoString898 := fmt.Appendf(buf, "", fromInterface246) + return intoString898 +} + +func TaintStepTest_FmtAppendln_B0I0O0(sourceCQL interface{}) interface{} { + fromInterface598 := sourceCQL.([]byte) + intoString631 := fmt.Appendln(fromInterface598, "clean") + return intoString631 +} + +func TaintStepTest_FmtAppend_B0I0O0_buftest(sourceCQL interface{}) interface{} { + fromInterface494 := sourceCQL.([]byte) + intoString873 := fmt.Append(fromInterface494, "clean") + return intoString873 +} + +func TaintStepTest_FmtAppendf_B0I0O0_buftest(sourceCQL interface{}) interface{} { + fromString599 := sourceCQL.([]byte) + intoString409 := fmt.Appendf(fromString599, "%p", nil) + return intoString409 +} + +func TaintStepTest_FmtAppendln_B0I0O0_buftest(sourceCQL interface{}) interface{} { + fromInterface598 := sourceCQL.(interface{}) + buf := make([]byte, 4) + intoString631 := fmt.Appendln(buf, fromInterface598) + return intoString631 +} + func TaintStepTest_FmtSscan_B0I0O0(sourceCQL interface{}) interface{} { fromString165 := sourceCQL.(string) var intoInterface150 interface{} @@ -275,4 +322,39 @@ func RunAllTaints_Fmt() { out := TaintStepTest_FmtStateWrite_B0I0O0(source) sink(22, out) } + { + source := newSource(23) + out := TaintStepTest_FmtAppend_B0I0O0(source) + sink(23, out) + } + { + source := newSource(24) + out := TaintStepTest_FmtAppendf_B0I0O0(source) + sink(24, out) + } + { + source := newSource(25) + out := TaintStepTest_FmtAppendf_B0I1O0(source) + sink(25, out) + } + { + source := newSource(26) + out := TaintStepTest_FmtAppendln_B0I0O0(source) + sink(26, out) + } + { + source := newSource(27) + out := TaintStepTest_FmtAppend_B0I0O0_buftest(source) + sink(27, out) + } + { + source := newSource(28) + out := TaintStepTest_FmtAppendf_B0I0O0_buftest(source) + sink(28, out) + } + { + source := newSource(29) + out := TaintStepTest_FmtAppendln_B0I0O0_buftest(source) + sink(29, out) + } } From 45f922b3f2fd7d653aea4e5e47413692ddff8765 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 18 Aug 2022 19:03:46 +0100 Subject: [PATCH 071/659] Add models for Go 1.19's new url.JoinPath and URL.JoinPath functions --- go/ql/lib/semmle/go/frameworks/Stdlib.qll | 19 ++++++++++++++++++ .../dataflow/FlowSteps/LocalFlowStep.expected | 20 +++++++++++++++++++ .../FlowSteps/LocalTaintStep.expected | 18 +++++++++++++++++ .../semmle/go/dataflow/FlowSteps/url.go | 13 ++++++++++++ 4 files changed, 70 insertions(+) diff --git a/go/ql/lib/semmle/go/frameworks/Stdlib.qll b/go/ql/lib/semmle/go/frameworks/Stdlib.qll index c351ce23335..8d520d6e0ca 100644 --- a/go/ql/lib/semmle/go/frameworks/Stdlib.qll +++ b/go/ql/lib/semmle/go/frameworks/Stdlib.qll @@ -170,6 +170,25 @@ module URL { } } + /** The `JoinPath` function. */ + class JoinPath extends TaintTracking::FunctionModel { + JoinPath() { this.hasQualifiedName("net/url", "JoinPath") } + + override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { + inp.isParameter(_) and outp.isResult(0) + } + } + + /** The method `URL.JoinPath`. */ + class JoinPathMethod extends TaintTracking::FunctionModel, Method { + JoinPathMethod() { this.hasQualifiedName("net/url", "URL", "JoinPath") } + + override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { + (inp.isReceiver() or inp.isParameter(_)) and + outp.isResult(0) + } + } + /** A method that returns a part of a URL. */ class UrlGetter extends TaintTracking::FunctionModel, Method { UrlGetter() { diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected index 7f049c6e057..abfb7918d15 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalFlowStep.expected @@ -2,9 +2,15 @@ | file://:0:0:0:0 | function EscapedPath | url.go:28:14:28:26 | selection of EscapedPath | | file://:0:0:0:0 | function Get | url.go:52:14:52:18 | selection of Get | | file://:0:0:0:0 | function Hostname | url.go:29:14:29:23 | selection of Hostname | +| file://:0:0:0:0 | function JoinPath | url.go:57:16:57:27 | selection of JoinPath | +| file://:0:0:0:0 | function JoinPath | url.go:58:16:58:27 | selection of JoinPath | +| file://:0:0:0:0 | function JoinPath | url.go:60:15:60:28 | selection of JoinPath | +| file://:0:0:0:0 | function JoinPath | url.go:66:9:66:25 | selection of JoinPath | | file://:0:0:0:0 | function MarshalBinary | url.go:30:11:30:25 | selection of MarshalBinary | | file://:0:0:0:0 | function Parse | url.go:23:10:23:18 | selection of Parse | | file://:0:0:0:0 | function Parse | url.go:32:9:32:15 | selection of Parse | +| file://:0:0:0:0 | function Parse | url.go:59:14:59:22 | selection of Parse | +| file://:0:0:0:0 | function Parse | url.go:65:17:65:25 | selection of Parse | | file://:0:0:0:0 | function ParseQuery | url.go:50:10:50:23 | selection of ParseQuery | | file://:0:0:0:0 | function ParseRequestURI | url.go:27:9:27:27 | selection of ParseRequestURI | | file://:0:0:0:0 | function Password | url.go:43:11:43:21 | selection of Password | @@ -164,3 +170,17 @@ | url.go:50:2:50:2 | definition of v | url.go:52:14:52:14 | v | | url.go:50:2:50:2 | definition of v | url.go:53:9:53:9 | v | | url.go:50:2:50:26 | ... := ...[0] | url.go:50:2:50:2 | definition of v | +| url.go:56:12:56:12 | argument corresponding to q | url.go:56:12:56:12 | definition of q | +| url.go:56:12:56:12 | definition of q | url.go:57:29:57:29 | q | +| url.go:57:2:57:8 | definition of joined1 | url.go:58:38:58:44 | joined1 | +| url.go:57:2:57:39 | ... := ...[0] | url.go:57:2:57:8 | definition of joined1 | +| url.go:58:2:58:8 | definition of joined2 | url.go:59:24:59:30 | joined2 | +| url.go:58:2:58:45 | ... := ...[0] | url.go:58:2:58:8 | definition of joined2 | +| url.go:59:2:59:6 | definition of asUrl | url.go:60:15:60:19 | asUrl | +| url.go:59:2:59:31 | ... := ...[0] | url.go:59:2:59:6 | definition of asUrl | +| url.go:60:2:60:10 | definition of joinedUrl | url.go:61:9:61:17 | joinedUrl | +| url.go:60:15:60:37 | call to JoinPath | url.go:60:2:60:10 | definition of joinedUrl | +| url.go:64:13:64:13 | argument corresponding to q | url.go:64:13:64:13 | definition of q | +| url.go:64:13:64:13 | definition of q | url.go:66:27:66:27 | q | +| url.go:65:2:65:9 | definition of cleanUrl | url.go:66:9:66:16 | cleanUrl | +| url.go:65:2:65:48 | ... := ...[0] | url.go:65:2:65:9 | definition of cleanUrl | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected index 30f26fbef39..1397e71759d 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/LocalTaintStep.expected @@ -66,3 +66,21 @@ | url.go:50:25:50:25 | q | url.go:50:2:50:26 | ... := ...[0] | | url.go:51:14:51:14 | v | url.go:51:14:51:23 | call to Encode | | url.go:52:14:52:14 | v | url.go:52:14:52:26 | call to Get | +| url.go:57:16:57:39 | call to JoinPath | url.go:57:2:57:39 | ... := ...[0] | +| url.go:57:16:57:39 | call to JoinPath | url.go:57:2:57:39 | ... := ...[1] | +| url.go:57:29:57:29 | q | url.go:57:2:57:39 | ... := ...[0] | +| url.go:57:32:57:38 | "clean" | url.go:57:2:57:39 | ... := ...[0] | +| url.go:58:16:58:45 | call to JoinPath | url.go:58:2:58:45 | ... := ...[0] | +| url.go:58:16:58:45 | call to JoinPath | url.go:58:2:58:45 | ... := ...[1] | +| url.go:58:29:58:35 | "clean" | url.go:58:2:58:45 | ... := ...[0] | +| url.go:58:38:58:44 | joined1 | url.go:58:2:58:45 | ... := ...[0] | +| url.go:59:14:59:31 | call to Parse | url.go:59:2:59:31 | ... := ...[0] | +| url.go:59:14:59:31 | call to Parse | url.go:59:2:59:31 | ... := ...[1] | +| url.go:59:24:59:30 | joined2 | url.go:59:2:59:31 | ... := ...[0] | +| url.go:60:15:60:19 | asUrl | url.go:60:15:60:37 | call to JoinPath | +| url.go:60:30:60:36 | "clean" | url.go:60:15:60:37 | call to JoinPath | +| url.go:65:17:65:48 | call to Parse | url.go:65:2:65:48 | ... := ...[0] | +| url.go:65:17:65:48 | call to Parse | url.go:65:2:65:48 | ... := ...[1] | +| url.go:65:27:65:47 | "http://harmless.org" | url.go:65:2:65:48 | ... := ...[0] | +| url.go:66:9:66:16 | cleanUrl | url.go:66:9:66:28 | call to JoinPath | +| url.go:66:27:66:27 | q | url.go:66:9:66:28 | call to JoinPath | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go index da3df63faea..3781349fa3e 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go @@ -52,3 +52,16 @@ func func8(q string) url.Values { fmt.Println(v.Get("page")) return v } + +func func9(q string) *url.URL { + joined1, _ := url.JoinPath(q, "clean") + joined2, _ := url.JoinPath("clean", joined1) + asUrl, _ := url.Parse(joined2) + joinedUrl := asUrl.JoinPath("clean") + return joinedUrl +} + +func func10(q string) *url.URL { + cleanUrl, _ := url.Parse("http://harmless.org") + return cleanUrl.JoinPath(q) +} \ No newline at end of file From e2afc80aff9efafbbec4033abe36eb86823042ac Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 19 Aug 2022 10:29:23 +0100 Subject: [PATCH 072/659] Autoformat go --- go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go index 3781349fa3e..70d4941f644 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/FlowSteps/url.go @@ -64,4 +64,4 @@ func func9(q string) *url.URL { func func10(q string) *url.URL { cleanUrl, _ := url.Parse("http://harmless.org") return cleanUrl.JoinPath(q) -} \ No newline at end of file +} From 949de2a8dd8b472ca96b527cc91b570785cb68c8 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 19 Aug 2022 11:15:23 +0100 Subject: [PATCH 073/659] Create 2022-08-19-java-19-support.md --- java/ql/lib/change-notes/2022-08-19-java-19-support.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-08-19-java-19-support.md diff --git a/java/ql/lib/change-notes/2022-08-19-java-19-support.md b/java/ql/lib/change-notes/2022-08-19-java-19-support.md new file mode 100644 index 00000000000..5cf26dec89f --- /dev/null +++ b/java/ql/lib/change-notes/2022-08-19-java-19-support.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Java 19 builds can now be extracted. There are no non-preview new language features in this release, so the only user-visible change is that the CodeQL extractor will now correctly trace compilations using the JDK 19 release of `javac`. From b0fbe3658dc9e6c54daac0f2bc801a7bfb7441b1 Mon Sep 17 00:00:00 2001 From: Sebastian Bauersfeld <> Date: Thu, 18 Aug 2022 15:02:35 +0700 Subject: [PATCH 074/659] Add java.lang.String taint tests. --- .../test/library-tests/dataflow/taint/B.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/java/ql/test/library-tests/dataflow/taint/B.java b/java/ql/test/library-tests/dataflow/taint/B.java index 94a09dd915f..f8ea5a6ffe2 100644 --- a/java/ql/test/library-tests/dataflow/taint/B.java +++ b/java/ql/test/library-tests/dataflow/taint/B.java @@ -189,4 +189,32 @@ public class B { public static boolean safe() { return true; } + + public static void extendedTests(){ + String s = taint()[0]; + + String replReceiver = s.replace("irrelevant", "irrelevant"); + sink(replReceiver); + + String replChar = "a".replace('a', s.charAt(0)); + sink(replChar); + + String replCharReceiver = s.replace('a', 'b'); + sink(replCharReceiver); + + String charAt = ""; + for(int i = 0; i < 10; i++) + charAt = charAt + s.charAt(i); + sink(charAt); + + byte[] bytes = new byte[10]; + s.getBytes(0, 1, bytes, 0); + sink(bytes); + + String replAll = s.replaceAll("irrelevant", "irrelevant"); + sink(replAll); + + String replFirst = s.replaceFirst("irrelevant", "irrelevant"); + sink(replFirst); + } } From 5cf320d553d4afedd5ee37b7f4ade0791848f721 Mon Sep 17 00:00:00 2001 From: Sebastian Bauersfeld <> Date: Thu, 18 Aug 2022 15:27:13 +0700 Subject: [PATCH 075/659] Add corresponding taint steps. --- java/ql/lib/semmle/code/java/frameworks/Strings.qll | 5 +++++ java/ql/test/library-tests/dataflow/taint/test.expected | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/java/ql/lib/semmle/code/java/frameworks/Strings.qll b/java/ql/lib/semmle/code/java/frameworks/Strings.qll index 63c83d0157d..620f464cfa4 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Strings.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Strings.qll @@ -20,10 +20,14 @@ private class StringSummaryCsv extends SummaryModelCsv { "java.lang;String;false;formatted;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual", "java.lang;String;false;getChars;;;Argument[-1];Argument[2];taint;manual", "java.lang;String;false;getBytes;;;Argument[-1];ReturnValue;taint;manual", + "java.lang;String;false;getBytes;;;Argument[-1];Argument[2];taint;manual", "java.lang;String;false;indent;;;Argument[-1];ReturnValue;taint;manual", "java.lang;String;false;intern;;;Argument[-1];ReturnValue;taint;manual", "java.lang;String;false;join;;;Argument[0..1];ReturnValue;taint;manual", "java.lang;String;false;repeat;(int);;Argument[-1];ReturnValue;taint;manual", + "java.lang;String;false;replace;;;Argument[-1];ReturnValue;taint;manual", + "java.lang;String;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual", + "java.lang;String;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual", "java.lang;String;false;split;;;Argument[-1];ReturnValue;taint;manual", "java.lang;String;false;String;;;Argument[0];Argument[-1];taint;manual", "java.lang;String;false;strip;;;Argument[-1];ReturnValue;taint;manual", @@ -55,6 +59,7 @@ private class StringSummaryCsv extends SummaryModelCsv { "java.lang;StringBuffer;true;StringBuffer;(CharSequence);;Argument[0];Argument[-1];taint;manual", "java.lang;StringBuffer;true;StringBuffer;(String);;Argument[0];Argument[-1];taint;manual", "java.lang;StringBuilder;true;StringBuilder;;;Argument[0];Argument[-1];taint;manual", + "java.lang;CharSequence;true;charAt;;;Argument[-1];ReturnValue;taint;manual", "java.lang;CharSequence;true;subSequence;;;Argument[-1];ReturnValue;taint;manual", "java.lang;CharSequence;true;toString;;;Argument[-1];ReturnValue;taint;manual" ] diff --git a/java/ql/test/library-tests/dataflow/taint/test.expected b/java/ql/test/library-tests/dataflow/taint/test.expected index 451248e18c0..8b7d85321b4 100644 --- a/java/ql/test/library-tests/dataflow/taint/test.expected +++ b/java/ql/test/library-tests/dataflow/taint/test.expected @@ -43,6 +43,13 @@ | B.java:15:21:15:27 | taint(...) | B.java:157:10:157:46 | toFile(...) | | B.java:15:21:15:27 | taint(...) | B.java:160:10:160:46 | getAbsoluteFile(...) | | B.java:15:21:15:27 | taint(...) | B.java:163:10:163:47 | getCanonicalFile(...) | +| B.java:194:16:194:22 | taint(...) | B.java:197:10:197:21 | replReceiver | +| B.java:194:16:194:22 | taint(...) | B.java:200:10:200:17 | replChar | +| B.java:194:16:194:22 | taint(...) | B.java:203:10:203:25 | replCharReceiver | +| B.java:194:16:194:22 | taint(...) | B.java:208:10:208:15 | charAt | +| B.java:194:16:194:22 | taint(...) | B.java:212:10:212:14 | bytes | +| B.java:194:16:194:22 | taint(...) | B.java:215:10:215:16 | replAll | +| B.java:194:16:194:22 | taint(...) | B.java:218:10:218:18 | replFirst | | CharSeq.java:7:26:7:32 | taint(...) | CharSeq.java:8:12:8:14 | seq | | CharSeq.java:7:26:7:32 | taint(...) | CharSeq.java:11:12:11:21 | seqFromSeq | | CharSeq.java:7:26:7:32 | taint(...) | CharSeq.java:14:12:14:24 | stringFromSeq | From 354a7fd252966aea0cb21a4d464d7667f67d11eb Mon Sep 17 00:00:00 2001 From: Sebastian Bauersfeld <> Date: Thu, 18 Aug 2022 15:41:10 +0700 Subject: [PATCH 076/659] Make taint flow through java.lang.String.(replace|replaceFirst|replaceAll) more permissive. --- .../dataflow/internal/TaintTrackingUtil.qll | 24 +------------------ .../semmle/code/java/frameworks/Strings.qll | 3 +++ .../test/library-tests/dataflow/taint/B.java | 2 +- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index e00dee7c8dd..d52b340e67a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -251,7 +251,7 @@ private predicate qualifierToArgumentStep(Expr tracked, Expr sink) { /** Access to a method that passes taint from the qualifier. */ private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) { - (taintPreservingQualifierToMethod(sink.getMethod()) or unsafeEscape(sink)) and + taintPreservingQualifierToMethod(sink.getMethod()) and tracked = sink.getQualifier() } @@ -282,28 +282,6 @@ private predicate taintPreservingQualifierToMethod(Method m) { ) } -private class StringReplaceMethod extends TaintPreservingCallable { - StringReplaceMethod() { - this.getDeclaringType() instanceof TypeString and - ( - this.hasName("replace") or - this.hasName("replaceAll") or - this.hasName("replaceFirst") - ) - } - - override predicate returnsTaintFrom(int arg) { arg = 1 } -} - -private predicate unsafeEscape(MethodAccess ma) { - // Removing `
  • + Mobile Security Testing Guide. +